Files
wxWidgets/src/osx/carbon/sound.cpp
Vadim Zeitlin ce00f59b5b No changes whatsoever, just remove trailing whitespace.
There are no real changes in this commit but it removes all trailing white
space from our source files. This avoids problems when applying patches and
making diffs and it would be nice to prevent it from reappearing.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65680 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2010-09-30 11:44:45 +00:00

375 lines
9.3 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/osx/carbon/sound.cpp
// Purpose: wxSound class implementation: optional
// Author: Ryan Norton
// Modified by: Stefan Csomor
// Created: 1998-01-01
// RCS-ID: $Id$
// Copyright: (c) Ryan Norton
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#if wxUSE_SOUND
#if wxOSX_USE_QUICKTIME
#include "wx/sound.h"
#ifndef WX_PRECOMP
#include "wx/object.h"
#include "wx/string.h"
#include "wx/intl.h"
#include "wx/log.h"
#include "wx/timer.h"
#endif
#include "wx/file.h"
// Carbon QT Implementation Details -
//
// Memory:
// 1) OpenDefaultComponent(MovieImportType, kQTFileTypeWave);
// 2) NewMovie(0);
// 3) MovieImportDataRef() //Pass Memory Location to this
// 4) PlayMovie();
// 5) IsMovieDone(), MoviesTask() //2nd param is minimum wait time to allocate to quicktime
//
// File:
// 1) Path as CFString
// 2) Call QTNewDataReferenceFromFullPathCFString
// 3) Call NewMovieFromDataRef
// 4) Call CloseMovieFile
// 4) PlayMovie();
// 5) IsMovieDone(), MoviesTask() //2nd param is minimum wait time to allocate to quicktime
//
#ifdef __WXMAC__
#include "wx/osx/private.h"
#if wxOSX_USE_COCOA_OR_CARBON
#include <QuickTime/QuickTimeComponents.h>
#endif
#else
#include <qtml.h>
#endif
#define MOVIE_DELAY 100
// ------------------------------------------------------------------
// SoundManager
// ------------------------------------------------------------------
class wxOSXSoundManagerSoundData : public wxSoundData
{
public:
wxOSXSoundManagerSoundData(const wxString& fileName);
~wxOSXSoundManagerSoundData();
virtual bool Play(unsigned flags);
virtual void SoundTask();
void DoStop();
protected:
SndListHandle m_hSnd;
SndChannelPtr m_pSndChannel;
};
wxOSXSoundManagerSoundData::wxOSXSoundManagerSoundData(const wxString& fileName) :
m_pSndChannel(NULL)
{
Str255 lpSnd ;
wxMacStringToPascal( fileName , lpSnd ) ;
m_hSnd = (SndListHandle) GetNamedResource('snd ', (const unsigned char *) lpSnd);
}
wxOSXSoundManagerSoundData::~wxOSXSoundManagerSoundData()
{
DoStop();
ReleaseResource((Handle)m_hSnd);
}
void wxOSXSoundManagerSoundData::DoStop()
{
if ( m_pSndChannel )
{
SndDisposeChannel(m_pSndChannel, TRUE /* stop immediately, not after playing */);
m_pSndChannel = NULL;
wxSound::SoundStopped(this);
}
if (IsMarkedForDeletion())
delete this;
}
bool wxOSXSoundManagerSoundData::Play(unsigned flags)
{
Stop();
m_flags = flags;
SoundComponentData data;
unsigned long numframes, offset;
ParseSndHeader((SndListHandle)m_hSnd, &data, &numframes, &offset);
SndNewChannel(&m_pSndChannel, sampledSynth,
initNoInterp
+ (data.numChannels == 1 ? initMono : initStereo), NULL);
if(SndPlay(m_pSndChannel, (SndListHandle) m_hSnd, flags & wxSOUND_ASYNC ? 1 : 0) != noErr)
return false;
if (flags & wxSOUND_ASYNC)
CreateAndStartTimer();
else
DoStop();
return true;
}
void wxOSXSoundManagerSoundData::SoundTask()
{
SCStatus stat;
if (SndChannelStatus((SndChannelPtr)m_pSndChannel, sizeof(SCStatus), &stat) != 0)
Stop();
//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_flags & wxSOUND_LOOP)
{
if(SndPlay((SndChannelPtr)m_pSndChannel, (SndListHandle) m_hSnd, true) != noErr)
Stop();
}
else
Stop();
}
}
// ------------------------------------------------------------------
// QuickTime
// ------------------------------------------------------------------
bool wxInitQT();
bool wxInitQT()
{
#ifndef __WXMAC__
int nError;
//-2093 no dll
if ((nError = InitializeQTML(0)) != noErr)
{
wxLogSysError(wxString::Format(wxT("Couldn't Initialize Quicktime-%i"), nError));
return false;
}
#endif
EnterMovies();
return true;
}
void wxExitQT();
void wxExitQT()
{
//Note that ExitMovies() is not necessary, but
//the docs are fuzzy on whether or not TerminateQTML is
ExitMovies();
#ifndef __WXMAC__
TerminateQTML();
#endif
}
class wxOSXQuickTimeSoundData : public wxSoundData
{
public:
wxOSXQuickTimeSoundData(const wxString& fileName);
wxOSXQuickTimeSoundData(int size, const wxByte* data);
~wxOSXQuickTimeSoundData();
virtual bool Play(unsigned flags);
virtual void SoundTask();
virtual void DoStop();
protected:
Movie m_movie;
wxString m_sndname; //file path
Handle m_soundHandle;
};
wxOSXQuickTimeSoundData::wxOSXQuickTimeSoundData(const wxString& fileName) :
m_movie(NULL), m_soundHandle(NULL)
{
m_sndname = fileName;
}
wxOSXQuickTimeSoundData::wxOSXQuickTimeSoundData(int size, const wxByte* data) :
m_movie(NULL)
{
m_soundHandle = NewHandleClear((Size)size);
BlockMove(data, *m_soundHandle, size);
}
wxOSXQuickTimeSoundData::~wxOSXQuickTimeSoundData()
{
if ( m_soundHandle )
DisposeHandle(m_soundHandle);
}
bool wxOSXQuickTimeSoundData::Play(unsigned flags)
{
if ( m_movie )
Stop();
m_flags = flags;
if (!wxInitQT())
return false;
if( m_soundHandle )
{
Handle dataRef = nil;
MovieImportComponent miComponent;
Track targetTrack = nil;
TimeValue addedDuration = 0;
long outFlags = 0;
OSErr err;
ComponentResult result;
err = PtrToHand(&m_soundHandle, &dataRef, sizeof(Handle));
HLock(m_soundHandle);
if (memcmp(&(*m_soundHandle)[8], "WAVE", 4) == 0)
miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeWave);
else if (memcmp(&(*m_soundHandle)[8], "AIFF", 4) == 0)
miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFF);
else if (memcmp(&(*m_soundHandle)[8], "AIFC", 4) == 0)
miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFC);
else
{
HUnlock(m_soundHandle);
wxLogSysError(wxT("wxSound - Location in memory does not contain valid data"));
return false;
}
HUnlock(m_soundHandle);
m_movie = NewMovie(0);
result = MovieImportDataRef(miComponent, dataRef,
HandleDataHandlerSubType, m_movie,
nil, &targetTrack,
nil, &addedDuration,
movieImportCreateTrack, &outFlags);
if (result != noErr)
{
wxLogSysError(wxString::Format(wxT("Couldn't import movie data\nError:%i"), (int)result));
}
SetMovieVolume(m_movie, kFullVolume);
GoToBeginningOfMovie(m_movie);
}
else
{
OSErr err = noErr ;
Handle dataRef = NULL;
OSType dataRefType;
err = QTNewDataReferenceFromFullPathCFString(wxCFStringRef(m_sndname,wxLocale::GetSystemEncoding()),
(UInt32)kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType);
wxASSERT(err == noErr);
if (NULL != dataRef || err != noErr)
{
err = NewMovieFromDataRef( &m_movie, newMovieDontAskUnresolvedDataRefs , NULL, dataRef, dataRefType );
wxASSERT(err == noErr);
DisposeHandle(dataRef);
}
if (err != noErr)
{
wxLogSysError(
wxString::Format(wxT("wxSound - Could not open file: %s\nError:%i"), m_sndname.c_str(), err )
);
return false;
}
}
//Start the m_movie!
StartMovie(m_movie);
if (flags & wxSOUND_ASYNC)
{
CreateAndStartTimer();
}
else
{
wxASSERT_MSG(!(flags & wxSOUND_LOOP), wxT("Can't loop and play syncronously at the same time"));
//Play movie until it ends, then exit
//Note that due to quicktime caching this may not always
//work 100% correctly
while (!IsMovieDone(m_movie))
MoviesTask(m_movie, 1);
DoStop();
}
return true;
}
void wxOSXQuickTimeSoundData::DoStop()
{
if( m_movie )
{
StopMovie(m_movie);
DisposeMovie(m_movie);
m_movie = NULL;
wxSound::SoundStopped(this);
wxExitQT();
}
}
void wxOSXQuickTimeSoundData::SoundTask()
{
if(IsMovieDone(m_movie))
{
if (m_flags & wxSOUND_LOOP)
{
StopMovie(m_movie);
GoToBeginningOfMovie(m_movie);
StartMovie(m_movie);
}
else
Stop();
}
else
MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie
}
bool wxSound::Create(int size, const wxByte* data)
{
m_data = new wxOSXQuickTimeSoundData(size,data);
return true;
}
bool wxSound::Create(const wxString& fileName, bool isResource)
{
if ( isResource )
m_data = new wxOSXSoundManagerSoundData(fileName);
else
m_data = new wxOSXQuickTimeSoundData(fileName);
return true;
}
#endif // wxOSX_USE_QUICKTIME
#endif //wxUSE_SOUND