18 #include "../stdafx.h" 19 #include "../os/macosx/macos.h" 24 #define Point OTTDPoint 25 #include <CoreServices/CoreServices.h> 26 #include <AudioUnit/AudioUnit.h> 27 #include <AudioToolbox/AudioToolbox.h> 31 #include "../safeguards.h" 33 #if !defined(HAVE_OSX_1011_SDK) 34 #define kMusicSequenceFile_AnyType 0 40 static MusicPlayer _player = NULL;
41 static MusicSequence _sequence = NULL;
42 static MusicTimeStamp _seq_length = 0;
43 static bool _playing =
false;
44 static byte _volume = 127;
48 static void DoSetVolume()
50 if (_sequence == NULL)
return;
53 MusicSequenceGetAUGraph(_sequence, &graph);
55 AudioUnit output_unit = NULL;
58 UInt32 node_count = 0;
59 AUGraphGetNodeCount(graph, &node_count);
60 for (UInt32 i = 0; i < node_count; i++) {
62 AUGraphGetIndNode(graph, i, &node);
67 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) 75 #if defined(__AUDIOCOMPONENT_H__) || defined(HAVE_OSX_107_SDK) 76 AudioComponentDescription desc;
78 ComponentDescription desc;
80 AUGraphNodeInfo(graph, node, &desc, &unit);
81 comp_type = desc.componentType;
85 #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) 86 ComponentDescription desc;
87 AUGraphGetNodeInfo(graph, node, &desc, NULL, NULL, &unit);
88 comp_type = desc.componentType;
92 if (comp_type == kAudioUnitType_Output) {
97 if (output_unit == NULL) {
98 DEBUG(driver, 1,
"cocoa_m: Failed to get output node to set volume");
102 Float32 vol = _volume / 127.0f;
103 AudioUnitSetParameter(output_unit, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, vol, 0);
112 if (NewMusicPlayer(&_player) != noErr)
return "failed to create music player";
123 if (!_playing)
return false;
125 MusicTimeStamp time = 0;
126 MusicPlayerGetTime(_player, &time);
127 return time < _seq_length;
136 if (_player != NULL) DisposeMusicPlayer(_player);
137 if (_sequence != NULL) DisposeMusicSequence(_sequence);
148 DEBUG(driver, 2,
"cocoa_m: trying to play '%s'", filename);
151 if (_sequence != NULL) {
152 DisposeMusicSequence(_sequence);
156 if (NewMusicSequence(&_sequence) != noErr) {
157 DEBUG(driver, 0,
"cocoa_m: Failed to create music sequence");
161 const char *os_file =
OTTD2FS(filename);
162 CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (
const UInt8*)os_file, strlen(os_file),
false);
164 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) 166 if (MusicSequenceFileLoad(_sequence, url, kMusicSequenceFile_AnyType, 0) != noErr) {
167 DEBUG(driver, 0,
"cocoa_m: Failed to load MIDI file");
174 #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) 176 if (!CFURLGetFSRef(url, &ref_file)) {
177 DEBUG(driver, 0,
"cocoa_m: Failed to make FSRef");
181 if (MusicSequenceLoadSMFWithFlags(_sequence, &ref_file, 0) != noErr) {
182 DEBUG(driver, 0,
"cocoa_m: Failed to load MIDI file old style");
191 AUGraph graph = NULL;
193 MusicSequenceGetAUGraph(_sequence, &graph);
195 if (AUGraphInitialize(graph) != noErr) {
196 DEBUG(driver, 0,
"cocoa_m: Failed to initialize AU graph");
202 MusicSequenceGetTrackCount(_sequence, &num_tracks);
204 for (UInt32 i = 0; i < num_tracks; i++) {
205 MusicTrack track = NULL;
206 MusicTimeStamp track_length = 0;
207 UInt32 prop_size =
sizeof(MusicTimeStamp);
208 MusicSequenceGetIndTrack(_sequence, i, &track);
209 MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength, &track_length, &prop_size);
210 if (track_length > _seq_length) _seq_length = track_length;
216 MusicPlayerSetSequence(_player, _sequence);
217 MusicPlayerPreroll(_player);
218 if (MusicPlayerStart(_player) != noErr)
return;
221 DEBUG(driver, 3,
"cocoa_m: playing '%s'", filename);
230 MusicPlayerStop(_player);
231 MusicPlayerSetSequence(_player, NULL);
const char * Start(const char *const *param)
Start this driver.
void StopSong()
Stop playing the current song.
static bool MacOSVersionIsAtLeast(long major, long minor, long bugfix)
Check if we are at least running on the specified version of Mac OS.
Base of music playback via CoreAudio.
const TCHAR * OTTD2FS(const char *name, bool console_cp)
Convert from OpenTTD's encoding to that of the local environment.
#define DEBUG(name, level,...)
Output a line of debugging information.
void PlaySong(const char *filename)
Play a particular song.
bool IsSongPlaying()
Are we currently playing a song?
void SetVolume(byte vol)
Set the volume, if possible.
void Stop()
Stop this driver.