Mercurial > sdl-ios-xcode
comparison src/cdrom/macosx/CDPlayer.c @ 1668:4da1ee79c9af SDL-1.3
more tweaking indent options
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 29 May 2006 04:04:35 +0000 |
parents | 782fd950bd46 |
children |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
65 Prototypes | 65 Prototypes |
66 //////////////////////////////////////////////////////////////////////////*/ | 66 //////////////////////////////////////////////////////////////////////////*/ |
67 | 67 |
68 #pragma mark -- Prototypes -- | 68 #pragma mark -- Prototypes -- |
69 | 69 |
70 static OSStatus CheckInit (); | 70 static OSStatus CheckInit(); |
71 | 71 |
72 static void FilePlayNotificationHandler (void *inRefCon, OSStatus inStatus); | 72 static void FilePlayNotificationHandler(void *inRefCon, OSStatus inStatus); |
73 | 73 |
74 static int RunCallBackThread (void *inRefCon); | 74 static int RunCallBackThread(void *inRefCon); |
75 | 75 |
76 | 76 |
77 #pragma mark -- Public Functions -- | 77 #pragma mark -- Public Functions -- |
78 | 78 |
79 void | 79 void |
80 Lock () | 80 Lock() |
81 { | 81 { |
82 if (!apiMutex) { | 82 if (!apiMutex) { |
83 apiMutex = SDL_CreateMutex (); | 83 apiMutex = SDL_CreateMutex(); |
84 } | 84 } |
85 SDL_mutexP (apiMutex); | 85 SDL_mutexP(apiMutex); |
86 } | 86 } |
87 | 87 |
88 void | 88 void |
89 Unlock () | 89 Unlock() |
90 { | 90 { |
91 SDL_mutexV (apiMutex); | 91 SDL_mutexV(apiMutex); |
92 } | 92 } |
93 | 93 |
94 int | 94 int |
95 DetectAudioCDVolumes (FSVolumeRefNum * volumes, int numVolumes) | 95 DetectAudioCDVolumes(FSVolumeRefNum * volumes, int numVolumes) |
96 { | 96 { |
97 int volumeIndex; | 97 int volumeIndex; |
98 int cdVolumeCount = 0; | 98 int cdVolumeCount = 0; |
99 OSStatus result = noErr; | 99 OSStatus result = noErr; |
100 | 100 |
101 for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++) { | 101 for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++) { |
102 FSVolumeRefNum actualVolume; | 102 FSVolumeRefNum actualVolume; |
103 FSVolumeInfo volumeInfo; | 103 FSVolumeInfo volumeInfo; |
104 | 104 |
105 memset (&volumeInfo, 0, sizeof (volumeInfo)); | 105 memset(&volumeInfo, 0, sizeof(volumeInfo)); |
106 | 106 |
107 result = FSGetVolumeInfo (kFSInvalidVolumeRefNum, | 107 result = FSGetVolumeInfo(kFSInvalidVolumeRefNum, |
108 volumeIndex, | 108 volumeIndex, |
109 &actualVolume, | 109 &actualVolume, |
110 kFSVolInfoFSInfo, &volumeInfo, NULL, NULL); | 110 kFSVolInfoFSInfo, &volumeInfo, NULL, NULL); |
111 | 111 |
112 if (result == noErr) { | 112 if (result == noErr) { |
113 if (volumeInfo.filesystemID == kAudioCDFilesystemID) { /* It's an audio CD */ | 113 if (volumeInfo.filesystemID == kAudioCDFilesystemID) { /* It's an audio CD */ |
114 if (volumes != NULL && cdVolumeCount < numVolumes) | 114 if (volumes != NULL && cdVolumeCount < numVolumes) |
115 volumes[cdVolumeCount] = actualVolume; | 115 volumes[cdVolumeCount] = actualVolume; |
124 | 124 |
125 return cdVolumeCount; | 125 return cdVolumeCount; |
126 } | 126 } |
127 | 127 |
128 int | 128 int |
129 ReadTOCData (FSVolumeRefNum theVolume, SDL_CD * theCD) | 129 ReadTOCData(FSVolumeRefNum theVolume, SDL_CD * theCD) |
130 { | 130 { |
131 HFSUniStr255 dataForkName; | 131 HFSUniStr255 dataForkName; |
132 OSStatus theErr; | 132 OSStatus theErr; |
133 SInt16 forkRefNum; | 133 SInt16 forkRefNum; |
134 SInt64 forkSize; | 134 SInt64 forkSize; |
147 fsRefPB.ioNamePtr = "\p.TOC.plist"; | 147 fsRefPB.ioNamePtr = "\p.TOC.plist"; |
148 fsRefPB.ioVRefNum = theVolume; | 148 fsRefPB.ioVRefNum = theVolume; |
149 fsRefPB.ioDirID = 0; | 149 fsRefPB.ioDirID = 0; |
150 fsRefPB.newRef = &tocPlistFSRef; | 150 fsRefPB.newRef = &tocPlistFSRef; |
151 | 151 |
152 theErr = PBMakeFSRefSync (&fsRefPB); | 152 theErr = PBMakeFSRefSync(&fsRefPB); |
153 if (theErr != noErr) { | 153 if (theErr != noErr) { |
154 error = "PBMakeFSRefSync"; | 154 error = "PBMakeFSRefSync"; |
155 goto bail; | 155 goto bail; |
156 } | 156 } |
157 | 157 |
158 /* Load and parse the TOC XML data */ | 158 /* Load and parse the TOC XML data */ |
159 | 159 |
160 theErr = FSGetDataForkName (&dataForkName); | 160 theErr = FSGetDataForkName(&dataForkName); |
161 if (theErr != noErr) { | 161 if (theErr != noErr) { |
162 error = "FSGetDataForkName"; | 162 error = "FSGetDataForkName"; |
163 goto bail; | 163 goto bail; |
164 } | 164 } |
165 | 165 |
166 theErr = | 166 theErr = |
167 FSOpenFork (&tocPlistFSRef, dataForkName.length, dataForkName.unicode, | 167 FSOpenFork(&tocPlistFSRef, dataForkName.length, dataForkName.unicode, |
168 fsRdPerm, &forkRefNum); | 168 fsRdPerm, &forkRefNum); |
169 if (theErr != noErr) { | 169 if (theErr != noErr) { |
170 error = "FSOpenFork"; | 170 error = "FSOpenFork"; |
171 goto bail; | 171 goto bail; |
172 } | 172 } |
173 | 173 |
174 theErr = FSGetForkSize (forkRefNum, &forkSize); | 174 theErr = FSGetForkSize(forkRefNum, &forkSize); |
175 if (theErr != noErr) { | 175 if (theErr != noErr) { |
176 error = "FSGetForkSize"; | 176 error = "FSGetForkSize"; |
177 goto bail; | 177 goto bail; |
178 } | 178 } |
179 | 179 |
180 /* Allocate some memory for the XML data */ | 180 /* Allocate some memory for the XML data */ |
181 forkData = NewPtr (forkSize); | 181 forkData = NewPtr(forkSize); |
182 if (forkData == NULL) { | 182 if (forkData == NULL) { |
183 error = "NewPtr"; | 183 error = "NewPtr"; |
184 goto bail; | 184 goto bail; |
185 } | 185 } |
186 | 186 |
187 theErr = FSReadFork (forkRefNum, fsFromStart, 0 /* offset location */ , | 187 theErr = FSReadFork(forkRefNum, fsFromStart, 0 /* offset location */ , |
188 forkSize, forkData, &actualRead); | 188 forkSize, forkData, &actualRead); |
189 if (theErr != noErr) { | 189 if (theErr != noErr) { |
190 error = "FSReadFork"; | 190 error = "FSReadFork"; |
191 goto bail; | 191 goto bail; |
192 } | 192 } |
193 | 193 |
194 dataRef = | 194 dataRef = CFDataCreate(kCFAllocatorDefault, (UInt8 *) forkData, forkSize); |
195 CFDataCreate (kCFAllocatorDefault, (UInt8 *) forkData, forkSize); | |
196 if (dataRef == 0) { | 195 if (dataRef == 0) { |
197 error = "CFDataCreate"; | 196 error = "CFDataCreate"; |
198 goto bail; | 197 goto bail; |
199 } | 198 } |
200 | 199 |
201 propertyListRef = CFPropertyListCreateFromXMLData (kCFAllocatorDefault, | 200 propertyListRef = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, |
202 dataRef, | 201 dataRef, |
203 kCFPropertyListImmutable, | 202 kCFPropertyListImmutable, |
204 NULL); | 203 NULL); |
205 if (propertyListRef == NULL) { | 204 if (propertyListRef == NULL) { |
206 error = "CFPropertyListCreateFromXMLData"; | 205 error = "CFPropertyListCreateFromXMLData"; |
207 goto bail; | 206 goto bail; |
208 } | 207 } |
209 | 208 |
210 /* Now we got the Property List in memory. Parse it. */ | 209 /* Now we got the Property List in memory. Parse it. */ |
211 | 210 |
212 /* First, make sure the root item is a CFDictionary. If not, release and bail. */ | 211 /* First, make sure the root item is a CFDictionary. If not, release and bail. */ |
213 if (CFGetTypeID (propertyListRef) == CFDictionaryGetTypeID ()) { | 212 if (CFGetTypeID(propertyListRef) == CFDictionaryGetTypeID()) { |
214 CFDictionaryRef dictRef = (CFDictionaryRef) propertyListRef; | 213 CFDictionaryRef dictRef = (CFDictionaryRef) propertyListRef; |
215 | 214 |
216 CFDataRef theRawTOCDataRef; | 215 CFDataRef theRawTOCDataRef; |
217 CFArrayRef theSessionArrayRef; | 216 CFArrayRef theSessionArrayRef; |
218 CFIndex numSessions; | 217 CFIndex numSessions; |
219 CFIndex index; | 218 CFIndex index; |
220 | 219 |
221 /* This is how we get the Raw TOC Data */ | 220 /* This is how we get the Raw TOC Data */ |
222 theRawTOCDataRef = | 221 theRawTOCDataRef = |
223 (CFDataRef) CFDictionaryGetValue (dictRef, | 222 (CFDataRef) CFDictionaryGetValue(dictRef, |
224 CFSTR (kRawTOCDataString)); | 223 CFSTR(kRawTOCDataString)); |
225 | 224 |
226 /* Get the session array info. */ | 225 /* Get the session array info. */ |
227 theSessionArrayRef = | 226 theSessionArrayRef = |
228 (CFArrayRef) CFDictionaryGetValue (dictRef, | 227 (CFArrayRef) CFDictionaryGetValue(dictRef, |
229 CFSTR (kSessionsString)); | 228 CFSTR(kSessionsString)); |
230 | 229 |
231 /* Find out how many sessions there are. */ | 230 /* Find out how many sessions there are. */ |
232 numSessions = CFArrayGetCount (theSessionArrayRef); | 231 numSessions = CFArrayGetCount(theSessionArrayRef); |
233 | 232 |
234 /* Initialize the total number of tracks to 0 */ | 233 /* Initialize the total number of tracks to 0 */ |
235 theCD->numtracks = 0; | 234 theCD->numtracks = 0; |
236 | 235 |
237 /* Iterate over all sessions, collecting the track data */ | 236 /* Iterate over all sessions, collecting the track data */ |
242 CFIndex numTracks; | 241 CFIndex numTracks; |
243 CFIndex trackIndex; | 242 CFIndex trackIndex; |
244 UInt32 value = 0; | 243 UInt32 value = 0; |
245 | 244 |
246 theSessionDict = (CFDictionaryRef) | 245 theSessionDict = (CFDictionaryRef) |
247 CFArrayGetValueAtIndex (theSessionArrayRef, index); | 246 CFArrayGetValueAtIndex(theSessionArrayRef, index); |
248 leadoutBlock = | 247 leadoutBlock = |
249 (CFNumberRef) CFDictionaryGetValue (theSessionDict, | 248 (CFNumberRef) CFDictionaryGetValue(theSessionDict, |
250 CFSTR | 249 CFSTR |
251 (kLeadoutBlockString)); | 250 (kLeadoutBlockString)); |
252 | 251 |
253 trackArray = | 252 trackArray = |
254 (CFArrayRef) CFDictionaryGetValue (theSessionDict, | 253 (CFArrayRef) CFDictionaryGetValue(theSessionDict, |
255 CFSTR (kTrackArrayString)); | 254 CFSTR(kTrackArrayString)); |
256 | 255 |
257 numTracks = CFArrayGetCount (trackArray); | 256 numTracks = CFArrayGetCount(trackArray); |
258 | 257 |
259 for (trackIndex = 0; trackIndex < numTracks; trackIndex++) { | 258 for (trackIndex = 0; trackIndex < numTracks; trackIndex++) { |
260 | 259 |
261 CFDictionaryRef theTrackDict; | 260 CFDictionaryRef theTrackDict; |
262 CFNumberRef trackNumber; | 261 CFNumberRef trackNumber; |
264 CFNumberRef startBlock; | 263 CFNumberRef startBlock; |
265 CFBooleanRef isDataTrack; | 264 CFBooleanRef isDataTrack; |
266 UInt32 value; | 265 UInt32 value; |
267 | 266 |
268 theTrackDict = (CFDictionaryRef) | 267 theTrackDict = (CFDictionaryRef) |
269 CFArrayGetValueAtIndex (trackArray, trackIndex); | 268 CFArrayGetValueAtIndex(trackArray, trackIndex); |
270 | 269 |
271 trackNumber = | 270 trackNumber = |
272 (CFNumberRef) CFDictionaryGetValue (theTrackDict, | 271 (CFNumberRef) CFDictionaryGetValue(theTrackDict, |
272 CFSTR | |
273 (kPointKeyString)); | |
274 sessionNumber = | |
275 (CFNumberRef) CFDictionaryGetValue(theTrackDict, | |
276 CFSTR | |
277 (kSessionNumberKeyString)); | |
278 startBlock = | |
279 (CFNumberRef) CFDictionaryGetValue(theTrackDict, | |
280 CFSTR | |
281 (kStartBlockKeyString)); | |
282 isDataTrack = | |
283 (CFBooleanRef) CFDictionaryGetValue(theTrackDict, | |
273 CFSTR | 284 CFSTR |
274 (kPointKeyString)); | 285 (kDataKeyString)); |
275 sessionNumber = | |
276 (CFNumberRef) CFDictionaryGetValue (theTrackDict, | |
277 CFSTR | |
278 (kSessionNumberKeyString)); | |
279 startBlock = | |
280 (CFNumberRef) CFDictionaryGetValue (theTrackDict, | |
281 CFSTR | |
282 (kStartBlockKeyString)); | |
283 isDataTrack = | |
284 (CFBooleanRef) CFDictionaryGetValue (theTrackDict, | |
285 CFSTR | |
286 (kDataKeyString)); | |
287 | 286 |
288 /* Fill in the SDL_CD struct */ | 287 /* Fill in the SDL_CD struct */ |
289 int idx = theCD->numtracks++; | 288 int idx = theCD->numtracks++; |
290 | 289 |
291 CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value); | 290 CFNumberGetValue(trackNumber, kCFNumberSInt32Type, &value); |
292 theCD->track[idx].id = value; | 291 theCD->track[idx].id = value; |
293 | 292 |
294 CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value); | 293 CFNumberGetValue(startBlock, kCFNumberSInt32Type, &value); |
295 theCD->track[idx].offset = value; | 294 theCD->track[idx].offset = value; |
296 | 295 |
297 theCD->track[idx].type = | 296 theCD->track[idx].type = |
298 (isDataTrack == | 297 (isDataTrack == |
299 kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK; | 298 kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK; |
305 1].offset; | 304 1].offset; |
306 } | 305 } |
307 } | 306 } |
308 | 307 |
309 /* Compute the length of the last track */ | 308 /* Compute the length of the last track */ |
310 CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value); | 309 CFNumberGetValue(leadoutBlock, kCFNumberSInt32Type, &value); |
311 | 310 |
312 theCD->track[theCD->numtracks - 1].length = | 311 theCD->track[theCD->numtracks - 1].length = |
313 value - theCD->track[theCD->numtracks - 1].offset; | 312 value - theCD->track[theCD->numtracks - 1].offset; |
314 | 313 |
315 /* Set offset to leadout track */ | 314 /* Set offset to leadout track */ |
319 } | 318 } |
320 | 319 |
321 theErr = 0; | 320 theErr = 0; |
322 goto cleanup; | 321 goto cleanup; |
323 bail: | 322 bail: |
324 SDL_SetError ("ReadTOCData: %s returned %d", error, theErr); | 323 SDL_SetError("ReadTOCData: %s returned %d", error, theErr); |
325 theErr = -1; | 324 theErr = -1; |
326 cleanup: | 325 cleanup: |
327 | 326 |
328 if (propertyListRef != NULL) | 327 if (propertyListRef != NULL) |
329 CFRelease (propertyListRef); | 328 CFRelease(propertyListRef); |
330 if (dataRef != NULL) | 329 if (dataRef != NULL) |
331 CFRelease (dataRef); | 330 CFRelease(dataRef); |
332 if (forkData != NULL) | 331 if (forkData != NULL) |
333 DisposePtr (forkData); | 332 DisposePtr(forkData); |
334 | 333 |
335 FSCloseFork (forkRefNum); | 334 FSCloseFork(forkRefNum); |
336 | 335 |
337 return theErr; | 336 return theErr; |
338 } | 337 } |
339 | 338 |
340 int | 339 int |
341 ListTrackFiles (FSVolumeRefNum theVolume, FSRef * trackFiles, int numTracks) | 340 ListTrackFiles(FSVolumeRefNum theVolume, FSRef * trackFiles, int numTracks) |
342 { | 341 { |
343 OSStatus result = -1; | 342 OSStatus result = -1; |
344 FSIterator iterator; | 343 FSIterator iterator; |
345 ItemCount actualObjects; | 344 ItemCount actualObjects; |
346 FSRef rootDirectory; | 345 FSRef rootDirectory; |
347 FSRef ref; | 346 FSRef ref; |
348 HFSUniStr255 nameStr; | 347 HFSUniStr255 nameStr; |
349 | 348 |
350 result = FSGetVolumeInfo (theVolume, | 349 result = FSGetVolumeInfo(theVolume, |
351 0, | 350 0, |
352 NULL, | 351 NULL, |
353 kFSVolInfoFSInfo, NULL, NULL, &rootDirectory); | 352 kFSVolInfoFSInfo, NULL, NULL, &rootDirectory); |
354 | 353 |
355 if (result != noErr) { | 354 if (result != noErr) { |
356 SDL_SetError ("ListTrackFiles: FSGetVolumeInfo returned %d", result); | 355 SDL_SetError("ListTrackFiles: FSGetVolumeInfo returned %d", result); |
357 return result; | 356 return result; |
358 } | 357 } |
359 | 358 |
360 result = FSOpenIterator (&rootDirectory, kFSIterateFlat, &iterator); | 359 result = FSOpenIterator(&rootDirectory, kFSIterateFlat, &iterator); |
361 if (result == noErr) { | 360 if (result == noErr) { |
362 do { | 361 do { |
363 result = FSGetCatalogInfoBulk (iterator, 1, &actualObjects, | 362 result = FSGetCatalogInfoBulk(iterator, 1, &actualObjects, |
364 NULL, kFSCatInfoNone, NULL, | 363 NULL, kFSCatInfoNone, NULL, |
365 &ref, NULL, &nameStr); | 364 &ref, NULL, &nameStr); |
366 if (result == noErr) { | 365 if (result == noErr) { |
367 | 366 |
368 CFStringRef name; | 367 CFStringRef name; |
369 name = | 368 name = |
370 CFStringCreateWithCharacters (NULL, nameStr.unicode, | 369 CFStringCreateWithCharacters(NULL, nameStr.unicode, |
371 nameStr.length); | 370 nameStr.length); |
372 | 371 |
373 /* Look for .aiff extension */ | 372 /* Look for .aiff extension */ |
374 if (CFStringHasSuffix (name, CFSTR (".aiff")) || | 373 if (CFStringHasSuffix(name, CFSTR(".aiff")) || |
375 CFStringHasSuffix (name, CFSTR (".cdda"))) { | 374 CFStringHasSuffix(name, CFSTR(".cdda"))) { |
376 | 375 |
377 /* Extract the track id from the filename */ | 376 /* Extract the track id from the filename */ |
378 int trackID = 0, i = 0; | 377 int trackID = 0, i = 0; |
379 while (i < nameStr.length | 378 while (i < nameStr.length && !isdigit(nameStr.unicode[i])) { |
380 && !isdigit (nameStr.unicode[i])) { | |
381 ++i; | 379 ++i; |
382 } | 380 } |
383 while (i < nameStr.length && isdigit (nameStr.unicode[i])) { | 381 while (i < nameStr.length && isdigit(nameStr.unicode[i])) { |
384 trackID = 10 * trackID + (nameStr.unicode[i] - '0'); | 382 trackID = 10 * trackID + (nameStr.unicode[i] - '0'); |
385 ++i; | 383 ++i; |
386 } | 384 } |
387 | 385 |
388 #if DEBUG_CDROM | 386 #if DEBUG_CDROM |
389 printf ("Found AIFF for track %d: '%s'\n", | 387 printf("Found AIFF for track %d: '%s'\n", |
390 trackID, CFStringGetCStringPtr (name, | 388 trackID, CFStringGetCStringPtr(name, |
391 CFStringGetSystemEncoding | 389 CFStringGetSystemEncoding |
392 ())); | 390 ())); |
393 #endif | 391 #endif |
394 | 392 |
395 /* Track ID's start at 1, but we want to start at 0 */ | 393 /* Track ID's start at 1, but we want to start at 0 */ |
396 trackID--; | 394 trackID--; |
397 | 395 |
398 assert (0 <= trackID && trackID <= SDL_MAX_TRACKS); | 396 assert(0 <= trackID && trackID <= SDL_MAX_TRACKS); |
399 | 397 |
400 if (trackID < numTracks) | 398 if (trackID < numTracks) |
401 memcpy (&trackFiles[trackID], &ref, sizeof (FSRef)); | 399 memcpy(&trackFiles[trackID], &ref, sizeof(FSRef)); |
402 } | 400 } |
403 CFRelease (name); | 401 CFRelease(name); |
404 } | 402 } |
405 } | 403 } |
406 while (noErr == result); | 404 while (noErr == result); |
407 FSCloseIterator (iterator); | 405 FSCloseIterator(iterator); |
408 } | 406 } |
409 | 407 |
410 return 0; | 408 return 0; |
411 } | 409 } |
412 | 410 |
413 int | 411 int |
414 LoadFile (const FSRef * ref, int startFrame, int stopFrame) | 412 LoadFile(const FSRef * ref, int startFrame, int stopFrame) |
415 { | 413 { |
416 int error = -1; | 414 int error = -1; |
417 | 415 |
418 if (CheckInit () < 0) | 416 if (CheckInit() < 0) |
419 goto bail; | 417 goto bail; |
420 | 418 |
421 /* release any currently playing file */ | 419 /* release any currently playing file */ |
422 if (ReleaseFile () < 0) | 420 if (ReleaseFile() < 0) |
423 goto bail; | 421 goto bail; |
424 | 422 |
425 #if DEBUG_CDROM | 423 #if DEBUG_CDROM |
426 printf ("LoadFile: %d %d\n", startFrame, stopFrame); | 424 printf("LoadFile: %d %d\n", startFrame, stopFrame); |
427 #endif | 425 #endif |
428 | 426 |
429 /*try { */ | 427 /*try { */ |
430 | 428 |
431 /* create a new player, and attach to the audio unit */ | 429 /* create a new player, and attach to the audio unit */ |
432 | 430 |
433 thePlayer = new_AudioFilePlayer (ref); | 431 thePlayer = new_AudioFilePlayer(ref); |
434 if (thePlayer == NULL) { | 432 if (thePlayer == NULL) { |
435 SDL_SetError ("LoadFile: Could not create player"); | 433 SDL_SetError("LoadFile: Could not create player"); |
436 return -3; /*throw (-3); */ | 434 return -3; /*throw (-3); */ |
437 } | 435 } |
438 | 436 |
439 if (!thePlayer->SetDestination (thePlayer, &theUnit)) | 437 if (!thePlayer->SetDestination(thePlayer, &theUnit)) |
440 goto bail; | 438 goto bail; |
441 | 439 |
442 if (startFrame >= 0) | 440 if (startFrame >= 0) |
443 thePlayer->SetStartFrame (thePlayer, startFrame); | 441 thePlayer->SetStartFrame(thePlayer, startFrame); |
444 | 442 |
445 if (stopFrame >= 0 && stopFrame > startFrame) | 443 if (stopFrame >= 0 && stopFrame > startFrame) |
446 thePlayer->SetStopFrame (thePlayer, stopFrame); | 444 thePlayer->SetStopFrame(thePlayer, stopFrame); |
447 | 445 |
448 /* we set the notifier later */ | 446 /* we set the notifier later */ |
449 /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL); */ | 447 /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL); */ |
450 | 448 |
451 if (!thePlayer->Connect (thePlayer)) | 449 if (!thePlayer->Connect(thePlayer)) |
452 goto bail; | 450 goto bail; |
453 | 451 |
454 #if DEBUG_CDROM | 452 #if DEBUG_CDROM |
455 thePlayer->Print (thePlayer); | 453 thePlayer->Print(thePlayer); |
456 fflush (stdout); | 454 fflush(stdout); |
457 #endif | 455 #endif |
458 /*} | 456 /*} |
459 catch (...) | 457 catch (...) |
460 { | 458 { |
461 goto bail; | 459 goto bail; |
466 bail: | 464 bail: |
467 return error; | 465 return error; |
468 } | 466 } |
469 | 467 |
470 int | 468 int |
471 ReleaseFile () | 469 ReleaseFile() |
472 { | 470 { |
473 int error = -1; | 471 int error = -1; |
474 | 472 |
475 /* (Don't see any way that the original C++ code could throw here.) --ryan. */ | 473 /* (Don't see any way that the original C++ code could throw here.) --ryan. */ |
476 /*try { */ | 474 /*try { */ |
477 if (thePlayer != NULL) { | 475 if (thePlayer != NULL) { |
478 | 476 |
479 thePlayer->Disconnect (thePlayer); | 477 thePlayer->Disconnect(thePlayer); |
480 | 478 |
481 delete_AudioFilePlayer (thePlayer); | 479 delete_AudioFilePlayer(thePlayer); |
482 | 480 |
483 thePlayer = NULL; | 481 thePlayer = NULL; |
484 } | 482 } |
485 /*} | 483 /*} |
486 catch (...) | 484 catch (...) |
493 /* bail: */ | 491 /* bail: */ |
494 return error; | 492 return error; |
495 } | 493 } |
496 | 494 |
497 int | 495 int |
498 PlayFile () | 496 PlayFile() |
499 { | 497 { |
500 OSStatus result = -1; | 498 OSStatus result = -1; |
501 | 499 |
502 if (CheckInit () < 0) | 500 if (CheckInit() < 0) |
503 goto bail; | 501 goto bail; |
504 | 502 |
505 /*try { */ | 503 /*try { */ |
506 | 504 |
507 // start processing of the audio unit | 505 // start processing of the audio unit |
508 result = AudioOutputUnitStart (theUnit); | 506 result = AudioOutputUnitStart(theUnit); |
509 if (result) | 507 if (result) |
510 goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart") | 508 goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart") |
511 | 509 |
512 /*} | 510 /*} |
513 catch (...) | 511 catch (...) |
520 bail: | 518 bail: |
521 return result; | 519 return result; |
522 } | 520 } |
523 | 521 |
524 int | 522 int |
525 PauseFile () | 523 PauseFile() |
526 { | 524 { |
527 OSStatus result = -1; | 525 OSStatus result = -1; |
528 | 526 |
529 if (CheckInit () < 0) | 527 if (CheckInit() < 0) |
530 goto bail; | 528 goto bail; |
531 | 529 |
532 /*try { */ | 530 /*try { */ |
533 | 531 |
534 /* stop processing the audio unit */ | 532 /* stop processing the audio unit */ |
535 result = AudioOutputUnitStop (theUnit); | 533 result = AudioOutputUnitStop(theUnit); |
536 if (result) | 534 if (result) |
537 goto bail; /*THROW_RESULT("PauseFile: AudioOutputUnitStop") */ | 535 goto bail; /*THROW_RESULT("PauseFile: AudioOutputUnitStop") */ |
538 /*} | 536 /*} |
539 catch (...) | 537 catch (...) |
540 { | 538 { |
545 bail: | 543 bail: |
546 return result; | 544 return result; |
547 } | 545 } |
548 | 546 |
549 void | 547 void |
550 SetCompletionProc (CDPlayerCompletionProc proc, SDL_CD * cdrom) | 548 SetCompletionProc(CDPlayerCompletionProc proc, SDL_CD * cdrom) |
551 { | 549 { |
552 assert (thePlayer != NULL); | 550 assert(thePlayer != NULL); |
553 | 551 |
554 theCDROM = cdrom; | 552 theCDROM = cdrom; |
555 completionProc = proc; | 553 completionProc = proc; |
556 thePlayer->SetNotifier (thePlayer, FilePlayNotificationHandler, cdrom); | 554 thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, cdrom); |
557 } | 555 } |
558 | 556 |
559 int | 557 int |
560 GetCurrentFrame () | 558 GetCurrentFrame() |
561 { | 559 { |
562 int frame; | 560 int frame; |
563 | 561 |
564 if (thePlayer == NULL) | 562 if (thePlayer == NULL) |
565 frame = 0; | 563 frame = 0; |
566 else | 564 else |
567 frame = thePlayer->GetCurrentFrame (thePlayer); | 565 frame = thePlayer->GetCurrentFrame(thePlayer); |
568 | 566 |
569 return frame; | 567 return frame; |
570 } | 568 } |
571 | 569 |
572 | 570 |
573 #pragma mark -- Private Functions -- | 571 #pragma mark -- Private Functions -- |
574 | 572 |
575 static OSStatus | 573 static OSStatus |
576 CheckInit () | 574 CheckInit() |
577 { | 575 { |
578 if (playBackWasInit) | 576 if (playBackWasInit) |
579 return 0; | 577 return 0; |
580 | 578 |
581 OSStatus result = noErr; | 579 OSStatus result = noErr; |
582 | 580 |
583 /* Create the callback semaphore */ | 581 /* Create the callback semaphore */ |
584 callbackSem = SDL_CreateSemaphore (0); | 582 callbackSem = SDL_CreateSemaphore(0); |
585 | 583 |
586 /* Start callback thread */ | 584 /* Start callback thread */ |
587 SDL_CreateThread (RunCallBackThread, NULL); | 585 SDL_CreateThread(RunCallBackThread, NULL); |
588 | 586 |
589 { /*try { */ | 587 { /*try { */ |
590 ComponentDescription desc; | 588 ComponentDescription desc; |
591 | 589 |
592 desc.componentType = kAudioUnitComponentType; | 590 desc.componentType = kAudioUnitComponentType; |
593 desc.componentSubType = kAudioUnitSubType_Output; | 591 desc.componentSubType = kAudioUnitSubType_Output; |
594 desc.componentManufacturer = kAudioUnitID_DefaultOutput; | 592 desc.componentManufacturer = kAudioUnitID_DefaultOutput; |
595 desc.componentFlags = 0; | 593 desc.componentFlags = 0; |
596 desc.componentFlagsMask = 0; | 594 desc.componentFlagsMask = 0; |
597 | 595 |
598 Component comp = FindNextComponent (NULL, &desc); | 596 Component comp = FindNextComponent(NULL, &desc); |
599 if (comp == NULL) { | 597 if (comp == NULL) { |
600 SDL_SetError ("CheckInit: FindNextComponent returned NULL"); | 598 SDL_SetError("CheckInit: FindNextComponent returned NULL"); |
601 if (result) | 599 if (result) |
602 return -1; //throw(internalComponentErr); | 600 return -1; //throw(internalComponentErr); |
603 } | 601 } |
604 | 602 |
605 result = OpenAComponent (comp, &theUnit); | 603 result = OpenAComponent(comp, &theUnit); |
606 if (result) | 604 if (result) |
607 return -1; //THROW_RESULT("CheckInit: OpenAComponent") | 605 return -1; //THROW_RESULT("CheckInit: OpenAComponent") |
608 | 606 |
609 // you need to initialize the output unit before you set it as a destination | 607 // you need to initialize the output unit before you set it as a destination |
610 result = AudioUnitInitialize (theUnit); | 608 result = AudioUnitInitialize(theUnit); |
611 if (result) | 609 if (result) |
612 return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize") | 610 return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize") |
613 | 611 |
614 | 612 |
615 playBackWasInit = true; | 613 playBackWasInit = true; |
621 | 619 |
622 return 0; | 620 return 0; |
623 } | 621 } |
624 | 622 |
625 static void | 623 static void |
626 FilePlayNotificationHandler (void *inRefCon, OSStatus inStatus) | 624 FilePlayNotificationHandler(void *inRefCon, OSStatus inStatus) |
627 { | 625 { |
628 if (inStatus == kAudioFilePlay_FileIsFinished) { | 626 if (inStatus == kAudioFilePlay_FileIsFinished) { |
629 | 627 |
630 /* notify non-CA thread to perform the callback */ | 628 /* notify non-CA thread to perform the callback */ |
631 SDL_SemPost (callbackSem); | 629 SDL_SemPost(callbackSem); |
632 | 630 |
633 } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) { | 631 } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) { |
634 | 632 |
635 SDL_SetError ("CDPlayer Notification: buffer underrun"); | 633 SDL_SetError("CDPlayer Notification: buffer underrun"); |
636 } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) { | 634 } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) { |
637 | 635 |
638 SDL_SetError ("CDPlayer Notification: player is uninitialized"); | 636 SDL_SetError("CDPlayer Notification: player is uninitialized"); |
639 } else { | 637 } else { |
640 | 638 |
641 SDL_SetError ("CDPlayer Notification: unknown error %ld", inStatus); | 639 SDL_SetError("CDPlayer Notification: unknown error %ld", inStatus); |
642 } | 640 } |
643 } | 641 } |
644 | 642 |
645 static int | 643 static int |
646 RunCallBackThread (void *param) | 644 RunCallBackThread(void *param) |
647 { | 645 { |
648 for (;;) { | 646 for (;;) { |
649 | 647 |
650 SDL_SemWait (callbackSem); | 648 SDL_SemWait(callbackSem); |
651 | 649 |
652 if (completionProc && theCDROM) { | 650 if (completionProc && theCDROM) { |
653 #if DEBUG_CDROM | 651 #if DEBUG_CDROM |
654 printf ("callback!\n"); | 652 printf("callback!\n"); |
655 #endif | 653 #endif |
656 (*completionProc) (theCDROM); | 654 (*completionProc) (theCDROM); |
657 } else { | 655 } else { |
658 #if DEBUG_CDROM | 656 #if DEBUG_CDROM |
659 printf ("callback?\n"); | 657 printf("callback?\n"); |
660 #endif | 658 #endif |
661 } | 659 } |
662 } | 660 } |
663 | 661 |
664 #if DEBUG_CDROM | 662 #if DEBUG_CDROM |
665 printf ("thread dying now...\n"); | 663 printf("thread dying now...\n"); |
666 #endif | 664 #endif |
667 | 665 |
668 return 0; | 666 return 0; |
669 } | 667 } |
670 | 668 |