Max has been reworking this code so it works on MacOS X 10.1
authorSam Lantinga <slouken@libsdl.org>
Sun, 04 Jan 2004 16:20:28 +0000
changeset 768de1b2c3063b9
parent 767 d9e79e31a7b7
child 769 b8d311d90021
Max has been reworking this code so it works on MacOS X 10.1
configure.in
src/cdrom/macosx/AudioFilePlayer.cpp
src/cdrom/macosx/AudioFilePlayer.h
src/cdrom/macosx/AudioFileReaderThread.cpp
src/cdrom/macosx/CAGuard.cpp
src/cdrom/macosx/CDPlayer.cpp
src/cdrom/macosx/CDPlayer.h
src/cdrom/macosx/SDL_syscdrom.c
src/cdrom/macosx/SDL_syscdrom_c.h
src/video/quartz/SDL_QuartzVideo.m
     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 +    bool                mReadFromFirstBuffer;
   3.100 +    bool                mLockUnsuccessful;
   3.101 +    bool                mIsEngaged;
   3.102 +    
   3.103 +    int                 mNumTimesAskedSinceFinished;
   3.104 +
   3.105 +public:
   3.106 +    const UInt32        mChunkSize;
   3.107 +    SInt64              mFileLength;
   3.108 +    SInt64              mReadFilePosition;
   3.109 +    bool                mWriteToFirstBuffer;
   3.110 +    bool                mFinishedReadingData;
   3.111 +
   3.112 +protected:
   3.113      OSStatus            Render (AudioBuffer &ioData);
   3.114 -
   3.115 -    int                         mByteCounter;
   3.116      
   3.117 -    virtual OSStatus    GetFileData (void** inOutData, UInt32 *inOutDataSize) = 0;
   3.118 +    OSStatus            GetFileData (void** inOutData, UInt32 *inOutDataSize);
   3.119      
   3.120 -    virtual void        DoConnect () = 0;
   3.121 +    void                DoConnect ();
   3.122          
   3.123 -    virtual void        AfterRender () = 0;
   3.124 +    void                AfterRender ();
   3.125  
   3.126  public:
   3.127      static OSStatus     FileInputProc (void                             *inRefCon, 
   3.128 @@ -199,42 +208,4 @@
   3.129  };
   3.130  
   3.131  
   3.132 -#pragma mark __________ AudioFileReaderThread
   3.133 -class AudioFileReaderThread 
   3.134 -    : public AudioFileManager
   3.135 -{
   3.136 -public:
   3.137 -    const UInt32    mChunkSize;
   3.138 -    SInt64          mFileLength;
   3.139 -    SInt64          mReadFilePosition;
   3.140 -    bool            mWriteToFirstBuffer;
   3.141 -    bool            mFinishedReadingData;
   3.142 -    
   3.143 -    AudioFileReaderThread (AudioFilePlayer  &inParent, 
   3.144 -                            AudioFileID     &inFile, 
   3.145 -                            SInt64          inFileLength,
   3.146 -                            UInt32          inChunkSize);
   3.147 -    
   3.148 -    virtual void        Disconnect ();
   3.149 -
   3.150 -    virtual void        SetPosition (SInt64 pos);  // seek/rewind in the file
   3.151 -    
   3.152 -    virtual void        SetEndOfFile (SInt64 pos);  // set the "EOF" (will behave just like it reached eof)
   3.153 -    
   3.154 -protected:
   3.155 -    virtual void        DoConnect ();
   3.156 -
   3.157 -    virtual OSStatus    GetFileData (void** inOutData, UInt32 *inOutDataSize);
   3.158 -
   3.159 -    virtual void        AfterRender ();
   3.160 -
   3.161 -private:
   3.162 -    bool                        mReadFromFirstBuffer;
   3.163 -    bool                        mLockUnsuccessful;
   3.164 -    bool                        mIsEngaged;
   3.165 -    
   3.166 -    int                         mNumTimesAskedSinceFinished;
   3.167 -};
   3.168 -
   3.169 -
   3.170  #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						RemoveReader (const AudioFileReaderThread* inItem);
    4.25 -		
    4.26 -		// returns true if succeeded
    4.27 -	bool						TryNextRead (AudioFileReaderThread* inItem)
    4.28 -	{
    4.29 -		bool didLock = false;
    4.30 -		bool succeeded = false;
    4.31 -		if (mGuard.Try (didLock))
    4.32 -		{
    4.33 -			mFileData.push_back (inItem);
    4.34 -			mGuard.Notify();
    4.35 -			succeeded = true;
    4.36 +    void                        AddReader();
    4.37 +    
    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 -	// we've now created the thread and started it
   4.177 -	// we'll now set the priority of the thread to the nominated priority
   4.178 -	// and we'll also make the thread fixed
   4.179 -    thread_extended_policy_data_t		theFixedPolicy;
   4.180 -    thread_precedence_policy_data_t		thePrecedencePolicy;
   4.181 -    SInt32								relativePriority;
   4.182 +    OSStatus result = pthread_attr_init(&theThreadAttrs);
   4.183 +        THROW_RESULT("pthread_attr_init - Thread attributes could not be created.")
   4.184 +    
   4.185 +    result = pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED);
   4.186 +        THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.")
   4.187 +    
   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 +void    *FileReaderThread::DiskReaderEntry (void *inRefCon)
   4.269  {
   4.270 -	FileReaderThread *This = (FileReaderThread *)inRefCon;
   4.271 -	This->ReadNextChunk();
   4.272 -	#if DEBUG
   4.273 -	printf ("finished with reading file\n");
   4.274 -	#endif
   4.275 -	
   4.276 -	return 0;
   4.277 +    FileReaderThread *This = (FileReaderThread *)inRefCon;
   4.278 +    This->ReadNextChunk();
   4.279 +    #if DEBUG
   4.280 +    printf ("finished with reading file\n");
   4.281 +    #endif
   4.282 +    
   4.283 +    return 0;
   4.284  }
   4.285  
   4.286 -void 	FileReaderThread::ReadNextChunk ()
   4.287 +void    FileReaderThread::ReadNextChunk ()
   4.288  {
   4.289 -	OSStatus result;
   4.290 -	UInt32	dataChunkSize;
   4.291 -	AudioFileReaderThread* theItem = 0;
   4.292 +    OSStatus result;
   4.293 +    UInt32  dataChunkSize;
   4.294 +    AudioFileManager* theItem = 0;
   4.295  
   4.296 -	for (;;) 
   4.297 -	{
   4.298 -		{ // this is a scoped based lock
   4.299 -			CAGuard::Locker fileReadLock (mGuard);
   4.300 -			
   4.301 -			if (this->mThreadShouldDie) {
   4.302 +    for (;;) 
   4.303 +    {
   4.304 +        { // this is a scoped based lock
   4.305 +            CAGuard::Locker fileReadLock (mGuard);
   4.306 +            
   4.307 +            if (this->mThreadShouldDie) {
   4.308              
   4.309                  mGuard.Notify();
   4.310                  return;
   4.311              }
   4.312 -			
   4.313 -			if (mFileData.empty())
   4.314 -			{
   4.315 -				mGuard.Wait();
   4.316 -			}
   4.317 -			            
   4.318 -			// kill thread
   4.319 -			if (this->mThreadShouldDie) {
   4.320 +            
   4.321 +            if (mFileData.empty())
   4.322 +            {
   4.323 +                mGuard.Wait();
   4.324 +            }
   4.325 +                        
   4.326 +            // kill thread
   4.327 +            if (this->mThreadShouldDie) {
   4.328              
   4.329                  mGuard.Notify();
   4.330                  return;
   4.331              }
   4.332  
   4.333 -			theItem = mFileData.front();
   4.334 -			mFileData.pop_front();
   4.335 -		}
   4.336 -	
   4.337 -		if ((theItem->mFileLength - theItem->mReadFilePosition) < theItem->mChunkSize)
   4.338 -			dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition;
   4.339 -		else
   4.340 -			dataChunkSize = theItem->mChunkSize;
   4.341 -		
   4.342 -			// this is the exit condition for the thread
   4.343 -		if (dataChunkSize == 0) {
   4.344 -			theItem->mFinishedReadingData = true;
   4.345 -			continue;
   4.346 -		}
   4.347 -			// construct pointer
   4.348 -		char* writePtr = const_cast<char*>(theItem->GetFileBuffer() + 
   4.349 -								(theItem->mWriteToFirstBuffer ? 0 : theItem->mChunkSize));
   4.350 -	
   4.351 +            theItem = mFileData.front();
   4.352 +            mFileData.pop_front();
   4.353 +        }
   4.354 +    
   4.355 +        if ((theItem->mFileLength - theItem->mReadFilePosition) < theItem->mChunkSize)
   4.356 +            dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition;
   4.357 +        else
   4.358 +            dataChunkSize = theItem->mChunkSize;
   4.359 +        
   4.360 +            // this is the exit condition for the thread
   4.361 +        if (dataChunkSize == 0) {
   4.362 +            theItem->mFinishedReadingData = true;
   4.363 +            continue;
   4.364 +        }
   4.365 +            // construct pointer
   4.366 +        char* writePtr = const_cast<char*>(theItem->GetFileBuffer() + 
   4.367 +                                (theItem->mWriteToFirstBuffer ? 0 : theItem->mChunkSize));
   4.368 +    
   4.369  /*
   4.370          printf ("AudioFileReadBytes: theItem=%.8X fileID=%.8X pos=%.8X sz=%.8X flen=%.8X ptr=%.8X\n", 
   4.371              (unsigned int)theItem, (unsigned int)theItem->GetFileID(),
   4.372              (unsigned int)theItem->mReadFilePosition, (unsigned int)dataChunkSize, 
   4.373              (unsigned int)theItem->mFileLength, (unsigned int)writePtr);
   4.374  */            
   4.375 -		result = AudioFileReadBytes (theItem->GetFileID(), 
   4.376 -									false,
   4.377 -									theItem->mReadFilePosition, 
   4.378 -									&dataChunkSize, 
   4.379 -									writePtr);
   4.380 -		if (result) {
   4.381 -			theItem->GetParent().DoNotification(result);
   4.382 -			continue;
   4.383 -		}
   4.384 -		
   4.385 -		if (dataChunkSize != theItem->mChunkSize)
   4.386 -		{
   4.387 -			writePtr += dataChunkSize;
   4.388 +        result = theItem->Read(writePtr, &dataChunkSize);
   4.389 +        if (result) {
   4.390 +            theItem->GetParent().DoNotification(result);
   4.391 +            continue;
   4.392 +        }
   4.393 +        
   4.394 +        if (dataChunkSize != theItem->mChunkSize)
   4.395 +        {
   4.396 +            writePtr += dataChunkSize;
   4.397  
   4.398              // can't exit yet.. we still have to pass the partial buffer back
   4.399              memset (writePtr, 0, (theItem->mChunkSize - dataChunkSize));
   4.400          }
   4.401 -		
   4.402 -		theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer;	// switch buffers
   4.403 -		
   4.404 -		theItem->mReadFilePosition += dataChunkSize;		// increment count
   4.405 -	}
   4.406 +        
   4.407 +        theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer;   // switch buffers
   4.408 +        
   4.409 +        theItem->mReadFilePosition += dataChunkSize;        // increment count
   4.410 +    }
   4.411  }
   4.412  
   4.413  
   4.414  static FileReaderThread sReaderThread;
   4.415  
   4.416 -AudioFileReaderThread::AudioFileReaderThread (AudioFilePlayer	&inParent, 
   4.417 -										AudioFileID 			&inFile, 
   4.418 -										SInt64 					inFileLength,
   4.419 -										UInt32					inChunkSize)
   4.420 -	: AudioFileManager (inParent, inFile),
   4.421 -	  mChunkSize (inChunkSize),
   4.422 -	  mFileLength (inFileLength),
   4.423 -	  mReadFilePosition (0),
   4.424 -	  mWriteToFirstBuffer (false),
   4.425 -	  mFinishedReadingData (false),
   4.426 +AudioFileManager::AudioFileManager (AudioFilePlayer &inParent, 
   4.427 +                                    SInt16          inForkRefNum, 
   4.428 +                                    SInt64          inFileLength,
   4.429 +                                    UInt32          inChunkSize)
   4.430 +    : mParent (inParent),
   4.431 +      mForkRefNum (inForkRefNum),
   4.432 +      mFileBuffer (0),
   4.433 +      mByteCounter (0),
   4.434 +      mLockUnsuccessful (false),
   4.435 +      mIsEngaged (false),
   4.436  
   4.437 -	  mLockUnsuccessful (false),
   4.438 -	  mIsEngaged (false)
   4.439 +      mChunkSize (inChunkSize),
   4.440 +      mFileLength (inFileLength),
   4.441 +      mReadFilePosition (0),
   4.442 +      mWriteToFirstBuffer (false),
   4.443 +      mFinishedReadingData (false)
   4.444 +
   4.445  {
   4.446 -	mFileBuffer = (char*) malloc (mChunkSize * 2);
   4.447 +    mFileBuffer = (char*) malloc (mChunkSize * 2);
   4.448 +    FSGetForkPosition(mForkRefNum, &mAudioDataOffset);
   4.449      assert (mFileBuffer != NULL);
   4.450  }
   4.451  
   4.452 -void	AudioFileReaderThread::DoConnect ()
   4.453 +void    AudioFileManager::DoConnect ()
   4.454  {
   4.455 -	if (!mIsEngaged)
   4.456 -	{
   4.457 -		//mReadFilePosition = 0;
   4.458 -		mFinishedReadingData = false;
   4.459 +    if (!mIsEngaged)
   4.460 +    {
   4.461 +        //mReadFilePosition = 0;
   4.462 +        mFinishedReadingData = false;
   4.463  
   4.464 -		mNumTimesAskedSinceFinished = -1;
   4.465 -		mLockUnsuccessful = false;
   4.466 -		
   4.467 -		UInt32 dataChunkSize;
   4.468 +        mNumTimesAskedSinceFinished = -1;
   4.469 +        mLockUnsuccessful = false;
   4.470 +        
   4.471 +        OSStatus result;
   4.472 +        UInt32 dataChunkSize;
   4.473          
   4.474          if ((mFileLength - mReadFilePosition) < mChunkSize)
   4.475 -			dataChunkSize = mFileLength - mReadFilePosition;
   4.476 -		else
   4.477 -			dataChunkSize = mChunkSize;
   4.478 +            dataChunkSize = mFileLength - mReadFilePosition;
   4.479 +        else
   4.480 +            dataChunkSize = mChunkSize;
   4.481          
   4.482 -		OSStatus result = AudioFileReadBytes ( mAudioFileID, 
   4.483 -												false, 
   4.484 -												mReadFilePosition, 
   4.485 -												&dataChunkSize, 
   4.486 -												mFileBuffer);
   4.487 -            THROW_RESULT("AudioFileReadBytes")
   4.488 -            
   4.489 -		mReadFilePosition += dataChunkSize;
   4.490 -				
   4.491 -		mWriteToFirstBuffer = false;
   4.492 -		mReadFromFirstBuffer = true;
   4.493 +        result = Read(mFileBuffer, &dataChunkSize);
   4.494 +           THROW_RESULT("AudioFileManager::DoConnect(): Read")
   4.495  
   4.496 -		sReaderThread.AddReader();
   4.497 -		
   4.498 -		mIsEngaged = true;
   4.499 -	}
   4.500 -	else
   4.501 -		throw static_cast<OSStatus>(-1); //thread has already been started
   4.502 +        mReadFilePosition += dataChunkSize;
   4.503 +                
   4.504 +        mWriteToFirstBuffer = false;
   4.505 +        mReadFromFirstBuffer = true;
   4.506 +
   4.507 +        sReaderThread.AddReader();
   4.508 +        
   4.509 +        mIsEngaged = true;
   4.510 +    }
   4.511 +    else
   4.512 +        throw static_cast<OSStatus>(-1); //thread has already been started
   4.513  }
   4.514  
   4.515 -void	AudioFileReaderThread::Disconnect ()
   4.516 +void    AudioFileManager::Disconnect ()
   4.517  {
   4.518 -	if (mIsEngaged) 
   4.519 -	{
   4.520 -		sReaderThread.RemoveReader (this);
   4.521 -		mIsEngaged = false;
   4.522 -	}
   4.523 +    if (mIsEngaged) 
   4.524 +    {
   4.525 +        sReaderThread.RemoveReader (this);
   4.526 +        mIsEngaged = false;
   4.527 +    }
   4.528  }
   4.529  
   4.530 -OSStatus AudioFileReaderThread::GetFileData (void** inOutData, UInt32 *inOutDataSize)
   4.531 +OSStatus AudioFileManager::Read(char *buffer, UInt32 *len)
   4.532  {
   4.533 -	if (mFinishedReadingData) 
   4.534 -	{
   4.535 -		++mNumTimesAskedSinceFinished;
   4.536 -		*inOutDataSize = 0;
   4.537 -		*inOutData = 0;
   4.538 -		return noErr;
   4.539 -	}
   4.540 -	
   4.541 -	if (mReadFromFirstBuffer == mWriteToFirstBuffer) {
   4.542 -		#if DEBUG
   4.543 -		printf ("* * * * * * * Can't keep up with reading file:%ld\n", mParent.GetBusNumber());
   4.544 -		#endif
   4.545 -		
   4.546 -		mParent.DoNotification (kAudioFilePlayErr_FilePlayUnderrun);
   4.547 -		*inOutDataSize = 0;
   4.548 -		*inOutData = 0;
   4.549 -	} else {
   4.550 -		*inOutDataSize = mChunkSize;
   4.551 -		*inOutData = mReadFromFirstBuffer ? mFileBuffer : (mFileBuffer + mChunkSize);
   4.552 -	}
   4.553 -
   4.554 -	mLockUnsuccessful = !sReaderThread.TryNextRead (this);
   4.555 -	
   4.556 -	mReadFromFirstBuffer = !mReadFromFirstBuffer;
   4.557 -
   4.558 -	return noErr;
   4.559 +    return FSReadFork (mForkRefNum,
   4.560 +                       fsFromStart,
   4.561 +                       mReadFilePosition + mAudioDataOffset,
   4.562 +                       *len,
   4.563 +                       buffer,
   4.564 +                       len);
   4.565  }
   4.566  
   4.567 -void 	AudioFileReaderThread::AfterRender ()
   4.568 +OSStatus AudioFileManager::GetFileData (void** inOutData, UInt32 *inOutDataSize)
   4.569  {
   4.570 -	if (mNumTimesAskedSinceFinished > 0)
   4.571 -	{
   4.572 -		bool didLock = false;
   4.573 -		if (sReaderThread.GetGuard().Try (didLock)) {
   4.574 -			mParent.DoNotification (kAudioFilePlay_FileIsFinished);
   4.575 -			if (didLock)
   4.576 -				sReaderThread.GetGuard().Unlock();
   4.577 -		}
   4.578 -	}
   4.579 +    if (mFinishedReadingData) 
   4.580 +    {
   4.581 +        ++mNumTimesAskedSinceFinished;
   4.582 +        *inOutDataSize = 0;
   4.583 +        *inOutData = 0;
   4.584 +        return noErr;
   4.585 +    }
   4.586 +    
   4.587 +    if (mReadFromFirstBuffer == mWriteToFirstBuffer) {
   4.588 +        #if DEBUG
   4.589 +        printf ("* * * * * * * Can't keep up with reading file:%ld\n", mParent.GetBusNumber());
   4.590 +        #endif
   4.591 +        
   4.592 +        mParent.DoNotification (kAudioFilePlayErr_FilePlayUnderrun);
   4.593 +        *inOutDataSize = 0;
   4.594 +        *inOutData = 0;
   4.595 +    } else {
   4.596 +        *inOutDataSize = mChunkSize;
   4.597 +        *inOutData = mReadFromFirstBuffer ? mFileBuffer : (mFileBuffer + mChunkSize);
   4.598 +    }
   4.599  
   4.600 -	if (mLockUnsuccessful)
   4.601 -		mLockUnsuccessful = !sReaderThread.TryNextRead (this);
   4.602 +    mLockUnsuccessful = !sReaderThread.TryNextRead (this);
   4.603 +    
   4.604 +    mReadFromFirstBuffer = !mReadFromFirstBuffer;
   4.605 +
   4.606 +    return noErr;
   4.607  }
   4.608  
   4.609 -void 	AudioFileReaderThread::SetPosition (SInt64 pos)
   4.610 +void    AudioFileManager::AfterRender ()
   4.611 +{
   4.612 +    if (mNumTimesAskedSinceFinished > 0)
   4.613 +    {
   4.614 +        bool didLock = false;
   4.615 +        if (sReaderThread.GetGuard().Try (didLock)) {
   4.616 +            mParent.DoNotification (kAudioFilePlay_FileIsFinished);
   4.617 +            if (didLock)
   4.618 +                sReaderThread.GetGuard().Unlock();
   4.619 +        }
   4.620 +    }
   4.621 +
   4.622 +    if (mLockUnsuccessful)
   4.623 +        mLockUnsuccessful = !sReaderThread.TryNextRead (this);
   4.624 +}
   4.625 +
   4.626 +void    AudioFileManager::SetPosition (SInt64 pos)
   4.627  {
   4.628      if (pos < 0 || pos >= mFileLength) {
   4.629 -        SDL_SetError ("AudioFileReaderThread::SetPosition - position invalid: %d filelen=%d\n", 
   4.630 +        SDL_SetError ("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n", 
   4.631              (unsigned int)pos, (unsigned int)mFileLength);
   4.632          pos = 0;
   4.633      }
   4.634 @@ -408,10 +411,10 @@
   4.635      mReadFilePosition = pos;
   4.636  }
   4.637      
   4.638 -void 	AudioFileReaderThread::SetEndOfFile (SInt64 pos)
   4.639 +void    AudioFileManager::SetEndOfFile (SInt64 pos)
   4.640  {
   4.641      if (pos <= 0 || pos > mFileLength) {
   4.642 -        SDL_SetError ("AudioFileReaderThread::SetEndOfFile - position beyond actual eof\n");
   4.643 +        SDL_SetError ("AudioFileManager::SetEndOfFile - position beyond actual eof\n");
   4.644          pos = mFileLength;
   4.645      }
   4.646      
     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);