comparison src/cdrom/macosx/CDPlayer.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents dc6b59e925a2
children e27bdcc80744
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
30 30
31 /*/////////////////////////////////////////////////////////////////////////// 31 /*///////////////////////////////////////////////////////////////////////////
32 Constants 32 Constants
33 //////////////////////////////////////////////////////////////////////////*/ 33 //////////////////////////////////////////////////////////////////////////*/
34 34
35 #define kAudioCDFilesystemID (UInt16)(('J' << 8) | 'H') /* 'JH'; this avoids compiler warning */ 35 #define kAudioCDFilesystemID (UInt16)(('J' << 8) | 'H') /* 'JH'; this avoids compiler warning */
36 36
37 /* XML PList keys */ 37 /* XML PList keys */
38 #define kRawTOCDataString "Format 0x02 TOC Data" 38 #define kRawTOCDataString "Format 0x02 TOC Data"
39 #define kSessionsString "Sessions" 39 #define kSessionsString "Sessions"
40 #define kSessionTypeString "Session Type" 40 #define kSessionTypeString "Session Type"
43 #define kLastTrackInSessionString "Last Track" 43 #define kLastTrackInSessionString "Last Track"
44 #define kLeadoutBlockString "Leadout Block" 44 #define kLeadoutBlockString "Leadout Block"
45 #define kDataKeyString "Data" 45 #define kDataKeyString "Data"
46 #define kPointKeyString "Point" 46 #define kPointKeyString "Point"
47 #define kSessionNumberKeyString "Session Number" 47 #define kSessionNumberKeyString "Session Number"
48 #define kStartBlockKeyString "Start Block" 48 #define kStartBlockKeyString "Start Block"
49 49
50 /*/////////////////////////////////////////////////////////////////////////// 50 /*///////////////////////////////////////////////////////////////////////////
51 Globals 51 Globals
52 //////////////////////////////////////////////////////////////////////////*/ 52 //////////////////////////////////////////////////////////////////////////*/
53 53
54 #pragma mark -- Globals -- 54 #pragma mark -- Globals --
55 55
56 static int playBackWasInit = 0; 56 static int playBackWasInit = 0;
57 static AudioUnit theUnit; 57 static AudioUnit theUnit;
58 static AudioFilePlayer* thePlayer = NULL; 58 static AudioFilePlayer *thePlayer = NULL;
59 static CDPlayerCompletionProc completionProc = NULL; 59 static CDPlayerCompletionProc completionProc = NULL;
60 static SDL_mutex *apiMutex = NULL; 60 static SDL_mutex *apiMutex = NULL;
61 static SDL_sem *callbackSem; 61 static SDL_sem *callbackSem;
62 static SDL_CD* theCDROM; 62 static SDL_CD *theCDROM;
63 63
64 /*/////////////////////////////////////////////////////////////////////////// 64 /*///////////////////////////////////////////////////////////////////////////
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 Lock () 79 void
80 Lock()
80 { 81 {
81 if (!apiMutex) { 82 if (!apiMutex) {
82 apiMutex = SDL_CreateMutex(); 83 apiMutex = SDL_CreateMutex();
83 } 84 }
84 SDL_mutexP(apiMutex); 85 SDL_mutexP(apiMutex);
85 } 86 }
86 87
87 void Unlock () 88 void
89 Unlock()
88 { 90 {
89 SDL_mutexV(apiMutex); 91 SDL_mutexV(apiMutex);
90 } 92 }
91 93
92 int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes) 94 int
95 DetectAudioCDVolumes(FSVolumeRefNum * volumes, int numVolumes)
93 { 96 {
94 int volumeIndex; 97 int volumeIndex;
95 int cdVolumeCount = 0; 98 int cdVolumeCount = 0;
96 OSStatus result = noErr; 99 OSStatus result = noErr;
97 100
98 for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++) 101 for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++) {
99 { 102 FSVolumeRefNum actualVolume;
100 FSVolumeRefNum actualVolume; 103 FSVolumeInfo volumeInfo;
101 FSVolumeInfo volumeInfo; 104
102 105 memset(&volumeInfo, 0, sizeof(volumeInfo));
103 memset (&volumeInfo, 0, sizeof(volumeInfo)); 106
104 107 result = FSGetVolumeInfo(kFSInvalidVolumeRefNum,
105 result = FSGetVolumeInfo (kFSInvalidVolumeRefNum, 108 volumeIndex,
106 volumeIndex, 109 &actualVolume,
107 &actualVolume, 110 kFSVolInfoFSInfo, &volumeInfo, NULL, NULL);
108 kFSVolInfoFSInfo, 111
109 &volumeInfo, 112 if (result == noErr) {
110 NULL, 113 if (volumeInfo.filesystemID == kAudioCDFilesystemID) { /* It's an audio CD */
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) 114 if (volumes != NULL && cdVolumeCount < numVolumes)
118 volumes[cdVolumeCount] = actualVolume; 115 volumes[cdVolumeCount] = actualVolume;
119 116
120 cdVolumeCount++; 117 cdVolumeCount++;
121 } 118 }
119 } else {
120 /* I'm commenting this out because it seems to be harmless */
121 /*SDL_SetError ("DetectAudioCDVolumes: FSGetVolumeInfo returned %d", result); */
122 } 122 }
123 else 123 }
124 { 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; 125 return cdVolumeCount;
131 } 126 }
132 127
133 int ReadTOCData (FSVolumeRefNum theVolume, SDL_CD *theCD) 128 int
134 { 129 ReadTOCData(FSVolumeRefNum theVolume, SDL_CD * theCD)
135 HFSUniStr255 dataForkName; 130 {
136 OSStatus theErr; 131 HFSUniStr255 dataForkName;
137 SInt16 forkRefNum; 132 OSStatus theErr;
138 SInt64 forkSize; 133 SInt16 forkRefNum;
139 Ptr forkData = 0; 134 SInt64 forkSize;
140 ByteCount actualRead; 135 Ptr forkData = 0;
141 CFDataRef dataRef = 0; 136 ByteCount actualRead;
137 CFDataRef dataRef = 0;
142 CFPropertyListRef propertyListRef = 0; 138 CFPropertyListRef propertyListRef = 0;
143 139
144 FSRefParam fsRefPB; 140 FSRefParam fsRefPB;
145 FSRef tocPlistFSRef; 141 FSRef tocPlistFSRef;
146 142
147 const char* error = "Unspecified Error"; 143 const char *error = "Unspecified Error";
148 144
149 /* get stuff from .TOC.plist */ 145 /* get stuff from .TOC.plist */
150 fsRefPB.ioCompletion = NULL; 146 fsRefPB.ioCompletion = NULL;
151 fsRefPB.ioNamePtr = "\p.TOC.plist"; 147 fsRefPB.ioNamePtr = "\p.TOC.plist";
152 fsRefPB.ioVRefNum = theVolume; 148 fsRefPB.ioVRefNum = theVolume;
153 fsRefPB.ioDirID = 0; 149 fsRefPB.ioDirID = 0;
154 fsRefPB.newRef = &tocPlistFSRef; 150 fsRefPB.newRef = &tocPlistFSRef;
155 151
156 theErr = PBMakeFSRefSync (&fsRefPB); 152 theErr = PBMakeFSRefSync(&fsRefPB);
157 if(theErr != noErr) { 153 if (theErr != noErr) {
158 error = "PBMakeFSRefSync"; 154 error = "PBMakeFSRefSync";
159 goto bail; 155 goto bail;
160 } 156 }
161 157
162 /* Load and parse the TOC XML data */ 158 /* Load and parse the TOC XML data */
163 159
164 theErr = FSGetDataForkName (&dataForkName); 160 theErr = FSGetDataForkName(&dataForkName);
165 if (theErr != noErr) { 161 if (theErr != noErr) {
166 error = "FSGetDataForkName"; 162 error = "FSGetDataForkName";
167 goto bail; 163 goto bail;
168 } 164 }
169 165
170 theErr = FSOpenFork (&tocPlistFSRef, dataForkName.length, dataForkName.unicode, fsRdPerm, &forkRefNum); 166 theErr =
167 FSOpenFork(&tocPlistFSRef, dataForkName.length, dataForkName.unicode,
168 fsRdPerm, &forkRefNum);
171 if (theErr != noErr) { 169 if (theErr != noErr) {
172 error = "FSOpenFork"; 170 error = "FSOpenFork";
173 goto bail; 171 goto bail;
174 } 172 }
175 173
176 theErr = FSGetForkSize (forkRefNum, &forkSize); 174 theErr = FSGetForkSize(forkRefNum, &forkSize);
177 if (theErr != noErr) { 175 if (theErr != noErr) {
178 error = "FSGetForkSize"; 176 error = "FSGetForkSize";
179 goto bail; 177 goto bail;
180 } 178 }
181 179
182 /* Allocate some memory for the XML data */ 180 /* Allocate some memory for the XML data */
183 forkData = NewPtr (forkSize); 181 forkData = NewPtr(forkSize);
184 if(forkData == NULL) { 182 if (forkData == NULL) {
185 error = "NewPtr"; 183 error = "NewPtr";
186 goto bail; 184 goto bail;
187 } 185 }
188 186
189 theErr = FSReadFork (forkRefNum, fsFromStart, 0 /* offset location */, forkSize, forkData, &actualRead); 187 theErr = FSReadFork(forkRefNum, fsFromStart, 0 /* offset location */ ,
190 if(theErr != noErr) { 188 forkSize, forkData, &actualRead);
189 if (theErr != noErr) {
191 error = "FSReadFork"; 190 error = "FSReadFork";
192 goto bail; 191 goto bail;
193 } 192 }
194 193
195 dataRef = CFDataCreate (kCFAllocatorDefault, (UInt8 *)forkData, forkSize); 194 dataRef = 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 { 213 CFDictionaryRef dictRef = (CFDictionaryRef) propertyListRef;
215 CFDictionaryRef dictRef = (CFDictionaryRef)propertyListRef; 214
216 215 CFDataRef theRawTOCDataRef;
217 CFDataRef theRawTOCDataRef; 216 CFArrayRef theSessionArrayRef;
218 CFArrayRef theSessionArrayRef; 217 CFIndex numSessions;
219 CFIndex numSessions; 218 CFIndex index;
220 CFIndex index; 219
221
222 /* This is how we get the Raw TOC Data */ 220 /* This is how we get the Raw TOC Data */
223 theRawTOCDataRef = (CFDataRef)CFDictionaryGetValue (dictRef, CFSTR(kRawTOCDataString)); 221 theRawTOCDataRef =
224 222 (CFDataRef) CFDictionaryGetValue(dictRef,
223 CFSTR(kRawTOCDataString));
224
225 /* Get the session array info. */ 225 /* Get the session array info. */
226 theSessionArrayRef = (CFArrayRef)CFDictionaryGetValue (dictRef, CFSTR(kSessionsString)); 226 theSessionArrayRef =
227 227 (CFArrayRef) CFDictionaryGetValue(dictRef,
228 CFSTR(kSessionsString));
229
228 /* Find out how many sessions there are. */ 230 /* Find out how many sessions there are. */
229 numSessions = CFArrayGetCount (theSessionArrayRef); 231 numSessions = CFArrayGetCount(theSessionArrayRef);
230 232
231 /* Initialize the total number of tracks to 0 */ 233 /* Initialize the total number of tracks to 0 */
232 theCD->numtracks = 0; 234 theCD->numtracks = 0;
233 235
234 /* Iterate over all sessions, collecting the track data */ 236 /* Iterate over all sessions, collecting the track data */
235 for(index = 0; index < numSessions; index++) 237 for (index = 0; index < numSessions; index++) {
236 {
237 CFDictionaryRef theSessionDict; 238 CFDictionaryRef theSessionDict;
238 CFNumberRef leadoutBlock; 239 CFNumberRef leadoutBlock;
239 CFArrayRef trackArray; 240 CFArrayRef trackArray;
240 CFIndex numTracks; 241 CFIndex numTracks;
241 CFIndex trackIndex; 242 CFIndex trackIndex;
242 UInt32 value = 0; 243 UInt32 value = 0;
243 244
244 theSessionDict = (CFDictionaryRef) CFArrayGetValueAtIndex (theSessionArrayRef, index); 245 theSessionDict = (CFDictionaryRef)
245 leadoutBlock = (CFNumberRef) CFDictionaryGetValue (theSessionDict, CFSTR(kLeadoutBlockString)); 246 CFArrayGetValueAtIndex(theSessionArrayRef, index);
246 247 leadoutBlock =
247 trackArray = (CFArrayRef)CFDictionaryGetValue (theSessionDict, CFSTR(kTrackArrayString)); 248 (CFNumberRef) CFDictionaryGetValue(theSessionDict,
248 249 CFSTR
249 numTracks = CFArrayGetCount (trackArray); 250 (kLeadoutBlockString));
250 251
251 for(trackIndex = 0; trackIndex < numTracks; trackIndex++) { 252 trackArray =
252 253 (CFArrayRef) CFDictionaryGetValue(theSessionDict,
254 CFSTR(kTrackArrayString));
255
256 numTracks = CFArrayGetCount(trackArray);
257
258 for (trackIndex = 0; trackIndex < numTracks; trackIndex++) {
259
253 CFDictionaryRef theTrackDict; 260 CFDictionaryRef theTrackDict;
254 CFNumberRef trackNumber; 261 CFNumberRef trackNumber;
255 CFNumberRef sessionNumber; 262 CFNumberRef sessionNumber;
256 CFNumberRef startBlock; 263 CFNumberRef startBlock;
257 CFBooleanRef isDataTrack; 264 CFBooleanRef isDataTrack;
258 UInt32 value; 265 UInt32 value;
259 266
260 theTrackDict = (CFDictionaryRef) CFArrayGetValueAtIndex (trackArray, trackIndex); 267 theTrackDict = (CFDictionaryRef)
261 268 CFArrayGetValueAtIndex(trackArray, trackIndex);
262 trackNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kPointKeyString)); 269
263 sessionNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kSessionNumberKeyString)); 270 trackNumber =
264 startBlock = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kStartBlockKeyString)); 271 (CFNumberRef) CFDictionaryGetValue(theTrackDict,
265 isDataTrack = (CFBooleanRef) CFDictionaryGetValue (theTrackDict, CFSTR(kDataKeyString)); 272 CFSTR
266 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,
284 CFSTR
285 (kDataKeyString));
286
267 /* Fill in the SDL_CD struct */ 287 /* Fill in the SDL_CD struct */
268 int idx = theCD->numtracks++; 288 int idx = theCD->numtracks++;
269 289
270 CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value); 290 CFNumberGetValue(trackNumber, kCFNumberSInt32Type, &value);
271 theCD->track[idx].id = value; 291 theCD->track[idx].id = value;
272 292
273 CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value); 293 CFNumberGetValue(startBlock, kCFNumberSInt32Type, &value);
274 theCD->track[idx].offset = value; 294 theCD->track[idx].offset = value;
275 295
276 theCD->track[idx].type = (isDataTrack == kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK; 296 theCD->track[idx].type =
297 (isDataTrack ==
298 kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK;
277 299
278 /* Since the track lengths are not stored in .TOC.plist we compute them. */ 300 /* Since the track lengths are not stored in .TOC.plist we compute them. */
279 if (trackIndex > 0) { 301 if (trackIndex > 0) {
280 theCD->track[idx-1].length = theCD->track[idx].offset - theCD->track[idx-1].offset; 302 theCD->track[idx - 1].length =
303 theCD->track[idx].offset - theCD->track[idx -
304 1].offset;
281 } 305 }
282 } 306 }
283 307
284 /* Compute the length of the last track */ 308 /* Compute the length of the last track */
285 CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value); 309 CFNumberGetValue(leadoutBlock, kCFNumberSInt32Type, &value);
286 310
287 theCD->track[theCD->numtracks-1].length = 311 theCD->track[theCD->numtracks - 1].length =
288 value - theCD->track[theCD->numtracks-1].offset; 312 value - theCD->track[theCD->numtracks - 1].offset;
289 313
290 /* Set offset to leadout track */ 314 /* Set offset to leadout track */
291 theCD->track[theCD->numtracks].offset = value; 315 theCD->track[theCD->numtracks].offset = value;
292 } 316 }
293 317
294 } 318 }
295 319
296 theErr = 0; 320 theErr = 0;
297 goto cleanup; 321 goto cleanup;
298 bail: 322 bail:
299 SDL_SetError ("ReadTOCData: %s returned %d", error, theErr); 323 SDL_SetError("ReadTOCData: %s returned %d", error, theErr);
300 theErr = -1; 324 theErr = -1;
301 cleanup: 325 cleanup:
302 326
303 if (propertyListRef != NULL) 327 if (propertyListRef != NULL)
304 CFRelease(propertyListRef); 328 CFRelease(propertyListRef);
305 if (dataRef != NULL) 329 if (dataRef != NULL)
306 CFRelease(dataRef); 330 CFRelease(dataRef);
307 if (forkData != NULL) 331 if (forkData != NULL)
308 DisposePtr(forkData); 332 DisposePtr(forkData);
309 333
310 FSCloseFork (forkRefNum); 334 FSCloseFork(forkRefNum);
311 335
312 return theErr; 336 return theErr;
313 } 337 }
314 338
315 int ListTrackFiles (FSVolumeRefNum theVolume, FSRef *trackFiles, int numTracks) 339 int
316 { 340 ListTrackFiles(FSVolumeRefNum theVolume, FSRef * trackFiles, int numTracks)
317 OSStatus result = -1; 341 {
318 FSIterator iterator; 342 OSStatus result = -1;
319 ItemCount actualObjects; 343 FSIterator iterator;
320 FSRef rootDirectory; 344 ItemCount actualObjects;
321 FSRef ref; 345 FSRef rootDirectory;
322 HFSUniStr255 nameStr; 346 FSRef ref;
323 347 HFSUniStr255 nameStr;
324 result = FSGetVolumeInfo (theVolume, 348
325 0, 349 result = FSGetVolumeInfo(theVolume,
326 NULL, 350 0,
327 kFSVolInfoFSInfo, 351 NULL,
328 NULL, 352 kFSVolInfoFSInfo, NULL, NULL, &rootDirectory);
329 NULL, 353
330 &rootDirectory);
331
332 if (result != noErr) { 354 if (result != noErr) {
333 SDL_SetError ("ListTrackFiles: FSGetVolumeInfo returned %d", result); 355 SDL_SetError("ListTrackFiles: FSGetVolumeInfo returned %d", result);
334 return result; 356 return result;
335 } 357 }
336 358
337 result = FSOpenIterator (&rootDirectory, kFSIterateFlat, &iterator); 359 result = FSOpenIterator(&rootDirectory, kFSIterateFlat, &iterator);
338 if (result == noErr) { 360 if (result == noErr) {
339 do 361 do {
340 { 362 result = FSGetCatalogInfoBulk(iterator, 1, &actualObjects,
341 result = FSGetCatalogInfoBulk (iterator, 1, &actualObjects, 363 NULL, kFSCatInfoNone, NULL,
342 NULL, kFSCatInfoNone, NULL, &ref, NULL, &nameStr); 364 &ref, NULL, &nameStr);
343 if (result == noErr) { 365 if (result == noErr) {
344 366
345 CFStringRef name; 367 CFStringRef name;
346 name = CFStringCreateWithCharacters (NULL, nameStr.unicode, nameStr.length); 368 name =
347 369 CFStringCreateWithCharacters(NULL, nameStr.unicode,
370 nameStr.length);
371
348 /* Look for .aiff extension */ 372 /* Look for .aiff extension */
349 if (CFStringHasSuffix (name, CFSTR(".aiff")) || 373 if (CFStringHasSuffix(name, CFSTR(".aiff")) ||
350 CFStringHasSuffix (name, CFSTR(".cdda"))) { 374 CFStringHasSuffix(name, CFSTR(".cdda"))) {
351 375
352 /* Extract the track id from the filename */ 376 /* Extract the track id from the filename */
353 int trackID = 0, i = 0; 377 int trackID = 0, i = 0;
354 while (i < nameStr.length && !isdigit(nameStr.unicode[i])) { 378 while (i < nameStr.length && !isdigit(nameStr.unicode[i])) {
355 ++i; 379 ++i;
356 } 380 }
357 while (i < nameStr.length && isdigit(nameStr.unicode[i])) { 381 while (i < nameStr.length && isdigit(nameStr.unicode[i])) {
358 trackID = 10 * trackID +(nameStr.unicode[i] - '0'); 382 trackID = 10 * trackID + (nameStr.unicode[i] - '0');
359 ++i; 383 ++i;
360 } 384 }
361 385
362 #if DEBUG_CDROM 386 #if DEBUG_CDROM
363 printf("Found AIFF for track %d: '%s'\n", trackID, 387 printf("Found AIFF for track %d: '%s'\n",
364 CFStringGetCStringPtr (name, CFStringGetSystemEncoding())); 388 trackID, CFStringGetCStringPtr(name,
365 #endif 389 CFStringGetSystemEncoding
366 390 ()));
391 #endif
392
367 /* 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 */
368 trackID--; 394 trackID--;
369 395
370 assert(0 <= trackID && trackID <= SDL_MAX_TRACKS); 396 assert(0 <= trackID && trackID <= SDL_MAX_TRACKS);
371 397
372 if (trackID < numTracks) 398 if (trackID < numTracks)
373 memcpy (&trackFiles[trackID], &ref, sizeof(FSRef)); 399 memcpy(&trackFiles[trackID], &ref, sizeof(FSRef));
374 } 400 }
375 CFRelease (name); 401 CFRelease(name);
376 } 402 }
377 } while(noErr == result); 403 }
378 FSCloseIterator (iterator); 404 while (noErr == result);
379 } 405 FSCloseIterator(iterator);
380 406 }
407
381 return 0; 408 return 0;
382 } 409 }
383 410
384 int LoadFile (const FSRef *ref, int startFrame, int stopFrame) 411 int
412 LoadFile(const FSRef * ref, int startFrame, int stopFrame)
385 { 413 {
386 int error = -1; 414 int error = -1;
387 415
388 if (CheckInit () < 0) 416 if (CheckInit() < 0)
389 goto bail; 417 goto bail;
390 418
391 /* release any currently playing file */ 419 /* release any currently playing file */
392 if (ReleaseFile () < 0) 420 if (ReleaseFile() < 0)
393 goto bail; 421 goto bail;
394 422
395 #if DEBUG_CDROM 423 #if DEBUG_CDROM
396 printf ("LoadFile: %d %d\n", startFrame, stopFrame); 424 printf("LoadFile: %d %d\n", startFrame, stopFrame);
397 #endif 425 #endif
398 426
399 /*try {*/ 427 /*try { */
400 428
401 /* create a new player, and attach to the audio unit */ 429 /* create a new player, and attach to the audio unit */
402 430
403 thePlayer = new_AudioFilePlayer(ref); 431 thePlayer = new_AudioFilePlayer(ref);
404 if (thePlayer == NULL) { 432 if (thePlayer == NULL) {
405 SDL_SetError ("LoadFile: Could not create player"); 433 SDL_SetError("LoadFile: Could not create player");
406 return -3; /*throw (-3);*/ 434 return -3; /*throw (-3); */
407 } 435 }
408 436
409 if (!thePlayer->SetDestination(thePlayer, &theUnit)) 437 if (!thePlayer->SetDestination(thePlayer, &theUnit))
410 goto bail; 438 goto bail;
411 439
412 if (startFrame >= 0) 440 if (startFrame >= 0)
413 thePlayer->SetStartFrame (thePlayer, startFrame); 441 thePlayer->SetStartFrame(thePlayer, startFrame);
414 442
415 if (stopFrame >= 0 && stopFrame > startFrame) 443 if (stopFrame >= 0 && stopFrame > startFrame)
416 thePlayer->SetStopFrame (thePlayer, stopFrame); 444 thePlayer->SetStopFrame(thePlayer, stopFrame);
417 445
418 /* we set the notifier later */ 446 /* we set the notifier later */
419 /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL);*/ 447 /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL); */
420 448
421 if (!thePlayer->Connect(thePlayer)) 449 if (!thePlayer->Connect(thePlayer))
422 goto bail; 450 goto bail;
423 451
424 #if DEBUG_CDROM 452 #if DEBUG_CDROM
425 thePlayer->Print(thePlayer); 453 thePlayer->Print(thePlayer);
426 fflush (stdout); 454 fflush(stdout);
427 #endif 455 #endif
428 /*} 456 /*}
429 catch (...) 457 catch (...)
430 { 458 {
431 goto bail; 459 goto bail;
432 }*/ 460 } */
433 461
434 error = 0; 462 error = 0;
435 463
436 bail: 464 bail:
437 return error; 465 return error;
438 } 466 }
439 467
440 int ReleaseFile () 468 int
469 ReleaseFile()
441 { 470 {
442 int error = -1; 471 int error = -1;
443 472
444 /* (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. */
445 /*try {*/ 474 /*try { */
446 if (thePlayer != NULL) { 475 if (thePlayer != NULL) {
447 476
448 thePlayer->Disconnect(thePlayer); 477 thePlayer->Disconnect(thePlayer);
449 478
450 delete_AudioFilePlayer(thePlayer); 479 delete_AudioFilePlayer(thePlayer);
451 480
452 thePlayer = NULL; 481 thePlayer = NULL;
453 } 482 }
454 /*} 483 /*}
455 catch (...) 484 catch (...)
456 { 485 {
457 goto bail; 486 goto bail;
458 }*/ 487 } */
459 488
460 error = 0; 489 error = 0;
461 490
462 /* bail: */ 491 /* bail: */
463 return error; 492 return error;
464 } 493 }
465 494
466 int PlayFile () 495 int
496 PlayFile()
467 { 497 {
468 OSStatus result = -1; 498 OSStatus result = -1;
469 499
470 if (CheckInit () < 0) 500 if (CheckInit() < 0)
471 goto bail; 501 goto bail;
472 502
473 /*try {*/ 503 /*try { */
474 504
475 // start processing of the audio unit 505 // start processing of the audio unit
476 result = AudioOutputUnitStart (theUnit); 506 result = AudioOutputUnitStart(theUnit);
477 if (result) goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart") 507 if (result)
478 508 goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart")
509
479 /*} 510 /*}
480 catch (...) 511 catch (...)
481 { 512 {
482 goto bail; 513 goto bail;
483 }*/ 514 } */
484 515
485 result = 0; 516 result = 0;
486 517
487 bail: 518 bail:
488 return result; 519 return result;
489 } 520 }
490 521
491 int PauseFile () 522 int
523 PauseFile()
492 { 524 {
493 OSStatus result = -1; 525 OSStatus result = -1;
494 526
495 if (CheckInit () < 0) 527 if (CheckInit() < 0)
496 goto bail; 528 goto bail;
497 529
498 /*try {*/ 530 /*try { */
499 531
500 /* stop processing the audio unit */ 532 /* stop processing the audio unit */
501 result = AudioOutputUnitStop (theUnit); 533 result = AudioOutputUnitStop(theUnit);
502 if (result) goto bail; /*THROW_RESULT("PauseFile: AudioOutputUnitStop")*/ 534 if (result)
535 goto bail; /*THROW_RESULT("PauseFile: AudioOutputUnitStop") */
503 /*} 536 /*}
504 catch (...) 537 catch (...)
505 { 538 {
506 goto bail; 539 goto bail;
507 }*/ 540 } */
508 541
509 result = 0; 542 result = 0;
510 bail: 543 bail:
511 return result; 544 return result;
512 } 545 }
513 546
514 void SetCompletionProc (CDPlayerCompletionProc proc, SDL_CD *cdrom) 547 void
548 SetCompletionProc(CDPlayerCompletionProc proc, SDL_CD * cdrom)
515 { 549 {
516 assert(thePlayer != NULL); 550 assert(thePlayer != NULL);
517 551
518 theCDROM = cdrom; 552 theCDROM = cdrom;
519 completionProc = proc; 553 completionProc = proc;
520 thePlayer->SetNotifier (thePlayer, FilePlayNotificationHandler, cdrom); 554 thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, cdrom);
521 } 555 }
522 556
523 int GetCurrentFrame () 557 int
524 { 558 GetCurrentFrame()
559 {
525 int frame; 560 int frame;
526 561
527 if (thePlayer == NULL) 562 if (thePlayer == NULL)
528 frame = 0; 563 frame = 0;
529 else 564 else
530 frame = thePlayer->GetCurrentFrame (thePlayer); 565 frame = thePlayer->GetCurrentFrame(thePlayer);
531 566
532 return frame; 567 return frame;
533 } 568 }
534 569
535 570
536 #pragma mark -- Private Functions -- 571 #pragma mark -- Private Functions --
537 572
538 static OSStatus CheckInit () 573 static OSStatus
539 { 574 CheckInit()
575 {
540 if (playBackWasInit) 576 if (playBackWasInit)
541 return 0; 577 return 0;
542 578
543 OSStatus result = noErr; 579 OSStatus result = noErr;
544 580
545 /* Create the callback semaphore */ 581 /* Create the callback semaphore */
546 callbackSem = SDL_CreateSemaphore(0); 582 callbackSem = SDL_CreateSemaphore(0);
547 583
548 /* Start callback thread */ 584 /* Start callback thread */
549 SDL_CreateThread(RunCallBackThread, NULL); 585 SDL_CreateThread(RunCallBackThread, NULL);
550 586
551 { /*try {*/ 587 { /*try { */
552 ComponentDescription desc; 588 ComponentDescription desc;
553 589
554 desc.componentType = kAudioUnitComponentType; 590 desc.componentType = kAudioUnitComponentType;
555 desc.componentSubType = kAudioUnitSubType_Output; 591 desc.componentSubType = kAudioUnitSubType_Output;
556 desc.componentManufacturer = kAudioUnitID_DefaultOutput; 592 desc.componentManufacturer = kAudioUnitID_DefaultOutput;
557 desc.componentFlags = 0; 593 desc.componentFlags = 0;
558 desc.componentFlagsMask = 0; 594 desc.componentFlagsMask = 0;
559 595
560 Component comp = FindNextComponent (NULL, &desc); 596 Component comp = FindNextComponent(NULL, &desc);
561 if (comp == NULL) { 597 if (comp == NULL) {
562 SDL_SetError ("CheckInit: FindNextComponent returned NULL"); 598 SDL_SetError("CheckInit: FindNextComponent returned NULL");
563 if (result) return -1; //throw(internalComponentErr); 599 if (result)
600 return -1; //throw(internalComponentErr);
564 } 601 }
565 602
566 result = OpenAComponent (comp, &theUnit); 603 result = OpenAComponent(comp, &theUnit);
567 if (result) return -1; //THROW_RESULT("CheckInit: OpenAComponent") 604 if (result)
568 605 return -1; //THROW_RESULT("CheckInit: OpenAComponent")
606
569 // 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
570 result = AudioUnitInitialize (theUnit); 608 result = AudioUnitInitialize(theUnit);
571 if (result) return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize") 609 if (result)
572 610 return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize")
573 611
612
574 playBackWasInit = true; 613 playBackWasInit = true;
575 } 614 }
576 /*catch (...) 615 /*catch (...)
577 { 616 {
578 return -1; 617 return -1;
579 }*/ 618 } */
580 619
581 return 0; 620 return 0;
582 } 621 }
583 622
584 static void FilePlayNotificationHandler(void * inRefCon, OSStatus inStatus) 623 static void
624 FilePlayNotificationHandler(void *inRefCon, OSStatus inStatus)
585 { 625 {
586 if (inStatus == kAudioFilePlay_FileIsFinished) { 626 if (inStatus == kAudioFilePlay_FileIsFinished) {
587 627
588 /* notify non-CA thread to perform the callback */ 628 /* notify non-CA thread to perform the callback */
589 SDL_SemPost(callbackSem); 629 SDL_SemPost(callbackSem);
590 630
591 } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) { 631 } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) {
592 632
593 SDL_SetError ("CDPlayer Notification: buffer underrun"); 633 SDL_SetError("CDPlayer Notification: buffer underrun");
594 } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) { 634 } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) {
595 635
596 SDL_SetError ("CDPlayer Notification: player is uninitialized"); 636 SDL_SetError("CDPlayer Notification: player is uninitialized");
597 } else { 637 } else {
598 638
599 SDL_SetError ("CDPlayer Notification: unknown error %ld", inStatus); 639 SDL_SetError("CDPlayer Notification: unknown error %ld", inStatus);
600 } 640 }
601 } 641 }
602 642
603 static int RunCallBackThread (void *param) 643 static int
644 RunCallBackThread(void *param)
604 { 645 {
605 for (;;) { 646 for (;;) {
606 647
607 SDL_SemWait(callbackSem); 648 SDL_SemWait(callbackSem);
608 649
609 if (completionProc && theCDROM) { 650 if (completionProc && theCDROM) {
610 #if DEBUG_CDROM 651 #if DEBUG_CDROM
611 printf ("callback!\n"); 652 printf("callback!\n");
612 #endif 653 #endif
613 (*completionProc)(theCDROM); 654 (*completionProc) (theCDROM);
614 } else { 655 } else {
615 #if DEBUG_CDROM 656 #if DEBUG_CDROM
616 printf ("callback?\n"); 657 printf("callback?\n");
617 #endif 658 #endif
618 } 659 }
619 } 660 }
620 661
621 #if DEBUG_CDROM 662 #if DEBUG_CDROM
622 printf ("thread dying now...\n"); 663 printf("thread dying now...\n");
623 #endif 664 #endif
624 665
625 return 0; 666 return 0;
626 } 667 }
627 668
628 /*}; // extern "C" */ 669 /*}; // extern "C" */
670 /* vi: set ts=4 sw=4 expandtab: */