📄 cdplayer.c
字号:
{ 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" */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -