Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
OOMusicController.m
Go to the documentation of this file.
1/*
2
3OOMusicController.m
4
5
6Oolite
7Copyright (C) 2004-2013 Giles C Williams and contributors
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22MA 02110-1301, USA.
23
24*/
25
26#import "OOMusicController.h"
27#import "OOSound.h"
29#import "ResourceManager.h"
30
31
32static id sSingleton = nil;
33
34
35@interface OOMusicController (Private)
36
37- (void) playiTunesPlaylist:(NSString *)playlistName;
38- (void) pauseiTunes;
39
40@end
41
42
43
44// Values for _special
45enum
46{
52};
53
54
55@implementation OOMusicController
56
57+ (OOMusicController *) sharedController
58{
59 if (sSingleton == nil)
60 {
61 sSingleton = [[self alloc] init];
62 }
63
64 return sSingleton;
65}
66
67
68- (id) init
69{
70 self = [super init];
71 if (self != nil)
72 {
73 NSString *modeString = [[NSUserDefaults standardUserDefaults] stringForKey:@"music mode"];
74 if ([modeString isEqualToString:@"off"]) _mode = kOOMusicOff;
75 else if ([modeString isEqualToString:@"iTunes"]) _mode = kOOMusicITunes;
76 else _mode = kOOMusicOn;
77
78 // Handle unlikely case of taking prefs from iTunes-enabled system to other.
79 if (_mode > kOOMusicModeMax) _mode = kOOMusicModeMax;
80
81 [self setMissionMusic:@"OoliteTheme.ogg"];
82 }
83
84 return self;
85}
86
87
88- (void) playMusicNamed:(NSString *)name loop:(BOOL)loop
89{
90 [self playMusicNamed:name loop:loop gain:OO_DEFAULT_SOUNDSOURCE_GAIN];
91}
92
93
94- (void) playMusicNamed:(NSString *)name loop:(BOOL)loop gain:(float)gain
95{
96 if ([self isPlaying] && [name isEqual:[self playingMusic]]) return;
97
98 if (_mode == kOOMusicOn || (_mode == kOOMusicITunes && [name isEqualToString:@"OoliteTheme.ogg"]))
99 {
100 OOMusic *music = [ResourceManager ooMusicNamed:name inFolder:@"Music"];
101 if (music != nil)
102 {
103 [_current stop];
104
105 [music setMusicGain:OOClamp_0_1_f(gain)];
106 [music playLooped:loop];
107
108 [_current release];
109 _current = [music retain];
110 }
111 }
112}
113
114
115- (void) playThemeMusic
116{
117 _special = kSpecialTheme;
118 [self playMusicNamed:@"OoliteTheme.ogg" loop:YES];
119}
120
121
122- (void) playDockingMusic
123{
124 _special = kSpecialDocking;
125
126 if (_mode == kOOMusicITunes)
127 {
128 [self playiTunesPlaylist:@"Oolite-Docking"];
129 }
130 else
131 {
132 [self playMusicNamed:@"BlueDanube.ogg" loop:YES];
133 }
134}
135
136
137- (void) playDockedMusic
138{
139 _special = kSpecialDocked;
140
141 if (_mode == kOOMusicITunes)
142 {
143 [self playiTunesPlaylist:@"Oolite-Docked"];
144 }
145 else
146 {
147 [self playMusicNamed:@"OoliteDocked.ogg" loop:NO];
148 }
149}
150
151
152- (void) setMissionMusic:(NSString *)missionMusicName
153{
154 [_missionMusic autorelease];
155 _missionMusic = [missionMusicName copy];
156}
157
158
159- (void) playMissionMusic
160{
161 if (_missionMusic != nil)
162 {
163 _special = kSpecialMission;
164 [self playMusicNamed:_missionMusic loop:NO];
165 }
166}
167
168
169// Stop without switching iTunes to in-flight music.
170- (void) justStop
171{
172 [_current stop];
173 [_current release];
174 _current = nil;
175 _special = kSpecialNone;
176}
177
178
179- (void) stop
180{
181 [self justStop];
182
183 if (_mode == kOOMusicITunes)
184 {
185 [self playiTunesPlaylist:@"Oolite-Inflight"];
186 }
187}
188
189
190- (void) stopMusicNamed:(NSString *)name
191{
192 if ([name isEqual:[self playingMusic]]) [self stop];
193}
194
195
196- (void) stopThemeMusic
197{
198 if (_special == kSpecialTheme)
199 {
200 [self justStop];
201 [self playDockedMusic];
202 }
203}
204
205
206- (void) stopDockingMusic
207{
208 if (_special == kSpecialDocking) [self stop];
209}
210
211
212- (void) stopMissionMusic
213{
214 if (_special == kSpecialMission) [self stop];
215}
216
217
218- (void) toggleDockingMusic
219{
220 if (_mode != kOOMusicOn) return;
221
222 if (![self isPlaying]) [self playDockingMusic];
223 else if (_special == kSpecialDocking) [self stop];
224}
225
226
227- (OOSoundSource *) soundSource
228{
229 return [_current musicSoundSource];
230}
231
232
233- (NSString *) playingMusic
234{
235 return [_current name];
236}
237
238
239- (BOOL) isPlaying
240{
241 return [_current isPlaying];
242}
243
244
246{
247 return _mode;
248}
249
250
251- (void) setMode:(OOMusicMode)mode
252{
253 if (mode <= kOOMusicModeMax && _mode != mode)
254 {
255 if (_mode == kOOMusicITunes) [self pauseiTunes];
256 _mode = mode;
257
258 if (_mode == kOOMusicOff) [self stop];
259 else switch (_special)
260 {
261 case kSpecialNone:
262 [self stop];
263 break;
264
265 case kSpecialTheme:
266 [self playThemeMusic];
267 break;
268
269 case kSpecialDocked:
270 [self playDockedMusic];
271 break;
272
273 case kSpecialDocking:
274 [self playDockingMusic];
275 break;
276
277 case kSpecialMission:
278 [self playMissionMusic];
279 break;
280 }
281
282 NSString *modeString = nil;
283 switch (_mode)
284 {
285 case kOOMusicOff: modeString = @"off"; break;
286 case kOOMusicOn: modeString = @"on"; break;
287 case kOOMusicITunes: modeString = @"iTunes"; break;
288 }
289 [[NSUserDefaults standardUserDefaults] setObject:modeString forKey:@"music mode"];
290 }
291}
292
293@end
294
295
296
297@implementation OOMusicController (Singleton)
298
299/* Canonical singleton boilerplate.
300 See Cocoa Fundamentals Guide: Creating a Singleton Instance.
301 See also +sharedController above.
302
303 NOTE: assumes single-threaded access.
304*/
305
306+ (id) allocWithZone:(NSZone *)inZone
307{
308 if (sSingleton == nil)
309 {
310 sSingleton = [super allocWithZone:inZone];
311 return sSingleton;
312 }
313 return nil;
314}
315
316
317- (id) copyWithZone:(NSZone *)inZone
318{
319 return self;
320}
321
322
323- (id) retain
324{
325 return self;
326}
327
328
329- (NSUInteger) retainCount
330{
331 return UINT_MAX;
332}
333
334
335- (void) release
336{}
337
338
339- (id) autorelease
340{
341 return self;
342}
343
344@end
345
346
347@implementation OOMusicController (Private)
348
349#if OOLITE_MAC_OS_X
350- (void) playiTunesPlaylist:(NSString *)playlistName
351{
352 NSString *ootunesScriptString =
353 [NSString stringWithFormat:
354 @"with timeout of 1 second\n"
355 " tell application \"iTunes\"\n"
356 " copy playlist \"%@\" to thePlaylist\n"
357 " if thePlaylist exists then\n"
358 " play some track of thePlaylist\n"
359 " end if\n"
360 " end tell\n"
361 "end timeout",
362 playlistName];
363
364 NSAppleScript *ootunesScript = [[[NSAppleScript alloc] initWithSource:ootunesScriptString] autorelease];
365 NSDictionary *errDict = nil;
366
367 [ootunesScript executeAndReturnError:&errDict];
368 if (errDict)
369 OOLog(@"sound.music.iTunesIntegration.failed", @"ootunes returned :%@", errDict);
370}
371
372
373- (void) pauseiTunes
374{
375 NSString *ootunesScriptString = [NSString stringWithFormat:@"try\nignoring application responses\ntell application \"iTunes\" to pause\nend ignoring\nend try"];
376 NSAppleScript *ootunesScript = [[NSAppleScript alloc] initWithSource:ootunesScriptString];
377 NSDictionary *errDict = nil;
378 [ootunesScript executeAndReturnError:&errDict];
379 if (errDict)
380 OOLog(@"sound.music.iTunesIntegration.failed", @"ootunes returned :%@", errDict);
381 [ootunesScript release];
382}
383#else
384- (void) playiTunesPlaylist:(NSString *)playlistName {}
385- (void) pauseiTunes {}
386#endif
387
388@end
static OODebugMonitor * sSingleton
#define OOLog(class, format,...)
Definition OOLogging.h:88
OOMusicMode
@ kOOMusicOn
@ kOOMusicITunes
@ kOOMusicOff
@ kOOMusicModeMax
@ kSpecialTheme
@ kSpecialDocked
@ kSpecialMission
@ kSpecialNone
@ kSpecialDocking
static id sSingleton
return nil
void setMusicGain:(float newValue)
Definition OOALMusic.m:74
void playLooped:(BOOL looped)
Definition OOALMusic.m:90
OOMusic * ooMusicNamed:inFolder:(NSString *fileName,[inFolder] NSString *folderName)
const char int mode
Definition ioapi.h:133