Applied #10362: wxMac's wxSound doesn't work

By Cyball


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@62181 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2009-09-28 08:12:24 +00:00
parent 1a956a9823
commit d8813f69c8
3 changed files with 75 additions and 161 deletions

View File

@@ -21,20 +21,23 @@ class WXDLLEXPORT wxSound : public wxSoundBase
{ {
public: public:
wxSound(); wxSound();
wxSound(const wxString& fileName, bool isResource = FALSE); wxSound(const wxString& fileName, bool isResource = false);
wxSound(int size, const wxByte* data); wxSound(int size, const wxByte* data);
virtual ~wxSound(); virtual ~wxSound();
public: public:
bool Create(const wxString& fileName, bool isResource = FALSE); bool Create(const wxString& fileName, bool isResource = false);
bool IsOk() const { return !m_sndname.IsEmpty(); } bool IsOk() const { return !m_sndname.IsEmpty() || m_hSnd; }
static void Stop(); static void Stop();
static bool IsPlaying(); static bool IsPlaying();
void* GetHandle(); void* GetHandle();
protected: protected:
bool DoPlay(unsigned flags) const; bool DoPlay(unsigned flags) const;
public:
#if wxABI_VERSION >= 20811
bool Create(int size, const wxByte* data);
#endif
private: private:
wxString m_sndname; //file path wxString m_sndname; //file path
char* m_hSnd; //pointer to resource or memory location char* m_hSnd; //pointer to resource or memory location

View File

@@ -224,7 +224,6 @@ MyFrame::MyFrame(const wxString& title)
bool MyFrame::CreateSound(wxSound& snd) const bool MyFrame::CreateSound(wxSound& snd) const
{ {
#ifndef __WXMAC__
if ( m_useMemory ) if ( m_useMemory )
{ {
// this is the dump of cuckoo.wav // this is the dump of cuckoo.wav
@@ -957,7 +956,6 @@ bool MyFrame::CreateSound(wxSound& snd) const
return snd.Create(sizeof(data), data); return snd.Create(sizeof(data), data);
} }
#endif // !__WXMAC__
#ifdef __WXMSW__ #ifdef __WXMSW__
if ( !m_soundRes.empty() ) if ( !m_soundRes.empty() )

View File

@@ -86,6 +86,7 @@ static bool lastSoundIsPlaying=false;
#endif #endif
#if USE_QUICKTIME #if USE_QUICKTIME
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// wxQTTimer - Handle Asyncronous Playing // wxQTTimer - Handle Asyncronous Playing
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@@ -154,65 +155,6 @@ public:
}; };
class wxSMTimer : public wxTimer
{
public:
wxSMTimer(void* hSnd, void* pSndChannel, bool bLoop, bool* playing)
: m_hSnd(hSnd), m_pSndChannel(pSndChannel), m_bLoop(bLoop), m_pbPlaying(playing)
{
}
virtual ~wxSMTimer()
{
if(m_pbPlaying)
*m_pbPlaying = false;
SndDisposeChannel((SndChannelPtr)m_pSndChannel, TRUE);
Stop();
}
void Notify()
{
if (m_pbPlaying && !*m_pbPlaying)
{
Shutdown();
}
SCStatus stat;
if (SndChannelStatus((SndChannelPtr)m_pSndChannel, sizeof(SCStatus), &stat) != 0)
Shutdown();
//if the sound isn't playing anymore, see if it's looped,
//and if so play it again, otherwise close things up
if (stat.scChannelBusy == FALSE)
{
if (m_bLoop)
{
if(SndPlay((SndChannelPtr)m_pSndChannel, (SndListHandle) m_hSnd, true) != noErr)
Shutdown();
}
else
Shutdown();
}
}
void Shutdown()
{
delete this;
}
void* GetChannel() {return m_pSndChannel;}
protected:
void* m_hSnd;
void* m_pSndChannel;
bool m_bLoop;
public:
bool* m_pbPlaying;
};
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// wxSound // wxSound
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@@ -265,8 +207,9 @@ wxSound::wxSound(const wxString& sFileName, bool isResource)
} }
wxSound::wxSound(int size, const wxByte* data) wxSound::wxSound(int size, const wxByte* data)
: m_hSnd((char*)data), m_waveLength(size), m_pTimer(NULL), m_type(wxSound_MEMORY) : m_hSnd(NULL), m_waveLength(0), m_pTimer(NULL), m_type(wxSound_NONE)
{ {
Create(size, data);
} }
wxSound::~wxSound() wxSound::~wxSound()
@@ -277,19 +220,25 @@ bool wxSound::Create(const wxString& fileName, bool isResource)
{ {
Stop(); Stop();
m_sndname.Empty();
if (isResource) if (isResource)
{ {
#ifdef __WXMAC__ #ifdef __WXMAC__
m_type = wxSound_RESOURCE; CFURLRef url;
CFStringRef path;
Str255 lpSnd ; url = CFBundleCopyResourceURL(CFBundleGetMainBundle(),
wxMacCFStringHolder(fileName,wxLocale::GetSystemEncoding()),
wxMacStringToPascal( fileName , lpSnd ) ; NULL,
NULL);
m_sndname = fileName; if (url)
m_hSnd = (char*) GetNamedResource('snd ', (const unsigned char *) lpSnd); {
#else path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
return false; CFRelease(url);
m_type = wxSound_FILE;
m_sndname = wxMacCFStringHolder(path).AsString(wxLocale::GetSystemEncoding());
}
#endif #endif
} }
else else
@@ -298,6 +247,15 @@ bool wxSound::Create(const wxString& fileName, bool isResource)
m_sndname = fileName; m_sndname = fileName;
} }
return !m_sndname.IsEmpty();
}
bool wxSound::Create(int size, const wxByte* data)
{
m_hSnd = (char *)data;
m_waveLength = size;
m_type = wxSound_MEMORY;
return true; return true;
} }
@@ -308,107 +266,70 @@ bool wxSound::DoPlay(unsigned flags) const
#if USE_QUICKTIME #if USE_QUICKTIME
Movie movie; Movie movie;
Handle dataRef = nil;
OSType dataRefType;
OSErr err = noErr;
if (!wxInitQT())
return false;
switch(m_type) switch(m_type)
{ {
case wxSound_MEMORY: case wxSound_MEMORY:
{ {
if (!wxInitQT()) Handle myHandle = nil;
return false; unsigned long type;
Handle myHandle, dataRef = nil; unsigned long atoms[5];
MovieImportComponent miComponent;
Track targetTrack = nil;
TimeValue addedDuration = 0;
long outFlags = 0;
OSErr err;
ComponentResult result;
myHandle = NewHandleClear((Size)m_waveLength);
BlockMove(m_hSnd, *myHandle, m_waveLength);
err = PtrToHand(&myHandle, &dataRef, sizeof(Handle));
if (memcmp(&m_hSnd[8], "WAVE", 4) == 0) if (memcmp(&m_hSnd[8], "WAVE", 4) == 0)
miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeWave); type = kQTFileTypeWave;
else if (memcmp(&m_hSnd[8], "AIFF", 4) == 0) else if (memcmp(&m_hSnd[8], "AIFF", 4) == 0)
miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFF); type = kQTFileTypeAIFF;
else if (memcmp(&m_hSnd[8], "AIFC", 4) == 0) else if (memcmp(&m_hSnd[8], "AIFC", 4) == 0)
miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFC); type = kQTFileTypeAIFC;
else else
{ {
wxLogSysError(wxT("wxSound - Location in memory does not contain valid data")); wxLogSysError(wxT("wxSound - Location in memory does not contain valid data"));
return false; return false;
} }
movie = NewMovie(0); atoms[0] = EndianU32_NtoB(sizeof(long) * 3);
atoms[1] = EndianU32_NtoB(kDataRefExtensionMacOSFileType);
atoms[2] = EndianU32_NtoB(type);
atoms[3] = EndianU32_NtoB(sizeof(long) * 2 + m_waveLength);
atoms[4] = EndianU32_NtoB(kDataRefExtensionInitializationData);
result = MovieImportDataRef(miComponent, dataRef, err = 0;
HandleDataHandlerSubType, movie, err |= PtrToHand(&myHandle, &dataRef, sizeof(Handle));
nil, &targetTrack, err |= PtrAndHand("\p", dataRef, 1);
nil, &addedDuration, err |= PtrAndHand(atoms, dataRef, sizeof(long) * 5);
movieImportCreateTrack, &outFlags); err |= PtrAndHand(m_hSnd, dataRef, m_waveLength);
if (result != noErr) dataRefType = HandleDataHandlerSubType;
{
wxLogSysError(wxString::Format(wxT("Couldn't import movie data\nError:%i"), (int)result));
}
SetMovieVolume(movie, kFullVolume);
GoToBeginningOfMovie(movie);
DisposeHandle(myHandle);
}
break;
case wxSound_RESOURCE:
{
SoundComponentData data;
unsigned long numframes, offset;
ParseSndHeader((SndListHandle)m_hSnd, &data, &numframes, &offset);
//m_waveLength = numFrames * data.numChannels;
SndChannelPtr pSndChannel;
SndNewChannel(&pSndChannel, sampledSynth,
initNoInterp
+ (data.numChannels == 1 ? initMono : initStereo), NULL);
if(SndPlay(pSndChannel, (SndListHandle) m_hSnd, flags & wxSOUND_ASYNC ? 1 : 0) != noErr)
return false;
if (flags & wxSOUND_ASYNC)
{
lastSoundTimer = ((wxSMTimer*&)m_pTimer)
= new wxSMTimer(pSndChannel, m_hSnd, flags & wxSOUND_LOOP ? 1 : 0,
&lastSoundIsPlaying);
lastSoundIsPlaying = true;
((wxTimer*)m_pTimer)->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
}
else
SndDisposeChannel(pSndChannel, TRUE);
return true;
} }
break; break;
case wxSound_FILE: case wxSound_FILE:
{ {
if (!wxInitQT())
return false;
OSErr err = noErr ;
Handle dataRef = NULL;
OSType dataRefType;
err = QTNewDataReferenceFromFullPathCFString(wxMacCFStringHolder(m_sndname,wxLocale::GetSystemEncoding()), err = QTNewDataReferenceFromFullPathCFString(wxMacCFStringHolder(m_sndname,wxLocale::GetSystemEncoding()),
(UInt32)kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType); (UInt32)kQTNativeDefaultPathStyle,
0,
&dataRef,
&dataRefType);
}
break;
default:
return false;
}//end switch(m_type)
wxASSERT(err == noErr); wxASSERT(err == noErr);
if (NULL != dataRef || err != noErr) if (NULL != dataRef || err != noErr)
{ {
err = NewMovieFromDataRef( &movie, newMovieDontAskUnresolvedDataRefs , NULL, dataRef, dataRefType ); err = NewMovieFromDataRef(&movie,
0,
nil,
dataRef,
dataRefType);
wxASSERT(err == noErr); wxASSERT(err == noErr);
DisposeHandle(dataRef); DisposeHandle(dataRef);
} }
@@ -416,17 +337,13 @@ bool wxSound::DoPlay(unsigned flags) const
if (err != noErr) if (err != noErr)
{ {
wxLogSysError( wxLogSysError(
wxString::Format(wxT("wxSound - Could not open file: %s\nError:%i"), m_sndname.c_str(), err ) wxString::Format(wxT("wxSound - Could not create movie\nError:%i"), err)
); );
return false; return false;
} }
}
break;
default:
return false;
}//end switch(m_type)
//Start the movie! SetMovieVolume(movie, kFullVolume);
GoToBeginningOfMovie(movie);
StartMovie(movie); StartMovie(movie);
if (flags & wxSOUND_ASYNC) if (flags & wxSOUND_ASYNC)
@@ -473,12 +390,8 @@ void wxSound::Stop()
void* wxSound::GetHandle() void* wxSound::GetHandle()
{ {
#if USE_QUICKTIME #if USE_QUICKTIME
if(m_type == wxSound_RESOURCE)
return (void*) ((wxSMTimer*)m_pTimer)->GetChannel();
return (void*) ((wxQTTimer*) m_pTimer)->GetMovie(); return (void*) ((wxQTTimer*) m_pTimer)->GetMovie();
#endif #endif
return NULL; return NULL;
} }
#endif //wxUSE_SOUND #endif //wxUSE_SOUND