Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
OOSoundSource.m
Go to the documentation of this file.
1/*
2
3OOSoundSource.m
4
5
6Copyright (C) 2006-2013 Jens Ayton
7
8Permission is hereby granted, free of charge, to any person obtaining a copy
9of this software and associated documentation files (the "Software"), to deal
10in the Software without restriction, including without limitation the rights
11to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12copies of the Software, and to permit persons to whom the Software is
13furnished to do so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in all
16copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24SOFTWARE.
25
26*/
27
28#import "OOSoundInternal.h"
29#import "OOLogging.h"
30#import "OOMaths.h"
31
32static NSMutableSet *sPlayingSoundSources;
33
34
35@implementation OOSoundSource
36
37+ (instancetype) sourceWithSound:(OOSound *)inSound
38{
39 return [[[self alloc] initWithSound:inSound] autorelease];
40}
41
42
43- (id) init
44{
45 self = [super init];
46 if (!self) return nil;
47
48 _positional = NO;
50 _gain = OO_DEFAULT_SOUNDSOURCE_GAIN;
51 return self;
52}
53
54
55- (id) initWithSound:(OOSound *)inSound
56{
57 self = [self init];
58 if (!self) return nil;
59
60 [self setSound:inSound];
61
62 return self;
63}
64
65
66- (void) dealloc
67{
68 [self stop];
69 [_sound autorelease];
70
71 [super dealloc];
72}
73
74
75- (NSString *) descriptionComponents
76{
77 if ([self isPlaying])
78 {
79 return [NSString stringWithFormat:@"sound=%@, loop=%s, repeatCount=%u, playing on channel %@", _sound, [self loop] ? "YES" : "NO", [self repeatCount], _channel];
80 }
81 else
82 {
83 return [NSString stringWithFormat:@"sound=%@, loop=%s, repeatCount=%u, not playing", _sound, [self loop] ? "YES" : "NO", [self repeatCount]];
84 }
85}
86
87
88- (OOSound *) sound
89{
90 return _sound;
91}
92
93
94- (void) setSound:(OOSound *)sound
95{
96 if (_sound != sound)
97 {
98 [self stop];
99 [_sound autorelease];
100 _sound = [sound retain];
101 }
102}
103
104
105- (BOOL) loop
106{
107 return _loop;
108}
109
110
111- (void) setLoop:(BOOL)loop
112{
113 _loop = !!loop;
114}
115
116
117- (uint8_t) repeatCount
118{
119 return _repeatCount ? _repeatCount : 1;
120}
121
122
123- (void) setRepeatCount:(uint8_t)count
124{
126}
127
128
129- (BOOL) isPlaying
130{
131 return _channel != nil;
132}
133
134
135- (void)play
136{
137 if ([self sound] == nil) return;
138
140
141 if (_channel) [self stop];
142
144 if (nil != _channel)
145 {
146 _remainingCount = [self repeatCount];
147 [_channel setDelegate:self];
148 [_channel setPosition:_position];
149 [_channel setGain:_gain];
150 [_channel playSound:[self sound] looped:[self loop]];
151 [self retain];
152 }
153
155 {
156 sPlayingSoundSources = [[NSMutableSet alloc] init];
157 }
158 [sPlayingSoundSources addObject:self];
159
161}
162
163
164- (void) playOrRepeat
165{
166 if (![self isPlaying]) [self play];
167 else ++_remainingCount;
168}
169
170
171- (void)stop
172{
174
175 if (nil != _channel)
176 {
177 [_channel setDelegate:[self class]];
178 [_channel stop];
179 _channel = nil;
180
181 [sPlayingSoundSources removeObject:self];
182 [self release];
183 }
184
186}
187
188
189+ (void) stopAll
190{
191 /* We're not allowed to mutate sPlayingSoundSources during iteration. The
192 normal solution would be to copy the set, but since we know it will
193 end up empty we may as well use the original set and let a new one be
194 set up lazily.
195 */
196 NSMutableSet *playing = sPlayingSoundSources;
198
199 [playing makeObjectsPerformSelector:@selector(stop)];
200 [playing release];
201}
202
203
204- (void) playSound:(OOSound *)sound
205{
206 [self playSound:sound repeatCount:_repeatCount];
207}
208
209
210- (void) playSound:(OOSound *)sound repeatCount:(uint8_t)count
211{
212 [self stop];
213 [self setSound:sound];
214 [self setRepeatCount:count];
215 [self play];
216}
217
218
219- (void) playOrRepeatSound:(OOSound *)sound
220{
221 if (_sound != sound) [self playSound:sound];
222 else [self playOrRepeat];
223}
224
225
226- (void) setPositional:(BOOL)inPositional
227{
228 if (inPositional)
229 {
230 _positional = YES;
231 }
232 else
233 {
234 /* OpenAL doesn't easily do non-positional sounds beyond the
235 * stereo/mono distinction, but setting the position to the
236 * zero vector is probably close enough */
237 _positional = NO;
238 [self setPosition:kZeroVector];
239 }
240}
241
242
243- (BOOL) positional
244{
245 return _positional;
246}
247
248
249- (void) setPosition:(Vector)inPosition
250{
251 _position = inPosition;
252 if (inPosition.x != 0.0 || inPosition.y != 0.0 || inPosition.z != 0.0)
253 {
254 _positional = YES;
255 }
256 if (_channel)
257 {
258 [_channel setPosition:_position];
259 }
260}
261
262
263- (Vector) position
264{
265 return _position;
266}
267
268
269- (void) setGain:(float)gain
270{
271 _gain = gain;
272 if (_channel)
273 {
274 [_channel setGain:_gain];
275 }
276}
277
278
279- (float) gain
280{
281 return _gain;
282}
283
284
285/* Following not yet implemented */
286- (void) setVelocity:(Vector)inVelocity
287{
288
289}
290
291
292- (void) setOrientation:(Vector)inOrientation
293{
294
295}
296
297
298- (void) setConeAngle:(float)inAngle
299{
300
301}
302
303
304- (void) setGainInsideCone:(float)inInside outsideCone:(float)inOutside
305{
306
307}
308
309
310- (void) positionRelativeTo:(OOSoundReferencePoint *)inPoint
311{
312
313}
314
315
316// OOSoundChannelDelegate
317- (void)channel:(OOSoundChannel *)channel didFinishPlayingSound:(OOSound *)sound
318{
319 assert(_channel == channel);
320
322
323 if (--_remainingCount)
324 {
325 [_channel playSound:[self sound] looped:NO];
326 }
327 else
328 {
329 [_channel setDelegate:nil];
331 _channel = nil;
332 [self release];
333 }
335}
336
337
338+ (void)channel:(OOSoundChannel *)inChannel didFinishPlayingSound:(OOSound *)inSound
339{
340 // This delegate is used for a stopped source
342}
343
344@end
#define EXPECT_NOT(x)
unsigned count
return nil
#define OOSoundReleaseLock()
#define OOSoundAcquireLock()
static NSMutableSet * sPlayingSoundSources
const Vector kZeroVector
Definition OOVector.m:28
void pushChannel:(OOSoundChannel *channel)
OOSoundChannel * popChannel()
uint8_t repeatCount()
OOSound * _sound
OOSoundChannel * _channel
NSString * descriptionComponents()
uint8_t _remainingCount
OOSound * sound()
uint8_t _repeatCount