1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxSound class implementation: optional
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "sound.h"
16 #include "wx/object.h"
17 #include "wx/string.h"
23 #include "wx/cocoa/autorelease.h"
24 #include "wx/cocoa/string.h"
26 #import <AppKit/AppKit.h>
29 // NB: Vaclav's new wxSound API is really tricky -
30 // Basically, we need to make sure that if the wxSound
31 // object is still in scope we don't release it's NSSound
34 WX_NSSound lastSound=NULL;
35 bool isLastSoundLooping = NO;
36 bool isLastSoundInScope = NO;
38 // ========================================================================
40 // ========================================================================
41 @interface wxNSSoundDelegate : NSObject
46 - (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)bOK;
47 @end // interface wxNSSoundDelegate : NSObject
49 @implementation wxNSSoundDelegate : NSObject
51 - (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)bOK
53 if (bOK && isLastSoundLooping)
55 else if (isLastSoundInScope = NO)
62 @end // wxNSSoundDelegate
64 // ------------------------------------------------------------------
66 // ------------------------------------------------------------------
69 : m_hSnd(NULL), m_waveLength(0)
73 wxSound::wxSound(const wxString& sFileName, bool isResource)
74 : m_hSnd(NULL), m_waveLength(0)
76 Create(sFileName, isResource);
79 wxSound::wxSound(int size, const wxByte* data)
80 : m_hSnd(NULL), m_waveLength(size)
82 NSData* theData = [[NSData alloc] dataWithBytesNoCopy:(void*)data length:size];
83 m_hSnd = [[NSSound alloc] initWithData:theData];
85 m_cocoaSoundDelegate = [[wxNSSoundDelegate alloc] init];
90 if (m_hSnd != lastSound)
93 [m_cocoaSoundDelegate release];
96 isLastSoundInScope = NO;
99 bool wxSound::Create(const wxString& fileName, bool isResource)
101 wxAutoNSAutoreleasePool thePool;
107 //oftype could be @"snd" @"wav" or @"aiff", nil or @"" autodetects (?)
108 m_hSnd = [[NSSound alloc] initWithContentsOfFile:
109 [[NSBundle mainBundle] pathForResource:wxNSStringWithWxString(fileName) ofType:nil]
113 m_hSnd = [[NSSound alloc] initWithContentsOfFile:wxNSStringWithWxString(fileName) byReference:YES];
115 m_cocoaSoundDelegate = [[wxNSSoundDelegate alloc] init];
117 m_sndname = fileName;
118 return m_hSnd != nil;
121 bool wxSound::DoPlay(unsigned flags) const
123 wxASSERT_MSG(!( (flags & wxSOUND_SYNC) && (flags & wxSOUND_LOOP)),
124 wxT("Invalid flag combination passed to wxSound::Play"));
128 if (flags & wxSOUND_ASYNC)
131 isLastSoundLooping = (flags & wxSOUND_LOOP) == wxSOUND_LOOP;
132 isLastSoundInScope = YES;
133 [m_hSnd setDelegate:m_cocoaSoundDelegate];
134 return [m_hSnd play];
138 [m_hSnd setDelegate:nil];
141 bool bOK = [m_hSnd play];
143 while ([m_hSnd isPlaying])
145 wxTheApp->Yield(false);
151 bool wxSound::IsPlaying()
153 return [lastSound isPlaying];
158 if (isLastSoundInScope)
160 isLastSoundInScope = NO;
162 //remember that even though we're
163 //programatically stopping it, the
164 //delegate will still be called -
165 //so it will free the memory here
166 [((NSSound*&)lastSound) stop];