applied patch #997019: '[wxMac] updated wxSound', adds static IsPlaying() and Stop()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@28557 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Dimitri Schoolwerth
2004-07-31 07:36:13 +00:00
parent eaca2a2cfc
commit 4b430ee141
2 changed files with 137 additions and 100 deletions

View File

@@ -2,11 +2,11 @@
// Name: sound.h // Name: sound.h
// Purpose: wxSound class (loads and plays short Windows .wav files). // Purpose: wxSound class (loads and plays short Windows .wav files).
// Optional on non-Windows platforms. // Optional on non-Windows platforms.
// Author: Stefan Csomor // Author: Ryan Norton, Stefan Csomor
// Modified by: // Modified by:
// Created: 1998-01-01 // Created: 1998-01-01
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Stefan Csomor // Copyright: (c) Ryan Norton, Stefan Csomor
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@@ -32,12 +32,11 @@ public:
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(); }
static void Stop();
static bool IsPlaying();
void* GetHandle(); void* GetHandle();
protected: protected:
// prevent collision with some BSD definitions of macro Free()
bool FreeData();
bool DoPlay(unsigned flags) const; bool DoPlay(unsigned flags) const;
private: private:

View File

@@ -1,7 +1,7 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: sound.cpp // Name: sound.cpp
// Purpose: wxSound class implementation: optional // Purpose: wxSound class implementation: optional
// Author: Ryan Norton, Stefan Csomor // Author: Ryan Norton
// Modified by: // Modified by:
// Created: 1998-01-01 // Created: 1998-01-01
// RCS-ID: $Id$ // RCS-ID: $Id$
@@ -72,34 +72,41 @@
class wxQTTimer : public wxTimer class wxQTTimer : public wxTimer
{ {
public: public:
wxQTTimer(Movie movie, bool bLoop) : wxQTTimer(Movie movie, bool bLoop, bool& playing) :
m_movie(movie), m_bLoop(bLoop) m_movie(movie), m_bLoop(bLoop), m_pbPlaying(&playing)
{ {
} }
~wxQTTimer() ~wxQTTimer()
{ {
Shutdown(); if(m_pbPlaying)
} *m_pbPlaying = false;
void Shutdown()
{
StopMovie(m_movie); StopMovie(m_movie);
DisposeMovie(m_movie); DisposeMovie(m_movie);
m_movie = NULL ;
Stop(); Stop();
//Note that ExitMovies() is not neccessary, but //Note that ExitMovies() is not neccessary, but
//the docs are fuzzy on whether or not TerminateQTML is //the docs are fuzzy on whether or not TerminateQTML is
ExitMovies(); ExitMovies();
#ifndef __WXMAC__ #ifndef __WXMAC__
TerminateQTML(); TerminateQTML();
#endif #endif
}
void Shutdown()
{
delete this;
} }
void Notify() void Notify()
{ {
if (m_pbPlaying && !*m_pbPlaying)
{
Shutdown();
}
if(IsMovieDone(m_movie)) if(IsMovieDone(m_movie))
{ {
if (!m_bLoop) if (!m_bLoop)
@@ -109,7 +116,7 @@ public:
StopMovie(m_movie); StopMovie(m_movie);
GoToBeginningOfMovie(m_movie); GoToBeginningOfMovie(m_movie);
StartMovie(m_movie); StartMovie(m_movie);
} }
} }
else else
MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie
@@ -117,61 +124,80 @@ public:
Movie& GetMovie() {return m_movie;} Movie& GetMovie() {return m_movie;}
protected: protected:
Movie m_movie; Movie m_movie;
bool m_bLoop; bool m_bLoop;
public:
bool* m_pbPlaying;
}; };
class wxSMTimer : public wxTimer class wxSMTimer : public wxTimer
{ {
public: public:
wxSMTimer(void* hSnd, void* pSndChannel, const bool& bLoop) wxSMTimer(void* hSnd, void* pSndChannel, const bool& bLoop, bool& playing)
: m_hSnd(hSnd), m_pSndChannel(pSndChannel), m_bLoop(bLoop) : m_hSnd(hSnd), m_pSndChannel(pSndChannel), m_bLoop(bLoop), m_pbPlaying(&playing)
{ {
} }
~wxSMTimer() ~wxSMTimer()
{ {
Shutdown(); if(m_pbPlaying)
} *m_pbPlaying = false;
SndDisposeChannel((SndChannelPtr)m_pSndChannel, TRUE);
Stop();
}
void Notify() void Notify()
{
if (m_pbPlaying && !*m_pbPlaying)
{ {
SCStatus stat; Shutdown();
}
SCStatus stat;
if (SndChannelStatus((SndChannelPtr)m_pSndChannel, sizeof(SCStatus), &stat) != 0) if (SndChannelStatus((SndChannelPtr)m_pSndChannel, sizeof(SCStatus), &stat) != 0)
Shutdown(); Shutdown();
//if the sound isn't playing anymore, see if it's looped, //if the sound isn't playing anymore, see if it's looped,
//and if so play it again, otherwise close things up //and if so play it again, otherwise close things up
if (stat.scChannelBusy == FALSE) if (stat.scChannelBusy == FALSE)
{ {
if (m_bLoop) if (m_bLoop)
{ {
if(SndPlay((SndChannelPtr)m_pSndChannel, (SndListHandle) m_hSnd, true) != noErr) if(SndPlay((SndChannelPtr)m_pSndChannel, (SndListHandle) m_hSnd, true) != noErr)
Shutdown(); Shutdown();
} }
else else
Shutdown(); Shutdown();
} }
} }
void Shutdown() void Shutdown()
{ {
SndDisposeChannel((SndChannelPtr)m_pSndChannel, TRUE); delete this;
Stop();
} }
void* GetChannel() {return m_pSndChannel;}
protected: protected:
void* m_hSnd; void* m_hSnd;
void* m_pSndChannel; void* m_pSndChannel;
bool m_bLoop; bool m_bLoop;
public:
bool* m_pbPlaying;
}; };
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// wxSound // wxSound
// ------------------------------------------------------------------ // ------------------------------------------------------------------
wxTimer* lastSoundTimer=NULL;
bool lastSoundIsPlaying=false;
//Determines whether version 4 of QT is installed //Determines whether version 4 of QT is installed
Boolean wxIsQuickTime4Installed (void) Boolean wxIsQuickTime4Installed (void)
@@ -201,10 +227,10 @@ inline bool wxInitQT ()
return true; return true;
} }
else else
{ {
wxLogSysError("Quicktime is not installed, or Your Version of Quicktime is <= 4."); wxLogSysError("Quicktime is not installed, or Your Version of Quicktime is <= 4.");
return false; return false;
} }
} }
wxSound::wxSound() wxSound::wxSound()
@@ -221,20 +247,22 @@ 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((char*)data), m_waveLength(size), m_pTimer(NULL), m_type(wxSound_MEMORY)
{ {
if (!wxInitQT())
m_type = wxSound_NONE;
} }
wxSound::~wxSound() wxSound::~wxSound()
{ {
if(lastSoundIsPlaying)
{
if(m_type == wxSound_RESOURCE)
((wxSMTimer*)lastSoundTimer)->m_pbPlaying = NULL;
else
((wxQTTimer*)lastSoundTimer)->m_pbPlaying = NULL;
}
} }
bool wxSound::Create(const wxString& fileName, bool isResource) bool wxSound::Create(const wxString& fileName, bool isResource)
{ {
if(!wxInitQT()) Stop();
return false;
FreeData();
if (isResource) if (isResource)
{ {
@@ -245,14 +273,14 @@ bool wxSound::Create(const wxString& fileName, bool isResource)
wxMacStringToPascal( fileName , lpSnd ) ; wxMacStringToPascal( fileName , lpSnd ) ;
m_sndname = lpSnd; m_sndname = lpSnd;
m_hSnd = (char*) GetNamedResource('snd ', (const unsigned char *) lpSnd); m_hSnd = (char*) GetNamedResource('snd ', (const unsigned char *) lpSnd);
#else #else
return false; return false;
#endif #endif
} }
else else
{ {
m_type = wxSound_FILE; m_type = wxSound_FILE;
m_sndname = fileName; m_sndname = fileName;
} }
@@ -262,8 +290,7 @@ bool wxSound::Create(const wxString& fileName, bool isResource)
bool wxSound::DoPlay(unsigned flags) const bool wxSound::DoPlay(unsigned flags) const
{ {
// wxASSERT(m_pTimer == NULL || !((wxTimer*)m_pTimer)->IsRunning() ); Stop();
FreeData();
Movie movie; Movie movie;
@@ -271,6 +298,8 @@ bool wxSound::DoPlay(unsigned flags) const
{ {
case wxSound_MEMORY: case wxSound_MEMORY:
{ {
if (!wxInitQT())
return false;
Handle myHandle, dataRef = nil; Handle myHandle, dataRef = nil;
MovieImportComponent miComponent; MovieImportComponent miComponent;
Track targetTrack = nil; Track targetTrack = nil;
@@ -292,7 +321,7 @@ bool wxSound::DoPlay(unsigned flags) const
else if (memcmp(&m_hSnd[8], "AIFC", 4) == 0) else if (memcmp(&m_hSnd[8], "AIFC", 4) == 0)
miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFC); miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFC);
else else
{ {
wxLogSysError("wxSound - Location in memory does not contain valid data"); wxLogSysError("wxSound - Location in memory does not contain valid data");
return false; return false;
} }
@@ -308,7 +337,7 @@ bool wxSound::DoPlay(unsigned flags) const
if (result != noErr) if (result != noErr)
{ {
wxLogSysError(wxString::Format(wxT("Couldn't import movie data\nError:%i"), (int)result)); wxLogSysError(wxString::Format(wxT("Couldn't import movie data\nError:%i"), (int)result));
} }
SetMovieVolume(movie, kFullVolume); SetMovieVolume(movie, kFullVolume);
GoToBeginningOfMovie(movie); GoToBeginningOfMovie(movie);
@@ -326,19 +355,21 @@ bool wxSound::DoPlay(unsigned flags) const
SndChannelPtr pSndChannel; SndChannelPtr pSndChannel;
SndNewChannel(&pSndChannel, sampledSynth, SndNewChannel(&pSndChannel, sampledSynth,
initNoInterp + initNoInterp
(data.numChannels == 1 ? initMono : initStereo), NULL); + (data.numChannels == 1 ? initMono : initStereo), NULL);
if(SndPlay(pSndChannel, (SndListHandle) m_hSnd, flags & wxSOUND_ASYNC ? 1 : 0) != noErr) if(SndPlay(pSndChannel, (SndListHandle) m_hSnd, flags & wxSOUND_ASYNC ? 1 : 0) != noErr)
return false; return false;
if (flags & wxSOUND_ASYNC) if (flags & wxSOUND_ASYNC)
{ {
((wxSMTimer*&)m_pTimer) = new wxSMTimer(pSndChannel, m_hSnd, flags & wxSOUND_LOOP ? 1 : 0); lastSoundTimer = ((wxSMTimer*&)m_pTimer)
= new wxSMTimer(pSndChannel, m_hSnd, flags & wxSOUND_LOOP ? 1 : 0,
lastSoundIsPlaying=true);
((wxTimer*)m_pTimer)->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS); ((wxTimer*)m_pTimer)->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
} }
else else
SndDisposeChannel(pSndChannel, TRUE); SndDisposeChannel(pSndChannel, TRUE);
return true; return true;
@@ -346,6 +377,9 @@ bool wxSound::DoPlay(unsigned flags) const
break; break;
case wxSound_FILE: case wxSound_FILE:
{ {
if (!wxInitQT())
return false;
short movieResFile; short movieResFile;
FSSpec sfFile; FSSpec sfFile;
@@ -354,11 +388,11 @@ bool wxSound::DoPlay(unsigned flags) const
#else #else
int nError; int nError;
if ((nError = NativePathNameToFSSpec ((char*) m_sndname.c_str(), &sfFile, 0)) != noErr) if ((nError = NativePathNameToFSSpec ((char*) m_sndname.c_str(), &sfFile, 0)) != noErr)
{ {
wxLogSysError(wxString::Format(wxT("File:%s does not exist\nError:%i"), wxLogSysError(wxString::Format(wxT("File:%s does not exist\nError:%i"),
m_sndname.c_str(), nError)); m_sndname.c_str(), nError));
return false; return false;
} }
#endif #endif
if (OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr) if (OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr)
@@ -383,12 +417,12 @@ bool wxSound::DoPlay(unsigned flags) const
CloseMovieFile (movieResFile); CloseMovieFile (movieResFile);
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 open file: %s\nError:%i"), m_sndname.c_str(), err )
); );
return false; return false;
} }
} }
break; break;
default: default:
@@ -399,13 +433,7 @@ bool wxSound::DoPlay(unsigned flags) const
//Start the movie! //Start the movie!
StartMovie(movie); StartMovie(movie);
if (flags & wxSOUND_ASYNC) if (flags & wxSOUND_SYNC)
{
//Start timer and play movie asyncronously
((wxQTTimer*&)m_pTimer) = new wxQTTimer(movie, flags & wxSOUND_LOOP ? 1 : 0);
((wxQTTimer*)m_pTimer)->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
}
else
{ {
wxASSERT_MSG(!(flags & wxSOUND_LOOP), "Can't loop and play syncronously at the same time"); wxASSERT_MSG(!(flags & wxSOUND_LOOP), "Can't loop and play syncronously at the same time");
@@ -415,26 +443,36 @@ bool wxSound::DoPlay(unsigned flags) const
DisposeMovie(movie); DisposeMovie(movie);
} }
else
return true;
}
void* wxSound::GetHandle()
{
return (void*) ((wxQTTimer*) m_pTimer)->GetMovie();
}
bool wxSound::FreeData()
{
if (m_pTimer != NULL)
{ {
delete (wxQTTimer*) m_pTimer; //Start timer and play movie asyncronously
m_pTimer = NULL; lastSoundTimer = ((wxQTTimer*&)m_pTimer) = new wxQTTimer(movie, flags & wxSOUND_LOOP ? 1 : 0,lastSoundIsPlaying=true);
((wxQTTimer*)m_pTimer)->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
} }
return true; return true;
} }
bool wxSound::IsPlaying()
{
return lastSoundIsPlaying;
}
void wxSound::Stop()
{
if(lastSoundIsPlaying)
{
delete (wxTimer*&) lastSoundTimer;
lastSoundIsPlaying = false;
}
}
void* wxSound::GetHandle()
{
if(m_type == wxSound_RESOURCE)
return (void*) ((wxSMTimer*)m_pTimer)->GetChannel();
return (void*) ((wxQTTimer*) m_pTimer)->GetMovie();
}
#endif //wxUSE_SOUND #endif //wxUSE_SOUND