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:
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

View File

@@ -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() )

View File

@@ -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