1.1 --- a/configure.in Sun Jan 04 15:57:16 2004 +0000
1.2 +++ b/configure.in Sun Jan 04 16:20:28 2004 +0000
1.3 @@ -2430,11 +2430,9 @@
1.4 # Set up files for the cdrom library
1.5 if test x$enable_cdrom = xyes; then
1.6 # The CD-ROM code won't work on old versions of MacOS X yet...
1.7 - #CDROM_SUBDIRS="$CDROM_SUBDIRS macosx"
1.8 - #CDROM_DRIVERS="$CDROM_DRIVERS macosx/libcdrom_macosx.la"
1.9 - #SYSTEM_LIBS="$SYSTEM_LIBS -framework AudioToolbox -framework AudioUnit -lstdc++"
1.10 - CDROM_SUBDIRS="$CDROM_SUBDIRS dummy"
1.11 - CDROM_DRIVERS="$CDROM_DRIVERS dummy/libcdrom_dummy.la"
1.12 + CDROM_SUBDIRS="$CDROM_SUBDIRS macosx"
1.13 + CDROM_DRIVERS="$CDROM_DRIVERS macosx/libcdrom_macosx.la"
1.14 + SYSTEM_LIBS="$SYSTEM_LIBS -framework AudioToolbox -framework AudioUnit -lstdc++"
1.15 fi
1.16 # Set up files for the thread library
1.17 if test x$enable_threads = xyes; then
2.1 --- a/src/cdrom/macosx/AudioFilePlayer.cpp Sun Jan 04 15:57:16 2004 +0000
2.2 +++ b/src/cdrom/macosx/AudioFilePlayer.cpp Sun Jan 04 16:20:28 2004 +0000
2.3 @@ -28,31 +28,9 @@
2.4 //
2.5 #include "AudioFilePlayer.h"
2.6
2.7 -extern const char* AudioFilePlayerErrorStr (OSStatus error)
2.8 -{
2.9 - const char *str;
2.10 -
2.11 - switch (error) {
2.12 - case kAudioFileUnspecifiedError: str = "wht?"; break;
2.13 - case kAudioFileUnsupportedFileTypeError: str = "typ?"; break;
2.14 - case kAudioFileUnsupportedDataFormatError: str = "fmt?"; break;
2.15 - case kAudioFileUnsupportedPropertyError: str = "pty?"; break;
2.16 - case kAudioFileBadPropertySizeError: str = "!siz"; break;
2.17 - case kAudioFileNotOptimizedError: str = "optm"; break;
2.18 - case kAudioFilePermissionsError: str = "prm?"; break;
2.19 - case kAudioFileFormatNameUnavailableError: str = "nme?"; break;
2.20 - case kAudioFileInvalidChunkError: str = "chk?"; break;
2.21 - case kAudioFileDoesNotAllow64BitDataSizeError: str = "off?"; break;
2.22 - default: str = "error unspecified";
2.23 - }
2.24 -
2.25 - return str;
2.26 -}
2.27 -
2.28 void ThrowResult (OSStatus result, const char* str)
2.29 {
2.30 - SDL_SetError ("Error: %s %d (%s)",
2.31 - str, result, AudioFilePlayerErrorStr(result));
2.32 + SDL_SetError ("Error: %s %d", str, result);
2.33 throw result;
2.34 }
2.35
2.36 @@ -133,31 +111,25 @@
2.37 OpenFile (inFileRef, fileDataSize);
2.38
2.39 // we want about a seconds worth of data for the buffer
2.40 - int secsBytes = UInt32 (mFileDescription.mSampleRate * mFileDescription.mBytesPerFrame);
2.41 + int bytesPerSecond = UInt32 (mFileDescription.mSampleRate * mFileDescription.mBytesPerFrame);
2.42
2.43 #if DEBUG
2.44 printf("File format:\n");
2.45 PrintStreamDesc (&mFileDescription);
2.46 #endif
2.47
2.48 - //round to a 32K boundary
2.49 - //if ((secsBytes & 0xFFFF8000) > (128 * 1024))
2.50 - //secsBytes &= 0xFFFF8000;
2.51 - //else
2.52 - //secsBytes = (secsBytes + 0x7FFF) & 0xFFFF8000;
2.53 -
2.54 - mAudioFileManager = new AudioFileReaderThread (*this,
2.55 - mAudioFileID,
2.56 + mAudioFileManager = new AudioFileManager (*this,
2.57 + mForkRefNum,
2.58 fileDataSize,
2.59 - secsBytes);
2.60 + bytesPerSecond);
2.61 }
2.62
2.63 // you can put a rate scalar here to play the file faster or slower
2.64 // by multiplying the same rate by the desired factor
2.65 // eg fileSampleRate * 2 -> twice as fast
2.66 // before you create the AudioConverter
2.67 -void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit,
2.68 - int inBusNumber)
2.69 +void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit,
2.70 + int inBusNumber)
2.71 {
2.72 if (mConnected) throw static_cast<OSStatus>(-1); //can't set dest if already engaged
2.73
2.74 @@ -194,43 +166,15 @@
2.75 // we're going to use this to know which convert routine to call
2.76 // a v1 audio unit will have a type of 'aunt'
2.77 // a v2 audio unit will have one of several different types.
2.78 - mIsAUNTUnit = (desc.componentType == kAudioUnitComponentType);
2.79 -
2.80 - if (!mIsAUNTUnit) {
2.81 + if (desc.componentType != kAudioUnitComponentType) {
2.82 result = badComponentInstance;
2.83 THROW_RESULT("BAD COMPONENT")
2.84 }
2.85
2.86
2.87 - // HACK - the AIFF files on CDs are in little endian order!
2.88 - if (mFileDescription.mFormatFlags == 0xE)
2.89 - mFileDescription.mFormatFlags &= ~kAudioFormatFlagIsBigEndian;
2.90 -
2.91 -
2.92 result = AudioConverterNew (&mFileDescription, &destDesc, &mConverter);
2.93 THROW_RESULT("AudioConverterNew")
2.94
2.95 -
2.96 -/*
2.97 - // if we have a mono source, we're going to copy each channel into
2.98 - // the destination's channel source...
2.99 - if (mFileDescription.mChannelsPerFrame == 1) {
2.100 -
2.101 - SInt32* channelMap = new SInt32 [destDesc.mChannelsPerFrame];
2.102 - for (unsigned int i = 0; i < destDesc.mChannelsPerFrame; ++i)
2.103 - channelMap[i] = 0; //set first channel to all output channels
2.104 -
2.105 - result = AudioConverterSetProperty(mConverter,
2.106 - kAudioConverterChannelMap,
2.107 - (sizeof(SInt32) * destDesc.mChannelsPerFrame),
2.108 - channelMap);
2.109 - THROW_RESULT("AudioConverterSetProperty")
2.110 -
2.111 - delete [] channelMap;
2.112 - }
2.113 -*/
2.114 - assert (mFileDescription.mChannelsPerFrame == 2);
2.115 -
2.116 #if 0
2.117 // this uses the better quality SRC
2.118 UInt32 srcID = kAudioUnitSRCAlgorithm_Polyphase;
2.119 @@ -272,9 +216,9 @@
2.120 mAudioFileManager = 0;
2.121 }
2.122
2.123 - if (mAudioFileID) {
2.124 - ::AudioFileClose (mAudioFileID);
2.125 - mAudioFileID = 0;
2.126 + if (mForkRefNum) {
2.127 + FSClose (mForkRefNum);
2.128 + mForkRefNum = 0;
2.129 }
2.130
2.131 if (mConverter) {
2.132 @@ -293,18 +237,16 @@
2.133 mAudioFileManager->Connect(mConverter);
2.134
2.135 // set the render callback for the file data to be supplied to the sound converter AU
2.136 - if (mIsAUNTUnit) {
2.137 - mInputCallback.inputProc = AudioFileManager::FileInputProc;
2.138 - mInputCallback.inputProcRefCon = mAudioFileManager;
2.139 + mInputCallback.inputProc = AudioFileManager::FileInputProc;
2.140 + mInputCallback.inputProcRefCon = mAudioFileManager;
2.141
2.142 - OSStatus result = AudioUnitSetProperty (mPlayUnit,
2.143 - kAudioUnitProperty_SetInputCallback,
2.144 - kAudioUnitScope_Input,
2.145 - mBusNumber,
2.146 - &mInputCallback,
2.147 - sizeof(mInputCallback));
2.148 - THROW_RESULT("AudioUnitSetProperty")
2.149 - }
2.150 + OSStatus result = AudioUnitSetProperty (mPlayUnit,
2.151 + kAudioUnitProperty_SetInputCallback,
2.152 + kAudioUnitScope_Input,
2.153 + mBusNumber,
2.154 + &mInputCallback,
2.155 + sizeof(mInputCallback));
2.156 + THROW_RESULT("AudioUnitSetProperty")
2.157 mConnected = true;
2.158 }
2.159 }
2.160 @@ -317,9 +259,7 @@
2.161
2.162 if (mNotifier) {
2.163 (*mNotifier) (mRefCon, inStatus);
2.164 - }
2.165 -
2.166 - else {
2.167 + } else {
2.168 SDL_SetError ("Notification posted with no notifier in place");
2.169
2.170 if (inStatus == kAudioFilePlay_FileIsFinished)
2.171 @@ -338,40 +278,89 @@
2.172 {
2.173 mConnected = false;
2.174
2.175 - if (mIsAUNTUnit) {
2.176 - mInputCallback.inputProc = 0;
2.177 - mInputCallback.inputProcRefCon = 0;
2.178 - OSStatus result = AudioUnitSetProperty (mPlayUnit,
2.179 - kAudioUnitProperty_SetInputCallback,
2.180 - kAudioUnitScope_Input,
2.181 - mBusNumber,
2.182 - &mInputCallback,
2.183 - sizeof(mInputCallback));
2.184 - if (result)
2.185 - SDL_SetError ("AudioUnitSetProperty:RemoveInputCallback:%ld", result);
2.186 + mInputCallback.inputProc = 0;
2.187 + mInputCallback.inputProcRefCon = 0;
2.188 + OSStatus result = AudioUnitSetProperty (mPlayUnit,
2.189 + kAudioUnitProperty_SetInputCallback,
2.190 + kAudioUnitScope_Input,
2.191 + mBusNumber,
2.192 + &mInputCallback,
2.193 + sizeof(mInputCallback));
2.194 + if (result)
2.195 + SDL_SetError ("AudioUnitSetProperty:RemoveInputCallback:%ld", result);
2.196
2.197 - }
2.198 -
2.199 mAudioFileManager->Disconnect();
2.200 }
2.201 }
2.202
2.203 +struct SSNDData {
2.204 + UInt32 offset;
2.205 + UInt32 blockSize;
2.206 +};
2.207 +
2.208 void AudioFilePlayer::OpenFile (const FSRef *inRef, SInt64& outFileDataSize)
2.209 -{
2.210 - OSStatus result = AudioFileOpen (inRef, fsRdPerm, 0, &mAudioFileID);
2.211 - THROW_RESULT("AudioFileOpen")
2.212 -
2.213 - UInt32 dataSize = sizeof(AudioStreamBasicDescription);
2.214 - result = AudioFileGetProperty (mAudioFileID,
2.215 - kAudioFilePropertyDataFormat,
2.216 - &dataSize,
2.217 - &mFileDescription);
2.218 - THROW_RESULT("AudioFileGetProperty")
2.219 -
2.220 - dataSize = sizeof (SInt64);
2.221 - result = AudioFileGetProperty (mAudioFileID,
2.222 - kAudioFilePropertyAudioDataByteCount,
2.223 - &dataSize,
2.224 - &outFileDataSize);
2.225 - THROW_RESULT("AudioFileGetProperty")
2.226 -}
2.227 \ No newline at end of file
2.228 +{
2.229 + ContainerChunk chunkHeader;
2.230 + ChunkHeader chunk;
2.231 + SSNDData ssndData;
2.232 +
2.233 + OSErr result;
2.234 + HFSUniStr255 dfName;
2.235 + ByteCount actual;
2.236 + SInt64 offset;
2.237 +
2.238 + // Open the data fork of the input file
2.239 + result = FSGetDataForkName(&dfName);
2.240 + THROW_RESULT("AudioFilePlayer::OpenFile(): FSGetDataForkName")
2.241 +
2.242 + result = FSOpenFork(inRef, dfName.length, dfName.unicode, fsRdPerm, &mForkRefNum);
2.243 + THROW_RESULT("AudioFilePlayer::OpenFile(): FSOpenFork")
2.244 +
2.245 + // Read the file header, and check if it's indeed an AIFC file
2.246 + result = FSReadFork(mForkRefNum, fsAtMark, 0, sizeof(chunkHeader), &chunkHeader, &actual);
2.247 + THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork")
2.248 +
2.249 + if (chunkHeader.ckID != 'FORM') {
2.250 + result = -1;
2.251 + THROW_RESULT("AudioFilePlayer::OpenFile(): chunk id is not 'FORM'");
2.252 + }
2.253 +
2.254 + if (chunkHeader.formType != 'AIFC') {
2.255 + result = -1;
2.256 + THROW_RESULT("AudioFilePlayer::OpenFile(): file format is not 'AIFC'");
2.257 + }
2.258 +
2.259 + // Search for the SSND chunk. We ignore all compression etc. information
2.260 + // in other chunks. Of course that is kind of evil, but for now we are lazy
2.261 + // and rely on the cdfs to always give us the same fixed format.
2.262 + // TODO: Parse the COMM chunk we currently skip to fill in mFileDescription.
2.263 + offset = 0;
2.264 + do {
2.265 + result = FSReadFork(mForkRefNum, fsFromMark, offset, sizeof(chunk), &chunk, &actual);
2.266 + THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork")
2.267 +
2.268 + // Skip the chunk data
2.269 + offset = chunk.ckSize;
2.270 + } while (chunk.ckID != 'SSND');
2.271 +
2.272 + // Read the header of the SSND chunk. After this, we are positioned right
2.273 + // at the start of the audio data.
2.274 + result = FSReadFork(mForkRefNum, fsAtMark, 0, sizeof(ssndData), &ssndData, &actual);
2.275 + THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork")
2.276 +
2.277 + result = FSSetForkPosition(mForkRefNum, fsFromMark, ssndData.offset);
2.278 + THROW_RESULT("AudioFilePlayer::OpenFile(): FSSetForkPosition")
2.279 +
2.280 + // Data size
2.281 + outFileDataSize = chunk.ckSize - ssndData.offset;
2.282 +
2.283 + // File format
2.284 + mFileDescription.mSampleRate = 44100;
2.285 + mFileDescription.mFormatID = kAudioFormatLinearPCM;
2.286 + mFileDescription.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger;
2.287 + mFileDescription.mBytesPerPacket = 4;
2.288 + mFileDescription.mFramesPerPacket = 1;
2.289 + mFileDescription.mBytesPerFrame = 4;
2.290 + mFileDescription.mChannelsPerFrame = 2;
2.291 + mFileDescription.mBitsPerChannel = 16;
2.292 +}
3.1 --- a/src/cdrom/macosx/AudioFilePlayer.h Sun Jan 04 15:57:16 2004 +0000
3.2 +++ b/src/cdrom/macosx/AudioFilePlayer.h Sun Jan 04 16:20:28 2004 +0000
3.3 @@ -31,7 +31,7 @@
3.4
3.5 #include <CoreServices/CoreServices.h>
3.6
3.7 -#include <AudioToolbox/AudioToolbox.h>
3.8 +#include <AudioToolbox/AudioConverter.h>
3.9 #include <AudioUnit/AudioUnit.h>
3.10
3.11 #include "SDL_error.h"
3.12 @@ -97,12 +97,9 @@
3.13 #if DEBUG
3.14 void Print() const
3.15 {
3.16 - CAShow (mAudioFileID);
3.17 printf ("Destination Bus:%ld\n", GetBusNumber());
3.18 - printf ("Is 'aunt' unit:%s\n", (mIsAUNTUnit ? "true" : "false"));
3.19 printf ("Is Connected:%s\n", (IsConnected() ? "true" : "false"));
3.20 - if (mConverter) CAShow (mConverter);
3.21 - printf ("- - - - - - - - - - - - - - \n");
3.22 + printf ("- - - - - - - - - - - - - - \n");
3.23 }
3.24 #endif
3.25
3.26 @@ -111,14 +108,13 @@
3.27 private:
3.28 AudioUnit mPlayUnit;
3.29 UInt32 mBusNumber;
3.30 - AudioFileID mAudioFileID;
3.31 + SInt16 mForkRefNum;
3.32
3.33 AudioUnitInputCallback mInputCallback;
3.34
3.35 AudioStreamBasicDescription mFileDescription;
3.36
3.37 bool mConnected;
3.38 - bool mIsAUNTUnit;
3.39
3.40 AudioFileManager* mAudioFileManager;
3.41 AudioConverterRef mConverter;
3.42 @@ -137,14 +133,12 @@
3.43 class AudioFileManager
3.44 {
3.45 public:
3.46 - AudioFileManager (AudioFilePlayer& inParent, AudioFileID inFile)
3.47 - : mParent (inParent),
3.48 - mAudioFileID (inFile),
3.49 - mFileBuffer (0),
3.50 - mByteCounter (0)
3.51 - {}
3.52 + AudioFileManager (AudioFilePlayer &inParent,
3.53 + SInt16 inForkRefNum,
3.54 + SInt64 inFileLength,
3.55 + UInt32 inChunkSize);
3.56
3.57 - virtual ~AudioFileManager();
3.58 + ~AudioFileManager();
3.59
3.60
3.61 void Connect (AudioConverterRef inConverter)
3.62 @@ -155,36 +149,51 @@
3.63
3.64 // this method should NOT be called by an object of this class
3.65 // as it is called by the parent's Disconnect() method
3.66 - virtual void Disconnect () {}
3.67 + void Disconnect ();
3.68
3.69 - const AudioFileID& GetFileID() const { return mAudioFileID; }
3.70 + OSStatus Read(char *buffer, UInt32 *len);
3.71
3.72 const char* GetFileBuffer () { return mFileBuffer; }
3.73
3.74 const AudioFilePlayer& GetParent () const { return mParent; }
3.75
3.76 - virtual void SetPosition (SInt64 pos) = 0; // seek/rewind in the file
3.77 + void SetPosition (SInt64 pos); // seek/rewind in the file
3.78
3.79 - virtual int GetByteCounter () { return mByteCounter; } // return actual bytes streamed to audio hardware
3.80 + int GetByteCounter () { return mByteCounter; } // return actual bytes streamed to audio hardware
3.81
3.82 - virtual void SetEndOfFile (SInt64 pos) = 0; // set the "EOF" (will behave just like it reached eof)
3.83 + void SetEndOfFile (SInt64 pos); // set the "EOF" (will behave just like it reached eof)
3.84
3.85 protected:
3.86 - AudioFilePlayer& mParent;
3.87 - AudioConverterRef mParentConverter;
3.88 - const AudioFileID mAudioFileID;
3.89 + AudioFilePlayer& mParent;
3.90 + AudioConverterRef mParentConverter;
3.91 + SInt16 mForkRefNum;
3.92 + SInt64 mAudioDataOffset;
3.93
3.94 - char* mFileBuffer;
3.95 + char* mFileBuffer;
3.96 +
3.97 + int mByteCounter;
3.98
3.99 - OSStatus Render (AudioBuffer &ioData);
3.100 + bool mReadFromFirstBuffer;
3.101 + bool mLockUnsuccessful;
3.102 + bool mIsEngaged;
3.103 +
3.104 + int mNumTimesAskedSinceFinished;
3.105
3.106 - int mByteCounter;
3.107 -
3.108 - virtual OSStatus GetFileData (void** inOutData, UInt32 *inOutDataSize) = 0;
3.109 +public:
3.110 + const UInt32 mChunkSize;
3.111 + SInt64 mFileLength;
3.112 + SInt64 mReadFilePosition;
3.113 + bool mWriteToFirstBuffer;
3.114 + bool mFinishedReadingData;
3.115 +
3.116 +protected:
3.117 + OSStatus Render (AudioBuffer &ioData);
3.118
3.119 - virtual void DoConnect () = 0;
3.120 + OSStatus GetFileData (void** inOutData, UInt32 *inOutDataSize);
3.121 +
3.122 + void DoConnect ();
3.123
3.124 - virtual void AfterRender () = 0;
3.125 + void AfterRender ();
3.126
3.127 public:
3.128 static OSStatus FileInputProc (void *inRefCon,
3.129 @@ -199,42 +208,4 @@
3.130 };
3.131
3.132
3.133 -#pragma mark __________ AudioFileReaderThread
3.134 -class AudioFileReaderThread
3.135 - : public AudioFileManager
3.136 -{
3.137 -public:
3.138 - const UInt32 mChunkSize;
3.139 - SInt64 mFileLength;
3.140 - SInt64 mReadFilePosition;
3.141 - bool mWriteToFirstBuffer;
3.142 - bool mFinishedReadingData;
3.143 -
3.144 - AudioFileReaderThread (AudioFilePlayer &inParent,
3.145 - AudioFileID &inFile,
3.146 - SInt64 inFileLength,
3.147 - UInt32 inChunkSize);
3.148 -
3.149 - virtual void Disconnect ();
3.150 -
3.151 - virtual void SetPosition (SInt64 pos); // seek/rewind in the file
3.152 -
3.153 - virtual void SetEndOfFile (SInt64 pos); // set the "EOF" (will behave just like it reached eof)
3.154 -
3.155 -protected:
3.156 - virtual void DoConnect ();
3.157 -
3.158 - virtual OSStatus GetFileData (void** inOutData, UInt32 *inOutDataSize);
3.159 -
3.160 - virtual void AfterRender ();
3.161 -
3.162 -private:
3.163 - bool mReadFromFirstBuffer;
3.164 - bool mLockUnsuccessful;
3.165 - bool mIsEngaged;
3.166 -
3.167 - int mNumTimesAskedSinceFinished;
3.168 -};
3.169 -
3.170 -
3.171 #endif
4.1 --- a/src/cdrom/macosx/AudioFileReaderThread.cpp Sun Jan 04 15:57:16 2004 +0000
4.2 +++ b/src/cdrom/macosx/AudioFileReaderThread.cpp Sun Jan 04 16:20:28 2004 +0000
4.3 @@ -24,7 +24,7 @@
4.4 */
4.5
4.6 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4.7 -// AudioFileReaderThread.cpp
4.8 +// AudioFileManager.cpp
4.9 //
4.10 #include "AudioFilePlayer.h"
4.11 #include <mach/mach.h> //used for setting policy of thread
4.12 @@ -35,115 +35,110 @@
4.13
4.14 class FileReaderThread {
4.15 public:
4.16 - FileReaderThread ();
4.17 + FileReaderThread ();
4.18
4.19 - CAGuard& GetGuard() { return mGuard; }
4.20 + CAGuard& GetGuard() { return mGuard; }
4.21 +
4.22 + void AddReader();
4.23
4.24 - void AddReader();
4.25 -
4.26 - void RemoveReader (const AudioFileReaderThread* inItem);
4.27 -
4.28 - // returns true if succeeded
4.29 - bool TryNextRead (AudioFileReaderThread* inItem)
4.30 - {
4.31 - bool didLock = false;
4.32 - bool succeeded = false;
4.33 - if (mGuard.Try (didLock))
4.34 - {
4.35 - mFileData.push_back (inItem);
4.36 - mGuard.Notify();
4.37 - succeeded = true;
4.38 + void RemoveReader (AudioFileManager* inItem);
4.39 +
4.40 + // returns true if succeeded
4.41 + bool TryNextRead (AudioFileManager* inItem)
4.42 + {
4.43 + bool didLock = false;
4.44 + bool succeeded = false;
4.45 + if (mGuard.Try (didLock))
4.46 + {
4.47 + mFileData.push_back (inItem);
4.48 + mGuard.Notify();
4.49 + succeeded = true;
4.50
4.51 - if (didLock)
4.52 - mGuard.Unlock();
4.53 - }
4.54 -
4.55 - return succeeded;
4.56 - }
4.57 -
4.58 - int mThreadShouldDie;
4.59 + if (didLock)
4.60 + mGuard.Unlock();
4.61 + }
4.62 +
4.63 + return succeeded;
4.64 + }
4.65 +
4.66 + int mThreadShouldDie;
4.67
4.68 private:
4.69 - typedef std::list<AudioFileReaderThread*> FileData;
4.70 + typedef std::list<AudioFileManager*> FileData;
4.71
4.72 - CAGuard mGuard;
4.73 - UInt32 mThreadPriority;
4.74 -
4.75 - int mNumReaders;
4.76 - FileData mFileData;
4.77 + CAGuard mGuard;
4.78 + UInt32 mThreadPriority;
4.79 +
4.80 + int mNumReaders;
4.81 + FileData mFileData;
4.82
4.83
4.84 - void ReadNextChunk ();
4.85 -
4.86 - void StartFixedPriorityThread ();
4.87 - static UInt32 GetThreadBasePriority (pthread_t inThread);
4.88 + void ReadNextChunk ();
4.89
4.90 - static void* DiskReaderEntry (void *inRefCon);
4.91 + void StartFixedPriorityThread ();
4.92 + static UInt32 GetThreadBasePriority (pthread_t inThread);
4.93 +
4.94 + static void* DiskReaderEntry (void *inRefCon);
4.95 };
4.96
4.97 FileReaderThread::FileReaderThread ()
4.98 - : mThreadPriority (62),
4.99 - mNumReaders (0)
4.100 + : mThreadPriority (62),
4.101 + mNumReaders (0)
4.102 {
4.103 }
4.104
4.105 -void FileReaderThread::AddReader()
4.106 +void FileReaderThread::AddReader()
4.107 {
4.108 - if (mNumReaders == 0)
4.109 - {
4.110 - mThreadShouldDie = false;
4.111 -
4.112 - StartFixedPriorityThread ();
4.113 - }
4.114 - mNumReaders++;
4.115 + if (mNumReaders == 0)
4.116 + {
4.117 + mThreadShouldDie = false;
4.118 +
4.119 + StartFixedPriorityThread ();
4.120 + }
4.121 + mNumReaders++;
4.122 }
4.123
4.124 -void FileReaderThread::RemoveReader (const AudioFileReaderThread* inItem)
4.125 +void FileReaderThread::RemoveReader (AudioFileManager* inItem)
4.126 {
4.127 - if (mNumReaders > 0)
4.128 - {
4.129 - CAGuard::Locker fileReadLock (mGuard);
4.130 -
4.131 - for (FileData::iterator iter = mFileData.begin(); iter != mFileData.end(); ++iter)
4.132 - {
4.133 - if ((*iter) == inItem) {
4.134 - mFileData.erase (iter);
4.135 - }
4.136 - }
4.137 -
4.138 - if (--mNumReaders == 0) {
4.139 - mThreadShouldDie = true;
4.140 - mGuard.Notify(); // wake up thread so it will quit
4.141 + if (mNumReaders > 0)
4.142 + {
4.143 + CAGuard::Locker fileReadLock (mGuard);
4.144 +
4.145 + mFileData.remove (inItem);
4.146 +
4.147 + if (--mNumReaders == 0) {
4.148 + mThreadShouldDie = true;
4.149 + mGuard.Notify(); // wake up thread so it will quit
4.150 mGuard.Wait(); // wait for thread to die
4.151 - }
4.152 - }
4.153 + }
4.154 + }
4.155 }
4.156
4.157 -void FileReaderThread::StartFixedPriorityThread ()
4.158 +void FileReaderThread::StartFixedPriorityThread ()
4.159 {
4.160 - pthread_attr_t theThreadAttrs;
4.161 - pthread_t pThread;
4.162 -
4.163 - OSStatus result = pthread_attr_init(&theThreadAttrs);
4.164 - THROW_RESULT("pthread_attr_init - Thread attributes could not be created.")
4.165 -
4.166 - result = pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED);
4.167 - THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.")
4.168 -
4.169 - result = pthread_create (&pThread, &theThreadAttrs, DiskReaderEntry, this);
4.170 - THROW_RESULT("pthread_create - Create and start the thread.")
4.171 -
4.172 - pthread_attr_destroy(&theThreadAttrs);
4.173 + pthread_attr_t theThreadAttrs;
4.174 + pthread_t pThread;
4.175 +
4.176 + OSStatus result = pthread_attr_init(&theThreadAttrs);
4.177 + THROW_RESULT("pthread_attr_init - Thread attributes could not be created.")
4.178 +
4.179 + result = pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED);
4.180 + THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.")
4.181
4.182 - // we've now created the thread and started it
4.183 - // we'll now set the priority of the thread to the nominated priority
4.184 - // and we'll also make the thread fixed
4.185 - thread_extended_policy_data_t theFixedPolicy;
4.186 - thread_precedence_policy_data_t thePrecedencePolicy;
4.187 - SInt32 relativePriority;
4.188 + result = pthread_create (&pThread, &theThreadAttrs, DiskReaderEntry, this);
4.189 + THROW_RESULT("pthread_create - Create and start the thread.")
4.190 +
4.191 + pthread_attr_destroy(&theThreadAttrs);
4.192 +
4.193 + // we've now created the thread and started it
4.194 + // we'll now set the priority of the thread to the nominated priority
4.195 + // and we'll also make the thread fixed
4.196 + thread_extended_policy_data_t theFixedPolicy;
4.197 + thread_precedence_policy_data_t thePrecedencePolicy;
4.198 + SInt32 relativePriority;
4.199
4.200 // make thread fixed
4.201 - theFixedPolicy.timeshare = false; // set to true for a non-fixed thread
4.202 + theFixedPolicy.timeshare = false; // set to true for a non-fixed thread
4.203 result = thread_policy_set (pthread_mach_thread_np(pThread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT);
4.204 THROW_RESULT("thread_policy - Couldn't set thread as fixed priority.")
4.205 // set priority
4.206 @@ -155,26 +150,26 @@
4.207 THROW_RESULT("thread_policy - Couldn't set thread priority.")
4.208 }
4.209
4.210 -UInt32 FileReaderThread::GetThreadBasePriority (pthread_t inThread)
4.211 +UInt32 FileReaderThread::GetThreadBasePriority (pthread_t inThread)
4.212 {
4.213 - thread_basic_info_data_t threadInfo;
4.214 - policy_info_data_t thePolicyInfo;
4.215 - unsigned int count;
4.216 + thread_basic_info_data_t threadInfo;
4.217 + policy_info_data_t thePolicyInfo;
4.218 + unsigned int count;
4.219
4.220 // get basic info
4.221 count = THREAD_BASIC_INFO_COUNT;
4.222 thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, (integer_t*)&threadInfo, &count);
4.223
4.224 - switch (threadInfo.policy) {
4.225 - case POLICY_TIMESHARE:
4.226 - count = POLICY_TIMESHARE_INFO_COUNT;
4.227 - thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (integer_t*)&(thePolicyInfo.ts), &count);
4.228 - return thePolicyInfo.ts.base_priority;
4.229 + switch (threadInfo.policy) {
4.230 + case POLICY_TIMESHARE:
4.231 + count = POLICY_TIMESHARE_INFO_COUNT;
4.232 + thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (integer_t*)&(thePolicyInfo.ts), &count);
4.233 + return thePolicyInfo.ts.base_priority;
4.234 break;
4.235
4.236 case POLICY_FIFO:
4.237 - count = POLICY_FIFO_INFO_COUNT;
4.238 - thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (integer_t*)&(thePolicyInfo.fifo), &count);
4.239 + count = POLICY_FIFO_INFO_COUNT;
4.240 + thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (integer_t*)&(thePolicyInfo.fifo), &count);
4.241 if (thePolicyInfo.fifo.depressed) {
4.242 return thePolicyInfo.fifo.depress_priority;
4.243 } else {
4.244 @@ -182,225 +177,233 @@
4.245 }
4.246 break;
4.247
4.248 - case POLICY_RR:
4.249 - count = POLICY_RR_INFO_COUNT;
4.250 - thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (integer_t*)&(thePolicyInfo.rr), &count);
4.251 - if (thePolicyInfo.rr.depressed) {
4.252 + case POLICY_RR:
4.253 + count = POLICY_RR_INFO_COUNT;
4.254 + thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (integer_t*)&(thePolicyInfo.rr), &count);
4.255 + if (thePolicyInfo.rr.depressed) {
4.256 return thePolicyInfo.rr.depress_priority;
4.257 } else {
4.258 return thePolicyInfo.rr.base_priority;
4.259 }
4.260 break;
4.261 - }
4.262 + }
4.263 +
4.264 + return 0;
4.265 +}
4.266 +
4.267 +void *FileReaderThread::DiskReaderEntry (void *inRefCon)
4.268 +{
4.269 + FileReaderThread *This = (FileReaderThread *)inRefCon;
4.270 + This->ReadNextChunk();
4.271 + #if DEBUG
4.272 + printf ("finished with reading file\n");
4.273 + #endif
4.274
4.275 return 0;
4.276 }
4.277
4.278 -void *FileReaderThread::DiskReaderEntry (void *inRefCon)
4.279 +void FileReaderThread::ReadNextChunk ()
4.280 {
4.281 - FileReaderThread *This = (FileReaderThread *)inRefCon;
4.282 - This->ReadNextChunk();
4.283 - #if DEBUG
4.284 - printf ("finished with reading file\n");
4.285 - #endif
4.286 -
4.287 - return 0;
4.288 -}
4.289 + OSStatus result;
4.290 + UInt32 dataChunkSize;
4.291 + AudioFileManager* theItem = 0;
4.292
4.293 -void FileReaderThread::ReadNextChunk ()
4.294 -{
4.295 - OSStatus result;
4.296 - UInt32 dataChunkSize;
4.297 - AudioFileReaderThread* theItem = 0;
4.298 -
4.299 - for (;;)
4.300 - {
4.301 - { // this is a scoped based lock
4.302 - CAGuard::Locker fileReadLock (mGuard);
4.303 -
4.304 - if (this->mThreadShouldDie) {
4.305 + for (;;)
4.306 + {
4.307 + { // this is a scoped based lock
4.308 + CAGuard::Locker fileReadLock (mGuard);
4.309 +
4.310 + if (this->mThreadShouldDie) {
4.311
4.312 mGuard.Notify();
4.313 return;
4.314 }
4.315 -
4.316 - if (mFileData.empty())
4.317 - {
4.318 - mGuard.Wait();
4.319 - }
4.320 -
4.321 - // kill thread
4.322 - if (this->mThreadShouldDie) {
4.323 +
4.324 + if (mFileData.empty())
4.325 + {
4.326 + mGuard.Wait();
4.327 + }
4.328 +
4.329 + // kill thread
4.330 + if (this->mThreadShouldDie) {
4.331
4.332 mGuard.Notify();
4.333 return;
4.334 }
4.335
4.336 - theItem = mFileData.front();
4.337 - mFileData.pop_front();
4.338 - }
4.339 -
4.340 - if ((theItem->mFileLength - theItem->mReadFilePosition) < theItem->mChunkSize)
4.341 - dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition;
4.342 - else
4.343 - dataChunkSize = theItem->mChunkSize;
4.344 -
4.345 - // this is the exit condition for the thread
4.346 - if (dataChunkSize == 0) {
4.347 - theItem->mFinishedReadingData = true;
4.348 - continue;
4.349 - }
4.350 - // construct pointer
4.351 - char* writePtr = const_cast<char*>(theItem->GetFileBuffer() +
4.352 - (theItem->mWriteToFirstBuffer ? 0 : theItem->mChunkSize));
4.353 -
4.354 + theItem = mFileData.front();
4.355 + mFileData.pop_front();
4.356 + }
4.357 +
4.358 + if ((theItem->mFileLength - theItem->mReadFilePosition) < theItem->mChunkSize)
4.359 + dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition;
4.360 + else
4.361 + dataChunkSize = theItem->mChunkSize;
4.362 +
4.363 + // this is the exit condition for the thread
4.364 + if (dataChunkSize == 0) {
4.365 + theItem->mFinishedReadingData = true;
4.366 + continue;
4.367 + }
4.368 + // construct pointer
4.369 + char* writePtr = const_cast<char*>(theItem->GetFileBuffer() +
4.370 + (theItem->mWriteToFirstBuffer ? 0 : theItem->mChunkSize));
4.371 +
4.372 /*
4.373 printf ("AudioFileReadBytes: theItem=%.8X fileID=%.8X pos=%.8X sz=%.8X flen=%.8X ptr=%.8X\n",
4.374 (unsigned int)theItem, (unsigned int)theItem->GetFileID(),
4.375 (unsigned int)theItem->mReadFilePosition, (unsigned int)dataChunkSize,
4.376 (unsigned int)theItem->mFileLength, (unsigned int)writePtr);
4.377 */
4.378 - result = AudioFileReadBytes (theItem->GetFileID(),
4.379 - false,
4.380 - theItem->mReadFilePosition,
4.381 - &dataChunkSize,
4.382 - writePtr);
4.383 - if (result) {
4.384 - theItem->GetParent().DoNotification(result);
4.385 - continue;
4.386 - }
4.387 -
4.388 - if (dataChunkSize != theItem->mChunkSize)
4.389 - {
4.390 - writePtr += dataChunkSize;
4.391 + result = theItem->Read(writePtr, &dataChunkSize);
4.392 + if (result) {
4.393 + theItem->GetParent().DoNotification(result);
4.394 + continue;
4.395 + }
4.396 +
4.397 + if (dataChunkSize != theItem->mChunkSize)
4.398 + {
4.399 + writePtr += dataChunkSize;
4.400
4.401 // can't exit yet.. we still have to pass the partial buffer back
4.402 memset (writePtr, 0, (theItem->mChunkSize - dataChunkSize));
4.403 }
4.404 -
4.405 - theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; // switch buffers
4.406 -
4.407 - theItem->mReadFilePosition += dataChunkSize; // increment count
4.408 - }
4.409 +
4.410 + theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; // switch buffers
4.411 +
4.412 + theItem->mReadFilePosition += dataChunkSize; // increment count
4.413 + }
4.414 }
4.415
4.416
4.417 static FileReaderThread sReaderThread;
4.418
4.419 -AudioFileReaderThread::AudioFileReaderThread (AudioFilePlayer &inParent,
4.420 - AudioFileID &inFile,
4.421 - SInt64 inFileLength,
4.422 - UInt32 inChunkSize)
4.423 - : AudioFileManager (inParent, inFile),
4.424 - mChunkSize (inChunkSize),
4.425 - mFileLength (inFileLength),
4.426 - mReadFilePosition (0),
4.427 - mWriteToFirstBuffer (false),
4.428 - mFinishedReadingData (false),
4.429 +AudioFileManager::AudioFileManager (AudioFilePlayer &inParent,
4.430 + SInt16 inForkRefNum,
4.431 + SInt64 inFileLength,
4.432 + UInt32 inChunkSize)
4.433 + : mParent (inParent),
4.434 + mForkRefNum (inForkRefNum),
4.435 + mFileBuffer (0),
4.436 + mByteCounter (0),
4.437 + mLockUnsuccessful (false),
4.438 + mIsEngaged (false),
4.439
4.440 - mLockUnsuccessful (false),
4.441 - mIsEngaged (false)
4.442 + mChunkSize (inChunkSize),
4.443 + mFileLength (inFileLength),
4.444 + mReadFilePosition (0),
4.445 + mWriteToFirstBuffer (false),
4.446 + mFinishedReadingData (false)
4.447 +
4.448 {
4.449 - mFileBuffer = (char*) malloc (mChunkSize * 2);
4.450 + mFileBuffer = (char*) malloc (mChunkSize * 2);
4.451 + FSGetForkPosition(mForkRefNum, &mAudioDataOffset);
4.452 assert (mFileBuffer != NULL);
4.453 }
4.454
4.455 -void AudioFileReaderThread::DoConnect ()
4.456 +void AudioFileManager::DoConnect ()
4.457 {
4.458 - if (!mIsEngaged)
4.459 - {
4.460 - //mReadFilePosition = 0;
4.461 - mFinishedReadingData = false;
4.462 + if (!mIsEngaged)
4.463 + {
4.464 + //mReadFilePosition = 0;
4.465 + mFinishedReadingData = false;
4.466
4.467 - mNumTimesAskedSinceFinished = -1;
4.468 - mLockUnsuccessful = false;
4.469 -
4.470 - UInt32 dataChunkSize;
4.471 + mNumTimesAskedSinceFinished = -1;
4.472 + mLockUnsuccessful = false;
4.473 +
4.474 + OSStatus result;
4.475 + UInt32 dataChunkSize;
4.476
4.477 if ((mFileLength - mReadFilePosition) < mChunkSize)
4.478 - dataChunkSize = mFileLength - mReadFilePosition;
4.479 - else
4.480 - dataChunkSize = mChunkSize;
4.481 + dataChunkSize = mFileLength - mReadFilePosition;
4.482 + else
4.483 + dataChunkSize = mChunkSize;
4.484
4.485 - OSStatus result = AudioFileReadBytes ( mAudioFileID,
4.486 - false,
4.487 - mReadFilePosition,
4.488 - &dataChunkSize,
4.489 - mFileBuffer);
4.490 - THROW_RESULT("AudioFileReadBytes")
4.491 -
4.492 - mReadFilePosition += dataChunkSize;
4.493 -
4.494 - mWriteToFirstBuffer = false;
4.495 - mReadFromFirstBuffer = true;
4.496 + result = Read(mFileBuffer, &dataChunkSize);
4.497 + THROW_RESULT("AudioFileManager::DoConnect(): Read")
4.498
4.499 - sReaderThread.AddReader();
4.500 -
4.501 - mIsEngaged = true;
4.502 - }
4.503 - else
4.504 - throw static_cast<OSStatus>(-1); //thread has already been started
4.505 + mReadFilePosition += dataChunkSize;
4.506 +
4.507 + mWriteToFirstBuffer = false;
4.508 + mReadFromFirstBuffer = true;
4.509 +
4.510 + sReaderThread.AddReader();
4.511 +
4.512 + mIsEngaged = true;
4.513 + }
4.514 + else
4.515 + throw static_cast<OSStatus>(-1); //thread has already been started
4.516 }
4.517
4.518 -void AudioFileReaderThread::Disconnect ()
4.519 +void AudioFileManager::Disconnect ()
4.520 {
4.521 - if (mIsEngaged)
4.522 - {
4.523 - sReaderThread.RemoveReader (this);
4.524 - mIsEngaged = false;
4.525 - }
4.526 + if (mIsEngaged)
4.527 + {
4.528 + sReaderThread.RemoveReader (this);
4.529 + mIsEngaged = false;
4.530 + }
4.531 }
4.532
4.533 -OSStatus AudioFileReaderThread::GetFileData (void** inOutData, UInt32 *inOutDataSize)
4.534 +OSStatus AudioFileManager::Read(char *buffer, UInt32 *len)
4.535 {
4.536 - if (mFinishedReadingData)
4.537 - {
4.538 - ++mNumTimesAskedSinceFinished;
4.539 - *inOutDataSize = 0;
4.540 - *inOutData = 0;
4.541 - return noErr;
4.542 - }
4.543 -
4.544 - if (mReadFromFirstBuffer == mWriteToFirstBuffer) {
4.545 - #if DEBUG
4.546 - printf ("* * * * * * * Can't keep up with reading file:%ld\n", mParent.GetBusNumber());
4.547 - #endif
4.548 -
4.549 - mParent.DoNotification (kAudioFilePlayErr_FilePlayUnderrun);
4.550 - *inOutDataSize = 0;
4.551 - *inOutData = 0;
4.552 - } else {
4.553 - *inOutDataSize = mChunkSize;
4.554 - *inOutData = mReadFromFirstBuffer ? mFileBuffer : (mFileBuffer + mChunkSize);
4.555 - }
4.556 -
4.557 - mLockUnsuccessful = !sReaderThread.TryNextRead (this);
4.558 -
4.559 - mReadFromFirstBuffer = !mReadFromFirstBuffer;
4.560 -
4.561 - return noErr;
4.562 + return FSReadFork (mForkRefNum,
4.563 + fsFromStart,
4.564 + mReadFilePosition + mAudioDataOffset,
4.565 + *len,
4.566 + buffer,
4.567 + len);
4.568 }
4.569
4.570 -void AudioFileReaderThread::AfterRender ()
4.571 +OSStatus AudioFileManager::GetFileData (void** inOutData, UInt32 *inOutDataSize)
4.572 {
4.573 - if (mNumTimesAskedSinceFinished > 0)
4.574 - {
4.575 - bool didLock = false;
4.576 - if (sReaderThread.GetGuard().Try (didLock)) {
4.577 - mParent.DoNotification (kAudioFilePlay_FileIsFinished);
4.578 - if (didLock)
4.579 - sReaderThread.GetGuard().Unlock();
4.580 - }
4.581 - }
4.582 + if (mFinishedReadingData)
4.583 + {
4.584 + ++mNumTimesAskedSinceFinished;
4.585 + *inOutDataSize = 0;
4.586 + *inOutData = 0;
4.587 + return noErr;
4.588 + }
4.589 +
4.590 + if (mReadFromFirstBuffer == mWriteToFirstBuffer) {
4.591 + #if DEBUG
4.592 + printf ("* * * * * * * Can't keep up with reading file:%ld\n", mParent.GetBusNumber());
4.593 + #endif
4.594 +
4.595 + mParent.DoNotification (kAudioFilePlayErr_FilePlayUnderrun);
4.596 + *inOutDataSize = 0;
4.597 + *inOutData = 0;
4.598 + } else {
4.599 + *inOutDataSize = mChunkSize;
4.600 + *inOutData = mReadFromFirstBuffer ? mFileBuffer : (mFileBuffer + mChunkSize);
4.601 + }
4.602
4.603 - if (mLockUnsuccessful)
4.604 - mLockUnsuccessful = !sReaderThread.TryNextRead (this);
4.605 + mLockUnsuccessful = !sReaderThread.TryNextRead (this);
4.606 +
4.607 + mReadFromFirstBuffer = !mReadFromFirstBuffer;
4.608 +
4.609 + return noErr;
4.610 }
4.611
4.612 -void AudioFileReaderThread::SetPosition (SInt64 pos)
4.613 +void AudioFileManager::AfterRender ()
4.614 +{
4.615 + if (mNumTimesAskedSinceFinished > 0)
4.616 + {
4.617 + bool didLock = false;
4.618 + if (sReaderThread.GetGuard().Try (didLock)) {
4.619 + mParent.DoNotification (kAudioFilePlay_FileIsFinished);
4.620 + if (didLock)
4.621 + sReaderThread.GetGuard().Unlock();
4.622 + }
4.623 + }
4.624 +
4.625 + if (mLockUnsuccessful)
4.626 + mLockUnsuccessful = !sReaderThread.TryNextRead (this);
4.627 +}
4.628 +
4.629 +void AudioFileManager::SetPosition (SInt64 pos)
4.630 {
4.631 if (pos < 0 || pos >= mFileLength) {
4.632 - SDL_SetError ("AudioFileReaderThread::SetPosition - position invalid: %d filelen=%d\n",
4.633 + SDL_SetError ("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n",
4.634 (unsigned int)pos, (unsigned int)mFileLength);
4.635 pos = 0;
4.636 }
4.637 @@ -408,10 +411,10 @@
4.638 mReadFilePosition = pos;
4.639 }
4.640
4.641 -void AudioFileReaderThread::SetEndOfFile (SInt64 pos)
4.642 +void AudioFileManager::SetEndOfFile (SInt64 pos)
4.643 {
4.644 if (pos <= 0 || pos > mFileLength) {
4.645 - SDL_SetError ("AudioFileReaderThread::SetEndOfFile - position beyond actual eof\n");
4.646 + SDL_SetError ("AudioFileManager::SetEndOfFile - position beyond actual eof\n");
4.647 pos = mFileLength;
4.648 }
4.649
5.1 --- a/src/cdrom/macosx/CAGuard.cpp Sun Jan 04 15:57:16 2004 +0000
5.2 +++ b/src/cdrom/macosx/CAGuard.cpp Sun Jan 04 16:20:28 2004 +0000
5.3 @@ -70,7 +70,7 @@
5.4
5.5 #include <stdio.h>
5.6
5.7 -#define NDEBUG 1
5.8 +//#define NDEBUG 1
5.9 #include <assert.h>
5.10
5.11
6.1 --- a/src/cdrom/macosx/CDPlayer.cpp Sun Jan 04 15:57:16 2004 +0000
6.2 +++ b/src/cdrom/macosx/CDPlayer.cpp Sun Jan 04 16:20:28 2004 +0000
6.3 @@ -114,9 +114,7 @@
6.4 for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++)
6.5 {
6.6 FSVolumeRefNum actualVolume;
6.7 - HFSUniStr255 volumeName;
6.8 FSVolumeInfo volumeInfo;
6.9 - FSRef rootDirectory;
6.10
6.11 memset (&volumeInfo, 0, sizeof(volumeInfo));
6.12
6.13 @@ -125,13 +123,13 @@
6.14 &actualVolume,
6.15 kFSVolInfoFSInfo,
6.16 &volumeInfo,
6.17 - &volumeName,
6.18 - &rootDirectory);
6.19 + NULL,
6.20 + NULL);
6.21
6.22 if (result == noErr)
6.23 {
6.24 if (volumeInfo.filesystemID == kAudioCDFilesystemID) // It's an audio CD
6.25 - {
6.26 + {
6.27 if (volumes != NULL && cdVolumeCount < numVolumes)
6.28 volumes[cdVolumeCount] = actualVolume;
6.29
7.1 --- a/src/cdrom/macosx/CDPlayer.h Sun Jan 04 15:57:16 2004 +0000
7.2 +++ b/src/cdrom/macosx/CDPlayer.h Sun Jan 04 16:20:28 2004 +0000
7.3 @@ -25,9 +25,8 @@
7.4
7.5 #include <string.h>
7.6
7.7 +#include <Carbon/Carbon.h>
7.8 #include <CoreFoundation/CoreFoundation.h>
7.9 -#include <Carbon/Carbon.h>
7.10 -
7.11 #include <AudioUnit/AudioUnit.h>
7.12
7.13 #include "SDL.h"
8.1 --- a/src/cdrom/macosx/SDL_syscdrom.c Sun Jan 04 15:57:16 2004 +0000
8.2 +++ b/src/cdrom/macosx/SDL_syscdrom.c Sun Jan 04 16:20:28 2004 +0000
8.3 @@ -265,19 +265,25 @@
8.4 /* Get the Unix disk name of the volume */
8.5 static const char *SDL_SYS_CDName (int drive)
8.6 {
8.7 - CFStringRef diskID;
8.8 OSStatus err = noErr;
8.9 -
8.10 + HParamBlockRec pb;
8.11 + GetVolParmsInfoBuffer volParmsInfo;
8.12 +
8.13 if (fakeCD)
8.14 return "Fake CD-ROM Device";
8.15 -
8.16 - err = FSCopyDiskIDForVolume (volumes[drive], &diskID);
8.17 +
8.18 + pb.ioParam.ioNamePtr = NULL;
8.19 + pb.ioParam.ioVRefNum = volumes[drive];
8.20 + pb.ioParam.ioBuffer = (Ptr)&volParmsInfo;
8.21 + pb.ioParam.ioReqCount = (SInt32)sizeof(volParmsInfo);
8.22 + err = PBHGetVolParmsSync(&pb);
8.23 +
8.24 if (err != noErr) {
8.25 - SDL_SetError ("FSCopyDiskIDForVolume returned %d", err);
8.26 + SDL_SetError ("PBHGetVolParmsSync returned %d", err);
8.27 return NULL;
8.28 }
8.29 -
8.30 - return CFStringGetCStringPtr (diskID, 0);
8.31 +
8.32 + return volParmsInfo.vMDeviceID;
8.33 }
8.34
8.35 /* Open the "device" */
8.36 @@ -318,14 +324,15 @@
8.37 /* Get CD-ROM status */
8.38 static CDstatus SDL_SYS_CDStatus (SDL_CD *cdrom, int *position)
8.39 {
8.40 - int trackFrame;
8.41 + if (position) {
8.42 + int trackFrame;
8.43 +
8.44 + Lock ();
8.45 + trackFrame = GetCurrentFrame ();
8.46 + Unlock ();
8.47
8.48 - Lock ();
8.49 - trackFrame = GetCurrentFrame ();
8.50 - Unlock ();
8.51 -
8.52 - if (position)
8.53 - *position = cdrom->track[currentTrack].offset + trackFrame;
8.54 + *position = cdrom->track[currentTrack].offset + trackFrame;
8.55 + }
8.56
8.57 return status;
8.58 }
8.59 @@ -383,8 +390,10 @@
8.60
8.61 Lock ();
8.62
8.63 - if (PauseFile () < 0)
8.64 + if (PauseFile () < 0) {
8.65 + Unlock ();
8.66 return -2;
8.67 + }
8.68
8.69 status = CD_PAUSED;
8.70
8.71 @@ -403,8 +412,10 @@
8.72
8.73 Lock ();
8.74
8.75 - if (PlayFile () < 0)
8.76 + if (PauseFile () < 0) {
8.77 + Unlock ();
8.78 return -2;
8.79 + }
8.80
8.81 status = CD_PLAYING;
8.82
8.83 @@ -423,11 +434,15 @@
8.84
8.85 Lock ();
8.86
8.87 - if (PauseFile () < 0)
8.88 + if (PauseFile () < 0) {
8.89 + Unlock ();
8.90 return -2;
8.91 + }
8.92
8.93 - if (ReleaseFile () < 0)
8.94 + if (ReleaseFile () < 0) {
8.95 + Unlock ();
8.96 return -3;
8.97 + }
8.98
8.99 status = CD_STOPPED;
8.100
8.101 @@ -440,6 +455,7 @@
8.102 static int SDL_SYS_CDEject(SDL_CD *cdrom)
8.103 {
8.104 OSStatus err;
8.105 + HParamBlockRec pb;
8.106
8.107 if (fakeCD) {
8.108 SDL_SetError (kErrorFakeDevice);
8.109 @@ -448,20 +464,28 @@
8.110
8.111 Lock ();
8.112
8.113 - if (PauseFile () < 0)
8.114 + if (PauseFile () < 0) {
8.115 + Unlock ();
8.116 return -2;
8.117 + }
8.118
8.119 - if (ReleaseFile () < 0)
8.120 + if (ReleaseFile () < 0) {
8.121 + Unlock ();
8.122 return -3;
8.123 + }
8.124
8.125 status = CD_STOPPED;
8.126
8.127 - err = FSEjectVolumeSync (volumes[cdrom->id], 0, NULL);
8.128 -
8.129 - if (err != noErr) {
8.130 - SDL_SetError ("FSEjectVolumeSync returned %d", err);
8.131 - return -4;
8.132 - }
8.133 + // Eject the volume
8.134 + pb.ioParam.ioNamePtr = NULL;
8.135 + pb.ioParam.ioVRefNum = volumes[cdrom->id];
8.136 + err = PBUnmountVol((ParamBlockRec *) &pb);
8.137 +
8.138 + if (err != noErr) {
8.139 + Unlock ();
8.140 + SDL_SetError ("PBUnmountVol returned %d", err);
8.141 + return -4;
8.142 + }
8.143
8.144 status = CD_TRAYEMPTY;
8.145
9.1 --- a/src/cdrom/macosx/SDL_syscdrom_c.h Sun Jan 04 15:57:16 2004 +0000
9.2 +++ b/src/cdrom/macosx/SDL_syscdrom_c.h Sun Jan 04 16:20:28 2004 +0000
9.3 @@ -20,6 +20,9 @@
9.4 slouken@libsdl.org
9.5 */
9.6
9.7 +/* This is the Mac OS X / CoreAudio specific header for the SDL CD-ROM API
9.8 + Contributed by Darrell Walisser and Max Horn
9.9 + */
9.10
9.11 /***********************************************************************************
9.12 Implementation Notes
10.1 --- a/src/video/quartz/SDL_QuartzVideo.m Sun Jan 04 15:57:16 2004 +0000
10.2 +++ b/src/video/quartz/SDL_QuartzVideo.m Sun Jan 04 16:20:28 2004 +0000
10.3 @@ -1365,7 +1365,7 @@
10.4 SDL_RWops *rw;
10.5 SDL_Surface *tmp;
10.6
10.7 - rw = SDL_RWFromMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon));
10.8 + rw = SDL_RWFromConstMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon));
10.9 tmp = SDL_LoadBMP_RW (rw, SDL_TRUE);
10.10
10.11 resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY);