From d8813f69c88c8a2fc57ad0d6e51876cc29908e41 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Mon, 28 Sep 2009 08:12:24 +0000 Subject: [PATCH] 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 --- include/wx/mac/carbon/sound.h | 11 +- samples/sound/sound.cpp | 2 - src/mac/carbon/sound.cpp | 223 +++++++++++----------------------- 3 files changed, 75 insertions(+), 161 deletions(-) diff --git a/include/wx/mac/carbon/sound.h b/include/wx/mac/carbon/sound.h index ab2555f5e9..8bb3ff232c 100644 --- a/include/wx/mac/carbon/sound.h +++ b/include/wx/mac/carbon/sound.h @@ -21,20 +21,23 @@ class WXDLLEXPORT wxSound : public wxSoundBase { public: wxSound(); - wxSound(const wxString& fileName, bool isResource = FALSE); + wxSound(const wxString& fileName, bool isResource = false); wxSound(int size, const wxByte* data); virtual ~wxSound(); public: - bool Create(const wxString& fileName, bool isResource = FALSE); - bool IsOk() const { return !m_sndname.IsEmpty(); } + bool Create(const wxString& fileName, bool isResource = false); + bool IsOk() const { return !m_sndname.IsEmpty() || m_hSnd; } static void Stop(); static bool IsPlaying(); void* GetHandle(); protected: bool DoPlay(unsigned flags) const; - +public: +#if wxABI_VERSION >= 20811 + bool Create(int size, const wxByte* data); +#endif private: wxString m_sndname; //file path char* m_hSnd; //pointer to resource or memory location diff --git a/samples/sound/sound.cpp b/samples/sound/sound.cpp index f42ba21cd8..a517d1a405 100644 --- a/samples/sound/sound.cpp +++ b/samples/sound/sound.cpp @@ -224,7 +224,6 @@ MyFrame::MyFrame(const wxString& title) bool MyFrame::CreateSound(wxSound& snd) const { -#ifndef __WXMAC__ if ( m_useMemory ) { // this is the dump of cuckoo.wav @@ -957,7 +956,6 @@ bool MyFrame::CreateSound(wxSound& snd) const return snd.Create(sizeof(data), data); } -#endif // !__WXMAC__ #ifdef __WXMSW__ if ( !m_soundRes.empty() ) diff --git a/src/mac/carbon/sound.cpp b/src/mac/carbon/sound.cpp index c99967756a..ff906c640c 100644 --- a/src/mac/carbon/sound.cpp +++ b/src/mac/carbon/sound.cpp @@ -86,6 +86,7 @@ static bool lastSoundIsPlaying=false; #endif #if USE_QUICKTIME + // ------------------------------------------------------------------ // 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 // ------------------------------------------------------------------ @@ -265,8 +207,9 @@ wxSound::wxSound(const wxString& sFileName, bool isResource) } 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() @@ -277,19 +220,25 @@ bool wxSound::Create(const wxString& fileName, bool isResource) { Stop(); + m_sndname.Empty(); + if (isResource) { #ifdef __WXMAC__ - m_type = wxSound_RESOURCE; + CFURLRef url; + CFStringRef path; - Str255 lpSnd ; - - wxMacStringToPascal( fileName , lpSnd ) ; - - m_sndname = fileName; - m_hSnd = (char*) GetNamedResource('snd ', (const unsigned char *) lpSnd); -#else - return false; + url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), + wxMacCFStringHolder(fileName,wxLocale::GetSystemEncoding()), + NULL, + NULL); + if (url) + { + path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); + CFRelease(url); + m_type = wxSound_FILE; + m_sndname = wxMacCFStringHolder(path).AsString(wxLocale::GetSystemEncoding()); + } #endif } else @@ -298,6 +247,15 @@ bool wxSound::Create(const wxString& fileName, bool isResource) 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; } @@ -308,107 +266,70 @@ bool wxSound::DoPlay(unsigned flags) const #if USE_QUICKTIME Movie movie; + Handle dataRef = nil; + OSType dataRefType; + OSErr err = noErr; + + if (!wxInitQT()) + return false; switch(m_type) { case wxSound_MEMORY: { - if (!wxInitQT()) - return false; - Handle myHandle, dataRef = nil; - 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)); + Handle myHandle = nil; + unsigned long type; + unsigned long atoms[5]; if (memcmp(&m_hSnd[8], "WAVE", 4) == 0) - miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeWave); + type = kQTFileTypeWave; else if (memcmp(&m_hSnd[8], "AIFF", 4) == 0) - miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFF); + type = kQTFileTypeAIFF; else if (memcmp(&m_hSnd[8], "AIFC", 4) == 0) - miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFC); + type = kQTFileTypeAIFC; else { wxLogSysError(wxT("wxSound - Location in memory does not contain valid data")); 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, - HandleDataHandlerSubType, movie, - nil, &targetTrack, - nil, &addedDuration, - movieImportCreateTrack, &outFlags); + err = 0; + err |= PtrToHand(&myHandle, &dataRef, sizeof(Handle)); + err |= PtrAndHand("\p", dataRef, 1); + err |= PtrAndHand(atoms, dataRef, sizeof(long) * 5); + err |= PtrAndHand(m_hSnd, dataRef, m_waveLength); - if (result != noErr) - { - 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; + dataRefType = HandleDataHandlerSubType; } break; case wxSound_FILE: - { - if (!wxInitQT()) - return false; - - OSErr err = noErr ; - - Handle dataRef = NULL; - OSType dataRefType; - + { 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); if (NULL != dataRef || err != noErr) { - err = NewMovieFromDataRef( &movie, newMovieDontAskUnresolvedDataRefs , NULL, dataRef, dataRefType ); + err = NewMovieFromDataRef(&movie, + 0, + nil, + dataRef, + dataRefType); wxASSERT(err == noErr); DisposeHandle(dataRef); } @@ -416,17 +337,13 @@ bool wxSound::DoPlay(unsigned flags) const if (err != noErr) { 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; } - } - break; - default: - return false; - }//end switch(m_type) - //Start the movie! + SetMovieVolume(movie, kFullVolume); + GoToBeginningOfMovie(movie); StartMovie(movie); if (flags & wxSOUND_ASYNC) @@ -473,12 +390,8 @@ void wxSound::Stop() void* wxSound::GetHandle() { #if USE_QUICKTIME - if(m_type == wxSound_RESOURCE) - return (void*) ((wxSMTimer*)m_pTimer)->GetChannel(); - return (void*) ((wxQTTimer*) m_pTimer)->GetMovie(); #endif return NULL; } - #endif //wxUSE_SOUND