diff --git a/stepmania/src/arch/Sound/CAHelpers.cpp b/stepmania/src/arch/Sound/CAHelpers.cpp deleted file mode 100644 index b65721dda7..0000000000 --- a/stepmania/src/arch/Sound/CAHelpers.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "global.h" -#include "RageSoundDriver_CA.h" -#include "CAHelpers.h" - -AudioConverter::AudioConverter( RageSound_CA *driver, const Desc &procFormat ) - : mBuffer(NULL), mBufferSize(0) -{ - const Desc SMFormat(44100.0, kAudioFormatLinearPCM, kBytesPerPacket, - kFramesPerPacket, kBytesPerFrame, kChannelsPerFrame, - kBitsPerChannel, kFormatFlags); - - SMFormat.Print(); - procFormat.Print(); - - if( this->Initialize(SMFormat, procFormat) ) - RageException::ThrowNonfatal( "Couldn't create the converter." ); - - mDriver = driver; -} - -OSStatus AudioConverter::FormatConverterInputProc(UInt32& ioNumberDataPackets, - AudioBufferList& ioData, - AudioStreamPacketDescription **outDesc) -{ - AudioBuffer& buf = ioData.mBuffers[0]; - - if( mBufferSize < buf.mDataByteSize ) - { - delete [] mBuffer; - mBuffer = new UInt8[buf.mDataByteSize]; - mBufferSize = buf.mDataByteSize; - } - buf.mData = mBuffer; - - const int frames = buf.mDataByteSize / kBytesPerPacket; - mDriver->FillConverter( buf.mData, frames ); - return noErr; -} - -/* - * (c) 2004 Steve Checkoway - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ diff --git a/stepmania/src/arch/Sound/CAHelpers.h b/stepmania/src/arch/Sound/CAHelpers.h deleted file mode 100644 index 906040a39d..0000000000 --- a/stepmania/src/arch/Sound/CAHelpers.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef CA_HELPERS_H -#define CA_HELPERS_H - -#include "FormatConverterClient.h" -#include "CAStreamBasicDescription.h" - -static const UInt32 kFramesPerPacket = 1; -static const UInt32 kChannelsPerFrame = 2; -static const UInt32 kBitsPerChannel = 16; -static const UInt32 kBytesPerPacket = kChannelsPerFrame * kBitsPerChannel / 8; -static const UInt32 kBytesPerFrame = kBytesPerPacket; -static const UInt32 kFormatFlags = kAudioFormatFlagsNativeEndian | -kAudioFormatFlagIsSignedInteger; - -typedef CAStreamBasicDescription Desc; - -class AudioConverter : public FormatConverterClient -{ -public: - AudioConverter( RageSound_CA *driver, const Desc &procFormat ); - ~AudioConverter() { delete [] mBuffer; } -protected: - OSStatus FormatConverterInputProc(UInt32& ioNumberDataPackets, - AudioBufferList& ioData, - AudioStreamPacketDescription **outDesc); -private: - RageSound_CA *mDriver; - UInt8 *mBuffer; - UInt32 mBufferSize; -}; - - -#endif - -/* - * (c) 2004 Steve Checkoway - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ diff --git a/stepmania/src/arch/Sound/RageSoundDriver_CA.cpp b/stepmania/src/arch/Sound/RageSoundDriver_CA.cpp index f9acd0e55c..d6e3908d03 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_CA.cpp +++ b/stepmania/src/arch/Sound/RageSoundDriver_CA.cpp @@ -1,10 +1,10 @@ #include "global.h" #include "RageUtil.h" #include "RageSoundDriver_CA.h" -#include "CAHelpers.h" #include "RageLog.h" #include "RageTimer.h" +#include #include "CAAudioHardwareSystem.h" #include "CAAudioHardwareDevice.h" #include "CAAudioHardwareStream.h" @@ -15,7 +15,16 @@ #include #include -static AudioConverter *gConverter = NULL; +static const UInt32 kFramesPerPacket = 1; +static const UInt32 kChannelsPerFrame = 2; +static const UInt32 kBitsPerChannel = 16; +static const UInt32 kBytesPerPacket = kChannelsPerFrame * kBitsPerChannel / 8; +static const UInt32 kBytesPerFrame = kBytesPerPacket; +static const UInt32 kFormatFlags = kAudioFormatFlagsNativeEndian | +kAudioFormatFlagIsSignedInteger; + +typedef CAStreamBasicDescription Desc; + /* temporary hack: */ static float g_fLastIOProcTime = 0; @@ -40,79 +49,8 @@ static CString FormatToString( int fmt ) return ssprintf( "%c%c%c%c", c[0], c[1], c[2], c[3] ); } -static Desc FindClosestFormat(const vector& formats, - RageSound_CA::format& type) -{ - vector v; - - vector::const_iterator i; - for (i = formats.begin(); i != formats.end(); ++i) - { - const Desc& format = *i; - - if( !format.IsPCM() ) - continue; - - if( format.mSampleRate != 0. && format.mSampleRate != 44100.0 ) - continue; - - if (format.SampleWordSize() == 2 && - (format.mFormatFlags & kFormatFlags) == kFormatFlags) - { // exact match - type = RageSound_CA::EXACT; - return format; - } - v.push_back(format); - } - - const Desc CanonicalFormat(44100.0, kAudioFormatLinearPCM, 8, 1, 8, 2, 32, - kAudioFormatFlagsNativeFloatPacked); - - for (i = v.begin(); i != v.end(); ++i) - { - const Desc& format = *i; - - if (format == CanonicalFormat) - { - type = RageSound_CA::CANONICAL; - return format; - } - } - if (v.empty()) - RageException::ThrowNonfatal("Couldn't find a close format."); - type = RageSound_CA::OTHER; - return v[0]; // something is better than nothing. -} - -static void GetIOProcFormats( CAAudioHardwareStream stream, - vector &procFormats ) -{ - UInt32 numFormats = stream.GetNumberAvailableIOProcFormats(); - - for( UInt32 i=0; i &physicalFormats ) -{ - UInt32 numFormats = stream.GetNumberAvailablePhysicalFormats(); - for( UInt32 i=0; iWarn("Could not install the overload listener."); } - vector physicalFormats; - GetPhysicalFormats( sID, physicalFormats ); - unsigned i; - LOG->Info("Available physical formats:"); - for (i = 0; i < physicalFormats.size(); ++i) + const Desc CanonicalFormat(44100.0, kAudioFormatLinearPCM, 8, 1, 8, 2, 32, + kAudioFormatFlagsNativeFloatPacked); + const Desc SMFormat(44100.0, kAudioFormatLinearPCM, kBytesPerPacket, + kFramesPerPacket, kBytesPerFrame, kChannelsPerFrame, + kBitsPerChannel, kFormatFlags); + + stream.SetCurrentIOProcFormat(CanonicalFormat); + + if (AudioConverterNew(&SMFormat, &CanonicalFormat, &mConverter)) { - const Desc& f = physicalFormats[i]; - - LOG->Info("Format %u: Rate: %i ID: %s Flags 0x%lx bpp %lu fpp %lu" - " bpf %lu channels %lu bits %lu", i, int(f.mSampleRate), - FormatToString(f.mFormatID).c_str(), f.mFormatFlags, - f.mBytesPerPacket, f.mFramesPerPacket, f.mBytesPerFrame, - f.mChannelsPerFrame, f.mBitsPerChannel); + delete mOutputDevice; + RageException::ThrowNonfatal("Couldn't create the audio converter"); } - const Desc& physicalFormat = FindClosestFormat( physicalFormats, mFormat ); - stream.SetCurrentPhysicalFormat( physicalFormat ); - - vector procFormats; - GetIOProcFormats( sID, procFormats ); - LOG->Info("Available I/O procedure formats:"); - for (i = 0; i < procFormats.size(); ++i) - { - const Desc& f = procFormats[i]; - - LOG->Info("Format %u: Rate: %i ID: %s Flags 0x%lx bpp %lu fpp %lu" - " bpf %lu channels %lu bits %lu", i, int(f.mSampleRate), - FormatToString(f.mFormatID).c_str(), f.mFormatFlags, - f.mBytesPerPacket, f.mFramesPerPacket, f.mBytesPerFrame, - f.mChannelsPerFrame, f.mBitsPerChannel); - } - - const Desc& procFormat = FindClosestFormat( procFormats, mFormat ); - stream.SetCurrentIOProcFormat( procFormat ); - - LOG->Info("Proc format is %s.", - mFormat == EXACT ? "exact" : (mFormat == CANONICAL ? - "canonical" : "other")); - + try { UInt32 bufferSize = mOutputDevice->GetIOBufferSize(); @@ -218,13 +132,11 @@ RageSound_CA::RageSound_CA() catch (const CAException& e) { delete mOutputDevice; + AudioConverterDispose(mConverter); RageException::ThrowNonfatal("Couldn't get Latency."); } StartDecodeThread(); - - if (mFormat == OTHER) - gConverter = new AudioConverter( this, procFormat ); try { @@ -233,8 +145,8 @@ RageSound_CA::RageSound_CA() } catch(const CAException& e) { - delete gConverter; delete mOutputDevice; + AudioConverterDispose(mConverter); RageException::Throw("Couldn't start the IOProc."); } } @@ -243,7 +155,7 @@ RageSound_CA::~RageSound_CA() { mOutputDevice->StopIOProc(GetData); delete mOutputDevice; - delete gConverter; + AudioConverterDispose(mConverter); } int64_t RageSound_CA::GetPosition(const RageSoundBase *sound) const @@ -254,17 +166,6 @@ int64_t RageSound_CA::GetPosition(const RageSoundBase *sound) const return int64_t(time.mSampleTime); } -void RageSound_CA::FillConverter( void *data, UInt32 frames ) -{ - RageTimer tm; - - Mix( (int16_t *)data, frames, mDecodePos, mNow ); - - g_fLastMixTimes[g_fLastMixTimePos] = tm.GetDeltaTime(); - ++g_fLastMixTimePos; - wrap( g_fLastMixTimePos, NUM_MIX_TIMES ); -} - OSStatus RageSound_CA::GetData(AudioDeviceID inDevice, const AudioTimeStamp *inNow, const AudioBufferList *inInputData, @@ -276,50 +177,21 @@ OSStatus RageSound_CA::GetData(AudioDeviceID inDevice, RageTimer tm; RageSound_CA *This = (RageSound_CA *)inClientData; AudioBuffer& buf = outOutputData->mBuffers[0]; - UInt32 dataPackets = buf.mDataByteSize; + UInt32 dataPackets = buf.mDataByteSize >> 3; // 8 byes per packet int64_t decodePos = int64_t(inOutputTime->mSampleTime); int64_t now = int64_t(inNow->mSampleTime); - if (This->mFormat == OTHER) - { - dataPackets /= gConverter->GetOutputFormat().mBytesPerPacket; - This->mDecodePos = decodePos; - This->mNow = now; - gConverter->FillComplexBuffer(dataPackets, *outOutputData, NULL); - } - else - { - RageTimer mixTM; + RageTimer tm2; + int16_t buffer[dataPackets * (kBytesPerPacket >> 1)]; - if (This->mFormat == EXACT) - { - dataPackets /= kBytesPerPacket; - This->Mix((int16_t *)buf.mData, dataPackets, decodePos, now); - } - else // This->mFormat == CANONICAL - { - dataPackets /= 8; // 8 bytes per packet (1 frame per packet) - - int16_t buffer[dataPackets * kBytesPerPacket]; - int16_t *ip = buffer; - float *fp = (float *)buf.mData; - - This->Mix(buffer, dataPackets, decodePos, now); - - // Convert from signed 16 bit int to signed 32 bit float - for (unsigned i = 0; i < buf.mDataByteSize; i += 4) - { - int16_t val = *(ip++); - - *(fp++) = val / (val < 0 ? 32768.0f : 32767.0f); - } - } + This->Mix(buffer, dataPackets, decodePos, now); + g_fLastMixTimes[g_fLastMixTimePos] = tm2.GetDeltaTime(); + ++g_fLastMixTimePos; + wrap(g_fLastMixTimePos, NUM_MIX_TIMES); + + AudioConverterConvertBuffer(This->mConverter, dataPackets * kBytesPerPacket, + buffer, &buf.mDataByteSize, buf.mData); - g_fLastMixTimes[g_fLastMixTimePos] = tm.GetDeltaTime(); - ++g_fLastMixTimePos; - wrap(g_fLastMixTimePos, NUM_MIX_TIMES); - } - g_fLastIOProcTime = tm.GetDeltaTime(); ++g_iNumIOProcCalls; diff --git a/stepmania/src/arch/Sound/RageSoundDriver_CA.h b/stepmania/src/arch/Sound/RageSoundDriver_CA.h index a682537b22..4b07719a47 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_CA.h +++ b/stepmania/src/arch/Sound/RageSoundDriver_CA.h @@ -5,6 +5,8 @@ struct AudioTimeStamp; struct AudioBufferList; +struct OpaqueAudioConverter; +typedef struct OpaqueAudioConverter *AudioConverterRef; typedef unsigned long UInt32; typedef UInt32 AudioDeviceID; typedef UInt32 AudioDevicePropertyID; @@ -15,20 +17,11 @@ class RageSoundBase; class RageSound_CA : public RageSound_Generic_Software { -public: - enum format - { - EXACT, - CANONICAL, - OTHER - }; - private: int64_t mDecodePos; float mLatency; CAAudioHardwareDevice *mOutputDevice; - int64_t mNow; - format mFormat; + AudioConverterRef mConverter; static OSStatus GetData(AudioDeviceID inDevice, const AudioTimeStamp *inNow, @@ -45,7 +38,6 @@ private: void *inData); public: - void FillConverter( void *data, UInt32 frames ); RageSound_CA(); ~RageSound_CA(); float GetPlayLatency() const { return mLatency; }