diff options
Diffstat (limited to 'distrib/sdl-1.2.12/src/cdrom/macosx/CDPlayer.c')
-rw-r--r-- | distrib/sdl-1.2.12/src/cdrom/macosx/CDPlayer.c | 628 |
1 files changed, 0 insertions, 628 deletions
diff --git a/distrib/sdl-1.2.12/src/cdrom/macosx/CDPlayer.c b/distrib/sdl-1.2.12/src/cdrom/macosx/CDPlayer.c deleted file mode 100644 index 16dc213..0000000 --- a/distrib/sdl-1.2.12/src/cdrom/macosx/CDPlayer.c +++ /dev/null @@ -1,628 +0,0 @@ -/* - 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 -*/ -#include "SDL_config.h" - -#include "CDPlayer.h" -#include "AudioFilePlayer.h" -#include "SDLOSXCAGuard.h" - -/* we're exporting these functions into C land for SDL_syscdrom.c */ -/*extern "C" {*/ - -/*/////////////////////////////////////////////////////////////////////////// - Constants - //////////////////////////////////////////////////////////////////////////*/ - -#define kAudioCDFilesystemID (UInt16)(('J' << 8) | 'H') /* 'JH'; this avoids compiler warning */ - -/* XML PList keys */ -#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" -#define kStartBlockKeyString "Start Block" - -/*/////////////////////////////////////////////////////////////////////////// - Globals - //////////////////////////////////////////////////////////////////////////*/ - -#pragma mark -- Globals -- - -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; - -/*/////////////////////////////////////////////////////////////////////////// - Prototypes - //////////////////////////////////////////////////////////////////////////*/ - -#pragma mark -- Prototypes -- - -static OSStatus CheckInit (); - -static void FilePlayNotificationHandler (void* inRefCon, OSStatus inStatus); - -static int RunCallBackThread (void* inRefCon); - - -#pragma mark -- Public Functions -- - -void Lock () -{ - if (!apiMutex) { - apiMutex = SDL_CreateMutex(); - } - SDL_mutexP(apiMutex); -} - -void Unlock () -{ - SDL_mutexV(apiMutex); -} - -int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes) -{ - int volumeIndex; - int cdVolumeCount = 0; - OSStatus result = noErr; - - for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++) - { - FSVolumeRefNum actualVolume; - FSVolumeInfo volumeInfo; - - memset (&volumeInfo, 0, sizeof(volumeInfo)); - - result = FSGetVolumeInfo (kFSInvalidVolumeRefNum, - volumeIndex, - &actualVolume, - kFSVolInfoFSInfo, - &volumeInfo, - NULL, - NULL); - - if (result == noErr) - { - if (volumeInfo.filesystemID == kAudioCDFilesystemID) /* It's an audio CD */ - { - if (volumes != NULL && cdVolumeCount < numVolumes) - volumes[cdVolumeCount] = actualVolume; - - cdVolumeCount++; - } - } - else - { - /* I'm commenting this out because it seems to be harmless */ - /*SDL_SetError ("DetectAudioCDVolumes: FSGetVolumeInfo returned %d", result);*/ - } - } - - return cdVolumeCount; -} - -int ReadTOCData (FSVolumeRefNum theVolume, SDL_CD *theCD) -{ - HFSUniStr255 dataForkName; - OSStatus theErr; - SInt16 forkRefNum; - SInt64 forkSize; - Ptr forkData = 0; - ByteCount actualRead; - CFDataRef dataRef = 0; - CFPropertyListRef propertyListRef = 0; - - FSRefParam fsRefPB; - FSRef tocPlistFSRef; - - const char* error = "Unspecified Error"; - - /* get stuff from .TOC.plist */ - fsRefPB.ioCompletion = NULL; - fsRefPB.ioNamePtr = "\p.TOC.plist"; - fsRefPB.ioVRefNum = theVolume; - fsRefPB.ioDirID = 0; - fsRefPB.newRef = &tocPlistFSRef; - - theErr = PBMakeFSRefSync (&fsRefPB); - if(theErr != noErr) { - error = "PBMakeFSRefSync"; - goto bail; - } - - /* Load and parse the TOC XML data */ - - theErr = FSGetDataForkName (&dataForkName); - if (theErr != noErr) { - error = "FSGetDataForkName"; - goto bail; - } - - theErr = FSOpenFork (&tocPlistFSRef, dataForkName.length, dataForkName.unicode, fsRdPerm, &forkRefNum); - if (theErr != noErr) { - error = "FSOpenFork"; - goto bail; - } - - theErr = FSGetForkSize (forkRefNum, &forkSize); - if (theErr != noErr) { - error = "FSGetForkSize"; - goto bail; - } - - /* Allocate some memory for the XML data */ - forkData = NewPtr (forkSize); - if(forkData == NULL) { - error = "NewPtr"; - goto bail; - } - - theErr = FSReadFork (forkRefNum, fsFromStart, 0 /* offset location */, forkSize, forkData, &actualRead); - if(theErr != noErr) { - error = "FSReadFork"; - goto bail; - } - - dataRef = CFDataCreate (kCFAllocatorDefault, (UInt8 *)forkData, forkSize); - if(dataRef == 0) { - error = "CFDataCreate"; - goto bail; - } - - propertyListRef = CFPropertyListCreateFromXMLData (kCFAllocatorDefault, - dataRef, - kCFPropertyListImmutable, - NULL); - if (propertyListRef == NULL) { - error = "CFPropertyListCreateFromXMLData"; - goto bail; - } - - /* Now we got the Property List in memory. Parse it. */ - - /* First, make sure the root item is a CFDictionary. If not, release and bail. */ - if(CFGetTypeID(propertyListRef)== CFDictionaryGetTypeID()) - { - CFDictionaryRef dictRef = (CFDictionaryRef)propertyListRef; - - CFDataRef theRawTOCDataRef; - CFArrayRef theSessionArrayRef; - CFIndex numSessions; - CFIndex index; - - /* This is how we get the Raw TOC Data */ - theRawTOCDataRef = (CFDataRef)CFDictionaryGetValue (dictRef, CFSTR(kRawTOCDataString)); - - /* Get the session array info. */ - theSessionArrayRef = (CFArrayRef)CFDictionaryGetValue (dictRef, CFSTR(kSessionsString)); - - /* Find out how many sessions there are. */ - numSessions = CFArrayGetCount (theSessionArrayRef); - - /* Initialize the total number of tracks to 0 */ - theCD->numtracks = 0; - - /* Iterate over all sessions, collecting the track data */ - for(index = 0; index < numSessions; index++) - { - CFDictionaryRef theSessionDict; - CFNumberRef leadoutBlock; - CFArrayRef trackArray; - CFIndex numTracks; - CFIndex trackIndex; - UInt32 value = 0; - - theSessionDict = (CFDictionaryRef) CFArrayGetValueAtIndex (theSessionArrayRef, index); - leadoutBlock = (CFNumberRef) CFDictionaryGetValue (theSessionDict, CFSTR(kLeadoutBlockString)); - - trackArray = (CFArrayRef)CFDictionaryGetValue (theSessionDict, CFSTR(kTrackArrayString)); - - numTracks = CFArrayGetCount (trackArray); - - for(trackIndex = 0; trackIndex < numTracks; trackIndex++) { - - CFDictionaryRef theTrackDict; - CFNumberRef trackNumber; - CFNumberRef sessionNumber; - CFNumberRef startBlock; - CFBooleanRef isDataTrack; - UInt32 value; - - theTrackDict = (CFDictionaryRef) CFArrayGetValueAtIndex (trackArray, trackIndex); - - trackNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kPointKeyString)); - sessionNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kSessionNumberKeyString)); - startBlock = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kStartBlockKeyString)); - isDataTrack = (CFBooleanRef) CFDictionaryGetValue (theTrackDict, CFSTR(kDataKeyString)); - - /* Fill in the SDL_CD struct */ - int idx = theCD->numtracks++; - - CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value); - theCD->track[idx].id = value; - - CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value); - theCD->track[idx].offset = value; - - theCD->track[idx].type = (isDataTrack == kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK; - - /* Since the track lengths are not stored in .TOC.plist we compute them. */ - if (trackIndex > 0) { - theCD->track[idx-1].length = theCD->track[idx].offset - theCD->track[idx-1].offset; - } - } - - /* Compute the length of the last track */ - CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value); - - theCD->track[theCD->numtracks-1].length = - value - theCD->track[theCD->numtracks-1].offset; - - /* Set offset to leadout track */ - theCD->track[theCD->numtracks].offset = value; - } - - } - - theErr = 0; - goto cleanup; -bail: - SDL_SetError ("ReadTOCData: %s returned %d", error, theErr); - theErr = -1; -cleanup: - - if (propertyListRef != NULL) - CFRelease(propertyListRef); - if (dataRef != NULL) - CFRelease(dataRef); - if (forkData != NULL) - DisposePtr(forkData); - - FSCloseFork (forkRefNum); - - return theErr; -} - -int ListTrackFiles (FSVolumeRefNum theVolume, FSRef *trackFiles, int numTracks) -{ - OSStatus result = -1; - FSIterator iterator; - ItemCount actualObjects; - FSRef rootDirectory; - FSRef ref; - HFSUniStr255 nameStr; - - result = FSGetVolumeInfo (theVolume, - 0, - NULL, - kFSVolInfoFSInfo, - NULL, - NULL, - &rootDirectory); - - if (result != noErr) { - SDL_SetError ("ListTrackFiles: FSGetVolumeInfo returned %d", result); - return result; - } - - result = FSOpenIterator (&rootDirectory, kFSIterateFlat, &iterator); - if (result == noErr) { - do - { - result = FSGetCatalogInfoBulk (iterator, 1, &actualObjects, - NULL, kFSCatInfoNone, NULL, &ref, NULL, &nameStr); - if (result == noErr) { - - CFStringRef name; - name = CFStringCreateWithCharacters (NULL, nameStr.unicode, nameStr.length); - - /* Look for .aiff extension */ - if (CFStringHasSuffix (name, CFSTR(".aiff")) || - CFStringHasSuffix (name, CFSTR(".cdda"))) { - - /* Extract the track id from the filename */ - int trackID = 0, i = 0; - while (i < nameStr.length && !isdigit(nameStr.unicode[i])) { - ++i; - } - while (i < nameStr.length && isdigit(nameStr.unicode[i])) { - trackID = 10 * trackID +(nameStr.unicode[i] - '0'); - ++i; - } - - #if DEBUG_CDROM - printf("Found AIFF for track %d: '%s'\n", trackID, - CFStringGetCStringPtr (name, CFStringGetSystemEncoding())); - #endif - - /* Track ID's start at 1, but we want to start at 0 */ - trackID--; - - assert(0 <= trackID && trackID <= SDL_MAX_TRACKS); - - if (trackID < numTracks) - memcpy (&trackFiles[trackID], &ref, sizeof(FSRef)); - } - CFRelease (name); - } - } while(noErr == result); - FSCloseIterator (iterator); - } - - return 0; -} - -int LoadFile (const FSRef *ref, int startFrame, int stopFrame) -{ - int error = -1; - - if (CheckInit () < 0) - goto bail; - - /* release any currently playing file */ - if (ReleaseFile () < 0) - goto bail; - - #if DEBUG_CDROM - printf ("LoadFile: %d %d\n", startFrame, stopFrame); - #endif - - /*try {*/ - - /* create a new player, and attach to the audio unit */ - - thePlayer = new_AudioFilePlayer(ref); - if (thePlayer == NULL) { - SDL_SetError ("LoadFile: Could not create player"); - return -3; /*throw (-3);*/ - } - - if (!thePlayer->SetDestination(thePlayer, &theUnit)) - goto bail; - - if (startFrame >= 0) - thePlayer->SetStartFrame (thePlayer, startFrame); - - if (stopFrame >= 0 && stopFrame > startFrame) - thePlayer->SetStopFrame (thePlayer, stopFrame); - - /* we set the notifier later */ - /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL);*/ - - if (!thePlayer->Connect(thePlayer)) - goto bail; - - #if DEBUG_CDROM - thePlayer->Print(thePlayer); - fflush (stdout); - #endif - /*} - catch (...) - { - goto bail; - }*/ - - error = 0; - - bail: - return error; -} - -int ReleaseFile () -{ - int error = -1; - - /* (Don't see any way that the original C++ code could throw here.) --ryan. */ - /*try {*/ - if (thePlayer != NULL) { - - thePlayer->Disconnect(thePlayer); - - delete_AudioFilePlayer(thePlayer); - - thePlayer = NULL; - } - /*} - catch (...) - { - goto bail; - }*/ - - error = 0; - -/* bail: */ - return error; -} - -int PlayFile () -{ - OSStatus result = -1; - - if (CheckInit () < 0) - goto bail; - - /*try {*/ - - // start processing of the audio unit - result = AudioOutputUnitStart (theUnit); - if (result) goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart") - - /*} - catch (...) - { - goto bail; - }*/ - - result = 0; - -bail: - return result; -} - -int PauseFile () -{ - OSStatus result = -1; - - if (CheckInit () < 0) - goto bail; - - /*try {*/ - - /* stop processing the audio unit */ - result = AudioOutputUnitStop (theUnit); - if (result) goto bail; /*THROW_RESULT("PauseFile: AudioOutputUnitStop")*/ - /*} - catch (...) - { - goto bail; - }*/ - - result = 0; -bail: - return result; -} - -void SetCompletionProc (CDPlayerCompletionProc proc, SDL_CD *cdrom) -{ - assert(thePlayer != NULL); - - theCDROM = cdrom; - completionProc = proc; - thePlayer->SetNotifier (thePlayer, FilePlayNotificationHandler, cdrom); -} - -int GetCurrentFrame () -{ - int frame; - - if (thePlayer == NULL) - frame = 0; - else - frame = thePlayer->GetCurrentFrame (thePlayer); - - return frame; -} - - -#pragma mark -- Private Functions -- - -static OSStatus CheckInit () -{ - if (playBackWasInit) - return 0; - - OSStatus result = noErr; - - /* Create the callback semaphore */ - callbackSem = SDL_CreateSemaphore(0); - - /* Start callback thread */ - SDL_CreateThread(RunCallBackThread, NULL); - - { /*try {*/ - ComponentDescription desc; - - desc.componentType = kAudioUnitComponentType; - desc.componentSubType = kAudioUnitSubType_Output; - desc.componentManufacturer = kAudioUnitID_DefaultOutput; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - - Component comp = FindNextComponent (NULL, &desc); - if (comp == NULL) { - SDL_SetError ("CheckInit: FindNextComponent returned NULL"); - if (result) return -1; //throw(internalComponentErr); - } - - result = OpenAComponent (comp, &theUnit); - if (result) return -1; //THROW_RESULT("CheckInit: OpenAComponent") - - // you need to initialize the output unit before you set it as a destination - result = AudioUnitInitialize (theUnit); - if (result) return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize") - - - playBackWasInit = true; - } - /*catch (...) - { - return -1; - }*/ - - return 0; -} - -static void FilePlayNotificationHandler(void * inRefCon, OSStatus inStatus) -{ - if (inStatus == kAudioFilePlay_FileIsFinished) { - - /* notify non-CA thread to perform the callback */ - SDL_SemPost(callbackSem); - - } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) { - - SDL_SetError ("CDPlayer Notification: buffer underrun"); - } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) { - - SDL_SetError ("CDPlayer Notification: player is uninitialized"); - } else { - - SDL_SetError ("CDPlayer Notification: unknown error %ld", inStatus); - } -} - -static int RunCallBackThread (void *param) -{ - for (;;) { - - SDL_SemWait(callbackSem); - - if (completionProc && theCDROM) { - #if DEBUG_CDROM - printf ("callback!\n"); - #endif - (*completionProc)(theCDROM); - } else { - #if DEBUG_CDROM - printf ("callback?\n"); - #endif - } - } - - #if DEBUG_CDROM - printf ("thread dying now...\n"); - #endif - - return 0; -} - -/*}; // extern "C" */ |