1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/mac/classic/sound.cpp
3// Purpose:     wxSound class implementation: optional
4// Author:      Stefan Csomor
5// Modified by:
6// Created:     1998-01-01
7// RCS-ID:      $Id: sound.cpp 38885 2006-04-24 08:46:59Z ABX $
8// Copyright:   (c) Stefan Csomor
9// Licence:     wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#if wxUSE_SOUND
16
17#include "wx/sound.h"
18
19#ifndef WX_PRECOMP
20    #include "wx/object.h"
21    #include "wx/string.h"
22#endif
23
24#ifdef __WXMAC__
25#include "wx/mac/private.h"
26#ifndef __DARWIN__
27#include <Sound.h>
28#endif
29#endif
30
31wxSound::wxSound()
32  : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
33{
34}
35
36wxSound::wxSound(const wxString& sFileName, bool isResource)
37  : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
38{
39    Create(sFileName, isResource);
40}
41
42
43wxSound::~wxSound()
44{
45    FreeData();
46}
47
48wxSound::wxSound(int size, const wxByte* data)
49  : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(false)
50{
51    //TODO convert data
52}
53
54bool wxSound::Create(const wxString& fileName, bool isResource)
55{
56    bool ret = false;
57    m_sndname = fileName;
58    m_isResource = isResource;
59
60    if (m_isResource)
61        ret = true;
62    else
63    { /*
64        if (sndChan)
65        {                                                                    // we're playing
66            FSClose(SndRefNum);
67            SndRefNum = 0;
68            SndDisposeChannel(sndChan, TRUE);
69            free(sndChan);
70            sndChan = 0;
71            KillTimer(0,timerID);
72        }
73
74        if (!lpSnd)
75            return true;
76
77        if (_access(lpSnd,0))                            // no file, no service
78            return false;
79
80        // Allocate SndChannel
81        sndChan = (SndChannelPtr) malloc (sizeof(SndChannel));
82
83        if (!sndChan)
84            return false;
85
86        sndChan->qLength = 128;
87
88        if (noErr != SndNewChannel (&sndChan, sampledSynth, initMono | initNoInterp, 0))
89        {
90            free(sndChan);
91            sndChan = 0;
92            return false;
93        }
94
95        if (!(SndRefNum = MacOpenSndFile ((char *)lpSnd)))
96        {
97            SndDisposeChannel(sndChan, TRUE);
98            free(sndChan);
99            sndChan = 0;
100
101            return false;
102        }
103
104        bool async = false;
105
106        if (fdwSound & SND_ASYNC)
107            async = true;
108
109        if (SndStartFilePlay(sndChan, SndRefNum, 0, 81920, 0, 0, 0, async) != noErr)
110        {
111            FSClose (SndRefNum);
112            SndRefNum = 0;
113            SndDisposeChannel (sndChan, TRUE);
114            free (sndChan);
115            sndChan = 0;
116            return false;
117        }
118
119        if (async)
120        {  // haven't finish yet
121            timerID = SetTimer(0, 0, 250, TimerCallBack);
122        }
123        else
124        {
125            FSClose (SndRefNum);
126            SndRefNum = 0;
127            SndDisposeChannel (sndChan, TRUE);
128            free (sndChan);
129            sndChan = 0;
130        }*/
131    }
132
133    return ret;
134}
135
136
137//don't know what to do with looped, wth
138bool wxSound::DoPlay(unsigned flags) const
139{
140    bool ret = false;
141
142    if (m_isResource)
143    {
144        Str255 snd ;
145        wxMacStringToPascal( m_sndname , snd ) ;
146        SndListHandle hSnd;
147
148        hSnd = (SndListHandle) GetNamedResource('snd ', snd);
149
150        if ((hSnd != NULL) && (SndPlay((SndChannelPtr)m_sndChan, (SndListHandle) hSnd, (flags & wxSOUND_ASYNC)) == noErr))
151            ret = true;
152    }
153
154    return ret;
155}
156
157
158bool wxSound::FreeData()
159{
160    bool ret = false;
161
162    if (m_isResource)
163    {
164        m_sndname.Empty();
165        ret = true;
166    }
167    else
168    {
169        //TODO,
170    }
171
172    return ret;
173}
174
175
176//code below is from an old implementation used for telinfo with MSVC crossplatform support
177//technology proceeds, so it would be the wisest to drop this code, but it's left here just
178//for the sake of a reference. BTW: Wave files can now be played with QT, starting from V3
179
180/*static short MacOpenSndFile (char * path)
181{
182    VolumeParam vp;
183    FSSpec fspec;
184    Str255 name;
185    char *c;
186
187    // first, get the volume reference number for the file.  Start by
188    // making a Pstring with just the volume name
189    strcpy ((char *) name, path);
190    if (c = strchr ((char *) name, ':'))
191    {
192        c++;
193        *c = '\0';
194    }
195
196    c2pstr ((char *) name);
197    vp.ioCompletion = 0;
198    vp.ioVolIndex    = -1;
199    vp.ioNamePtr    = name;
200    vp.ioVRefNum    = 0;
201
202    if (PBGetVInfo((ParamBlockRec *)&vp, 0) != noErr)
203        return 0;
204
205    // next, buld an FSSpec for the file
206    strcpy ((char *) name, path);
207    c2pstr ((char *) name);
208    if (FSMakeFSSpec (vp.ioVRefNum, 0, name, &fspec) != noErr)
209        return 0;
210
211    short frefnum;
212    // now open the file, and return it's reference number
213    if (FSpOpenDF(&fspec, fsRdPerm, &frefnum) != noErr)
214        return 0;
215
216    return frefnum;
217}
218
219
220void TimerCallBack(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
221{
222    if(!sndChan)
223    {
224        KillTimer(0,timerID);
225        return;
226    }
227
228    SCStatus    scstat;
229
230    if (noErr == SndChannelStatus (sndChan, sizeof (SCStatus), &scstat)) {
231        if (scstat.scChannelPaused || scstat.scChannelBusy)
232            return;                            // not done yet
233    }
234
235    // either error or done.
236    FSClose (SndRefNum);
237    SndRefNum = 0;
238    SndDisposeChannel (sndChan, TRUE);
239    free (sndChan);
240    sndChan = 0;
241    KillTimer(0,timerID);
242}*/
243
244#endif // wxUSE_SOUND
245