Mercurial > sdl-ios-xcode
diff src/cdrom/macosx/AudioFileReaderThread.cpp @ 768:de1b2c3063b9
Max has been reworking this code so it works on MacOS X 10.1
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 04 Jan 2004 16:20:28 +0000 |
parents | 9c6717a1c66f |
children | da0a2ad35bf4 |
line wrap: on
line diff
--- a/src/cdrom/macosx/AudioFileReaderThread.cpp Sun Jan 04 15:57:16 2004 +0000 +++ b/src/cdrom/macosx/AudioFileReaderThread.cpp Sun Jan 04 16:20:28 2004 +0000 @@ -24,7 +24,7 @@ */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// AudioFileReaderThread.cpp +// AudioFileManager.cpp // #include "AudioFilePlayer.h" #include <mach/mach.h> //used for setting policy of thread @@ -35,115 +35,110 @@ class FileReaderThread { public: - FileReaderThread (); + FileReaderThread (); - CAGuard& GetGuard() { return mGuard; } + CAGuard& GetGuard() { return mGuard; } + + void AddReader(); - void AddReader(); - - void RemoveReader (const AudioFileReaderThread* inItem); - - // returns true if succeeded - bool TryNextRead (AudioFileReaderThread* inItem) - { - bool didLock = false; - bool succeeded = false; - if (mGuard.Try (didLock)) - { - mFileData.push_back (inItem); - mGuard.Notify(); - succeeded = true; + void RemoveReader (AudioFileManager* inItem); + + // returns true if succeeded + bool TryNextRead (AudioFileManager* inItem) + { + bool didLock = false; + bool succeeded = false; + if (mGuard.Try (didLock)) + { + mFileData.push_back (inItem); + mGuard.Notify(); + succeeded = true; - if (didLock) - mGuard.Unlock(); - } - - return succeeded; - } - - int mThreadShouldDie; + if (didLock) + mGuard.Unlock(); + } + + return succeeded; + } + + int mThreadShouldDie; private: - typedef std::list<AudioFileReaderThread*> FileData; + typedef std::list<AudioFileManager*> FileData; - CAGuard mGuard; - UInt32 mThreadPriority; - - int mNumReaders; - FileData mFileData; + CAGuard mGuard; + UInt32 mThreadPriority; + + int mNumReaders; + FileData mFileData; - void ReadNextChunk (); - - void StartFixedPriorityThread (); - static UInt32 GetThreadBasePriority (pthread_t inThread); + void ReadNextChunk (); - static void* DiskReaderEntry (void *inRefCon); + void StartFixedPriorityThread (); + static UInt32 GetThreadBasePriority (pthread_t inThread); + + static void* DiskReaderEntry (void *inRefCon); }; FileReaderThread::FileReaderThread () - : mThreadPriority (62), - mNumReaders (0) + : mThreadPriority (62), + mNumReaders (0) { } -void FileReaderThread::AddReader() +void FileReaderThread::AddReader() { - if (mNumReaders == 0) - { - mThreadShouldDie = false; - - StartFixedPriorityThread (); - } - mNumReaders++; + if (mNumReaders == 0) + { + mThreadShouldDie = false; + + StartFixedPriorityThread (); + } + mNumReaders++; } -void FileReaderThread::RemoveReader (const AudioFileReaderThread* inItem) +void FileReaderThread::RemoveReader (AudioFileManager* inItem) { - if (mNumReaders > 0) - { - CAGuard::Locker fileReadLock (mGuard); - - for (FileData::iterator iter = mFileData.begin(); iter != mFileData.end(); ++iter) - { - if ((*iter) == inItem) { - mFileData.erase (iter); - } - } - - if (--mNumReaders == 0) { - mThreadShouldDie = true; - mGuard.Notify(); // wake up thread so it will quit + if (mNumReaders > 0) + { + CAGuard::Locker fileReadLock (mGuard); + + mFileData.remove (inItem); + + if (--mNumReaders == 0) { + mThreadShouldDie = true; + mGuard.Notify(); // wake up thread so it will quit mGuard.Wait(); // wait for thread to die - } - } + } + } } -void FileReaderThread::StartFixedPriorityThread () +void FileReaderThread::StartFixedPriorityThread () { - pthread_attr_t theThreadAttrs; - pthread_t pThread; - - OSStatus result = pthread_attr_init(&theThreadAttrs); - THROW_RESULT("pthread_attr_init - Thread attributes could not be created.") - - result = pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED); - THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.") - - result = pthread_create (&pThread, &theThreadAttrs, DiskReaderEntry, this); - THROW_RESULT("pthread_create - Create and start the thread.") - - pthread_attr_destroy(&theThreadAttrs); + pthread_attr_t theThreadAttrs; + pthread_t pThread; + + OSStatus result = pthread_attr_init(&theThreadAttrs); + THROW_RESULT("pthread_attr_init - Thread attributes could not be created.") + + result = pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED); + THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.") - // we've now created the thread and started it - // we'll now set the priority of the thread to the nominated priority - // and we'll also make the thread fixed - thread_extended_policy_data_t theFixedPolicy; - thread_precedence_policy_data_t thePrecedencePolicy; - SInt32 relativePriority; + result = pthread_create (&pThread, &theThreadAttrs, DiskReaderEntry, this); + THROW_RESULT("pthread_create - Create and start the thread.") + + pthread_attr_destroy(&theThreadAttrs); + + // we've now created the thread and started it + // we'll now set the priority of the thread to the nominated priority + // and we'll also make the thread fixed + thread_extended_policy_data_t theFixedPolicy; + thread_precedence_policy_data_t thePrecedencePolicy; + SInt32 relativePriority; // make thread fixed - theFixedPolicy.timeshare = false; // set to true for a non-fixed thread + theFixedPolicy.timeshare = false; // set to true for a non-fixed thread result = thread_policy_set (pthread_mach_thread_np(pThread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT); THROW_RESULT("thread_policy - Couldn't set thread as fixed priority.") // set priority @@ -155,26 +150,26 @@ THROW_RESULT("thread_policy - Couldn't set thread priority.") } -UInt32 FileReaderThread::GetThreadBasePriority (pthread_t inThread) +UInt32 FileReaderThread::GetThreadBasePriority (pthread_t inThread) { - thread_basic_info_data_t threadInfo; - policy_info_data_t thePolicyInfo; - unsigned int count; + thread_basic_info_data_t threadInfo; + policy_info_data_t thePolicyInfo; + unsigned int count; // get basic info count = THREAD_BASIC_INFO_COUNT; thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, (integer_t*)&threadInfo, &count); - switch (threadInfo.policy) { - case POLICY_TIMESHARE: - count = POLICY_TIMESHARE_INFO_COUNT; - thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (integer_t*)&(thePolicyInfo.ts), &count); - return thePolicyInfo.ts.base_priority; + switch (threadInfo.policy) { + case POLICY_TIMESHARE: + count = POLICY_TIMESHARE_INFO_COUNT; + thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (integer_t*)&(thePolicyInfo.ts), &count); + return thePolicyInfo.ts.base_priority; break; case POLICY_FIFO: - count = POLICY_FIFO_INFO_COUNT; - thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (integer_t*)&(thePolicyInfo.fifo), &count); + count = POLICY_FIFO_INFO_COUNT; + thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (integer_t*)&(thePolicyInfo.fifo), &count); if (thePolicyInfo.fifo.depressed) { return thePolicyInfo.fifo.depress_priority; } else { @@ -182,225 +177,233 @@ } break; - case POLICY_RR: - count = POLICY_RR_INFO_COUNT; - thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (integer_t*)&(thePolicyInfo.rr), &count); - if (thePolicyInfo.rr.depressed) { + case POLICY_RR: + count = POLICY_RR_INFO_COUNT; + thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (integer_t*)&(thePolicyInfo.rr), &count); + if (thePolicyInfo.rr.depressed) { return thePolicyInfo.rr.depress_priority; } else { return thePolicyInfo.rr.base_priority; } break; - } + } + + return 0; +} + +void *FileReaderThread::DiskReaderEntry (void *inRefCon) +{ + FileReaderThread *This = (FileReaderThread *)inRefCon; + This->ReadNextChunk(); + #if DEBUG + printf ("finished with reading file\n"); + #endif return 0; } -void *FileReaderThread::DiskReaderEntry (void *inRefCon) +void FileReaderThread::ReadNextChunk () { - FileReaderThread *This = (FileReaderThread *)inRefCon; - This->ReadNextChunk(); - #if DEBUG - printf ("finished with reading file\n"); - #endif - - return 0; -} + OSStatus result; + UInt32 dataChunkSize; + AudioFileManager* theItem = 0; -void FileReaderThread::ReadNextChunk () -{ - OSStatus result; - UInt32 dataChunkSize; - AudioFileReaderThread* theItem = 0; - - for (;;) - { - { // this is a scoped based lock - CAGuard::Locker fileReadLock (mGuard); - - if (this->mThreadShouldDie) { + for (;;) + { + { // this is a scoped based lock + CAGuard::Locker fileReadLock (mGuard); + + if (this->mThreadShouldDie) { mGuard.Notify(); return; } - - if (mFileData.empty()) - { - mGuard.Wait(); - } - - // kill thread - if (this->mThreadShouldDie) { + + if (mFileData.empty()) + { + mGuard.Wait(); + } + + // kill thread + if (this->mThreadShouldDie) { mGuard.Notify(); return; } - theItem = mFileData.front(); - mFileData.pop_front(); - } - - if ((theItem->mFileLength - theItem->mReadFilePosition) < theItem->mChunkSize) - dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition; - else - dataChunkSize = theItem->mChunkSize; - - // this is the exit condition for the thread - if (dataChunkSize == 0) { - theItem->mFinishedReadingData = true; - continue; - } - // construct pointer - char* writePtr = const_cast<char*>(theItem->GetFileBuffer() + - (theItem->mWriteToFirstBuffer ? 0 : theItem->mChunkSize)); - + theItem = mFileData.front(); + mFileData.pop_front(); + } + + if ((theItem->mFileLength - theItem->mReadFilePosition) < theItem->mChunkSize) + dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition; + else + dataChunkSize = theItem->mChunkSize; + + // this is the exit condition for the thread + if (dataChunkSize == 0) { + theItem->mFinishedReadingData = true; + continue; + } + // construct pointer + char* writePtr = const_cast<char*>(theItem->GetFileBuffer() + + (theItem->mWriteToFirstBuffer ? 0 : theItem->mChunkSize)); + /* printf ("AudioFileReadBytes: theItem=%.8X fileID=%.8X pos=%.8X sz=%.8X flen=%.8X ptr=%.8X\n", (unsigned int)theItem, (unsigned int)theItem->GetFileID(), (unsigned int)theItem->mReadFilePosition, (unsigned int)dataChunkSize, (unsigned int)theItem->mFileLength, (unsigned int)writePtr); */ - result = AudioFileReadBytes (theItem->GetFileID(), - false, - theItem->mReadFilePosition, - &dataChunkSize, - writePtr); - if (result) { - theItem->GetParent().DoNotification(result); - continue; - } - - if (dataChunkSize != theItem->mChunkSize) - { - writePtr += dataChunkSize; + result = theItem->Read(writePtr, &dataChunkSize); + if (result) { + theItem->GetParent().DoNotification(result); + continue; + } + + if (dataChunkSize != theItem->mChunkSize) + { + writePtr += dataChunkSize; // can't exit yet.. we still have to pass the partial buffer back memset (writePtr, 0, (theItem->mChunkSize - dataChunkSize)); } - - theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; // switch buffers - - theItem->mReadFilePosition += dataChunkSize; // increment count - } + + theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; // switch buffers + + theItem->mReadFilePosition += dataChunkSize; // increment count + } } static FileReaderThread sReaderThread; -AudioFileReaderThread::AudioFileReaderThread (AudioFilePlayer &inParent, - AudioFileID &inFile, - SInt64 inFileLength, - UInt32 inChunkSize) - : AudioFileManager (inParent, inFile), - mChunkSize (inChunkSize), - mFileLength (inFileLength), - mReadFilePosition (0), - mWriteToFirstBuffer (false), - mFinishedReadingData (false), +AudioFileManager::AudioFileManager (AudioFilePlayer &inParent, + SInt16 inForkRefNum, + SInt64 inFileLength, + UInt32 inChunkSize) + : mParent (inParent), + mForkRefNum (inForkRefNum), + mFileBuffer (0), + mByteCounter (0), + mLockUnsuccessful (false), + mIsEngaged (false), - mLockUnsuccessful (false), - mIsEngaged (false) + mChunkSize (inChunkSize), + mFileLength (inFileLength), + mReadFilePosition (0), + mWriteToFirstBuffer (false), + mFinishedReadingData (false) + { - mFileBuffer = (char*) malloc (mChunkSize * 2); + mFileBuffer = (char*) malloc (mChunkSize * 2); + FSGetForkPosition(mForkRefNum, &mAudioDataOffset); assert (mFileBuffer != NULL); } -void AudioFileReaderThread::DoConnect () +void AudioFileManager::DoConnect () { - if (!mIsEngaged) - { - //mReadFilePosition = 0; - mFinishedReadingData = false; + if (!mIsEngaged) + { + //mReadFilePosition = 0; + mFinishedReadingData = false; - mNumTimesAskedSinceFinished = -1; - mLockUnsuccessful = false; - - UInt32 dataChunkSize; + mNumTimesAskedSinceFinished = -1; + mLockUnsuccessful = false; + + OSStatus result; + UInt32 dataChunkSize; if ((mFileLength - mReadFilePosition) < mChunkSize) - dataChunkSize = mFileLength - mReadFilePosition; - else - dataChunkSize = mChunkSize; + dataChunkSize = mFileLength - mReadFilePosition; + else + dataChunkSize = mChunkSize; - OSStatus result = AudioFileReadBytes ( mAudioFileID, - false, - mReadFilePosition, - &dataChunkSize, - mFileBuffer); - THROW_RESULT("AudioFileReadBytes") - - mReadFilePosition += dataChunkSize; - - mWriteToFirstBuffer = false; - mReadFromFirstBuffer = true; + result = Read(mFileBuffer, &dataChunkSize); + THROW_RESULT("AudioFileManager::DoConnect(): Read") - sReaderThread.AddReader(); - - mIsEngaged = true; - } - else - throw static_cast<OSStatus>(-1); //thread has already been started + mReadFilePosition += dataChunkSize; + + mWriteToFirstBuffer = false; + mReadFromFirstBuffer = true; + + sReaderThread.AddReader(); + + mIsEngaged = true; + } + else + throw static_cast<OSStatus>(-1); //thread has already been started } -void AudioFileReaderThread::Disconnect () +void AudioFileManager::Disconnect () { - if (mIsEngaged) - { - sReaderThread.RemoveReader (this); - mIsEngaged = false; - } + if (mIsEngaged) + { + sReaderThread.RemoveReader (this); + mIsEngaged = false; + } } -OSStatus AudioFileReaderThread::GetFileData (void** inOutData, UInt32 *inOutDataSize) +OSStatus AudioFileManager::Read(char *buffer, UInt32 *len) { - if (mFinishedReadingData) - { - ++mNumTimesAskedSinceFinished; - *inOutDataSize = 0; - *inOutData = 0; - return noErr; - } - - if (mReadFromFirstBuffer == mWriteToFirstBuffer) { - #if DEBUG - printf ("* * * * * * * Can't keep up with reading file:%ld\n", mParent.GetBusNumber()); - #endif - - mParent.DoNotification (kAudioFilePlayErr_FilePlayUnderrun); - *inOutDataSize = 0; - *inOutData = 0; - } else { - *inOutDataSize = mChunkSize; - *inOutData = mReadFromFirstBuffer ? mFileBuffer : (mFileBuffer + mChunkSize); - } - - mLockUnsuccessful = !sReaderThread.TryNextRead (this); - - mReadFromFirstBuffer = !mReadFromFirstBuffer; - - return noErr; + return FSReadFork (mForkRefNum, + fsFromStart, + mReadFilePosition + mAudioDataOffset, + *len, + buffer, + len); } -void AudioFileReaderThread::AfterRender () +OSStatus AudioFileManager::GetFileData (void** inOutData, UInt32 *inOutDataSize) { - if (mNumTimesAskedSinceFinished > 0) - { - bool didLock = false; - if (sReaderThread.GetGuard().Try (didLock)) { - mParent.DoNotification (kAudioFilePlay_FileIsFinished); - if (didLock) - sReaderThread.GetGuard().Unlock(); - } - } + if (mFinishedReadingData) + { + ++mNumTimesAskedSinceFinished; + *inOutDataSize = 0; + *inOutData = 0; + return noErr; + } + + if (mReadFromFirstBuffer == mWriteToFirstBuffer) { + #if DEBUG + printf ("* * * * * * * Can't keep up with reading file:%ld\n", mParent.GetBusNumber()); + #endif + + mParent.DoNotification (kAudioFilePlayErr_FilePlayUnderrun); + *inOutDataSize = 0; + *inOutData = 0; + } else { + *inOutDataSize = mChunkSize; + *inOutData = mReadFromFirstBuffer ? mFileBuffer : (mFileBuffer + mChunkSize); + } - if (mLockUnsuccessful) - mLockUnsuccessful = !sReaderThread.TryNextRead (this); + mLockUnsuccessful = !sReaderThread.TryNextRead (this); + + mReadFromFirstBuffer = !mReadFromFirstBuffer; + + return noErr; } -void AudioFileReaderThread::SetPosition (SInt64 pos) +void AudioFileManager::AfterRender () +{ + if (mNumTimesAskedSinceFinished > 0) + { + bool didLock = false; + if (sReaderThread.GetGuard().Try (didLock)) { + mParent.DoNotification (kAudioFilePlay_FileIsFinished); + if (didLock) + sReaderThread.GetGuard().Unlock(); + } + } + + if (mLockUnsuccessful) + mLockUnsuccessful = !sReaderThread.TryNextRead (this); +} + +void AudioFileManager::SetPosition (SInt64 pos) { if (pos < 0 || pos >= mFileLength) { - SDL_SetError ("AudioFileReaderThread::SetPosition - position invalid: %d filelen=%d\n", + SDL_SetError ("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n", (unsigned int)pos, (unsigned int)mFileLength); pos = 0; } @@ -408,10 +411,10 @@ mReadFilePosition = pos; } -void AudioFileReaderThread::SetEndOfFile (SInt64 pos) +void AudioFileManager::SetEndOfFile (SInt64 pos) { if (pos <= 0 || pos > mFileLength) { - SDL_SetError ("AudioFileReaderThread::SetEndOfFile - position beyond actual eof\n"); + SDL_SetError ("AudioFileManager::SetEndOfFile - position beyond actual eof\n"); pos = mFileLength; }