📄 audiofilereaderthread.c
字号:
/* read data */ result = theItem->Read(theItem, writePtr, &dataChunkSize); if (result != noErr && result != eofErr) { AudioFilePlayer *afp = (AudioFilePlayer *) theItem->GetParent(theItem); afp->DoNotification(afp, result); continue; } if (dataChunkSize != theItem->mChunkSize) { writePtr += dataChunkSize; /* can't exit yet.. we still have to pass the partial buffer back */ SDL_memset(writePtr, 0, (theItem->mChunkSize - dataChunkSize)); } theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; /* switch buffers */ if (result == eofErr) theItem->mReadFilePosition = theItem->mFileLength; else theItem->mReadFilePosition += dataChunkSize; /* increment count */ }}void delete_FileReaderThread(FileReaderThread *frt){ if (frt != NULL) { delete_SDLOSXCAGuard(frt->mGuard); SDL_free(frt); }}FileReaderThread *new_FileReaderThread (){ FileReaderThread *frt = (FileReaderThread *) SDL_malloc(sizeof (FileReaderThread)); if (frt == NULL) return NULL; SDL_memset(frt, '\0', sizeof (*frt)); frt->mGuard = new_SDLOSXCAGuard(); if (frt->mGuard == NULL) { SDL_free(frt); return NULL; } #define SET_FILEREADERTHREAD_METHOD(m) frt->m = FileReaderThread_##m SET_FILEREADERTHREAD_METHOD(GetGuard); SET_FILEREADERTHREAD_METHOD(AddReader); SET_FILEREADERTHREAD_METHOD(RemoveReader); SET_FILEREADERTHREAD_METHOD(TryNextRead); SET_FILEREADERTHREAD_METHOD(ReadNextChunk); SET_FILEREADERTHREAD_METHOD(StartFixedPriorityThread); SET_FILEREADERTHREAD_METHOD(GetThreadBasePriority); SET_FILEREADERTHREAD_METHOD(DiskReaderEntry); #undef SET_FILEREADERTHREAD_METHOD frt->mThreadPriority = 62; return frt;}static FileReaderThread *sReaderThread;static int AudioFileManager_DoConnect (AudioFileManager *afm){ if (!afm->mIsEngaged) { OSStatus result; /*afm->mReadFilePosition = 0;*/ afm->mFinishedReadingData = 0; afm->mNumTimesAskedSinceFinished = 0; afm->mLockUnsuccessful = 0; UInt32 dataChunkSize; if ((afm->mFileLength - afm->mReadFilePosition) < afm->mChunkSize) dataChunkSize = afm->mFileLength - afm->mReadFilePosition; else dataChunkSize = afm->mChunkSize; result = afm->Read(afm, afm->mFileBuffer, &dataChunkSize); if (result) return 0; /*THROW_RESULT("AudioFileManager::DoConnect(): Read")*/ afm->mReadFilePosition += dataChunkSize; afm->mWriteToFirstBuffer = 0; afm->mReadFromFirstBuffer = 1; sReaderThread->AddReader(sReaderThread); afm->mIsEngaged = 1; } /* else throw static_cast<OSStatus>(-1); */ /* thread has already been started */ return 1;}static void AudioFileManager_Disconnect (AudioFileManager *afm){ if (afm->mIsEngaged) { sReaderThread->RemoveReader (sReaderThread, afm); afm->mIsEngaged = 0; }}static OSStatus AudioFileManager_Read(AudioFileManager *afm, char *buffer, UInt32 *len){ return FSReadFork (afm->mForkRefNum, fsFromStart, afm->mReadFilePosition + afm->mAudioDataOffset, *len, buffer, len);}static OSStatus AudioFileManager_GetFileData (AudioFileManager *afm, void** inOutData, UInt32 *inOutDataSize){ if (afm->mFinishedReadingData) { ++afm->mNumTimesAskedSinceFinished; *inOutDataSize = 0; *inOutData = 0; return noErr; } if (afm->mReadFromFirstBuffer == afm->mWriteToFirstBuffer) { #if DEBUG printf ("* * * * * * * Can't keep up with reading file\n"); #endif afm->mParent->DoNotification (afm->mParent, kAudioFilePlayErr_FilePlayUnderrun); *inOutDataSize = 0; *inOutData = 0; } else { *inOutDataSize = afm->mChunkSize; *inOutData = afm->mReadFromFirstBuffer ? afm->mFileBuffer : (afm->mFileBuffer + afm->mChunkSize); } afm->mLockUnsuccessful = !sReaderThread->TryNextRead (sReaderThread, afm); afm->mReadFromFirstBuffer = !afm->mReadFromFirstBuffer; return noErr;}static void AudioFileManager_AfterRender (AudioFileManager *afm){ if (afm->mNumTimesAskedSinceFinished > 0) { int didLock = 0; SDLOSXCAGuard *guard = sReaderThread->GetGuard(sReaderThread); if (guard->Try(guard, &didLock)) { afm->mParent->DoNotification (afm->mParent, kAudioFilePlay_FileIsFinished); if (didLock) guard->Unlock(guard); } } if (afm->mLockUnsuccessful) afm->mLockUnsuccessful = !sReaderThread->TryNextRead (sReaderThread, afm);}static void AudioFileManager_SetPosition (AudioFileManager *afm, SInt64 pos){ if (pos < 0 || pos >= afm->mFileLength) { SDL_SetError ("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n", (unsigned int)pos, (unsigned int)afm->mFileLength); pos = 0; } afm->mReadFilePosition = pos;} static void AudioFileManager_SetEndOfFile (AudioFileManager *afm, SInt64 pos){ if (pos <= 0 || pos > afm->mFileLength) { SDL_SetError ("AudioFileManager::SetEndOfFile - position beyond actual eof\n"); pos = afm->mFileLength; } afm->mFileLength = pos;}static const char *AudioFileManager_GetFileBuffer(AudioFileManager *afm){ return afm->mFileBuffer;}const AudioFilePlayer *AudioFileManager_GetParent(AudioFileManager *afm){ return afm->mParent;}static int AudioFileManager_GetByteCounter(AudioFileManager *afm){ return afm->mByteCounter;}static OSStatus AudioFileManager_FileInputProc (void *inRefCon, AudioUnitRenderActionFlags inActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, AudioBuffer *ioData){ AudioFileManager* afm = (AudioFileManager*)inRefCon; return afm->Render(afm, ioData);}static OSStatus AudioFileManager_Render (AudioFileManager *afm, AudioBuffer *ioData){ OSStatus result = noErr; if (afm->mBufferOffset >= afm->mBufferSize) { result = afm->GetFileData(afm, &afm->mTmpBuffer, &afm->mBufferSize); if (result) { SDL_SetError ("AudioConverterFillBuffer:%ld\n", result); afm->mParent->DoNotification(afm->mParent, result); return result; } afm->mBufferOffset = 0; } if (ioData->mDataByteSize > afm->mBufferSize - afm->mBufferOffset) ioData->mDataByteSize = afm->mBufferSize - afm->mBufferOffset; ioData->mData = (char *)afm->mTmpBuffer + afm->mBufferOffset; afm->mBufferOffset += ioData->mDataByteSize; afm->mByteCounter += ioData->mDataByteSize; afm->AfterRender(afm); return result;}void delete_AudioFileManager (AudioFileManager *afm){ if (afm != NULL) { if (afm->mFileBuffer) { free(afm->mFileBuffer); } SDL_free(afm); }}AudioFileManager *new_AudioFileManager(AudioFilePlayer *inParent, SInt16 inForkRefNum, SInt64 inFileLength, UInt32 inChunkSize){ AudioFileManager *afm; if (sReaderThread == NULL) { sReaderThread = new_FileReaderThread(); if (sReaderThread == NULL) return NULL; } afm = (AudioFileManager *) SDL_malloc(sizeof (AudioFileManager)); if (afm == NULL) return NULL; SDL_memset(afm, '\0', sizeof (*afm)); #define SET_AUDIOFILEMANAGER_METHOD(m) afm->m = AudioFileManager_##m SET_AUDIOFILEMANAGER_METHOD(Disconnect); SET_AUDIOFILEMANAGER_METHOD(DoConnect); SET_AUDIOFILEMANAGER_METHOD(Read); SET_AUDIOFILEMANAGER_METHOD(GetFileBuffer); SET_AUDIOFILEMANAGER_METHOD(GetParent); SET_AUDIOFILEMANAGER_METHOD(SetPosition); SET_AUDIOFILEMANAGER_METHOD(GetByteCounter); SET_AUDIOFILEMANAGER_METHOD(SetEndOfFile); SET_AUDIOFILEMANAGER_METHOD(Render); SET_AUDIOFILEMANAGER_METHOD(GetFileData); SET_AUDIOFILEMANAGER_METHOD(AfterRender); SET_AUDIOFILEMANAGER_METHOD(FileInputProc); #undef SET_AUDIOFILEMANAGER_METHOD afm->mParent = inParent; afm->mForkRefNum = inForkRefNum; afm->mBufferSize = inChunkSize; afm->mBufferOffset = inChunkSize; afm->mChunkSize = inChunkSize; afm->mFileLength = inFileLength; afm->mFileBuffer = (char*) SDL_malloc(afm->mChunkSize * 2); FSGetForkPosition(afm->mForkRefNum, &afm->mAudioDataOffset); assert (afm->mFileBuffer != NULL); return afm;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -