comparison src/cdrom/macosx/CDPlayer.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents dc6b59e925a2
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
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
88 { 89 Unlock ()
89 SDL_mutexV(apiMutex); 90 {
90 } 91 SDL_mutexV (apiMutex);
91 92 }
92 int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes) 93
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
105 result = FSGetVolumeInfo (kFSInvalidVolumeRefNum, 107 result = FSGetVolumeInfo (kFSInvalidVolumeRefNum,
106 volumeIndex, 108 volumeIndex,
107 &actualVolume, 109 &actualVolume,
108 kFSVolInfoFSInfo, 110 kFSVolInfoFSInfo, &volumeInfo, NULL, NULL);
109 &volumeInfo, 111
110 NULL, 112 if (result == noErr) {
111 NULL); 113 if (volumeInfo.filesystemID == kAudioCDFilesystemID) { /* It's an audio CD */
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 =
196 if(dataRef == 0) { 195 CFDataCreate (kCFAllocatorDefault, (UInt8 *) forkData, forkSize);
196 if (dataRef == 0) {
197 error = "CFDataCreate"; 197 error = "CFDataCreate";
198 goto bail; 198 goto bail;
199 } 199 }
200 200
201 propertyListRef = CFPropertyListCreateFromXMLData (kCFAllocatorDefault, 201 propertyListRef = CFPropertyListCreateFromXMLData (kCFAllocatorDefault,
206 error = "CFPropertyListCreateFromXMLData"; 206 error = "CFPropertyListCreateFromXMLData";
207 goto bail; 207 goto bail;
208 } 208 }
209 209
210 /* Now we got the Property List in memory. Parse it. */ 210 /* Now we got the Property List in memory. Parse it. */
211 211
212 /* First, make sure the root item is a CFDictionary. If not, release and bail. */ 212 /* First, make sure the root item is a CFDictionary. If not, release and bail. */
213 if(CFGetTypeID(propertyListRef)== CFDictionaryGetTypeID()) 213 if (CFGetTypeID (propertyListRef) == CFDictionaryGetTypeID ()) {
214 { 214 CFDictionaryRef dictRef = (CFDictionaryRef) propertyListRef;
215 CFDictionaryRef dictRef = (CFDictionaryRef)propertyListRef; 215
216 216 CFDataRef theRawTOCDataRef;
217 CFDataRef theRawTOCDataRef; 217 CFArrayRef theSessionArrayRef;
218 CFArrayRef theSessionArrayRef; 218 CFIndex numSessions;
219 CFIndex numSessions; 219 CFIndex index;
220 CFIndex index; 220
221
222 /* This is how we get the Raw TOC Data */ 221 /* This is how we get the Raw TOC Data */
223 theRawTOCDataRef = (CFDataRef)CFDictionaryGetValue (dictRef, CFSTR(kRawTOCDataString)); 222 theRawTOCDataRef =
224 223 (CFDataRef) CFDictionaryGetValue (dictRef,
224 CFSTR (kRawTOCDataString));
225
225 /* Get the session array info. */ 226 /* Get the session array info. */
226 theSessionArrayRef = (CFArrayRef)CFDictionaryGetValue (dictRef, CFSTR(kSessionsString)); 227 theSessionArrayRef =
227 228 (CFArrayRef) CFDictionaryGetValue (dictRef,
229 CFSTR (kSessionsString));
230
228 /* Find out how many sessions there are. */ 231 /* Find out how many sessions there are. */
229 numSessions = CFArrayGetCount (theSessionArrayRef); 232 numSessions = CFArrayGetCount (theSessionArrayRef);
230 233
231 /* Initialize the total number of tracks to 0 */ 234 /* Initialize the total number of tracks to 0 */
232 theCD->numtracks = 0; 235 theCD->numtracks = 0;
233 236
234 /* Iterate over all sessions, collecting the track data */ 237 /* Iterate over all sessions, collecting the track data */
235 for(index = 0; index < numSessions; index++) 238 for (index = 0; index < numSessions; index++) {
236 {
237 CFDictionaryRef theSessionDict; 239 CFDictionaryRef theSessionDict;
238 CFNumberRef leadoutBlock; 240 CFNumberRef leadoutBlock;
239 CFArrayRef trackArray; 241 CFArrayRef trackArray;
240 CFIndex numTracks; 242 CFIndex numTracks;
241 CFIndex trackIndex; 243 CFIndex trackIndex;
242 UInt32 value = 0; 244 UInt32 value = 0;
243 245
244 theSessionDict = (CFDictionaryRef) CFArrayGetValueAtIndex (theSessionArrayRef, index); 246 theSessionDict = (CFDictionaryRef)
245 leadoutBlock = (CFNumberRef) CFDictionaryGetValue (theSessionDict, CFSTR(kLeadoutBlockString)); 247 CFArrayGetValueAtIndex (theSessionArrayRef, index);
246 248 leadoutBlock =
247 trackArray = (CFArrayRef)CFDictionaryGetValue (theSessionDict, CFSTR(kTrackArrayString)); 249 (CFNumberRef) CFDictionaryGetValue (theSessionDict,
248 250 CFSTR
251 (kLeadoutBlockString));
252
253 trackArray =
254 (CFArrayRef) CFDictionaryGetValue (theSessionDict,
255 CFSTR (kTrackArrayString));
256
249 numTracks = CFArrayGetCount (trackArray); 257 numTracks = CFArrayGetCount (trackArray);
250 258
251 for(trackIndex = 0; trackIndex < numTracks; trackIndex++) { 259 for (trackIndex = 0; trackIndex < numTracks; trackIndex++) {
252 260
253 CFDictionaryRef theTrackDict; 261 CFDictionaryRef theTrackDict;
254 CFNumberRef trackNumber; 262 CFNumberRef trackNumber;
255 CFNumberRef sessionNumber; 263 CFNumberRef sessionNumber;
256 CFNumberRef startBlock; 264 CFNumberRef startBlock;
257 CFBooleanRef isDataTrack; 265 CFBooleanRef isDataTrack;
258 UInt32 value; 266 UInt32 value;
259 267
260 theTrackDict = (CFDictionaryRef) CFArrayGetValueAtIndex (trackArray, trackIndex); 268 theTrackDict = (CFDictionaryRef)
261 269 CFArrayGetValueAtIndex (trackArray, trackIndex);
262 trackNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kPointKeyString)); 270
263 sessionNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kSessionNumberKeyString)); 271 trackNumber =
264 startBlock = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kStartBlockKeyString)); 272 (CFNumberRef) CFDictionaryGetValue (theTrackDict,
265 isDataTrack = (CFBooleanRef) CFDictionaryGetValue (theTrackDict, CFSTR(kDataKeyString)); 273 CFSTR
266 274 (kPointKeyString));
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
267 /* Fill in the SDL_CD struct */ 288 /* Fill in the SDL_CD struct */
268 int idx = theCD->numtracks++; 289 int idx = theCD->numtracks++;
269 290
270 CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value); 291 CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value);
271 theCD->track[idx].id = value; 292 theCD->track[idx].id = value;
272 293
273 CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value); 294 CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value);
274 theCD->track[idx].offset = value; 295 theCD->track[idx].offset = value;
275 296
276 theCD->track[idx].type = (isDataTrack == kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK; 297 theCD->track[idx].type =
298 (isDataTrack ==
299 kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK;
277 300
278 /* Since the track lengths are not stored in .TOC.plist we compute them. */ 301 /* Since the track lengths are not stored in .TOC.plist we compute them. */
279 if (trackIndex > 0) { 302 if (trackIndex > 0) {
280 theCD->track[idx-1].length = theCD->track[idx].offset - theCD->track[idx-1].offset; 303 theCD->track[idx - 1].length =
304 theCD->track[idx].offset - theCD->track[idx -
305 1].offset;
281 } 306 }
282 } 307 }
283 308
284 /* Compute the length of the last track */ 309 /* Compute the length of the last track */
285 CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value); 310 CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value);
286 311
287 theCD->track[theCD->numtracks-1].length = 312 theCD->track[theCD->numtracks - 1].length =
288 value - theCD->track[theCD->numtracks-1].offset; 313 value - theCD->track[theCD->numtracks - 1].offset;
289 314
290 /* Set offset to leadout track */ 315 /* Set offset to leadout track */
291 theCD->track[theCD->numtracks].offset = value; 316 theCD->track[theCD->numtracks].offset = value;
292 } 317 }
293 318
294 } 319 }
295 320
296 theErr = 0; 321 theErr = 0;
297 goto cleanup; 322 goto cleanup;
298 bail: 323 bail:
299 SDL_SetError ("ReadTOCData: %s returned %d", error, theErr); 324 SDL_SetError ("ReadTOCData: %s returned %d", error, theErr);
300 theErr = -1; 325 theErr = -1;
301 cleanup: 326 cleanup:
302 327
303 if (propertyListRef != NULL) 328 if (propertyListRef != NULL)
304 CFRelease(propertyListRef); 329 CFRelease (propertyListRef);
305 if (dataRef != NULL) 330 if (dataRef != NULL)
306 CFRelease(dataRef); 331 CFRelease (dataRef);
307 if (forkData != NULL) 332 if (forkData != NULL)
308 DisposePtr(forkData); 333 DisposePtr (forkData);
309 334
310 FSCloseFork (forkRefNum); 335 FSCloseFork (forkRefNum);
311 336
312 return theErr; 337 return theErr;
313 } 338 }
314 339
315 int ListTrackFiles (FSVolumeRefNum theVolume, FSRef *trackFiles, int numTracks) 340 int
316 { 341 ListTrackFiles (FSVolumeRefNum theVolume, FSRef * trackFiles, int numTracks)
317 OSStatus result = -1; 342 {
318 FSIterator iterator; 343 OSStatus result = -1;
319 ItemCount actualObjects; 344 FSIterator iterator;
320 FSRef rootDirectory; 345 ItemCount actualObjects;
321 FSRef ref; 346 FSRef rootDirectory;
322 HFSUniStr255 nameStr; 347 FSRef ref;
323 348 HFSUniStr255 nameStr;
349
324 result = FSGetVolumeInfo (theVolume, 350 result = FSGetVolumeInfo (theVolume,
325 0, 351 0,
326 NULL, 352 NULL,
327 kFSVolInfoFSInfo, 353 kFSVolInfoFSInfo, NULL, NULL, &rootDirectory);
328 NULL, 354
329 NULL,
330 &rootDirectory);
331
332 if (result != noErr) { 355 if (result != noErr) {
333 SDL_SetError ("ListTrackFiles: FSGetVolumeInfo returned %d", result); 356 SDL_SetError ("ListTrackFiles: FSGetVolumeInfo returned %d", result);
334 return result; 357 return result;
335 } 358 }
336 359
337 result = FSOpenIterator (&rootDirectory, kFSIterateFlat, &iterator); 360 result = FSOpenIterator (&rootDirectory, kFSIterateFlat, &iterator);
338 if (result == noErr) { 361 if (result == noErr) {
339 do 362 do {
340 {
341 result = FSGetCatalogInfoBulk (iterator, 1, &actualObjects, 363 result = FSGetCatalogInfoBulk (iterator, 1, &actualObjects,
342 NULL, kFSCatInfoNone, NULL, &ref, NULL, &nameStr); 364 NULL, kFSCatInfoNone, NULL,
365 &ref, NULL, &nameStr);
343 if (result == noErr) { 366 if (result == noErr) {
344 367
345 CFStringRef name; 368 CFStringRef name;
346 name = CFStringCreateWithCharacters (NULL, nameStr.unicode, nameStr.length); 369 name =
347 370 CFStringCreateWithCharacters (NULL, nameStr.unicode,
371 nameStr.length);
372
348 /* Look for .aiff extension */ 373 /* Look for .aiff extension */
349 if (CFStringHasSuffix (name, CFSTR(".aiff")) || 374 if (CFStringHasSuffix (name, CFSTR (".aiff")) ||
350 CFStringHasSuffix (name, CFSTR(".cdda"))) { 375 CFStringHasSuffix (name, CFSTR (".cdda"))) {
351 376
352 /* Extract the track id from the filename */ 377 /* Extract the track id from the filename */
353 int trackID = 0, i = 0; 378 int trackID = 0, i = 0;
354 while (i < nameStr.length && !isdigit(nameStr.unicode[i])) { 379 while (i < nameStr.length
380 && !isdigit (nameStr.unicode[i])) {
355 ++i; 381 ++i;
356 } 382 }
357 while (i < nameStr.length && isdigit(nameStr.unicode[i])) { 383 while (i < nameStr.length && isdigit (nameStr.unicode[i])) {
358 trackID = 10 * trackID +(nameStr.unicode[i] - '0'); 384 trackID = 10 * trackID + (nameStr.unicode[i] - '0');
359 ++i; 385 ++i;
360 } 386 }
361 387
362 #if DEBUG_CDROM 388 #if DEBUG_CDROM
363 printf("Found AIFF for track %d: '%s'\n", trackID, 389 printf ("Found AIFF for track %d: '%s'\n",
364 CFStringGetCStringPtr (name, CFStringGetSystemEncoding())); 390 trackID, CFStringGetCStringPtr (name,
365 #endif 391 CFStringGetSystemEncoding
366 392 ()));
393 #endif
394
367 /* Track ID's start at 1, but we want to start at 0 */ 395 /* Track ID's start at 1, but we want to start at 0 */
368 trackID--; 396 trackID--;
369 397
370 assert(0 <= trackID && trackID <= SDL_MAX_TRACKS); 398 assert (0 <= trackID && trackID <= SDL_MAX_TRACKS);
371 399
372 if (trackID < numTracks) 400 if (trackID < numTracks)
373 memcpy (&trackFiles[trackID], &ref, sizeof(FSRef)); 401 memcpy (&trackFiles[trackID], &ref, sizeof (FSRef));
374 } 402 }
375 CFRelease (name); 403 CFRelease (name);
376 } 404 }
377 } while(noErr == result); 405 }
406 while (noErr == result);
378 FSCloseIterator (iterator); 407 FSCloseIterator (iterator);
379 } 408 }
380 409
381 return 0; 410 return 0;
382 } 411 }
383 412
384 int LoadFile (const FSRef *ref, int startFrame, int stopFrame) 413 int
414 LoadFile (const FSRef * ref, int startFrame, int stopFrame)
385 { 415 {
386 int error = -1; 416 int error = -1;
387 417
388 if (CheckInit () < 0) 418 if (CheckInit () < 0)
389 goto bail; 419 goto bail;
390 420
391 /* release any currently playing file */ 421 /* release any currently playing file */
392 if (ReleaseFile () < 0) 422 if (ReleaseFile () < 0)
393 goto bail; 423 goto bail;
394 424
395 #if DEBUG_CDROM 425 #if DEBUG_CDROM
396 printf ("LoadFile: %d %d\n", startFrame, stopFrame); 426 printf ("LoadFile: %d %d\n", startFrame, stopFrame);
397 #endif 427 #endif
398 428
399 /*try {*/ 429 /*try { */
400 430
401 /* create a new player, and attach to the audio unit */ 431 /* create a new player, and attach to the audio unit */
402 432
403 thePlayer = new_AudioFilePlayer(ref); 433 thePlayer = new_AudioFilePlayer (ref);
404 if (thePlayer == NULL) { 434 if (thePlayer == NULL) {
405 SDL_SetError ("LoadFile: Could not create player"); 435 SDL_SetError ("LoadFile: Could not create player");
406 return -3; /*throw (-3);*/ 436 return -3; /*throw (-3); */
407 } 437 }
408 438
409 if (!thePlayer->SetDestination(thePlayer, &theUnit)) 439 if (!thePlayer->SetDestination (thePlayer, &theUnit))
410 goto bail; 440 goto bail;
411 441
412 if (startFrame >= 0) 442 if (startFrame >= 0)
413 thePlayer->SetStartFrame (thePlayer, startFrame); 443 thePlayer->SetStartFrame (thePlayer, startFrame);
414 444
415 if (stopFrame >= 0 && stopFrame > startFrame) 445 if (stopFrame >= 0 && stopFrame > startFrame)
416 thePlayer->SetStopFrame (thePlayer, stopFrame); 446 thePlayer->SetStopFrame (thePlayer, stopFrame);
417 447
418 /* we set the notifier later */ 448 /* we set the notifier later */
419 /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL);*/ 449 /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL); */
420 450
421 if (!thePlayer->Connect(thePlayer)) 451 if (!thePlayer->Connect (thePlayer))
422 goto bail; 452 goto bail;
423 453
424 #if DEBUG_CDROM 454 #if DEBUG_CDROM
425 thePlayer->Print(thePlayer); 455 thePlayer->Print (thePlayer);
426 fflush (stdout); 456 fflush (stdout);
427 #endif 457 #endif
428 /*} 458 /*}
429 catch (...) 459 catch (...)
430 { 460 {
431 goto bail; 461 goto bail;
432 }*/ 462 } */
433 463
434 error = 0; 464 error = 0;
435 465
436 bail: 466 bail:
437 return error; 467 return error;
438 } 468 }
439 469
440 int ReleaseFile () 470 int
471 ReleaseFile ()
441 { 472 {
442 int error = -1; 473 int error = -1;
443 474
444 /* (Don't see any way that the original C++ code could throw here.) --ryan. */ 475 /* (Don't see any way that the original C++ code could throw here.) --ryan. */
445 /*try {*/ 476 /*try { */
446 if (thePlayer != NULL) { 477 if (thePlayer != NULL) {
447 478
448 thePlayer->Disconnect(thePlayer); 479 thePlayer->Disconnect (thePlayer);
449 480
450 delete_AudioFilePlayer(thePlayer); 481 delete_AudioFilePlayer (thePlayer);
451 482
452 thePlayer = NULL; 483 thePlayer = NULL;
453 } 484 }
454 /*} 485 /*}
455 catch (...) 486 catch (...)
456 { 487 {
457 goto bail; 488 goto bail;
458 }*/ 489 } */
459 490
460 error = 0; 491 error = 0;
461 492
462 /* bail: */ 493 /* bail: */
463 return error; 494 return error;
464 } 495 }
465 496
466 int PlayFile () 497 int
498 PlayFile ()
467 { 499 {
468 OSStatus result = -1; 500 OSStatus result = -1;
469 501
470 if (CheckInit () < 0) 502 if (CheckInit () < 0)
471 goto bail; 503 goto bail;
472 504
473 /*try {*/ 505 /*try { */
474 506
475 // start processing of the audio unit 507 // start processing of the audio unit
476 result = AudioOutputUnitStart (theUnit); 508 result = AudioOutputUnitStart (theUnit);
477 if (result) goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart") 509 if (result)
478 510 goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart")
511
479 /*} 512 /*}
480 catch (...) 513 catch (...)
481 { 514 {
482 goto bail; 515 goto bail;
483 }*/ 516 } */
484 517
485 result = 0; 518 result = 0;
486 519
487 bail: 520 bail:
488 return result; 521 return result;
489 } 522 }
490 523
491 int PauseFile () 524 int
525 PauseFile ()
492 { 526 {
493 OSStatus result = -1; 527 OSStatus result = -1;
494 528
495 if (CheckInit () < 0) 529 if (CheckInit () < 0)
496 goto bail; 530 goto bail;
497 531
498 /*try {*/ 532 /*try { */
499 533
500 /* stop processing the audio unit */ 534 /* stop processing the audio unit */
501 result = AudioOutputUnitStop (theUnit); 535 result = AudioOutputUnitStop (theUnit);
502 if (result) goto bail; /*THROW_RESULT("PauseFile: AudioOutputUnitStop")*/ 536 if (result)
537 goto bail; /*THROW_RESULT("PauseFile: AudioOutputUnitStop") */
503 /*} 538 /*}
504 catch (...) 539 catch (...)
505 { 540 {
506 goto bail; 541 goto bail;
507 }*/ 542 } */
508 543
509 result = 0; 544 result = 0;
510 bail: 545 bail:
511 return result; 546 return result;
512 } 547 }
513 548
514 void SetCompletionProc (CDPlayerCompletionProc proc, SDL_CD *cdrom) 549 void
515 { 550 SetCompletionProc (CDPlayerCompletionProc proc, SDL_CD * cdrom)
516 assert(thePlayer != NULL); 551 {
552 assert (thePlayer != NULL);
517 553
518 theCDROM = cdrom; 554 theCDROM = cdrom;
519 completionProc = proc; 555 completionProc = proc;
520 thePlayer->SetNotifier (thePlayer, FilePlayNotificationHandler, cdrom); 556 thePlayer->SetNotifier (thePlayer, FilePlayNotificationHandler, cdrom);
521 } 557 }
522 558
523 int GetCurrentFrame () 559 int
524 { 560 GetCurrentFrame ()
561 {
525 int frame; 562 int frame;
526 563
527 if (thePlayer == NULL) 564 if (thePlayer == NULL)
528 frame = 0; 565 frame = 0;
529 else 566 else
530 frame = thePlayer->GetCurrentFrame (thePlayer); 567 frame = thePlayer->GetCurrentFrame (thePlayer);
531 568
532 return frame; 569 return frame;
533 } 570 }
534 571
535 572
536 #pragma mark -- Private Functions -- 573 #pragma mark -- Private Functions --
537 574
538 static OSStatus CheckInit () 575 static OSStatus
539 { 576 CheckInit ()
577 {
540 if (playBackWasInit) 578 if (playBackWasInit)
541 return 0; 579 return 0;
542 580
543 OSStatus result = noErr; 581 OSStatus result = noErr;
544 582
545 /* Create the callback semaphore */ 583 /* Create the callback semaphore */
546 callbackSem = SDL_CreateSemaphore(0); 584 callbackSem = SDL_CreateSemaphore (0);
547 585
548 /* Start callback thread */ 586 /* Start callback thread */
549 SDL_CreateThread(RunCallBackThread, NULL); 587 SDL_CreateThread (RunCallBackThread, NULL);
550 588
551 { /*try {*/ 589 { /*try { */
552 ComponentDescription desc; 590 ComponentDescription desc;
553 591
554 desc.componentType = kAudioUnitComponentType; 592 desc.componentType = kAudioUnitComponentType;
555 desc.componentSubType = kAudioUnitSubType_Output; 593 desc.componentSubType = kAudioUnitSubType_Output;
556 desc.componentManufacturer = kAudioUnitID_DefaultOutput; 594 desc.componentManufacturer = kAudioUnitID_DefaultOutput;
557 desc.componentFlags = 0; 595 desc.componentFlags = 0;
558 desc.componentFlagsMask = 0; 596 desc.componentFlagsMask = 0;
559 597
560 Component comp = FindNextComponent (NULL, &desc); 598 Component comp = FindNextComponent (NULL, &desc);
561 if (comp == NULL) { 599 if (comp == NULL) {
562 SDL_SetError ("CheckInit: FindNextComponent returned NULL"); 600 SDL_SetError ("CheckInit: FindNextComponent returned NULL");
563 if (result) return -1; //throw(internalComponentErr); 601 if (result)
602 return -1; //throw(internalComponentErr);
564 } 603 }
565 604
566 result = OpenAComponent (comp, &theUnit); 605 result = OpenAComponent (comp, &theUnit);
567 if (result) return -1; //THROW_RESULT("CheckInit: OpenAComponent") 606 if (result)
568 607 return -1; //THROW_RESULT("CheckInit: OpenAComponent")
608
569 // you need to initialize the output unit before you set it as a destination 609 // you need to initialize the output unit before you set it as a destination
570 result = AudioUnitInitialize (theUnit); 610 result = AudioUnitInitialize (theUnit);
571 if (result) return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize") 611 if (result)
572 612 return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize")
573 613
614
574 playBackWasInit = true; 615 playBackWasInit = true;
575 } 616 }
576 /*catch (...) 617 /*catch (...)
577 { 618 {
578 return -1; 619 return -1;
579 }*/ 620 } */
580 621
581 return 0; 622 return 0;
582 } 623 }
583 624
584 static void FilePlayNotificationHandler(void * inRefCon, OSStatus inStatus) 625 static void
626 FilePlayNotificationHandler (void *inRefCon, OSStatus inStatus)
585 { 627 {
586 if (inStatus == kAudioFilePlay_FileIsFinished) { 628 if (inStatus == kAudioFilePlay_FileIsFinished) {
587 629
588 /* notify non-CA thread to perform the callback */ 630 /* notify non-CA thread to perform the callback */
589 SDL_SemPost(callbackSem); 631 SDL_SemPost (callbackSem);
590 632
591 } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) { 633 } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) {
592 634
593 SDL_SetError ("CDPlayer Notification: buffer underrun"); 635 SDL_SetError ("CDPlayer Notification: buffer underrun");
594 } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) { 636 } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) {
595 637
596 SDL_SetError ("CDPlayer Notification: player is uninitialized"); 638 SDL_SetError ("CDPlayer Notification: player is uninitialized");
597 } else { 639 } else {
598 640
599 SDL_SetError ("CDPlayer Notification: unknown error %ld", inStatus); 641 SDL_SetError ("CDPlayer Notification: unknown error %ld", inStatus);
600 } 642 }
601 } 643 }
602 644
603 static int RunCallBackThread (void *param) 645 static int
646 RunCallBackThread (void *param)
604 { 647 {
605 for (;;) { 648 for (;;) {
606 649
607 SDL_SemWait(callbackSem); 650 SDL_SemWait (callbackSem);
608 651
609 if (completionProc && theCDROM) { 652 if (completionProc && theCDROM) {
610 #if DEBUG_CDROM 653 #if DEBUG_CDROM
611 printf ("callback!\n"); 654 printf ("callback!\n");
612 #endif 655 #endif
613 (*completionProc)(theCDROM); 656 (*completionProc) (theCDROM);
614 } else { 657 } else {
615 #if DEBUG_CDROM 658 #if DEBUG_CDROM
616 printf ("callback?\n"); 659 printf ("callback?\n");
617 #endif 660 #endif
618 } 661 }
619 } 662 }
620 663
621 #if DEBUG_CDROM 664 #if DEBUG_CDROM
622 printf ("thread dying now...\n"); 665 printf ("thread dying now...\n");
623 #endif 666 #endif
624 667
625 return 0; 668 return 0;
626 } 669 }
627 670
628 /*}; // extern "C" */ 671 /*}; // extern "C" */
672 /* vi: set ts=4 sw=4 expandtab: */