From bee82341005c520b445b1297c8f2b6eabbe2f807 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sun, 28 Mar 2004 21:18:21 +0000 Subject: [PATCH] fix potential memory leak increase decoder thread priority init the hardware stream in the driver, not in the converter --- stepmania/src/arch/Sound/CAHelpers.cpp | 83 +++-------------- stepmania/src/arch/Sound/CAHelpers.h | 10 +- .../src/arch/Sound/RageSoundDriver_CA.cpp | 91 ++++++++++++++++++- stepmania/src/arch/Sound/RageSoundDriver_CA.h | 2 +- 4 files changed, 104 insertions(+), 82 deletions(-) diff --git a/stepmania/src/arch/Sound/CAHelpers.cpp b/stepmania/src/arch/Sound/CAHelpers.cpp index 7569d2f9f4..b4258c9177 100644 --- a/stepmania/src/arch/Sound/CAHelpers.cpp +++ b/stepmania/src/arch/Sound/CAHelpers.cpp @@ -2,50 +2,26 @@ #include "RageSoundDriver_CA.h" #include "CAHelpers.h" -#include "CAAudioHardwareDevice.h" -#include "CAAudioHardwareStream.h" -#include "CAException.h" +const UInt32 kFramesPerPacket = 1; +const UInt32 kChannelsPerFrame = 2; +const UInt32 kBitsPerChannel = 16; +const UInt32 kBytesPerPacket = kChannelsPerFrame * kBitsPerChannel / 8; +const UInt32 kBytesPerFrame = kBytesPerPacket; +const UInt32 kFormatFlags = kAudioFormatFlagsNativeEndian | + kAudioFormatFlagIsSignedInteger; -AudioConverter::AudioConverter(CAAudioHardwareDevice *dev, RageSound_CA *driver) +AudioConverter::AudioConverter( RageSound_CA *driver, const Desc &procFormat ) : mBuffer(NULL), mBufferSize(0) { - AudioStreamID sID = dev->GetStreamByIndex(kAudioDeviceSectionOutput, 0); - CAAudioHardwareStream stream(sID); - vector procFormats; - vector physicalFormats; - UInt32 numFormats = stream.GetNumberAvailableIOProcFormats(); - - for (UInt32 i=0; iInitialize(SMFormat, procFormat)) - RageException::ThrowNonfatal("Couldn't create the converter."); + + if( this->Initialize(SMFormat, procFormat) ) + RageException::ThrowNonfatal( "Couldn't create the converter." ); mDriver = driver; } @@ -57,9 +33,9 @@ OSStatus AudioConverter::FormatConverterInputProc(UInt32& ioNumberDataPackets, AudioBuffer& buf = ioData.mBuffers[0]; // This really shouldn't happen more than once, but better be sure. - if (mBufferSize != buf.mDataByteSize) + if( mBufferSize != buf.mDataByteSize ) { - delete mBuffer; // deleting NULL does not crash, unlike free(NULL) + delete mBuffer; mBufferSize = buf.mDataByteSize; mBuffer = new UInt8[mBufferSize]; } @@ -69,36 +45,3 @@ OSStatus AudioConverter::FormatConverterInputProc(UInt32& ioNumberDataPackets, return noErr; } -Desc AudioConverter::FindClosestFormat(const vector& formats) -{ - vector v; - - vector::const_iterator i; - for (i = formats.begin(); i != formats.end(); ++i) - { - const Desc& format = *i; - - if (!format.IsPCM() || format.mSampleRate != 44100.0) - continue; - - if (format.SampleWordSize() == 2 && - (format.mFormatFlags & kAudioFormatFlagIsSignedInteger) == - kAudioFormatFlagIsSignedInteger) - { // exact match - return format; - } - v.push_back(format); - } - - for (i = v.begin(); i != v.end(); ++i) - { - const Desc& format = *i; - if (format.SampleWordSize() == 2) - { - return format; // close - } - } - if (v.empty()) - RageException::ThrowNonfatal("Couldn't find a close format."); - return v[0]; // something is better than nothing. -} diff --git a/stepmania/src/arch/Sound/CAHelpers.h b/stepmania/src/arch/Sound/CAHelpers.h index 151f55499e..bb7297f761 100644 --- a/stepmania/src/arch/Sound/CAHelpers.h +++ b/stepmania/src/arch/Sound/CAHelpers.h @@ -1,24 +1,16 @@ #ifndef CA_HELPERS_H #define CA_HELPERS_H -#include #include "FormatConverterClient.h" #include "CAStreamBasicDescription.h" -const UInt32 kFramesPerPacket = 1; -const UInt32 kChannelsPerFrame = 2; -const UInt32 kBitsPerChannel = 16; -const UInt32 kBytesPerPacket = kChannelsPerFrame * kBitsPerChannel / 8; -const UInt32 kBytesPerFrame = kBytesPerPacket; -const UInt32 kFormatFlags = kAudioFormatFlagsNativeEndian | - kAudioFormatFlagIsSignedInteger; typedef CAStreamBasicDescription Desc; class AudioConverter : public FormatConverterClient { public: - AudioConverter(CAAudioHardwareDevice *dev, RageSound_CA *driver); + AudioConverter( RageSound_CA *driver, const Desc &procFormat ); ~AudioConverter() { delete mBuffer; } protected: OSStatus FormatConverterInputProc(UInt32& ioNumberDataPackets, diff --git a/stepmania/src/arch/Sound/RageSoundDriver_CA.cpp b/stepmania/src/arch/Sound/RageSoundDriver_CA.cpp index 9994af076b..49fdebbcd0 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_CA.cpp +++ b/stepmania/src/arch/Sound/RageSoundDriver_CA.cpp @@ -4,16 +4,78 @@ #include "CAAudioHardwareSystem.h" #include "CAAudioHardwareDevice.h" +#include "CAAudioHardwareStream.h" #include "CAStreamBasicDescription.h" #include "CAException.h" #include "archutils/Unix/CrashHandler.h" - +#include +#include namespace { AudioConverter *gConverter; } + +static Desc FindClosestFormat(const vector& formats) +{ + vector v; + + vector::const_iterator i; + for (i = formats.begin(); i != formats.end(); ++i) + { + const Desc& format = *i; + + if (!format.IsPCM() || format.mSampleRate != 44100.0) + continue; + + if (format.SampleWordSize() == 2 && + (format.mFormatFlags & kAudioFormatFlagIsSignedInteger) == + kAudioFormatFlagIsSignedInteger) + { // exact match + return format; + } + v.push_back(format); + } + + for (i = v.begin(); i != v.end(); ++i) + { + const Desc& format = *i; + if (format.SampleWordSize() == 2) + { + return format; // close + } + } + if (v.empty()) + RageException::ThrowNonfatal("Couldn't find a close format."); + 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; iGetStreamByIndex( kAudioDeviceSectionOutput, 0 ); + CAAudioHardwareStream stream( sID ); + + vector procFormats; + GetIOProcFormats( sID, procFormats ); + + vector physicalFormats; + GetPhysicalFormats( sID, physicalFormats ); + + const Desc& procFormat = FindClosestFormat( procFormats ); + stream.SetCurrentIOProcFormat( procFormat ); + + const Desc& physicalFormat = FindClosestFormat( physicalFormats ); + stream.SetCurrentPhysicalFormat( physicalFormat ); + + gConverter = new AudioConverter( this, procFormat ); try { @@ -45,6 +122,7 @@ RageSound_CA::RageSound_CA() } catch(const CAException& e) { + delete gConverter; RageException::Throw("Couldn't start the IOProc."); } } @@ -87,3 +165,12 @@ OSStatus RageSound_CA::GetData(AudioDeviceID inDevice, gConverter->FillComplexBuffer(dataPackets, *outOutputData, NULL); return noErr; } + +void RageSound_CA::SetupDecodingThread() +{ + /* Increase the scheduling precedence of the decoder thread. */ + thread_precedence_policy po; + po.importance = 5; + thread_policy_set( mach_thread_self(), THREAD_PRECEDENCE_POLICY, (int *)&po, THREAD_PRECEDENCE_POLICY_COUNT ); +} + diff --git a/stepmania/src/arch/Sound/RageSoundDriver_CA.h b/stepmania/src/arch/Sound/RageSoundDriver_CA.h index 77256afe74..e594f8e500 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_CA.h +++ b/stepmania/src/arch/Sound/RageSoundDriver_CA.h @@ -32,7 +32,7 @@ public: ~RageSound_CA(); float GetPlayLatency() const { return mLatency; } int64_t GetPosition(const RageSoundBase *sound) const; - //void VolumeChanged(); + void SetupDecodingThread(); }; #define RAGE_SOUND_CA