diff options
Diffstat (limited to 'apps/plugins/sdl/src/cdrom/macosx/CDPlayer.c')
-rw-r--r-- | apps/plugins/sdl/src/cdrom/macosx/CDPlayer.c | 636 |
1 files changed, 0 insertions, 636 deletions
diff --git a/apps/plugins/sdl/src/cdrom/macosx/CDPlayer.c b/apps/plugins/sdl/src/cdrom/macosx/CDPlayer.c deleted file mode 100644 index beb87cd85b..0000000000 --- a/apps/plugins/sdl/src/cdrom/macosx/CDPlayer.c +++ /dev/null | |||
@@ -1,636 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "CDPlayer.h" | ||
25 | #include "AudioFilePlayer.h" | ||
26 | #include "SDLOSXCAGuard.h" | ||
27 | |||
28 | /* we're exporting these functions into C land for SDL_syscdrom.c */ | ||
29 | /*extern "C" {*/ | ||
30 | |||
31 | /*/////////////////////////////////////////////////////////////////////////// | ||
32 | Constants | ||
33 | //////////////////////////////////////////////////////////////////////////*/ | ||
34 | |||
35 | #define kAudioCDFilesystemID (UInt16)(('J' << 8) | 'H') /* 'JH'; this avoids compiler warning */ | ||
36 | |||
37 | /* XML PList keys */ | ||
38 | #define kRawTOCDataString "Format 0x02 TOC Data" | ||
39 | #define kSessionsString "Sessions" | ||
40 | #define kSessionTypeString "Session Type" | ||
41 | #define kTrackArrayString "Track Array" | ||
42 | #define kFirstTrackInSessionString "First Track" | ||
43 | #define kLastTrackInSessionString "Last Track" | ||
44 | #define kLeadoutBlockString "Leadout Block" | ||
45 | #define kDataKeyString "Data" | ||
46 | #define kPointKeyString "Point" | ||
47 | #define kSessionNumberKeyString "Session Number" | ||
48 | #define kStartBlockKeyString "Start Block" | ||
49 | |||
50 | /*/////////////////////////////////////////////////////////////////////////// | ||
51 | Globals | ||
52 | //////////////////////////////////////////////////////////////////////////*/ | ||
53 | |||
54 | #pragma mark -- Globals -- | ||
55 | |||
56 | static int playBackWasInit = 0; | ||
57 | static AudioUnit theUnit; | ||
58 | static AudioFilePlayer* thePlayer = NULL; | ||
59 | static CDPlayerCompletionProc completionProc = NULL; | ||
60 | static SDL_mutex *apiMutex = NULL; | ||
61 | static SDL_sem *callbackSem; | ||
62 | static SDL_CD* theCDROM; | ||
63 | |||
64 | /*/////////////////////////////////////////////////////////////////////////// | ||
65 | Prototypes | ||
66 | //////////////////////////////////////////////////////////////////////////*/ | ||
67 | |||
68 | #pragma mark -- Prototypes -- | ||
69 | |||
70 | static OSStatus CheckInit (); | ||
71 | |||
72 | static void FilePlayNotificationHandler (void* inRefCon, OSStatus inStatus); | ||
73 | |||
74 | static int RunCallBackThread (void* inRefCon); | ||
75 | |||
76 | |||
77 | #pragma mark -- Public Functions -- | ||
78 | |||
79 | void Lock () | ||
80 | { | ||
81 | if (!apiMutex) { | ||
82 | apiMutex = SDL_CreateMutex(); | ||
83 | } | ||
84 | SDL_mutexP(apiMutex); | ||
85 | } | ||
86 | |||
87 | void Unlock () | ||
88 | { | ||
89 | SDL_mutexV(apiMutex); | ||
90 | } | ||
91 | |||
92 | int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes) | ||
93 | { | ||
94 | int volumeIndex; | ||
95 | int cdVolumeCount = 0; | ||
96 | OSStatus result = noErr; | ||
97 | |||
98 | for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++) | ||
99 | { | ||
100 | FSVolumeRefNum actualVolume; | ||
101 | FSVolumeInfo volumeInfo; | ||
102 | |||
103 | memset (&volumeInfo, 0, sizeof(volumeInfo)); | ||
104 | |||
105 | result = FSGetVolumeInfo (kFSInvalidVolumeRefNum, | ||
106 | volumeIndex, | ||
107 | &actualVolume, | ||
108 | kFSVolInfoFSInfo, | ||
109 | &volumeInfo, | ||
110 | NULL, | ||
111 | NULL); | ||
112 | |||
113 | if (result == noErr) | ||
114 | { | ||
115 | if (volumeInfo.filesystemID == kAudioCDFilesystemID) /* It's an audio CD */ | ||
116 | { | ||
117 | if (volumes != NULL && cdVolumeCount < numVolumes) | ||
118 | volumes[cdVolumeCount] = actualVolume; | ||
119 | |||
120 | cdVolumeCount++; | ||
121 | } | ||
122 | } | ||
123 | else | ||
124 | { | ||
125 | /* I'm commenting this out because it seems to be harmless */ | ||
126 | /*SDL_SetError ("DetectAudioCDVolumes: FSGetVolumeInfo returned %d", result);*/ | ||
127 | } | ||
128 | } | ||
129 | |||
130 | return cdVolumeCount; | ||
131 | } | ||
132 | |||
133 | int ReadTOCData (FSVolumeRefNum theVolume, SDL_CD *theCD) | ||
134 | { | ||
135 | HFSUniStr255 dataForkName; | ||
136 | OSStatus theErr; | ||
137 | FSIORefNum forkRefNum; | ||
138 | SInt64 forkSize; | ||
139 | Ptr forkData = 0; | ||
140 | ByteCount actualRead; | ||
141 | CFDataRef dataRef = 0; | ||
142 | CFPropertyListRef propertyListRef = 0; | ||
143 | FSRefParam fsRefPB; | ||
144 | FSRef tocPlistFSRef; | ||
145 | FSRef rootRef; | ||
146 | const char* error = "Unspecified Error"; | ||
147 | const UniChar uniName[] = { '.','T','O','C','.','p','l','i','s','t' }; | ||
148 | |||
149 | theErr = FSGetVolumeInfo(theVolume, 0, 0, kFSVolInfoNone, 0, 0, &rootRef); | ||
150 | if(theErr != noErr) { | ||
151 | error = "FSGetVolumeInfo"; | ||
152 | goto bail; | ||
153 | } | ||
154 | |||
155 | SDL_memset(&fsRefPB, '\0', sizeof (fsRefPB)); | ||
156 | |||
157 | /* get stuff from .TOC.plist */ | ||
158 | fsRefPB.ref = &rootRef; | ||
159 | fsRefPB.newRef = &tocPlistFSRef; | ||
160 | fsRefPB.nameLength = sizeof (uniName) / sizeof (uniName[0]); | ||
161 | fsRefPB.name = uniName; | ||
162 | fsRefPB.textEncodingHint = kTextEncodingUnknown; | ||
163 | |||
164 | theErr = PBMakeFSRefUnicodeSync (&fsRefPB); | ||
165 | if(theErr != noErr) { | ||
166 | error = "PBMakeFSRefUnicodeSync"; | ||
167 | goto bail; | ||
168 | } | ||
169 | |||
170 | /* Load and parse the TOC XML data */ | ||
171 | |||
172 | theErr = FSGetDataForkName (&dataForkName); | ||
173 | if (theErr != noErr) { | ||
174 | error = "FSGetDataForkName"; | ||
175 | goto bail; | ||
176 | } | ||
177 | |||
178 | theErr = FSOpenFork (&tocPlistFSRef, dataForkName.length, dataForkName.unicode, fsRdPerm, &forkRefNum); | ||
179 | if (theErr != noErr) { | ||
180 | error = "FSOpenFork"; | ||
181 | goto bail; | ||
182 | } | ||
183 | |||
184 | theErr = FSGetForkSize (forkRefNum, &forkSize); | ||
185 | if (theErr != noErr) { | ||
186 | error = "FSGetForkSize"; | ||
187 | goto bail; | ||
188 | } | ||
189 | |||
190 | /* Allocate some memory for the XML data */ | ||
191 | forkData = NewPtr (forkSize); | ||
192 | if(forkData == NULL) { | ||
193 | error = "NewPtr"; | ||
194 | goto bail; | ||
195 | } | ||
196 | |||
197 | theErr = FSReadFork (forkRefNum, fsFromStart, 0 /* offset location */, forkSize, forkData, &actualRead); | ||
198 | if(theErr != noErr) { | ||
199 | error = "FSReadFork"; | ||
200 | goto bail; | ||
201 | } | ||
202 | |||
203 | dataRef = CFDataCreate (kCFAllocatorDefault, (UInt8 *)forkData, forkSize); | ||
204 | if(dataRef == 0) { | ||
205 | error = "CFDataCreate"; | ||
206 | goto bail; | ||
207 | } | ||
208 | |||
209 | propertyListRef = CFPropertyListCreateFromXMLData (kCFAllocatorDefault, | ||
210 | dataRef, | ||
211 | kCFPropertyListImmutable, | ||
212 | NULL); | ||
213 | if (propertyListRef == NULL) { | ||
214 | error = "CFPropertyListCreateFromXMLData"; | ||
215 | goto bail; | ||
216 | } | ||
217 | |||
218 | /* Now we got the Property List in memory. Parse it. */ | ||
219 | |||
220 | /* First, make sure the root item is a CFDictionary. If not, release and bail. */ | ||
221 | if(CFGetTypeID(propertyListRef)== CFDictionaryGetTypeID()) | ||
222 | { | ||
223 | CFDictionaryRef dictRef = (CFDictionaryRef)propertyListRef; | ||
224 | |||
225 | CFDataRef theRawTOCDataRef; | ||
226 | CFArrayRef theSessionArrayRef; | ||
227 | CFIndex numSessions; | ||
228 | CFIndex index; | ||
229 | |||
230 | /* This is how we get the Raw TOC Data */ | ||
231 | theRawTOCDataRef = (CFDataRef)CFDictionaryGetValue (dictRef, CFSTR(kRawTOCDataString)); | ||
232 | |||
233 | /* Get the session array info. */ | ||
234 | theSessionArrayRef = (CFArrayRef)CFDictionaryGetValue (dictRef, CFSTR(kSessionsString)); | ||
235 | |||
236 | /* Find out how many sessions there are. */ | ||
237 | numSessions = CFArrayGetCount (theSessionArrayRef); | ||
238 | |||
239 | /* Initialize the total number of tracks to 0 */ | ||
240 | theCD->numtracks = 0; | ||
241 | |||
242 | /* Iterate over all sessions, collecting the track data */ | ||
243 | for(index = 0; index < numSessions; index++) | ||
244 | { | ||
245 | CFDictionaryRef theSessionDict; | ||
246 | CFNumberRef leadoutBlock; | ||
247 | CFArrayRef trackArray; | ||
248 | CFIndex numTracks; | ||
249 | CFIndex trackIndex; | ||
250 | UInt32 value = 0; | ||
251 | |||
252 | theSessionDict = (CFDictionaryRef) CFArrayGetValueAtIndex (theSessionArrayRef, index); | ||
253 | leadoutBlock = (CFNumberRef) CFDictionaryGetValue (theSessionDict, CFSTR(kLeadoutBlockString)); | ||
254 | |||
255 | trackArray = (CFArrayRef)CFDictionaryGetValue (theSessionDict, CFSTR(kTrackArrayString)); | ||
256 | |||
257 | numTracks = CFArrayGetCount (trackArray); | ||
258 | |||
259 | for(trackIndex = 0; trackIndex < numTracks; trackIndex++) { | ||
260 | |||
261 | CFDictionaryRef theTrackDict; | ||
262 | CFNumberRef trackNumber; | ||
263 | CFNumberRef sessionNumber; | ||
264 | CFNumberRef startBlock; | ||
265 | CFBooleanRef isDataTrack; | ||
266 | UInt32 value; | ||
267 | |||
268 | theTrackDict = (CFDictionaryRef) CFArrayGetValueAtIndex (trackArray, trackIndex); | ||
269 | |||
270 | trackNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kPointKeyString)); | ||
271 | sessionNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kSessionNumberKeyString)); | ||
272 | startBlock = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kStartBlockKeyString)); | ||
273 | isDataTrack = (CFBooleanRef) CFDictionaryGetValue (theTrackDict, CFSTR(kDataKeyString)); | ||
274 | |||
275 | /* Fill in the SDL_CD struct */ | ||
276 | int idx = theCD->numtracks++; | ||
277 | |||
278 | CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value); | ||
279 | theCD->track[idx].id = value; | ||
280 | |||
281 | CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value); | ||
282 | theCD->track[idx].offset = value; | ||
283 | |||
284 | theCD->track[idx].type = (isDataTrack == kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK; | ||
285 | |||
286 | /* Since the track lengths are not stored in .TOC.plist we compute them. */ | ||
287 | if (trackIndex > 0) { | ||
288 | theCD->track[idx-1].length = theCD->track[idx].offset - theCD->track[idx-1].offset; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | /* Compute the length of the last track */ | ||
293 | CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value); | ||
294 | |||
295 | theCD->track[theCD->numtracks-1].length = | ||
296 | value - theCD->track[theCD->numtracks-1].offset; | ||
297 | |||
298 | /* Set offset to leadout track */ | ||
299 | theCD->track[theCD->numtracks].offset = value; | ||
300 | } | ||
301 | |||
302 | } | ||
303 | |||
304 | theErr = 0; | ||
305 | goto cleanup; | ||
306 | bail: | ||
307 | SDL_SetError ("ReadTOCData: %s returned %d", error, theErr); | ||
308 | theErr = -1; | ||
309 | cleanup: | ||
310 | |||
311 | if (propertyListRef != NULL) | ||
312 | CFRelease(propertyListRef); | ||
313 | if (dataRef != NULL) | ||
314 | CFRelease(dataRef); | ||
315 | if (forkData != NULL) | ||
316 | DisposePtr(forkData); | ||
317 | |||
318 | FSCloseFork (forkRefNum); | ||
319 | |||
320 | return theErr; | ||
321 | } | ||
322 | |||
323 | int ListTrackFiles (FSVolumeRefNum theVolume, FSRef *trackFiles, int numTracks) | ||
324 | { | ||
325 | OSStatus result = -1; | ||
326 | FSIterator iterator; | ||
327 | ItemCount actualObjects; | ||
328 | FSRef rootDirectory; | ||
329 | FSRef ref; | ||
330 | HFSUniStr255 nameStr; | ||
331 | |||
332 | result = FSGetVolumeInfo (theVolume, | ||
333 | 0, | ||
334 | NULL, | ||
335 | kFSVolInfoFSInfo, | ||
336 | NULL, | ||
337 | NULL, | ||
338 | &rootDirectory); | ||
339 | |||
340 | if (result != noErr) { | ||
341 | SDL_SetError ("ListTrackFiles: FSGetVolumeInfo returned %d", result); | ||
342 | return result; | ||
343 | } | ||
344 | |||
345 | result = FSOpenIterator (&rootDirectory, kFSIterateFlat, &iterator); | ||
346 | if (result == noErr) { | ||
347 | do | ||
348 | { | ||
349 | result = FSGetCatalogInfoBulk (iterator, 1, &actualObjects, | ||
350 | NULL, kFSCatInfoNone, NULL, &ref, NULL, &nameStr); | ||
351 | if (result == noErr) { | ||
352 | |||
353 | CFStringRef name; | ||
354 | name = CFStringCreateWithCharacters (NULL, nameStr.unicode, nameStr.length); | ||
355 | |||
356 | /* Look for .aiff extension */ | ||
357 | if (CFStringHasSuffix (name, CFSTR(".aiff")) || | ||
358 | CFStringHasSuffix (name, CFSTR(".cdda"))) { | ||
359 | |||
360 | /* Extract the track id from the filename */ | ||
361 | int trackID = 0, i = 0; | ||
362 | while (i < nameStr.length && !isdigit(nameStr.unicode[i])) { | ||
363 | ++i; | ||
364 | } | ||
365 | while (i < nameStr.length && isdigit(nameStr.unicode[i])) { | ||
366 | trackID = 10 * trackID +(nameStr.unicode[i] - '0'); | ||
367 | ++i; | ||
368 | } | ||
369 | |||
370 | #if DEBUG_CDROM | ||
371 | printf("Found AIFF for track %d: '%s'\n", trackID, | ||
372 | CFStringGetCStringPtr (name, CFStringGetSystemEncoding())); | ||
373 | #endif | ||
374 | |||
375 | /* Track ID's start at 1, but we want to start at 0 */ | ||
376 | trackID--; | ||
377 | |||
378 | assert(0 <= trackID && trackID <= SDL_MAX_TRACKS); | ||
379 | |||
380 | if (trackID < numTracks) | ||
381 | memcpy (&trackFiles[trackID], &ref, sizeof(FSRef)); | ||
382 | } | ||
383 | CFRelease (name); | ||
384 | } | ||
385 | } while(noErr == result); | ||
386 | FSCloseIterator (iterator); | ||
387 | } | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | int LoadFile (const FSRef *ref, int startFrame, int stopFrame) | ||
393 | { | ||
394 | int error = -1; | ||
395 | |||
396 | if (CheckInit () < 0) | ||
397 | goto bail; | ||
398 | |||
399 | /* release any currently playing file */ | ||
400 | if (ReleaseFile () < 0) | ||
401 | goto bail; | ||
402 | |||
403 | #if DEBUG_CDROM | ||
404 | printf ("LoadFile: %d %d\n", startFrame, stopFrame); | ||
405 | #endif | ||
406 | |||
407 | /*try {*/ | ||
408 | |||
409 | /* create a new player, and attach to the audio unit */ | ||
410 | |||
411 | thePlayer = new_AudioFilePlayer(ref); | ||
412 | if (thePlayer == NULL) { | ||
413 | SDL_SetError ("LoadFile: Could not create player"); | ||
414 | return -3; /*throw (-3);*/ | ||
415 | } | ||
416 | |||
417 | if (!thePlayer->SetDestination(thePlayer, &theUnit)) | ||
418 | goto bail; | ||
419 | |||
420 | if (startFrame >= 0) | ||
421 | thePlayer->SetStartFrame (thePlayer, startFrame); | ||
422 | |||
423 | if (stopFrame >= 0 && stopFrame > startFrame) | ||
424 | thePlayer->SetStopFrame (thePlayer, stopFrame); | ||
425 | |||
426 | /* we set the notifier later */ | ||
427 | /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL);*/ | ||
428 | |||
429 | if (!thePlayer->Connect(thePlayer)) | ||
430 | goto bail; | ||
431 | |||
432 | #if DEBUG_CDROM | ||
433 | thePlayer->Print(thePlayer); | ||
434 | fflush (stdout); | ||
435 | #endif | ||
436 | /*} | ||
437 | catch (...) | ||
438 | { | ||
439 | goto bail; | ||
440 | }*/ | ||
441 | |||
442 | error = 0; | ||
443 | |||
444 | bail: | ||
445 | return error; | ||
446 | } | ||
447 | |||
448 | int ReleaseFile () | ||
449 | { | ||
450 | int error = -1; | ||
451 | |||
452 | /* (Don't see any way that the original C++ code could throw here.) --ryan. */ | ||
453 | /*try {*/ | ||
454 | if (thePlayer != NULL) { | ||
455 | |||
456 | thePlayer->Disconnect(thePlayer); | ||
457 | |||
458 | delete_AudioFilePlayer(thePlayer); | ||
459 | |||
460 | thePlayer = NULL; | ||
461 | } | ||
462 | /*} | ||
463 | catch (...) | ||
464 | { | ||
465 | goto bail; | ||
466 | }*/ | ||
467 | |||
468 | error = 0; | ||
469 | |||
470 | /* bail: */ | ||
471 | return error; | ||
472 | } | ||
473 | |||
474 | int PlayFile () | ||
475 | { | ||
476 | OSStatus result = -1; | ||
477 | |||
478 | if (CheckInit () < 0) | ||
479 | goto bail; | ||
480 | |||
481 | /*try {*/ | ||
482 | |||
483 | // start processing of the audio unit | ||
484 | result = AudioOutputUnitStart (theUnit); | ||
485 | if (result) goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart") | ||
486 | |||
487 | /*} | ||
488 | catch (...) | ||
489 | { | ||
490 | goto bail; | ||
491 | }*/ | ||
492 | |||
493 | result = 0; | ||
494 | |||
495 | bail: | ||
496 | return result; | ||
497 | } | ||
498 | |||
499 | int PauseFile () | ||
500 | { | ||
501 | OSStatus result = -1; | ||
502 | |||
503 | if (CheckInit () < 0) | ||
504 | goto bail; | ||
505 | |||
506 | /*try {*/ | ||
507 | |||
508 | /* stop processing the audio unit */ | ||
509 | result = AudioOutputUnitStop (theUnit); | ||
510 | if (result) goto bail; /*THROW_RESULT("PauseFile: AudioOutputUnitStop")*/ | ||
511 | /*} | ||
512 | catch (...) | ||
513 | { | ||
514 | goto bail; | ||
515 | }*/ | ||
516 | |||
517 | result = 0; | ||
518 | bail: | ||
519 | return result; | ||
520 | } | ||
521 | |||
522 | void SetCompletionProc (CDPlayerCompletionProc proc, SDL_CD *cdrom) | ||
523 | { | ||
524 | assert(thePlayer != NULL); | ||
525 | |||
526 | theCDROM = cdrom; | ||
527 | completionProc = proc; | ||
528 | thePlayer->SetNotifier (thePlayer, FilePlayNotificationHandler, cdrom); | ||
529 | } | ||
530 | |||
531 | int GetCurrentFrame () | ||
532 | { | ||
533 | int frame; | ||
534 | |||
535 | if (thePlayer == NULL) | ||
536 | frame = 0; | ||
537 | else | ||
538 | frame = thePlayer->GetCurrentFrame (thePlayer); | ||
539 | |||
540 | return frame; | ||
541 | } | ||
542 | |||
543 | |||
544 | #pragma mark -- Private Functions -- | ||
545 | |||
546 | static OSStatus CheckInit () | ||
547 | { | ||
548 | if (playBackWasInit) | ||
549 | return 0; | ||
550 | |||
551 | OSStatus result = noErr; | ||
552 | |||
553 | /* Create the callback semaphore */ | ||
554 | callbackSem = SDL_CreateSemaphore(0); | ||
555 | |||
556 | /* Start callback thread */ | ||
557 | SDL_CreateThread(RunCallBackThread, NULL); | ||
558 | |||
559 | { /*try {*/ | ||
560 | ComponentDescription desc; | ||
561 | |||
562 | desc.componentType = kAudioUnitType_Output; | ||
563 | desc.componentSubType = kAudioUnitSubType_DefaultOutput; | ||
564 | desc.componentManufacturer = kAudioUnitManufacturer_Apple; | ||
565 | desc.componentFlags = 0; | ||
566 | desc.componentFlagsMask = 0; | ||
567 | |||
568 | Component comp = FindNextComponent (NULL, &desc); | ||
569 | if (comp == NULL) { | ||
570 | SDL_SetError ("CheckInit: FindNextComponent returned NULL"); | ||
571 | if (result) return -1; //throw(internalComponentErr); | ||
572 | } | ||
573 | |||
574 | result = OpenAComponent (comp, &theUnit); | ||
575 | if (result) return -1; //THROW_RESULT("CheckInit: OpenAComponent") | ||
576 | |||
577 | // you need to initialize the output unit before you set it as a destination | ||
578 | result = AudioUnitInitialize (theUnit); | ||
579 | if (result) return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize") | ||
580 | |||
581 | |||
582 | playBackWasInit = true; | ||
583 | } | ||
584 | /*catch (...) | ||
585 | { | ||
586 | return -1; | ||
587 | }*/ | ||
588 | |||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | static void FilePlayNotificationHandler(void * inRefCon, OSStatus inStatus) | ||
593 | { | ||
594 | if (inStatus == kAudioFilePlay_FileIsFinished) { | ||
595 | |||
596 | /* notify non-CA thread to perform the callback */ | ||
597 | SDL_SemPost(callbackSem); | ||
598 | |||
599 | } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) { | ||
600 | |||
601 | SDL_SetError ("CDPlayer Notification: buffer underrun"); | ||
602 | } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) { | ||
603 | |||
604 | SDL_SetError ("CDPlayer Notification: player is uninitialized"); | ||
605 | } else { | ||
606 | |||
607 | SDL_SetError ("CDPlayer Notification: unknown error %ld", inStatus); | ||
608 | } | ||
609 | } | ||
610 | |||
611 | static int RunCallBackThread (void *param) | ||
612 | { | ||
613 | for (;;) { | ||
614 | |||
615 | SDL_SemWait(callbackSem); | ||
616 | |||
617 | if (completionProc && theCDROM) { | ||
618 | #if DEBUG_CDROM | ||
619 | printf ("callback!\n"); | ||
620 | #endif | ||
621 | (*completionProc)(theCDROM); | ||
622 | } else { | ||
623 | #if DEBUG_CDROM | ||
624 | printf ("callback?\n"); | ||
625 | #endif | ||
626 | } | ||
627 | } | ||
628 | |||
629 | #if DEBUG_CDROM | ||
630 | printf ("thread dying now...\n"); | ||
631 | #endif | ||
632 | |||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | /*}; // extern "C" */ | ||