From: Ryan Norton Date: Fri, 8 Oct 2004 00:47:47 +0000 (+0000) Subject: wxSound for wxCocoa X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/0c0be4a31821ac6de698e3b569371d95ff00e4c0 wxSound for wxCocoa git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29726 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/cocoa/sound.h b/include/wx/cocoa/sound.h index 8b13789179..03655103f9 100644 --- a/include/wx/cocoa/sound.h +++ b/include/wx/cocoa/sound.h @@ -1 +1,52 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: sound.h +// Purpose: wxSound class (loads and plays short Windows .wav files). +// Optional on non-Windows platforms. +// Author: Ryan Norton +// Modified by: +// Created: 2004-10-02 +// RCS-ID: $Id$ +// Copyright: (c) Ryan Norton +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// +#ifndef _WX_COCOA_SOUND_H_ +#define _WX_COCOA_SOUND_H_ + +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) +#pragma interface "sound.h" +#endif + +#if wxUSE_SOUND + +#include "wx/object.h" + +class WXDLLEXPORT wxSound : public wxSoundBase +{ +public: + wxSound(); + wxSound(const wxString& fileName, bool isResource = FALSE); + wxSound(int size, const wxByte* data); + ~wxSound(); + +public: + bool Create(const wxString& fileName, bool isResource = FALSE); + bool IsOk() const { return m_hSnd != NULL; } + static void Stop(); + static bool IsPlaying(); + + inline WX_NSSound GetNSSound() + { return m_hSnd; } +protected: + bool DoPlay(unsigned flags) const; + +private: + WX_NSSound m_hSnd; //NSSound handle + wxString m_sndname; //file path + int m_waveLength; //size of file in memory mode + struct objc_object * m_cocoaSoundDelegate; +}; + +#endif +#endif + // _WX_COCOA_SOUND_H_ diff --git a/include/wx/sound.h b/include/wx/sound.h index cb9f836554..db76105490 100644 --- a/include/wx/sound.h +++ b/include/wx/sound.h @@ -67,6 +67,8 @@ protected: #if defined(__WXMSW__) #include "wx/msw/sound.h" +#elif defined(__WXCOCOA__) + #include "wx/cocoa/sound.h" #elif defined(__WXMAC__) #include "wx/mac/sound.h" #elif defined(__WXPM__) diff --git a/src/cocoa/sound.mm b/src/cocoa/sound.mm index 8b13789179..dcfdd3acbd 100644 --- a/src/cocoa/sound.mm +++ b/src/cocoa/sound.mm @@ -1 +1,172 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: sound.cpp +// Purpose: wxSound class implementation: optional +// Author: Ryan Norton +// Modified by: +// Created: 2004-10-02 +// RCS-ID: $Id$ +// Copyright: (c) Ryan Norton +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// +#ifdef __GNUG__ +#pragma implementation "sound.h" +#endif + +#include "wx/object.h" +#include "wx/string.h" +#include "wx/sound.h" + +#if wxUSE_SOUND + +#include "wx/app.h" +#include "wx/cocoa/autorelease.h" +#include "wx/cocoa/string.h" + +#import + +// +// NB: Vaclav's new wxSound API is really tricky - +// Basically, we need to make sure that if the wxSound +// object is still in scope we don't release it's NSSound +// + +WX_NSSound lastSound=NULL; +bool isLastSoundLooping = NO; +bool isLastSoundInScope = NO; + +// ======================================================================== +// wxNSSoundDelegate +// ======================================================================== +@interface wxNSSoundDelegate : NSObject +{ +} + +// Delegate methods +- (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)bOK; +@end // interface wxNSSoundDelegate : NSObject + +@implementation wxNSSoundDelegate : NSObject + +- (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)bOK +{ + if (bOK && isLastSoundLooping) + [lastSound play]; + else if (isLastSoundInScope = NO) + { + [lastSound release]; + [self release]; + } +} + +@end // wxNSSoundDelegate + +// ------------------------------------------------------------------ +// wxSound +// ------------------------------------------------------------------ + +wxSound::wxSound() +: m_hSnd(NULL), m_waveLength(0) +{ +} + +wxSound::wxSound(const wxString& sFileName, bool isResource) +: m_hSnd(NULL), m_waveLength(0) +{ + Create(sFileName, isResource); +} + +wxSound::wxSound(int size, const wxByte* data) +: m_hSnd(NULL), m_waveLength(size) +{ + NSData* theData = [[NSData alloc] dataWithBytesNoCopy:(void*)data length:size]; + m_hSnd = [[NSSound alloc] initWithData:theData]; + + m_cocoaSoundDelegate = [[wxNSSoundDelegate alloc] init]; +} + +wxSound::~wxSound() +{ + if (m_hSnd != lastSound) + { + [m_hSnd release]; + [m_cocoaSoundDelegate release]; + } + else + isLastSoundInScope = NO; +} + +bool wxSound::Create(const wxString& fileName, bool isResource) +{ + wxAutoNSAutoreleasePool thePool; + + Stop(); + + if (isResource) + { + //oftype could be @"snd" @"wav" or @"aiff", nil or @"" autodetects (?) + m_hSnd = [[NSSound alloc] initWithContentsOfFile: + [[NSBundle mainBundle] pathForResource:wxNSStringWithWxString(fileName) ofType:nil] + byReference:NO]; + } + else + m_hSnd = [[NSSound alloc] initWithContentsOfFile:wxNSStringWithWxString(fileName) byReference:YES]; + + m_cocoaSoundDelegate = [[wxNSSoundDelegate alloc] init]; + + m_sndname = fileName; + return m_hSnd != nil; +} + +bool wxSound::DoPlay(unsigned flags) const +{ + wxASSERT_MSG(!( (flags & wxSOUND_SYNC) && (flags & wxSOUND_LOOP)), + wxT("Invalid flag combination passed to wxSound::Play")); + + Stop(); + + if (flags & wxSOUND_ASYNC) + { + lastSound = m_hSnd; + isLastSoundLooping = (flags & wxSOUND_LOOP) == wxSOUND_LOOP; + isLastSoundInScope = YES; + [m_hSnd setDelegate:m_cocoaSoundDelegate]; + return [m_hSnd play]; + } + else + { + [m_hSnd setDelegate:nil]; + + //play until done + bool bOK = [m_hSnd play]; + + while ([m_hSnd isPlaying]) + { + wxTheApp->Yield(false); + } + return bOK; + } +} + +bool wxSound::IsPlaying() +{ + return [lastSound isPlaying]; +} + +void wxSound::Stop() +{ + if (isLastSoundInScope) + { + isLastSoundInScope = NO; + + //remember that even though we're + //programatically stopping it, the + //delegate will still be called - + //so it will free the memory here + [((NSSound*&)lastSound) stop]; + } + + lastSound = nil; +} + +#endif //wxUSE_SOUND