Commit f4df35b9 authored by Sam Lantinga's avatar Sam Lantinga

Max has been reworking this code so it works on MacOS X 10.1

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40769
parent 86ec9803
...@@ -2430,11 +2430,9 @@ case "$target" in ...@@ -2430,11 +2430,9 @@ case "$target" in
# Set up files for the cdrom library # Set up files for the cdrom library
if test x$enable_cdrom = xyes; then if test x$enable_cdrom = xyes; then
# The CD-ROM code won't work on old versions of MacOS X yet... # The CD-ROM code won't work on old versions of MacOS X yet...
#CDROM_SUBDIRS="$CDROM_SUBDIRS macosx" CDROM_SUBDIRS="$CDROM_SUBDIRS macosx"
#CDROM_DRIVERS="$CDROM_DRIVERS macosx/libcdrom_macosx.la" CDROM_DRIVERS="$CDROM_DRIVERS macosx/libcdrom_macosx.la"
#SYSTEM_LIBS="$SYSTEM_LIBS -framework AudioToolbox -framework AudioUnit -lstdc++" SYSTEM_LIBS="$SYSTEM_LIBS -framework AudioToolbox -framework AudioUnit -lstdc++"
CDROM_SUBDIRS="$CDROM_SUBDIRS dummy"
CDROM_DRIVERS="$CDROM_DRIVERS dummy/libcdrom_dummy.la"
fi fi
# Set up files for the thread library # Set up files for the thread library
if test x$enable_threads = xyes; then if test x$enable_threads = xyes; then
......
...@@ -28,31 +28,9 @@ ...@@ -28,31 +28,9 @@
// //
#include "AudioFilePlayer.h" #include "AudioFilePlayer.h"
extern const char* AudioFilePlayerErrorStr (OSStatus error)
{
const char *str;
switch (error) {
case kAudioFileUnspecifiedError: str = "wht?"; break;
case kAudioFileUnsupportedFileTypeError: str = "typ?"; break;
case kAudioFileUnsupportedDataFormatError: str = "fmt?"; break;
case kAudioFileUnsupportedPropertyError: str = "pty?"; break;
case kAudioFileBadPropertySizeError: str = "!siz"; break;
case kAudioFileNotOptimizedError: str = "optm"; break;
case kAudioFilePermissionsError: str = "prm?"; break;
case kAudioFileFormatNameUnavailableError: str = "nme?"; break;
case kAudioFileInvalidChunkError: str = "chk?"; break;
case kAudioFileDoesNotAllow64BitDataSizeError: str = "off?"; break;
default: str = "error unspecified";
}
return str;
}
void ThrowResult (OSStatus result, const char* str) void ThrowResult (OSStatus result, const char* str)
{ {
SDL_SetError ("Error: %s %d (%s)", SDL_SetError ("Error: %s %d", str, result);
str, result, AudioFilePlayerErrorStr(result));
throw result; throw result;
} }
...@@ -133,23 +111,17 @@ AudioFilePlayer::AudioFilePlayer (const FSRef *inFileRef) ...@@ -133,23 +111,17 @@ AudioFilePlayer::AudioFilePlayer (const FSRef *inFileRef)
OpenFile (inFileRef, fileDataSize); OpenFile (inFileRef, fileDataSize);
// we want about a seconds worth of data for the buffer // we want about a seconds worth of data for the buffer
int secsBytes = UInt32 (mFileDescription.mSampleRate * mFileDescription.mBytesPerFrame); int bytesPerSecond = UInt32 (mFileDescription.mSampleRate * mFileDescription.mBytesPerFrame);
#if DEBUG #if DEBUG
printf("File format:\n"); printf("File format:\n");
PrintStreamDesc (&mFileDescription); PrintStreamDesc (&mFileDescription);
#endif #endif
//round to a 32K boundary mAudioFileManager = new AudioFileManager (*this,
//if ((secsBytes & 0xFFFF8000) > (128 * 1024)) mForkRefNum,
//secsBytes &= 0xFFFF8000;
//else
//secsBytes = (secsBytes + 0x7FFF) & 0xFFFF8000;
mAudioFileManager = new AudioFileReaderThread (*this,
mAudioFileID,
fileDataSize, fileDataSize,
secsBytes); bytesPerSecond);
} }
// you can put a rate scalar here to play the file faster or slower // you can put a rate scalar here to play the file faster or slower
...@@ -194,43 +166,15 @@ void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit, ...@@ -194,43 +166,15 @@ void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit,
// we're going to use this to know which convert routine to call // we're going to use this to know which convert routine to call
// a v1 audio unit will have a type of 'aunt' // a v1 audio unit will have a type of 'aunt'
// a v2 audio unit will have one of several different types. // a v2 audio unit will have one of several different types.
mIsAUNTUnit = (desc.componentType == kAudioUnitComponentType); if (desc.componentType != kAudioUnitComponentType) {
if (!mIsAUNTUnit) {
result = badComponentInstance; result = badComponentInstance;
THROW_RESULT("BAD COMPONENT") THROW_RESULT("BAD COMPONENT")
} }
// HACK - the AIFF files on CDs are in little endian order!
if (mFileDescription.mFormatFlags == 0xE)
mFileDescription.mFormatFlags &= ~kAudioFormatFlagIsBigEndian;
result = AudioConverterNew (&mFileDescription, &destDesc, &mConverter); result = AudioConverterNew (&mFileDescription, &destDesc, &mConverter);
THROW_RESULT("AudioConverterNew") THROW_RESULT("AudioConverterNew")
/*
// if we have a mono source, we're going to copy each channel into
// the destination's channel source...
if (mFileDescription.mChannelsPerFrame == 1) {
SInt32* channelMap = new SInt32 [destDesc.mChannelsPerFrame];
for (unsigned int i = 0; i < destDesc.mChannelsPerFrame; ++i)
channelMap[i] = 0; //set first channel to all output channels
result = AudioConverterSetProperty(mConverter,
kAudioConverterChannelMap,
(sizeof(SInt32) * destDesc.mChannelsPerFrame),
channelMap);
THROW_RESULT("AudioConverterSetProperty")
delete [] channelMap;
}
*/
assert (mFileDescription.mChannelsPerFrame == 2);
#if 0 #if 0
// this uses the better quality SRC // this uses the better quality SRC
UInt32 srcID = kAudioUnitSRCAlgorithm_Polyphase; UInt32 srcID = kAudioUnitSRCAlgorithm_Polyphase;
...@@ -272,9 +216,9 @@ AudioFilePlayer::~AudioFilePlayer() ...@@ -272,9 +216,9 @@ AudioFilePlayer::~AudioFilePlayer()
mAudioFileManager = 0; mAudioFileManager = 0;
} }
if (mAudioFileID) { if (mForkRefNum) {
::AudioFileClose (mAudioFileID); FSClose (mForkRefNum);
mAudioFileID = 0; mForkRefNum = 0;
} }
if (mConverter) { if (mConverter) {
...@@ -293,7 +237,6 @@ void AudioFilePlayer::Connect() ...@@ -293,7 +237,6 @@ void AudioFilePlayer::Connect()
mAudioFileManager->Connect(mConverter); mAudioFileManager->Connect(mConverter);
// set the render callback for the file data to be supplied to the sound converter AU // set the render callback for the file data to be supplied to the sound converter AU
if (mIsAUNTUnit) {
mInputCallback.inputProc = AudioFileManager::FileInputProc; mInputCallback.inputProc = AudioFileManager::FileInputProc;
mInputCallback.inputProcRefCon = mAudioFileManager; mInputCallback.inputProcRefCon = mAudioFileManager;
...@@ -304,7 +247,6 @@ void AudioFilePlayer::Connect() ...@@ -304,7 +247,6 @@ void AudioFilePlayer::Connect()
&mInputCallback, &mInputCallback,
sizeof(mInputCallback)); sizeof(mInputCallback));
THROW_RESULT("AudioUnitSetProperty") THROW_RESULT("AudioUnitSetProperty")
}
mConnected = true; mConnected = true;
} }
} }
...@@ -317,9 +259,7 @@ void AudioFilePlayer::DoNotification (OSStatus inStatus) const ...@@ -317,9 +259,7 @@ void AudioFilePlayer::DoNotification (OSStatus inStatus) const
if (mNotifier) { if (mNotifier) {
(*mNotifier) (mRefCon, inStatus); (*mNotifier) (mRefCon, inStatus);
} } else {
else {
SDL_SetError ("Notification posted with no notifier in place"); SDL_SetError ("Notification posted with no notifier in place");
if (inStatus == kAudioFilePlay_FileIsFinished) if (inStatus == kAudioFilePlay_FileIsFinished)
...@@ -338,7 +278,6 @@ void AudioFilePlayer::Disconnect () ...@@ -338,7 +278,6 @@ void AudioFilePlayer::Disconnect ()
{ {
mConnected = false; mConnected = false;
if (mIsAUNTUnit) {
mInputCallback.inputProc = 0; mInputCallback.inputProc = 0;
mInputCallback.inputProcRefCon = 0; mInputCallback.inputProcRefCon = 0;
OSStatus result = AudioUnitSetProperty (mPlayUnit, OSStatus result = AudioUnitSetProperty (mPlayUnit,
...@@ -350,28 +289,78 @@ void AudioFilePlayer::Disconnect () ...@@ -350,28 +289,78 @@ void AudioFilePlayer::Disconnect ()
if (result) if (result)
SDL_SetError ("AudioUnitSetProperty:RemoveInputCallback:%ld", result); SDL_SetError ("AudioUnitSetProperty:RemoveInputCallback:%ld", result);
}
mAudioFileManager->Disconnect(); mAudioFileManager->Disconnect();
} }
} }
struct SSNDData {
UInt32 offset;
UInt32 blockSize;
};
void AudioFilePlayer::OpenFile (const FSRef *inRef, SInt64& outFileDataSize) void AudioFilePlayer::OpenFile (const FSRef *inRef, SInt64& outFileDataSize)
{ {
OSStatus result = AudioFileOpen (inRef, fsRdPerm, 0, &mAudioFileID); ContainerChunk chunkHeader;
THROW_RESULT("AudioFileOpen") ChunkHeader chunk;
SSNDData ssndData;
UInt32 dataSize = sizeof(AudioStreamBasicDescription);
result = AudioFileGetProperty (mAudioFileID, OSErr result;
kAudioFilePropertyDataFormat, HFSUniStr255 dfName;
&dataSize, ByteCount actual;
&mFileDescription); SInt64 offset;
THROW_RESULT("AudioFileGetProperty")
// Open the data fork of the input file
dataSize = sizeof (SInt64); result = FSGetDataForkName(&dfName);
result = AudioFileGetProperty (mAudioFileID, THROW_RESULT("AudioFilePlayer::OpenFile(): FSGetDataForkName")
kAudioFilePropertyAudioDataByteCount,
&dataSize, result = FSOpenFork(inRef, dfName.length, dfName.unicode, fsRdPerm, &mForkRefNum);
&outFileDataSize); THROW_RESULT("AudioFilePlayer::OpenFile(): FSOpenFork")
THROW_RESULT("AudioFileGetProperty")
// Read the file header, and check if it's indeed an AIFC file
result = FSReadFork(mForkRefNum, fsAtMark, 0, sizeof(chunkHeader), &chunkHeader, &actual);
THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork")
if (chunkHeader.ckID != 'FORM') {
result = -1;
THROW_RESULT("AudioFilePlayer::OpenFile(): chunk id is not 'FORM'");
}
if (chunkHeader.formType != 'AIFC') {
result = -1;
THROW_RESULT("AudioFilePlayer::OpenFile(): file format is not 'AIFC'");
}
// Search for the SSND chunk. We ignore all compression etc. information
// in other chunks. Of course that is kind of evil, but for now we are lazy
// and rely on the cdfs to always give us the same fixed format.
// TODO: Parse the COMM chunk we currently skip to fill in mFileDescription.
offset = 0;
do {
result = FSReadFork(mForkRefNum, fsFromMark, offset, sizeof(chunk), &chunk, &actual);
THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork")
// Skip the chunk data
offset = chunk.ckSize;
} while (chunk.ckID != 'SSND');
// Read the header of the SSND chunk. After this, we are positioned right
// at the start of the audio data.
result = FSReadFork(mForkRefNum, fsAtMark, 0, sizeof(ssndData), &ssndData, &actual);
THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork")
result = FSSetForkPosition(mForkRefNum, fsFromMark, ssndData.offset);
THROW_RESULT("AudioFilePlayer::OpenFile(): FSSetForkPosition")
// Data size
outFileDataSize = chunk.ckSize - ssndData.offset;
// File format
mFileDescription.mSampleRate = 44100;
mFileDescription.mFormatID = kAudioFormatLinearPCM;
mFileDescription.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger;
mFileDescription.mBytesPerPacket = 4;
mFileDescription.mFramesPerPacket = 1;
mFileDescription.mBytesPerFrame = 4;
mFileDescription.mChannelsPerFrame = 2;
mFileDescription.mBitsPerChannel = 16;
} }
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <CoreServices/CoreServices.h> #include <CoreServices/CoreServices.h>
#include <AudioToolbox/AudioToolbox.h> #include <AudioToolbox/AudioConverter.h>
#include <AudioUnit/AudioUnit.h> #include <AudioUnit/AudioUnit.h>
#include "SDL_error.h" #include "SDL_error.h"
...@@ -97,11 +97,8 @@ public: ...@@ -97,11 +97,8 @@ public:
#if DEBUG #if DEBUG
void Print() const void Print() const
{ {
CAShow (mAudioFileID);
printf ("Destination Bus:%ld\n", GetBusNumber()); printf ("Destination Bus:%ld\n", GetBusNumber());
printf ("Is 'aunt' unit:%s\n", (mIsAUNTUnit ? "true" : "false"));
printf ("Is Connected:%s\n", (IsConnected() ? "true" : "false")); printf ("Is Connected:%s\n", (IsConnected() ? "true" : "false"));
if (mConverter) CAShow (mConverter);
printf ("- - - - - - - - - - - - - - \n"); printf ("- - - - - - - - - - - - - - \n");
} }
#endif #endif
...@@ -111,14 +108,13 @@ public: ...@@ -111,14 +108,13 @@ public:
private: private:
AudioUnit mPlayUnit; AudioUnit mPlayUnit;
UInt32 mBusNumber; UInt32 mBusNumber;
AudioFileID mAudioFileID; SInt16 mForkRefNum;
AudioUnitInputCallback mInputCallback; AudioUnitInputCallback mInputCallback;
AudioStreamBasicDescription mFileDescription; AudioStreamBasicDescription mFileDescription;
bool mConnected; bool mConnected;
bool mIsAUNTUnit;
AudioFileManager* mAudioFileManager; AudioFileManager* mAudioFileManager;
AudioConverterRef mConverter; AudioConverterRef mConverter;
...@@ -137,14 +133,12 @@ private: ...@@ -137,14 +133,12 @@ private:
class AudioFileManager class AudioFileManager
{ {
public: public:
AudioFileManager (AudioFilePlayer& inParent, AudioFileID inFile) AudioFileManager (AudioFilePlayer &inParent,
: mParent (inParent), SInt16 inForkRefNum,
mAudioFileID (inFile), SInt64 inFileLength,
mFileBuffer (0), UInt32 inChunkSize);
mByteCounter (0)
{}
virtual ~AudioFileManager(); ~AudioFileManager();
void Connect (AudioConverterRef inConverter) void Connect (AudioConverterRef inConverter)
...@@ -155,54 +149,36 @@ public: ...@@ -155,54 +149,36 @@ public:
// this method should NOT be called by an object of this class // this method should NOT be called by an object of this class
// as it is called by the parent's Disconnect() method // as it is called by the parent's Disconnect() method
virtual void Disconnect () {} void Disconnect ();
const AudioFileID& GetFileID() const { return mAudioFileID; } OSStatus Read(char *buffer, UInt32 *len);
const char* GetFileBuffer () { return mFileBuffer; } const char* GetFileBuffer () { return mFileBuffer; }
const AudioFilePlayer& GetParent () const { return mParent; } const AudioFilePlayer& GetParent () const { return mParent; }
virtual void SetPosition (SInt64 pos) = 0; // seek/rewind in the file void SetPosition (SInt64 pos); // seek/rewind in the file
virtual int GetByteCounter () { return mByteCounter; } // return actual bytes streamed to audio hardware int GetByteCounter () { return mByteCounter; } // return actual bytes streamed to audio hardware
virtual void SetEndOfFile (SInt64 pos) = 0; // set the "EOF" (will behave just like it reached eof) void SetEndOfFile (SInt64 pos); // set the "EOF" (will behave just like it reached eof)
protected: protected:
AudioFilePlayer& mParent; AudioFilePlayer& mParent;
AudioConverterRef mParentConverter; AudioConverterRef mParentConverter;
const AudioFileID mAudioFileID; SInt16 mForkRefNum;
SInt64 mAudioDataOffset;
char* mFileBuffer; char* mFileBuffer;
OSStatus Render (AudioBuffer &ioData);
int mByteCounter; int mByteCounter;
virtual OSStatus GetFileData (void** inOutData, UInt32 *inOutDataSize) = 0; bool mReadFromFirstBuffer;
bool mLockUnsuccessful;
virtual void DoConnect () = 0; bool mIsEngaged;
virtual void AfterRender () = 0;
public:
static OSStatus FileInputProc (void *inRefCon,
AudioUnitRenderActionFlags inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
AudioBuffer *ioData);
static OSStatus ACInputProc (AudioConverterRef inAudioConverter,
UInt32* outDataSize,
void** outData,
void* inUserData);
};
int mNumTimesAskedSinceFinished;
#pragma mark __________ AudioFileReaderThread
class AudioFileReaderThread
: public AudioFileManager
{
public: public:
const UInt32 mChunkSize; const UInt32 mChunkSize;
SInt64 mFileLength; SInt64 mFileLength;
...@@ -210,30 +186,25 @@ public: ...@@ -210,30 +186,25 @@ public:
bool mWriteToFirstBuffer; bool mWriteToFirstBuffer;
bool mFinishedReadingData; bool mFinishedReadingData;
AudioFileReaderThread (AudioFilePlayer &inParent,
AudioFileID &inFile,
SInt64 inFileLength,
UInt32 inChunkSize);
virtual void Disconnect ();
virtual void SetPosition (SInt64 pos); // seek/rewind in the file
virtual void SetEndOfFile (SInt64 pos); // set the "EOF" (will behave just like it reached eof)
protected: protected:
virtual void DoConnect (); OSStatus Render (AudioBuffer &ioData);
virtual OSStatus GetFileData (void** inOutData, UInt32 *inOutDataSize); OSStatus GetFileData (void** inOutData, UInt32 *inOutDataSize);
virtual void AfterRender (); void DoConnect ();
private: void AfterRender ();
bool mReadFromFirstBuffer;
bool mLockUnsuccessful;
bool mIsEngaged;
int mNumTimesAskedSinceFinished; public:
static OSStatus FileInputProc (void *inRefCon,
AudioUnitRenderActionFlags inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
AudioBuffer *ioData);
static OSStatus ACInputProc (AudioConverterRef inAudioConverter,
UInt32* outDataSize,
void** outData,
void* inUserData);
}; };
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
*/ */
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// AudioFileReaderThread.cpp // AudioFileManager.cpp
// //
#include "AudioFilePlayer.h" #include "AudioFilePlayer.h"
#include <mach/mach.h> //used for setting policy of thread #include <mach/mach.h> //used for setting policy of thread
...@@ -41,10 +41,10 @@ public: ...@@ -41,10 +41,10 @@ public:
void AddReader(); void AddReader();
void RemoveReader (const AudioFileReaderThread* inItem); void RemoveReader (AudioFileManager* inItem);
// returns true if succeeded // returns true if succeeded
bool TryNextRead (AudioFileReaderThread* inItem) bool TryNextRead (AudioFileManager* inItem)
{ {
bool didLock = false; bool didLock = false;
bool succeeded = false; bool succeeded = false;
...@@ -64,7 +64,7 @@ public: ...@@ -64,7 +64,7 @@ public:
int mThreadShouldDie; int mThreadShouldDie;
private: private:
typedef std::list<AudioFileReaderThread*> FileData; typedef std::list<AudioFileManager*> FileData;
CAGuard mGuard; CAGuard mGuard;
UInt32 mThreadPriority; UInt32 mThreadPriority;
...@@ -98,18 +98,13 @@ void FileReaderThread::AddReader() ...@@ -98,18 +98,13 @@ void FileReaderThread::AddReader()
mNumReaders++; mNumReaders++;
} }
void FileReaderThread::RemoveReader (const AudioFileReaderThread* inItem) void FileReaderThread::RemoveReader (AudioFileManager* inItem)
{ {
if (mNumReaders > 0) if (mNumReaders > 0)
{ {
CAGuard::Locker fileReadLock (mGuard); CAGuard::Locker fileReadLock (mGuard);
for (FileData::iterator iter = mFileData.begin(); iter != mFileData.end(); ++iter) mFileData.remove (inItem);
{
if ((*iter) == inItem) {
mFileData.erase (iter);
}
}
if (--mNumReaders == 0) { if (--mNumReaders == 0) {
mThreadShouldDie = true; mThreadShouldDie = true;
...@@ -211,7 +206,7 @@ void FileReaderThread::ReadNextChunk () ...@@ -211,7 +206,7 @@ void FileReaderThread::ReadNextChunk ()
{ {
OSStatus result; OSStatus result;
UInt32 dataChunkSize; UInt32 dataChunkSize;
AudioFileReaderThread* theItem = 0; AudioFileManager* theItem = 0;
for (;;) for (;;)
{ {
...@@ -260,11 +255,7 @@ void FileReaderThread::ReadNextChunk () ...@@ -260,11 +255,7 @@ void FileReaderThread::ReadNextChunk ()
(unsigned int)theItem->mReadFilePosition, (unsigned int)dataChunkSize, (unsigned int)theItem->mReadFilePosition, (unsigned int)dataChunkSize,
(unsigned int)theItem->mFileLength, (unsigned int)writePtr); (unsigned int)theItem->mFileLength, (unsigned int)writePtr);
*/ */
result = AudioFileReadBytes (theItem->GetFileID(), result = theItem->Read(writePtr, &dataChunkSize);
false,
theItem->mReadFilePosition,
&dataChunkSize,
writePtr);
if (result) { if (result) {
theItem->GetParent().DoNotification(result); theItem->GetParent().DoNotification(result);
continue; continue;
...@@ -287,25 +278,30 @@ void FileReaderThread::ReadNextChunk () ...@@ -287,25 +278,30 @@ void FileReaderThread::ReadNextChunk ()
static FileReaderThread sReaderThread; static FileReaderThread sReaderThread;
AudioFileReaderThread::AudioFileReaderThread (AudioFilePlayer &inParent, AudioFileManager::AudioFileManager (AudioFilePlayer &inParent,
AudioFileID &inFile, SInt16 inForkRefNum,
SInt64 inFileLength, SInt64 inFileLength,
UInt32 inChunkSize) UInt32 inChunkSize)
: AudioFileManager (inParent, inFile), : mParent (inParent),
mForkRefNum (inForkRefNum),
mFileBuffer (0),
mByteCounter (0),
mLockUnsuccessful (false),
mIsEngaged (false),
mChunkSize (inChunkSize), mChunkSize (inChunkSize),
mFileLength (inFileLength), mFileLength (inFileLength),
mReadFilePosition (0), mReadFilePosition (0),
mWriteToFirstBuffer (false), mWriteToFirstBuffer (false),
mFinishedReadingData (false), mFinishedReadingData (false)
mLockUnsuccessful (false),
mIsEngaged (false)
{ {
mFileBuffer = (char*) malloc (mChunkSize * 2); mFileBuffer = (char*) malloc (mChunkSize * 2);
FSGetForkPosition(mForkRefNum, &mAudioDataOffset);
assert (mFileBuffer != NULL); assert (mFileBuffer != NULL);
} }
void AudioFileReaderThread::DoConnect () void AudioFileManager::DoConnect ()
{ {
if (!mIsEngaged) if (!mIsEngaged)
{ {
...@@ -315,6 +311,7 @@ void AudioFileReaderThread::DoConnect () ...@@ -315,6 +311,7 @@ void AudioFileReaderThread::DoConnect ()
mNumTimesAskedSinceFinished = -1; mNumTimesAskedSinceFinished = -1;
mLockUnsuccessful = false; mLockUnsuccessful = false;
OSStatus result;
UInt32 dataChunkSize; UInt32 dataChunkSize;
if ((mFileLength - mReadFilePosition) < mChunkSize) if ((mFileLength - mReadFilePosition) < mChunkSize)
...@@ -322,12 +319,8 @@ void AudioFileReaderThread::DoConnect () ...@@ -322,12 +319,8 @@ void AudioFileReaderThread::DoConnect ()
else else
dataChunkSize = mChunkSize; dataChunkSize = mChunkSize;
OSStatus result = AudioFileReadBytes ( mAudioFileID, result = Read(mFileBuffer, &dataChunkSize);
false, THROW_RESULT("AudioFileManager::DoConnect(): Read")
mReadFilePosition,
&dataChunkSize,
mFileBuffer);
THROW_RESULT("AudioFileReadBytes")
mReadFilePosition += dataChunkSize; mReadFilePosition += dataChunkSize;
...@@ -342,7 +335,7 @@ void AudioFileReaderThread::DoConnect () ...@@ -342,7 +335,7 @@ void AudioFileReaderThread::DoConnect ()
throw static_cast<OSStatus>(-1); //thread has already been started throw static_cast<OSStatus>(-1); //thread has already been started
} }
void AudioFileReaderThread::Disconnect () void AudioFileManager::Disconnect ()
{ {
if (mIsEngaged) if (mIsEngaged)
{ {
...@@ -351,7 +344,17 @@ void AudioFileReaderThread::Disconnect () ...@@ -351,7 +344,17 @@ void AudioFileReaderThread::Disconnect ()
} }
} }
OSStatus AudioFileReaderThread::GetFileData (void** inOutData, UInt32 *inOutDataSize) OSStatus AudioFileManager::Read(char *buffer, UInt32 *len)
{
return FSReadFork (mForkRefNum,
fsFromStart,
mReadFilePosition + mAudioDataOffset,
*len,
buffer,
len);
}
OSStatus AudioFileManager::GetFileData (void** inOutData, UInt32 *inOutDataSize)
{ {
if (mFinishedReadingData) if (mFinishedReadingData)
{ {
...@@ -381,7 +384,7 @@ OSStatus AudioFileReaderThread::GetFileData (void** inOutData, UInt32 *inOutData ...@@ -381,7 +384,7 @@ OSStatus AudioFileReaderThread::GetFileData (void** inOutData, UInt32 *inOutData
return noErr; return noErr;
} }
void AudioFileReaderThread::AfterRender () void AudioFileManager::AfterRender ()
{ {
if (mNumTimesAskedSinceFinished > 0) if (mNumTimesAskedSinceFinished > 0)
{ {
...@@ -397,10 +400,10 @@ void AudioFileReaderThread::AfterRender () ...@@ -397,10 +400,10 @@ void AudioFileReaderThread::AfterRender ()
mLockUnsuccessful = !sReaderThread.TryNextRead (this); mLockUnsuccessful = !sReaderThread.TryNextRead (this);
} }
void AudioFileReaderThread::SetPosition (SInt64 pos) void AudioFileManager::SetPosition (SInt64 pos)
{ {
if (pos < 0 || pos >= mFileLength) { if (pos < 0 || pos >= mFileLength) {
SDL_SetError ("AudioFileReaderThread::SetPosition - position invalid: %d filelen=%d\n", SDL_SetError ("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n",
(unsigned int)pos, (unsigned int)mFileLength); (unsigned int)pos, (unsigned int)mFileLength);
pos = 0; pos = 0;
} }
...@@ -408,10 +411,10 @@ void AudioFileReaderThread::SetPosition (SInt64 pos) ...@@ -408,10 +411,10 @@ void AudioFileReaderThread::SetPosition (SInt64 pos)
mReadFilePosition = pos; mReadFilePosition = pos;
} }
void AudioFileReaderThread::SetEndOfFile (SInt64 pos) void AudioFileManager::SetEndOfFile (SInt64 pos)
{ {
if (pos <= 0 || pos > mFileLength) { if (pos <= 0 || pos > mFileLength) {
SDL_SetError ("AudioFileReaderThread::SetEndOfFile - position beyond actual eof\n"); SDL_SetError ("AudioFileManager::SetEndOfFile - position beyond actual eof\n");
pos = mFileLength; pos = mFileLength;
} }
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
#include <stdio.h> #include <stdio.h>
#define NDEBUG 1 //#define NDEBUG 1
#include <assert.h> #include <assert.h>
......
...@@ -114,9 +114,7 @@ int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes) ...@@ -114,9 +114,7 @@ int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes)
for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++) for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++)
{ {
FSVolumeRefNum actualVolume; FSVolumeRefNum actualVolume;
HFSUniStr255 volumeName;
FSVolumeInfo volumeInfo; FSVolumeInfo volumeInfo;
FSRef rootDirectory;
memset (&volumeInfo, 0, sizeof(volumeInfo)); memset (&volumeInfo, 0, sizeof(volumeInfo));
...@@ -125,8 +123,8 @@ int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes) ...@@ -125,8 +123,8 @@ int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes)
&actualVolume, &actualVolume,
kFSVolInfoFSInfo, kFSVolInfoFSInfo,
&volumeInfo, &volumeInfo,
&volumeName, NULL,
&rootDirectory); NULL);
if (result == noErr) if (result == noErr)
{ {
......
...@@ -25,9 +25,8 @@ ...@@ -25,9 +25,8 @@
#include <string.h> #include <string.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#include <CoreFoundation/CoreFoundation.h>
#include <AudioUnit/AudioUnit.h> #include <AudioUnit/AudioUnit.h>
#include "SDL.h" #include "SDL.h"
......
...@@ -265,19 +265,25 @@ void SDL_SYS_CDQuit(void) ...@@ -265,19 +265,25 @@ void SDL_SYS_CDQuit(void)
/* Get the Unix disk name of the volume */ /* Get the Unix disk name of the volume */
static const char *SDL_SYS_CDName (int drive) static const char *SDL_SYS_CDName (int drive)
{ {
CFStringRef diskID;
OSStatus err = noErr; OSStatus err = noErr;
HParamBlockRec pb;
GetVolParmsInfoBuffer volParmsInfo;
if (fakeCD) if (fakeCD)
return "Fake CD-ROM Device"; return "Fake CD-ROM Device";
err = FSCopyDiskIDForVolume (volumes[drive], &diskID); pb.ioParam.ioNamePtr = NULL;
pb.ioParam.ioVRefNum = volumes[drive];
pb.ioParam.ioBuffer = (Ptr)&volParmsInfo;
pb.ioParam.ioReqCount = (SInt32)sizeof(volParmsInfo);
err = PBHGetVolParmsSync(&pb);
if (err != noErr) { if (err != noErr) {
SDL_SetError ("FSCopyDiskIDForVolume returned %d", err); SDL_SetError ("PBHGetVolParmsSync returned %d", err);
return NULL; return NULL;
} }
return CFStringGetCStringPtr (diskID, 0); return volParmsInfo.vMDeviceID;
} }
/* Open the "device" */ /* Open the "device" */
...@@ -318,14 +324,15 @@ static int SDL_SYS_CDGetTOC (SDL_CD *cdrom) ...@@ -318,14 +324,15 @@ static int SDL_SYS_CDGetTOC (SDL_CD *cdrom)
/* Get CD-ROM status */ /* Get CD-ROM status */
static CDstatus SDL_SYS_CDStatus (SDL_CD *cdrom, int *position) static CDstatus SDL_SYS_CDStatus (SDL_CD *cdrom, int *position)
{ {
if (position) {
int trackFrame; int trackFrame;
Lock (); Lock ();
trackFrame = GetCurrentFrame (); trackFrame = GetCurrentFrame ();
Unlock (); Unlock ();
if (position)
*position = cdrom->track[currentTrack].offset + trackFrame; *position = cdrom->track[currentTrack].offset + trackFrame;
}
return status; return status;
} }
...@@ -383,8 +390,10 @@ static int SDL_SYS_CDPause(SDL_CD *cdrom) ...@@ -383,8 +390,10 @@ static int SDL_SYS_CDPause(SDL_CD *cdrom)
Lock (); Lock ();
if (PauseFile () < 0) if (PauseFile () < 0) {
Unlock ();
return -2; return -2;
}
status = CD_PAUSED; status = CD_PAUSED;
...@@ -403,8 +412,10 @@ static int SDL_SYS_CDResume(SDL_CD *cdrom) ...@@ -403,8 +412,10 @@ static int SDL_SYS_CDResume(SDL_CD *cdrom)
Lock (); Lock ();
if (PlayFile () < 0) if (PauseFile () < 0) {
Unlock ();
return -2; return -2;
}
status = CD_PLAYING; status = CD_PLAYING;
...@@ -423,11 +434,15 @@ static int SDL_SYS_CDStop(SDL_CD *cdrom) ...@@ -423,11 +434,15 @@ static int SDL_SYS_CDStop(SDL_CD *cdrom)
Lock (); Lock ();
if (PauseFile () < 0) if (PauseFile () < 0) {
Unlock ();
return -2; return -2;
}
if (ReleaseFile () < 0) if (ReleaseFile () < 0) {
Unlock ();
return -3; return -3;
}
status = CD_STOPPED; status = CD_STOPPED;
...@@ -440,6 +455,7 @@ static int SDL_SYS_CDStop(SDL_CD *cdrom) ...@@ -440,6 +455,7 @@ static int SDL_SYS_CDStop(SDL_CD *cdrom)
static int SDL_SYS_CDEject(SDL_CD *cdrom) static int SDL_SYS_CDEject(SDL_CD *cdrom)
{ {
OSStatus err; OSStatus err;
HParamBlockRec pb;
if (fakeCD) { if (fakeCD) {
SDL_SetError (kErrorFakeDevice); SDL_SetError (kErrorFakeDevice);
...@@ -448,18 +464,26 @@ static int SDL_SYS_CDEject(SDL_CD *cdrom) ...@@ -448,18 +464,26 @@ static int SDL_SYS_CDEject(SDL_CD *cdrom)
Lock (); Lock ();
if (PauseFile () < 0) if (PauseFile () < 0) {
Unlock ();
return -2; return -2;
}
if (ReleaseFile () < 0) if (ReleaseFile () < 0) {
Unlock ();
return -3; return -3;
}
status = CD_STOPPED; status = CD_STOPPED;
err = FSEjectVolumeSync (volumes[cdrom->id], 0, NULL); // Eject the volume
pb.ioParam.ioNamePtr = NULL;
pb.ioParam.ioVRefNum = volumes[cdrom->id];
err = PBUnmountVol((ParamBlockRec *) &pb);
if (err != noErr) { if (err != noErr) {
SDL_SetError ("FSEjectVolumeSync returned %d", err); Unlock ();
SDL_SetError ("PBUnmountVol returned %d", err);
return -4; return -4;
} }
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
slouken@libsdl.org slouken@libsdl.org
*/ */
/* This is the Mac OS X / CoreAudio specific header for the SDL CD-ROM API
Contributed by Darrell Walisser and Max Horn
*/
/*********************************************************************************** /***********************************************************************************
Implementation Notes Implementation Notes
......
...@@ -1365,7 +1365,7 @@ static void QZ_DrawResizeIcon (_THIS, RgnHandle dirtyRegion) { ...@@ -1365,7 +1365,7 @@ static void QZ_DrawResizeIcon (_THIS, RgnHandle dirtyRegion) {
SDL_RWops *rw; SDL_RWops *rw;
SDL_Surface *tmp; SDL_Surface *tmp;
rw = SDL_RWFromMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon)); rw = SDL_RWFromConstMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon));
tmp = SDL_LoadBMP_RW (rw, SDL_TRUE); tmp = SDL_LoadBMP_RW (rw, SDL_TRUE);
resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY); resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment