Commit 35c8da7a authored by Sam Lantinga's avatar Sam Lantinga

Audio improvements from Max Horn, including a new CoreAudio driver for MacOSX

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40936
parent fddd0153
...@@ -332,6 +332,7 @@ CheckDMEDIA() ...@@ -332,6 +332,7 @@ CheckDMEDIA()
],[ ],[
have_dmedia=yes have_dmedia=yes
]) ])
AC_MSG_RESULT($have_dmedia)
# Set up files for the audio library # Set up files for the audio library
if test x$have_dmedia = xyes; then if test x$have_dmedia = xyes; then
CFLAGS="$CFLAGS -DDMEDIA_SUPPORT" CFLAGS="$CFLAGS -DDMEDIA_SUPPORT"
...@@ -489,6 +490,29 @@ CheckAtariAudio() ...@@ -489,6 +490,29 @@ CheckAtariAudio()
fi fi
} }
dnl Check whether we want to use CoreAudio
CheckCoreAudio()
{
if test x$enable_audio = xyes; then
AC_MSG_CHECKING(for CoreAudio audio support)
have_coreaudio=no
AC_TRY_COMPILE([
#include <AudioUnit/AudioUnit.h>
],[
AudioUnitInputCallback callback;
],[
have_coreaudio=yes
])
AC_MSG_RESULT($have_coreaudio)
# Set up files for the audio library
if test x$have_coreaudio = xyes; then
CFLAGS="$CFLAGS -DCOREAUDIO_SUPPORT"
AUDIO_SUBDIRS="$AUDIO_SUBDIRS macosx"
AUDIO_DRIVERS="$AUDIO_DRIVERS macosx/libaudio_macosx.la"
fi
fi
}
dnl See if we can use x86 assembly blitters dnl See if we can use x86 assembly blitters
# NASM is available from: http://nasm.octium.net/ # NASM is available from: http://nasm.octium.net/
CheckNASM() CheckNASM()
...@@ -2507,10 +2531,15 @@ case "$target" in ...@@ -2507,10 +2531,15 @@ case "$target" in
ARCH=macosx ARCH=macosx
CheckDummyVideo CheckDummyVideo
CheckDiskAudio CheckDiskAudio
CheckCoreAudio
CheckQUARTZ CheckQUARTZ
CheckMacGL CheckMacGL
CheckPTHREAD CheckPTHREAD
CheckSIGACTION CheckSIGACTION
# If either the audio or CD driver is used, add the AudioUnit framework
if test x$enable_audio = xyes -o x$enable_cdrom = xyes; then
SYSTEM_LIBS="$SYSTEM_LIBS -framework AudioToolbox -framework AudioUnit"
fi
# Set up files for the audio library # Set up files for the audio library
if test x$enable_audio = xyes; then if test x$enable_audio = xyes; then
AUDIO_SUBDIRS="$AUDIO_SUBDIRS macrom" AUDIO_SUBDIRS="$AUDIO_SUBDIRS macrom"
...@@ -2526,7 +2555,7 @@ case "$target" in ...@@ -2526,7 +2555,7 @@ case "$target" in
if test x$enable_cdrom = xyes; then if test x$enable_cdrom = xyes; then
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 -lstdc++"
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
...@@ -2766,6 +2795,7 @@ src/audio/dma/Makefile ...@@ -2766,6 +2795,7 @@ src/audio/dma/Makefile
src/audio/dmedia/Makefile src/audio/dmedia/Makefile
src/audio/dsp/Makefile src/audio/dsp/Makefile
src/audio/esd/Makefile src/audio/esd/Makefile
src/audio/macosx/Makefile
src/audio/macrom/Makefile src/audio/macrom/Makefile
src/audio/mint/Makefile src/audio/mint/Makefile
src/audio/mme/Makefile src/audio/mme/Makefile
......
...@@ -15,6 +15,7 @@ DIST_SUBDIRS = \ ...@@ -15,6 +15,7 @@ DIST_SUBDIRS = \
dmedia \ dmedia \
dsp \ dsp \
esd \ esd \
macosx \
macrom \ macrom \
mint \ mint \
mme \ mme \
......
...@@ -77,6 +77,9 @@ static AudioBootStrap *bootstrap[] = { ...@@ -77,6 +77,9 @@ static AudioBootStrap *bootstrap[] = {
#ifdef __BEOS__ #ifdef __BEOS__
&BAUDIO_bootstrap, &BAUDIO_bootstrap,
#endif #endif
#ifdef COREAUDIO_SUPPORT
&COREAUDIO_bootstrap,
#endif
#if defined(macintosh) || TARGET_API_MAC_CARBON #if defined(macintosh) || TARGET_API_MAC_CARBON
&SNDMGR_bootstrap, &SNDMGR_bootstrap,
#endif #endif
......
...@@ -144,6 +144,9 @@ extern AudioBootStrap Paud_bootstrap; ...@@ -144,6 +144,9 @@ extern AudioBootStrap Paud_bootstrap;
#ifdef __BEOS__ #ifdef __BEOS__
extern AudioBootStrap BAUDIO_bootstrap; extern AudioBootStrap BAUDIO_bootstrap;
#endif #endif
#ifdef COREAUDIO_SUPPORT
extern AudioBootStrap COREAUDIO_bootstrap;
#endif
#if defined(macintosh) || TARGET_API_MAC_CARBON #if defined(macintosh) || TARGET_API_MAC_CARBON
extern AudioBootStrap SNDMGR_bootstrap; extern AudioBootStrap SNDMGR_bootstrap;
#endif #endif
......
Makefile.in
Makefile
.libs
*.o
*.lo
*.la
## Makefile.am for SDL using the Mac OS X CoreAudio driver
noinst_LTLIBRARIES = libaudio_macosx.la
libaudio_macosx_la_SOURCES = $(SRCS)
# The SDL audio driver sources
SRCS = SDL_coreaudio.c \
SDL_coreaudio.h
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#include <AudioUnit/AudioUnit.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL_endian.h"
#include "SDL_audio.h"
#include "SDL_audio_c.h"
#include "SDL_audiomem.h"
#include "SDL_sysaudio.h"
#include "SDL_coreaudio.h"
/* Audio driver functions */
static int Core_OpenAudio(_THIS, SDL_AudioSpec *spec);
static void Core_WaitAudio(_THIS);
static void Core_PlayAudio(_THIS);
static Uint8 *Core_GetAudioBuf(_THIS);
static void Core_CloseAudio(_THIS);
/* Audio driver bootstrap functions */
static int Audio_Available(void)
{
return(1);
}
static void Audio_DeleteDevice(SDL_AudioDevice *device)
{
free(device->hidden);
free(device);
}
static SDL_AudioDevice *Audio_CreateDevice(int devindex)
{
SDL_AudioDevice *this;
/* Initialize all variables that we clean on shutdown */
this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
if ( this ) {
memset(this, 0, (sizeof *this));
this->hidden = (struct SDL_PrivateAudioData *)
malloc((sizeof *this->hidden));
}
if ( (this == NULL) || (this->hidden == NULL) ) {
SDL_OutOfMemory();
if ( this ) {
free(this);
}
return(0);
}
memset(this->hidden, 0, (sizeof *this->hidden));
/* Set the function pointers */
this->OpenAudio = Core_OpenAudio;
this->WaitAudio = Core_WaitAudio;
this->PlayAudio = Core_PlayAudio;
this->GetAudioBuf = Core_GetAudioBuf;
this->CloseAudio = Core_CloseAudio;
this->free = Audio_DeleteDevice;
return this;
}
AudioBootStrap COREAUDIO_bootstrap = {
"coreaudio", "Mac OS X CoreAudio",
Audio_Available, Audio_CreateDevice
};
/* The CoreAudio callback */
static OSStatus audioCallback (void *inRefCon,
AudioUnitRenderActionFlags inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
AudioBuffer *ioData)
{
SDL_AudioDevice *this = (SDL_AudioDevice *)inRefCon;
UInt32 remaining, len;
void *ptr;
/* Only do anything if audio is enabled and not paused */
if ( ! this->enabled || this->paused ) {
memset(ioData->mData, this->spec.silence, ioData->mDataByteSize);
return 0;
}
/* No SDL conversion should be needed here, ever, since we accept
any input format in OpenAudio, and leave the conversion to CoreAudio.
*/
assert(!this->convert.needed);
assert(this->spec.channels == ioData->mNumberChannels);
remaining = ioData->mDataByteSize;
ptr = ioData->mData;
while (remaining > 0) {
if (bufferOffset >= bufferSize) {
/* Generate the data */
memset(buffer, this->spec.silence, bufferSize);
SDL_mutexP(this->mixer_lock);
(*this->spec.callback)(this->spec.userdata,
buffer, bufferSize);
SDL_mutexV(this->mixer_lock);
bufferOffset = 0;
}
len = bufferSize - bufferOffset;
if (len > remaining)
len = remaining;
memcpy(ptr, buffer + bufferOffset, len);
ptr += len;
remaining -= len;
bufferOffset += len;
}
return 0;
}
/* Dummy functions -- we don't use thread-based audio */
void Core_WaitAudio(_THIS)
{
return;
}
void Core_PlayAudio(_THIS)
{
return;
}
Uint8 *Core_GetAudioBuf(_THIS)
{
return(NULL);
}
void Core_CloseAudio(_THIS)
{
OSStatus result;
AudioUnitInputCallback callback;
/* stop processing the audio unit */
result = AudioOutputUnitStop (outputAudioUnit);
if (result != noErr) {
SDL_SetError("Core_CloseAudio: AudioOutputUnitStop");
return;
}
/* Remove the input callback */
callback.inputProc = 0;
callback.inputProcRefCon = 0;
result = AudioUnitSetProperty (outputAudioUnit,
kAudioUnitProperty_SetInputCallback,
kAudioUnitScope_Input,
0,
&callback,
sizeof(callback));
if (result != noErr) {
SDL_SetError("Core_CloseAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)");
return;
}
result = CloseComponent(outputAudioUnit);
if (result != noErr) {
SDL_SetError("Core_CloseAudio: CloseComponent");
return;
}
free(buffer);
}
#define CHECK_RESULT(msg) \
if (result != noErr) { \
SDL_SetError("Failed to start CoreAudio: " msg); \
return -1; \
}
int Core_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
OSStatus result = noErr;
Component comp;
ComponentDescription desc;
AudioUnitInputCallback callback;
AudioStreamBasicDescription requestedDesc;
/* Setup a AudioStreamBasicDescription with the requested format */
requestedDesc.mFormatID = kAudioFormatLinearPCM;
requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked;
requestedDesc.mChannelsPerFrame = spec->channels;
requestedDesc.mSampleRate = spec->freq;
requestedDesc.mBitsPerChannel = spec->format & 0xFF;
if (spec->format & 0x8000)
requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
if (spec->format & 0x1000)
requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
requestedDesc.mFramesPerPacket = 1;
requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8;
requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame * requestedDesc.mFramesPerPacket;
/* Locate the default output audio unit */
desc.componentType = kAudioUnitComponentType;
desc.componentSubType = kAudioUnitSubType_Output;
desc.componentManufacturer = kAudioUnitID_DefaultOutput;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
comp = FindNextComponent (NULL, &desc);
if (comp == NULL) {
SDL_SetError ("Failed to start CoreAudio: FindNextComponent returned NULL");
return -1;
}
/* Open & initialize the default output audio unit */
result = OpenAComponent (comp, &outputAudioUnit);
CHECK_RESULT("OpenAComponent")
result = AudioUnitInitialize (outputAudioUnit);
CHECK_RESULT("AudioUnitInitialize")
/* Set the input format of the audio unit. */
result = AudioUnitSetProperty (outputAudioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&requestedDesc,
sizeof (requestedDesc));
CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)")
/* Set the audio callback */
callback.inputProc = audioCallback;
callback.inputProcRefCon = this;
result = AudioUnitSetProperty (outputAudioUnit,
kAudioUnitProperty_SetInputCallback,
kAudioUnitScope_Input,
0,
&callback,
sizeof(callback));
CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)")
/* Calculate the final parameters for this audio specification */
SDL_CalculateAudioSpec(spec);
/* Allocate a sample buffer */
bufferOffset = bufferSize = this->spec.size;
buffer = malloc(bufferSize);
assert(buffer);
/* Finally, start processing of the audio unit */
result = AudioOutputUnitStart (outputAudioUnit);
CHECK_RESULT("AudioOutputUnitStart")
/* We're running! */
return(1);
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#ifndef _SDL_coreaudio_h
#define _SDL_coreaudio_h
#include "SDL_sysaudio.h"
/* Hidden "this" pointer for the video functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData {
AudioUnit outputAudioUnit;
void *buffer;
UInt32 bufferOffset;
UInt32 bufferSize;
};
/* Old variable names */
#define outputAudioUnit (this->hidden->outputAudioUnit)
#define buffer (this->hidden->buffer)
#define bufferOffset (this->hidden->bufferOffset)
#define bufferSize (this->hidden->bufferSize)
#endif /* _SDL_coreaudio_h */
...@@ -67,30 +67,29 @@ OSStatus AudioFileManager::FileInputProc (void *inRefCo ...@@ -67,30 +67,29 @@ OSStatus AudioFileManager::FileInputProc (void *inRefCo
OSStatus AudioFileManager::Render (AudioBuffer &ioData) OSStatus AudioFileManager::Render (AudioBuffer &ioData)
{ {
OSStatus result = AudioConverterFillBuffer(mParentConverter, OSStatus result = noErr;
AudioFileManager::ACInputProc,
this, if (mBufferOffset >= mBufferSize) {
&ioData.mDataByteSize, result = GetFileData(&mTmpBuffer, &mBufferSize);
ioData.mData); if (result) {
if (result) { SDL_SetError ("AudioConverterFillBuffer:%ld\n", result);
SDL_SetError ("AudioConverterFillBuffer:%ld\n", result); mParent.DoNotification (result);
mParent.DoNotification (result); return result;
} else { }
mByteCounter += ioData.mDataByteSize / 2;
AfterRender(); mBufferOffset = 0;
} }
if (ioData.mDataByteSize > mBufferSize - mBufferOffset)
ioData.mDataByteSize = mBufferSize - mBufferOffset;
ioData.mData = (char *)mTmpBuffer + mBufferOffset;
mBufferOffset += ioData.mDataByteSize;
mByteCounter += ioData.mDataByteSize;
AfterRender();
return result; return result;
} }
OSStatus AudioFileManager::ACInputProc (AudioConverterRef inAudioConverter,
UInt32* outDataSize,
void** outData,
void* inUserData)
{
AudioFileManager* THIS = (AudioFileManager*)inUserData;
return THIS->GetFileData(outData, outDataSize);
}
AudioFileManager::~AudioFileManager () AudioFileManager::~AudioFileManager ()
{ {
if (mFileBuffer) { if (mFileBuffer) {
...@@ -102,7 +101,6 @@ AudioFileManager::~AudioFileManager () ...@@ -102,7 +101,6 @@ AudioFileManager::~AudioFileManager ()
AudioFilePlayer::AudioFilePlayer (const FSRef *inFileRef) AudioFilePlayer::AudioFilePlayer (const FSRef *inFileRef)
: mConnected (false), : mConnected (false),
mAudioFileManager (0), mAudioFileManager (0),
mConverter (0),
mNotifier (0), mNotifier (0),
mStartFrame (0) mStartFrame (0)
{ {
...@@ -124,39 +122,14 @@ AudioFilePlayer::AudioFilePlayer (const FSRef *inFileRef) ...@@ -124,39 +122,14 @@ AudioFilePlayer::AudioFilePlayer (const FSRef *inFileRef)
bytesPerSecond); bytesPerSecond);
} }
// you can put a rate scalar here to play the file faster or slower void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit)
// by multiplying the same rate by the desired factor
// eg fileSampleRate * 2 -> twice as fast
// before you create the AudioConverter
void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit,
int inBusNumber)
{ {
if (mConnected) throw static_cast<OSStatus>(-1); //can't set dest if already engaged if (mConnected) throw static_cast<OSStatus>(-1); //can't set dest if already engaged
mPlayUnit = inDestUnit; mPlayUnit = inDestUnit;
mBusNumber = inBusNumber;
OSStatus result = noErr; OSStatus result = noErr;
if (mConverter) {
result = AudioConverterDispose (mConverter);
THROW_RESULT("AudioConverterDispose")
}
AudioStreamBasicDescription destDesc;
UInt32 size = sizeof (destDesc);
result = AudioUnitGetProperty (inDestUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
inBusNumber,
&destDesc,
&size);
THROW_RESULT("AudioUnitGetProperty")
#if DEBUG
printf("Destination format:\n");
PrintStreamDesc (&destDesc);
#endif
//we can "down" cast a component instance to a component //we can "down" cast a component instance to a component
ComponentDescription desc; ComponentDescription desc;
...@@ -171,19 +144,14 @@ void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit, ...@@ -171,19 +144,14 @@ void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit,
THROW_RESULT("BAD COMPONENT") THROW_RESULT("BAD COMPONENT")
} }
/* Set the input format of the audio unit. */
result = AudioConverterNew (&mFileDescription, &destDesc, &mConverter); result = AudioUnitSetProperty (inDestUnit,
THROW_RESULT("AudioConverterNew") kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
#if 0 0,
// this uses the better quality SRC &mFileDescription,
UInt32 srcID = kAudioUnitSRCAlgorithm_Polyphase; sizeof (mFileDescription));
result = AudioConverterSetProperty(mConverter, THROW_RESULT("AudioUnitSetProperty")
kAudioConverterSampleRateConverterAlgorithm,
sizeof(srcID),
&srcID);
THROW_RESULT("AudioConverterSetProperty")
#endif
} }
void AudioFilePlayer::SetStartFrame (int frame) void AudioFilePlayer::SetStartFrame (int frame)
...@@ -220,22 +188,18 @@ AudioFilePlayer::~AudioFilePlayer() ...@@ -220,22 +188,18 @@ AudioFilePlayer::~AudioFilePlayer()
FSClose (mForkRefNum); FSClose (mForkRefNum);
mForkRefNum = 0; mForkRefNum = 0;
} }
if (mConverter) {
AudioConverterDispose (mConverter);
mConverter = 0;
}
} }
void AudioFilePlayer::Connect() void AudioFilePlayer::Connect()
{ {
#if DEBUG #if DEBUG
printf ("Connect:%x,%ld, engaged=%d\n", (int)mPlayUnit, mBusNumber, (mConnected ? 1 : 0)); printf ("Connect:%x, engaged=%d\n", (int)mPlayUnit, (mConnected ? 1 : 0));
#endif #endif
if (!mConnected) if (!mConnected)
{ {
mAudioFileManager->Connect(mConverter); mAudioFileManager->DoConnect();
// 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
mInputCallback.inputProc = AudioFileManager::FileInputProc; mInputCallback.inputProc = AudioFileManager::FileInputProc;
mInputCallback.inputProcRefCon = mAudioFileManager; mInputCallback.inputProcRefCon = mAudioFileManager;
...@@ -243,7 +207,7 @@ void AudioFilePlayer::Connect() ...@@ -243,7 +207,7 @@ void AudioFilePlayer::Connect()
OSStatus result = AudioUnitSetProperty (mPlayUnit, OSStatus result = AudioUnitSetProperty (mPlayUnit,
kAudioUnitProperty_SetInputCallback, kAudioUnitProperty_SetInputCallback,
kAudioUnitScope_Input, kAudioUnitScope_Input,
mBusNumber, 0,
&mInputCallback, &mInputCallback,
sizeof(mInputCallback)); sizeof(mInputCallback));
THROW_RESULT("AudioUnitSetProperty") THROW_RESULT("AudioUnitSetProperty")
...@@ -272,7 +236,7 @@ void AudioFilePlayer::DoNotification (OSStatus inStatus) const ...@@ -272,7 +236,7 @@ void AudioFilePlayer::DoNotification (OSStatus inStatus) const
void AudioFilePlayer::Disconnect () void AudioFilePlayer::Disconnect ()
{ {
#if DEBUG #if DEBUG
printf ("Disconnect:%x,%ld, engaged=%d\n", (int)mPlayUnit, mBusNumber, (mConnected ? 1 : 0)); printf ("Disconnect:%x,%ld, engaged=%d\n", (int)mPlayUnit, 0, (mConnected ? 1 : 0));
#endif #endif
if (mConnected) if (mConnected)
{ {
...@@ -283,7 +247,7 @@ void AudioFilePlayer::Disconnect () ...@@ -283,7 +247,7 @@ void AudioFilePlayer::Disconnect ()
OSStatus result = AudioUnitSetProperty (mPlayUnit, OSStatus result = AudioUnitSetProperty (mPlayUnit,
kAudioUnitProperty_SetInputCallback, kAudioUnitProperty_SetInputCallback,
kAudioUnitScope_Input, kAudioUnitScope_Input,
mBusNumber, 0,
&mInputCallback, &mInputCallback,
sizeof(mInputCallback)); sizeof(mInputCallback));
if (result) if (result)
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include <CoreServices/CoreServices.h> #include <CoreServices/CoreServices.h>
#include <AudioToolbox/AudioConverter.h>
#include <AudioUnit/AudioUnit.h> #include <AudioUnit/AudioUnit.h>
#include "SDL_error.h" #include "SDL_error.h"
...@@ -65,8 +64,7 @@ public: ...@@ -65,8 +64,7 @@ public:
~AudioFilePlayer(); ~AudioFilePlayer();
void SetDestination (AudioUnit &inDestUnit, void SetDestination (AudioUnit &inDestUnit);
int inBusNumber);
void SetNotifier (AudioFilePlayNotifier inNotifier, void *inRefCon) void SetNotifier (AudioFilePlayNotifier inNotifier, void *inRefCon)
{ {
...@@ -88,26 +86,18 @@ public: ...@@ -88,26 +86,18 @@ public:
bool IsConnected () const { return mConnected; } bool IsConnected () const { return mConnected; }
UInt32 GetBusNumber () const { return mBusNumber; }
AudioUnit GetDestUnit () const { return mPlayUnit; } AudioUnit GetDestUnit () const { return mPlayUnit; }
AudioConverterRef GetAudioConverter() const { return mConverter; }
#if DEBUG #if DEBUG
void Print() const void Print() const
{ {
printf ("Destination Bus:%ld\n", GetBusNumber());
printf ("Is Connected:%s\n", (IsConnected() ? "true" : "false")); printf ("Is Connected:%s\n", (IsConnected() ? "true" : "false"));
printf ("- - - - - - - - - - - - - - \n"); printf ("- - - - - - - - - - - - - - \n");
} }
#endif #endif
const AudioStreamBasicDescription& GetFileFormat() const { return mFileDescription; }
private: private:
AudioUnit mPlayUnit; AudioUnit mPlayUnit;
UInt32 mBusNumber;
SInt16 mForkRefNum; SInt16 mForkRefNum;
AudioUnitInputCallback mInputCallback; AudioUnitInputCallback mInputCallback;
...@@ -117,7 +107,6 @@ private: ...@@ -117,7 +107,6 @@ private:
bool mConnected; bool mConnected;
AudioFileManager* mAudioFileManager; AudioFileManager* mAudioFileManager;
AudioConverterRef mConverter;
AudioFilePlayNotifier mNotifier; AudioFilePlayNotifier mNotifier;
void* mRefCon; void* mRefCon;
...@@ -141,15 +130,11 @@ public: ...@@ -141,15 +130,11 @@ public:
~AudioFileManager(); ~AudioFileManager();
void Connect (AudioConverterRef inConverter)
{
mParentConverter = inConverter;
DoConnect();
}
// 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
void Disconnect (); void Disconnect ();
void DoConnect ();
OSStatus Read(char *buffer, UInt32 *len); OSStatus Read(char *buffer, UInt32 *len);
...@@ -165,7 +150,6 @@ public: ...@@ -165,7 +150,6 @@ public:
protected: protected:
AudioFilePlayer& mParent; AudioFilePlayer& mParent;
AudioConverterRef mParentConverter;
SInt16 mForkRefNum; SInt16 mForkRefNum;
SInt64 mAudioDataOffset; SInt64 mAudioDataOffset;
...@@ -179,6 +163,10 @@ protected: ...@@ -179,6 +163,10 @@ protected:
int mNumTimesAskedSinceFinished; int mNumTimesAskedSinceFinished;
void* mTmpBuffer;
UInt32 mBufferSize;
UInt32 mBufferOffset;
public: public:
const UInt32 mChunkSize; const UInt32 mChunkSize;
SInt64 mFileLength; SInt64 mFileLength;
...@@ -190,8 +178,6 @@ protected: ...@@ -190,8 +178,6 @@ protected:
OSStatus Render (AudioBuffer &ioData); OSStatus Render (AudioBuffer &ioData);
OSStatus GetFileData (void** inOutData, UInt32 *inOutDataSize); OSStatus GetFileData (void** inOutData, UInt32 *inOutDataSize);
void DoConnect ();
void AfterRender (); void AfterRender ();
...@@ -201,10 +187,6 @@ public: ...@@ -201,10 +187,6 @@ public:
const AudioTimeStamp *inTimeStamp, const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber, UInt32 inBusNumber,
AudioBuffer *ioData); AudioBuffer *ioData);
static OSStatus ACInputProc (AudioConverterRef inAudioConverter,
UInt32* outDataSize,
void** outData,
void* inUserData);
}; };
......
...@@ -287,6 +287,8 @@ AudioFileManager::AudioFileManager (AudioFilePlayer &inParent, ...@@ -287,6 +287,8 @@ AudioFileManager::AudioFileManager (AudioFilePlayer &inParent,
mLockUnsuccessful (false), mLockUnsuccessful (false),
mIsEngaged (false), mIsEngaged (false),
mBufferSize (inChunkSize),
mBufferOffset (inChunkSize),
mChunkSize (inChunkSize), mChunkSize (inChunkSize),
mFileLength (inFileLength), mFileLength (inFileLength),
mReadFilePosition (0), mReadFilePosition (0),
...@@ -364,7 +366,7 @@ OSStatus AudioFileManager::GetFileData (void** inOutData, UInt32 *inOutDataSize) ...@@ -364,7 +366,7 @@ OSStatus AudioFileManager::GetFileData (void** inOutData, UInt32 *inOutDataSize)
if (mReadFromFirstBuffer == mWriteToFirstBuffer) { if (mReadFromFirstBuffer == mWriteToFirstBuffer) {
#if DEBUG #if DEBUG
printf ("* * * * * * * Can't keep up with reading file:%ld\n", mParent.GetBusNumber()); printf ("* * * * * * * Can't keep up with reading file\n");
#endif #endif
mParent.DoNotification (kAudioFilePlayErr_FilePlayUnderrun); mParent.DoNotification (kAudioFilePlayErr_FilePlayUnderrun);
......
...@@ -68,8 +68,6 @@ static SDL_CD* theCDROM; ...@@ -68,8 +68,6 @@ static SDL_CD* theCDROM;
static OSStatus CheckInit (); static OSStatus CheckInit ();
static OSStatus MatchAUFormats (AudioUnit theUnit, UInt32 theInputBus);
static void FilePlayNotificationHandler (void* inRefCon, OSStatus inStatus); static void FilePlayNotificationHandler (void* inRefCon, OSStatus inStatus);
static int RunCallBackThread (void* inRefCon); static int RunCallBackThread (void* inRefCon);
...@@ -423,7 +421,7 @@ int LoadFile (const FSRef *ref, int startFrame, int stopFrame) ...@@ -423,7 +421,7 @@ int LoadFile (const FSRef *ref, int startFrame, int stopFrame)
throw (-3); throw (-3);
} }
thePlayer->SetDestination(theUnit, 0); thePlayer->SetDestination(theUnit);
if (startFrame >= 0) if (startFrame >= 0)
thePlayer->SetStartFrame (startFrame); thePlayer->SetStartFrame (startFrame);
...@@ -605,16 +603,6 @@ static OSStatus CheckInit () ...@@ -605,16 +603,6 @@ static OSStatus CheckInit ()
THROW_RESULT("CheckInit: AudioUnitInitialize") THROW_RESULT("CheckInit: AudioUnitInitialize")
// In this case we first want to get the output format of the OutputUnit
// Then we set that as the input format. Why?
// So that only a single conversion process is done
// when SetDestination is called it will get the input format of the
// unit its supplying data to. This defaults to 44.1K, stereo, so if
// the device is not that, then we lose a possibly rendering of data
result = MatchAUFormats (theUnit, 0);
THROW_RESULT("CheckInit: MatchAUFormats")
playBackWasInit = true; playBackWasInit = true;
} }
catch (...) catch (...)
...@@ -625,29 +613,6 @@ static OSStatus CheckInit () ...@@ -625,29 +613,6 @@ static OSStatus CheckInit ()
return 0; return 0;
} }
static OSStatus MatchAUFormats (AudioUnit theUnit, UInt32 theInputBus)
{
AudioStreamBasicDescription theDesc;
UInt32 size = sizeof (theDesc);
OSStatus result = AudioUnitGetProperty (theUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&theDesc,
&size);
THROW_RESULT("MatchAUFormats: AudioUnitGetProperty")
result = AudioUnitSetProperty (theUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
theInputBus,
&theDesc,
size);
return result;
}
static void FilePlayNotificationHandler(void * inRefCon, OSStatus inStatus) static void FilePlayNotificationHandler(void * inRefCon, OSStatus inStatus)
{ {
if (inStatus == kAudioFilePlay_FileIsFinished) { if (inStatus == kAudioFilePlay_FileIsFinished) {
......
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