Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
670 lines (524 loc) · 18.4 KB

CDPlayer.c

File metadata and controls

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