]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/sound.mm
Renamed m_hSnd to m_cocoaNSSound (match rest of wxCocoa).
[wxWidgets.git] / src / cocoa / sound.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: sound.cpp
3 // Purpose: wxSound class implementation: optional
4 // Author: Ryan Norton
5 // Modified by:
6 // Created: 2004-10-02
7 // RCS-ID: $Id$
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "sound.h"
14 #endif
15
16 #include "wx/object.h"
17 #include "wx/string.h"
18 #include "wx/sound.h"
19
20 #if wxUSE_SOUND
21
22 #include "wx/app.h"
23 #include "wx/cocoa/autorelease.h"
24 #include "wx/cocoa/string.h"
25
26 #import <AppKit/AppKit.h>
27
28 //
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
32 //
33
34 WX_NSSound lastSound=NULL;
35 bool isLastSoundLooping = false;
36 bool isLastSoundInScope = false;
37
38 // ========================================================================
39 // wxNSSoundDelegate
40 // ========================================================================
41 @interface wxNSSoundDelegate : NSObject
42 {
43 }
44
45 // Delegate methods
46 - (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)bOK;
47 @end // interface wxNSSoundDelegate : NSObject
48
49 @implementation wxNSSoundDelegate : NSObject
50
51 - (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)bOK
52 {
53 if (bOK && isLastSoundLooping)
54 [lastSound play];
55 else if (!isLastSoundInScope)
56 {
57 [lastSound release];
58 [self release];
59 }
60 }
61
62 @end // wxNSSoundDelegate
63
64 const wxObjcAutoRefFromAlloc<struct objc_object*> wxSound::sm_cocoaDelegate = [[wxNSSoundDelegate alloc] init];
65
66 // ------------------------------------------------------------------
67 // wxSound
68 // ------------------------------------------------------------------
69
70 wxSound::wxSound()
71 : m_cocoaNSSound(nil)
72 , m_waveLength(0)
73 {
74 }
75
76 wxSound::wxSound(const wxString& sFileName, bool isResource)
77 : m_cocoaNSSound(nil)
78 , m_waveLength(0)
79 {
80 Create(sFileName, isResource);
81 }
82
83 wxSound::wxSound(int size, const wxByte* data)
84 : m_cocoaNSSound(nil)
85 , m_waveLength(size)
86 {
87 NSData* theData = [[NSData alloc] dataWithBytesNoCopy:(void*)data length:size];
88 m_cocoaNSSound = [[NSSound alloc] initWithData:theData];
89
90 }
91
92 wxSound::~wxSound()
93 {
94 if (m_cocoaNSSound != lastSound)
95 {
96 [m_cocoaNSSound release];
97 }
98 else
99 isLastSoundInScope = false;
100 }
101
102 bool wxSound::Create(const wxString& fileName, bool isResource)
103 {
104 wxAutoNSAutoreleasePool thePool;
105
106 Stop();
107
108 if (isResource)
109 {
110 //oftype could be @"snd" @"wav" or @"aiff"; nil or @"" autodetects (?)
111 m_cocoaNSSound = [[NSSound alloc]
112 initWithContentsOfFile:[[NSBundle mainBundle]
113 pathForResource:wxNSStringWithWxString(fileName)
114 ofType:nil]
115 byReference:YES];
116 }
117 else
118 m_cocoaNSSound = [[NSSound alloc] initWithContentsOfFile:wxNSStringWithWxString(fileName) byReference:YES];
119
120 m_sndname = fileName;
121 return m_cocoaNSSound;
122 }
123
124 bool wxSound::DoPlay(unsigned flags) const
125 {
126 wxASSERT_MSG(!( (flags & wxSOUND_SYNC) && (flags & wxSOUND_LOOP)),
127 wxT("Invalid flag combination passed to wxSound::Play"));
128
129 Stop();
130
131 if (flags & wxSOUND_ASYNC)
132 {
133 lastSound = m_cocoaNSSound;
134 isLastSoundLooping = (flags & wxSOUND_LOOP) == wxSOUND_LOOP;
135 isLastSoundInScope = true;
136 [m_cocoaNSSound setDelegate:sm_cocoaDelegate];
137 return [m_cocoaNSSound play];
138 }
139 else
140 {
141 [m_cocoaNSSound setDelegate:nil];
142
143 //play until done
144 bool bOK = [m_cocoaNSSound play];
145
146 while ([m_cocoaNSSound isPlaying])
147 {
148 wxTheApp->Yield(false);
149 }
150 return bOK;
151 }
152 }
153
154 bool wxSound::IsPlaying()
155 {
156 return [lastSound isPlaying];
157 }
158
159 void wxSound::Stop()
160 {
161 if (isLastSoundInScope)
162 {
163 isLastSoundInScope = false;
164
165 //remember that even though we're
166 //programatically stopping it, the
167 //delegate will still be called -
168 //so it will free the memory here
169 [((NSSound*&)lastSound) stop];
170 }
171
172 lastSound = nil;
173 }
174
175 #endif //wxUSE_SOUND