Mercurial > sdl-ios-xcode
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: */ |