From 576ac720c6926b44f3a3dea1cdadf92b37875ee0 Mon Sep 17 00:00:00 2001 From: Steve Checkoway Date: Wed, 24 Mar 2004 16:59:17 +0000 Subject: [PATCH] Add wrapper for the CoreAudio care of Apple. --- .../PublicUtility/CAAudioHardwareDevice.cpp | 990 ++++++++++++++++++ .../PublicUtility/CAAudioHardwareDevice.h | 238 +++++ .../PublicUtility/CAAudioHardwareStream.cpp | 561 ++++++++++ .../PublicUtility/CAAudioHardwareStream.h | 121 +++ .../PublicUtility/CAAudioHardwareSystem.cpp | 264 +++++ .../PublicUtility/CAAudioHardwareSystem.h | 96 ++ .../Darwin/PublicUtility/CAException.h | 79 ++ .../archutils/Darwin/PublicUtility/CAPrefix.h | 83 ++ .../CAStreamBasicDescription.cpp | 474 +++++++++ .../PublicUtility/CAStreamBasicDescription.h | 214 ++++ 10 files changed, 3120 insertions(+) create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareDevice.cpp create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareDevice.h create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareStream.cpp create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareStream.h create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareSystem.cpp create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareSystem.h create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAException.h create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAPrefix.h create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAStreamBasicDescription.cpp create mode 100644 stepmania/src/archutils/Darwin/PublicUtility/CAStreamBasicDescription.h diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareDevice.cpp b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareDevice.cpp new file mode 100644 index 0000000000..85816895d6 --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareDevice.cpp @@ -0,0 +1,990 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAAudioHardwareDevice.cpp + +=============================================================================*/ + +//============================================================================= +// Includes +//============================================================================= + +// Self Include +#include "CAAudioHardwareDevice.h" + +// Internal Includes +#include "CAAudioHardwareStream.h" + +// PublicUtility Includes +#include "CAAutoDisposer.h" +#include "CADebugMacros.h" +#include "CAException.h" + +// System Includes +#include +#include + +// Standard Library Includes +#include + +//============================================================================= +// CAAudioHardwareDevice +//============================================================================= + +CAAudioHardwareDevice::CAAudioHardwareDevice(AudioDeviceID inAudioDeviceID) +: + mAudioDeviceID(inAudioDeviceID) +{ +} + +CAAudioHardwareDevice::~CAAudioHardwareDevice() +{ +} + +CFStringRef CAAudioHardwareDevice::CopyName() const +{ + CFStringRef theAnswer = NULL; + try + { + UInt32 theSize = sizeof(CFStringRef); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceNameCFString, theSize, &theAnswer); + } + catch(...) + { + // Sometimes a device doesn't have a name. Rather than throw an exception here + // it is better for the rest of the code if it just return an empty string. + // At some point, this should probably go back to throwing an exception. + theAnswer = CFSTR(""); + } + return theAnswer; +} + +CFStringRef CAAudioHardwareDevice::CopyManufacturer() const +{ + CFStringRef theAnswer = NULL; + UInt32 theSize = sizeof(CFStringRef); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceManufacturerCFString, theSize, &theAnswer); + return theAnswer; +} + +CFStringRef CAAudioHardwareDevice::CopyUID() const +{ + CFStringRef theAnswer = NULL; + UInt32 theSize = sizeof(CFStringRef); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceUID, theSize, &theAnswer); + return theAnswer; +} + +CFStringRef CAAudioHardwareDevice::CopyConfigurationApplicationBundleID() const +{ + CFStringRef theAnswer = NULL; + UInt32 theSize = sizeof(CFStringRef); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyConfigurationApplication, theSize, &theAnswer); + return theAnswer; +} + +UInt32 CAAudioHardwareDevice::GetTransportType() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyTransportType, theSize, &theAnswer); + return theAnswer; +} + +bool CAAudioHardwareDevice::CanBeDefaultDevice(CAAudioHardwareDeviceSectionID inSection, bool inIsSystem) const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + AudioHardwarePropertyID thePropertyID = inIsSystem ? kAudioDevicePropertyDeviceCanBeDefaultSystemDevice : kAudioDevicePropertyDeviceCanBeDefaultDevice; + GetPropertyData(0, inSection, thePropertyID, theSize, &theAnswer); + return theAnswer != 0; +} + +bool CAAudioHardwareDevice::HasDevicePlugInStatus() const +{ + return HasProperty(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyPlugIn); +} + +OSStatus CAAudioHardwareDevice::GetDevicePlugInStatus() const +{ + OSStatus theAnswer = 0; + UInt32 theSize = sizeof(OSStatus); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyPlugIn, theSize, &theAnswer); + return theAnswer; +} + +bool CAAudioHardwareDevice::IsAlive() const +{ + bool theAnswer = HasProperty(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsAlive); + if(theAnswer) + { + UInt32 isAlive = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsAlive, theSize, &isAlive); + theAnswer = isAlive != 0; + } + return theAnswer; +} + +bool CAAudioHardwareDevice::IsRunning() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsRunning, theSize, &theAnswer); + return theAnswer != 0; +} + +void CAAudioHardwareDevice::SetIsRunning(bool inIsRunning) +{ + UInt32 theValue = inIsRunning ? 1 : 0; + UInt32 theSize = sizeof(UInt32); + SetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsRunning, theSize, &theValue); +} + +bool CAAudioHardwareDevice::IsRunningSomewhere() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsRunningSomewhere, theSize, &theAnswer); + return theAnswer != 0; +} + +pid_t CAAudioHardwareDevice::GetHogModeOwner() const +{ + pid_t theAnswer = 0; + UInt32 theSize = sizeof(pid_t); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyHogMode, theSize, &theAnswer); + return theAnswer; +} + +bool CAAudioHardwareDevice::TakeHogMode() +{ + pid_t thePID = 0; + UInt32 theSize = sizeof(pid_t); + SetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyHogMode, theSize, &thePID); + return thePID == getpid(); +} + +void CAAudioHardwareDevice::ReleaseHogMode() +{ + pid_t thePID = -1; + UInt32 theSize = sizeof(pid_t); + SetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyHogMode, theSize, &thePID); +} + +bool CAAudioHardwareDevice::SupportsChangingMixability() const +{ + bool theAnswer = HasProperty(0, kAudioDeviceSectionGlobal, kAudioDevicePropertySupportsMixing); + if(theAnswer) + { + theAnswer = PropertyIsSettable(0, kAudioDeviceSectionGlobal, kAudioDevicePropertySupportsMixing); + } + return theAnswer; +} + +bool CAAudioHardwareDevice::IsMixable() const +{ + UInt32 theAnswer = 1; + if(HasProperty(0, kAudioDeviceSectionGlobal, kAudioDevicePropertySupportsMixing)) + { + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertySupportsMixing, theSize, &theAnswer); + } + return theAnswer != 0; +} + +void CAAudioHardwareDevice::SetIsMixable(bool inIsMixable) +{ + UInt32 theValue = inIsMixable ? 1 : 0; + UInt32 theSize = sizeof(UInt32); + SetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertySupportsMixing, theSize, &theValue); +} + +bool CAAudioHardwareDevice::HasIsConnectedStatus(CAAudioHardwareDeviceSectionID inSection) const +{ + return HasProperty(0, inSection, kAudioDevicePropertyJackIsConnected); +} + +bool CAAudioHardwareDevice::GetIsConnectedStatus(CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, inSection, kAudioDevicePropertyJackIsConnected, theSize, &theAnswer); + return theAnswer != 0; +} + +bool CAAudioHardwareDevice::HasPreferredStereoChannels(CAAudioHardwareDeviceSectionID inSection) const +{ + return HasProperty(0, inSection, kAudioDevicePropertyPreferredChannelsForStereo); +} + +void CAAudioHardwareDevice::GetPreferredStereoChannels(CAAudioHardwareDeviceSectionID inSection, UInt32& outLeft, UInt32& outRight) const +{ + UInt32 theStereoPair[2] = { 0, 0 }; + UInt32 theSize = 2 * sizeof(UInt32); + GetPropertyData(0, inSection, kAudioDevicePropertyPreferredChannelsForStereo, theSize, theStereoPair); + outLeft = theStereoPair[0]; + outRight = theStereoPair[1]; +} + +void CAAudioHardwareDevice::SetPreferredStereoChannels(CAAudioHardwareDeviceSectionID inSection, UInt32 inLeft, UInt32 inRight) +{ + UInt32 theStereoPair[2] = { inLeft, inRight }; + UInt32 theSize = 2 * sizeof(UInt32); + SetPropertyData(0, inSection, kAudioDevicePropertyPreferredChannelsForStereo, theSize, theStereoPair); +} + +UInt32 CAAudioHardwareDevice::GetLatency(CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, inSection, kAudioDevicePropertyLatency, theSize, &theAnswer); + return theAnswer; +} + +UInt32 CAAudioHardwareDevice::GetSafetyOffset(CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, inSection, kAudioDevicePropertySafetyOffset, theSize, &theAnswer); + return theAnswer; +} + +bool CAAudioHardwareDevice::HasClockSourceControl() const +{ + return HasProperty(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockSource); +} + +bool CAAudioHardwareDevice::ClockSourceControlIsSettable() const +{ + return PropertyIsSettable(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockSource); +} + +UInt32 CAAudioHardwareDevice::GetCurrentClockSourceID() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockSource, theSize, &theAnswer); + return theAnswer; +} + +void CAAudioHardwareDevice::SetCurrentClockSourceByID(UInt32 inID) +{ + UInt32 theSize = sizeof(UInt32); + SetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockSource, theSize, &inID); +} + +UInt32 CAAudioHardwareDevice::GetNumberAvailableClockSources() const +{ + UInt32 theAnswer = 0; + if(HasClockSourceControl()) + { + UInt32 theSize = GetPropertyDataSize(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockSources); + theAnswer = theSize / sizeof(UInt32); + } + return theAnswer; +} + +UInt32 CAAudioHardwareDevice::GetAvailableClockSourceByIndex(UInt32 inIndex) const +{ + AudioStreamID theAnswer = 0; + UInt32 theNumberSources = GetNumberAvailableClockSources(); + if((theNumberSources > 0) && (inIndex < theNumberSources)) + { + CAAutoArrayDelete theSourceList(theNumberSources); + GetAvailableClockSources(theNumberSources, theSourceList); + theAnswer = theSourceList[inIndex]; + } + return theAnswer; +} + +void CAAudioHardwareDevice::GetAvailableClockSources(UInt32& ioNumberSources, UInt32* outSources) const +{ + UInt32 theNumberSources = std::min(GetNumberAvailableClockSources(), ioNumberSources); + UInt32 theSize = theNumberSources * sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockSources, theSize, outSources); + ioNumberSources = theSize / sizeof(UInt32); + UInt32* theFirstItem = &(outSources[0]); + UInt32* theLastItem = theFirstItem + ioNumberSources; + std::sort(theFirstItem, theLastItem); +} + +CFStringRef CAAudioHardwareDevice::CopyClockSourceNameForID(UInt32 inID) const +{ + CFStringRef theAnswer = NULL; + AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(CFStringRef) }; + UInt32 theSize = sizeof(AudioValueTranslation); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockSourceNameForIDCFString, theSize, &theTranslation); + return theAnswer; +} + +bool CAAudioHardwareDevice::HasDataSourceControl(CAAudioHardwareDeviceSectionID inSection) const +{ + return HasProperty(0, inSection, kAudioDevicePropertyDataSource); +} + +bool CAAudioHardwareDevice::DataSourceControlIsSettable(CAAudioHardwareDeviceSectionID inSection) const +{ + return PropertyIsSettable(0, inSection, kAudioDevicePropertyDataSource); +} + +UInt32 CAAudioHardwareDevice::GetCurrentDataSourceID(CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, inSection, kAudioDevicePropertyDataSource, theSize, &theAnswer); + return theAnswer; +} + +void CAAudioHardwareDevice::SetCurrentDataSourceByID(CAAudioHardwareDeviceSectionID inSection, UInt32 inID) +{ + UInt32 theSize = sizeof(UInt32); + SetPropertyData(0, inSection, kAudioDevicePropertyDataSource, theSize, &inID); +} + +UInt32 CAAudioHardwareDevice::GetNumberAvailableDataSources(CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theAnswer = 0; + if(HasDataSourceControl(inSection)) + { + UInt32 theSize = GetPropertyDataSize(0, inSection, kAudioDevicePropertyDataSources); + theAnswer = theSize / sizeof(UInt32); + } + return theAnswer; +} + +UInt32 CAAudioHardwareDevice::GetAvailableDataSourceByIndex(CAAudioHardwareDeviceSectionID inSection, UInt32 inIndex) const +{ + AudioStreamID theAnswer = 0; + UInt32 theNumberSources = GetNumberAvailableDataSources(inSection); + if((theNumberSources > 0) && (inIndex < theNumberSources)) + { + CAAutoArrayDelete theSourceList(theNumberSources); + GetAvailableDataSources(inSection, theNumberSources, theSourceList); + theAnswer = theSourceList[inIndex]; + } + return theAnswer; +} + +void CAAudioHardwareDevice::GetAvailableDataSources(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberSources, UInt32* outSources) const +{ + UInt32 theNumberSources = std::min(GetNumberAvailableDataSources(inSection), ioNumberSources); + UInt32 theSize = theNumberSources * sizeof(UInt32); + GetPropertyData(0, inSection, kAudioDevicePropertyDataSources, theSize, outSources); + ioNumberSources = theSize / sizeof(UInt32); + UInt32* theFirstItem = &(outSources[0]); + UInt32* theLastItem = theFirstItem + ioNumberSources; + std::sort(theFirstItem, theLastItem); +} + +CFStringRef CAAudioHardwareDevice::CopyDataSourceNameForID(CAAudioHardwareDeviceSectionID inSection, UInt32 inID) const +{ + CFStringRef theAnswer = NULL; + AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(CFStringRef) }; + UInt32 theSize = sizeof(AudioValueTranslation); + GetPropertyData(0, inSection, kAudioDevicePropertyDataSourceNameForIDCFString, theSize, &theTranslation); + return theAnswer; +} + +Float64 CAAudioHardwareDevice::GetActualSampleRate() const +{ + Float64 theAnswer = 0; + UInt32 theSize = sizeof(Float64); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyActualSampleRate, theSize, &theAnswer); + return theAnswer; +} + +Float64 CAAudioHardwareDevice::GetNominalSampleRate() const +{ + Float64 theAnswer = 0; + UInt32 theSize = sizeof(Float64); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, theSize, &theAnswer); + return theAnswer; +} + +void CAAudioHardwareDevice::SetNominalSampleRate(Float64 inSampleRate) +{ + UInt32 theSize = sizeof(Float64); + SetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, theSize, &inSampleRate); +} + +bool CAAudioHardwareDevice::IsValidNominalSampleRate(Float64 inSampleRate) const +{ + bool theAnswer = false; + UInt32 theNumberRanges = GetNumberNominalSampleRateRanges(); + CAAutoArrayDelete theRanges(theNumberRanges); + GetNominalSampleRateRanges(theNumberRanges, theRanges); + for(UInt32 theIndex = 0; !theAnswer && (theIndex < theNumberRanges); ++theIndex) + { + theAnswer = (inSampleRate >= theRanges[theIndex].mMinimum) && (inSampleRate <= theRanges[theIndex].mMinimum); + } + return theAnswer; +} + +UInt32 CAAudioHardwareDevice::GetNumberNominalSampleRateRanges() const +{ + UInt32 theSize = GetPropertyDataSize(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyAvailableNominalSampleRates); + return theSize / sizeof(AudioValueRange); +} + +void CAAudioHardwareDevice::GetNominalSampleRateRanges(UInt32& ioNumberRanges, AudioValueRange* outRanges) const +{ + UInt32 theSize = ioNumberRanges * sizeof(AudioValueRange); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyAvailableNominalSampleRates, theSize, outRanges); + ioNumberRanges = theSize / sizeof(AudioValueRange); +} + +void CAAudioHardwareDevice::GetNominalSampleRateRangeByIndex(UInt32 inIndex, Float64& outMinimum, Float64& outMaximum) const +{ + UInt32 theNumberRanges = GetNumberNominalSampleRateRanges(); + ThrowIf(inIndex >= theNumberRanges, CAException(kAudioHardwareIllegalOperationError), "CAAudioHardwareDevice::GetNominalSampleRateRangeByIndex: index out of range"); + CAAutoArrayDelete theRanges(theNumberRanges); + GetNominalSampleRateRanges(theNumberRanges, theRanges); + outMinimum = theRanges[inIndex].mMinimum; + outMaximum = theRanges[inIndex].mMaximum; +} + +UInt32 CAAudioHardwareDevice::GetIOBufferSize() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, theSize, &theAnswer); + return theAnswer; +} + +void CAAudioHardwareDevice::SetIOBufferSize(UInt32 inBufferSize) +{ + UInt32 theSize = sizeof(UInt32); + SetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, theSize, &inBufferSize); +} + +bool CAAudioHardwareDevice::UsesVariableIOBufferSizes() const +{ + return HasProperty(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyUsesVariableBufferFrameSizes); +} + +UInt32 CAAudioHardwareDevice::GetMaximumVariableIOBufferSize() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyUsesVariableBufferFrameSizes, theSize, &theAnswer); + return theAnswer; +} + +void CAAudioHardwareDevice::GetIOBufferSizeRange(UInt32& outMinimum, UInt32& outMaximum) const +{ + AudioValueRange theAnswer = { 0, 0 }; + UInt32 theSize = sizeof(AudioValueRange); + GetPropertyData(0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSizeRange, theSize, &theAnswer); + outMinimum = static_cast(theAnswer.mMinimum); + outMaximum = static_cast(theAnswer.mMaximum); +} + +void CAAudioHardwareDevice::AddIOProc(AudioDeviceIOProc inIOProc, void* inClientData) +{ + OSStatus theError = AudioDeviceAddIOProc(mAudioDeviceID, inIOProc, inClientData); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::AddIOProc: got an error adding an IOProc"); +} + +void CAAudioHardwareDevice::RemoveIOProc(AudioDeviceIOProc inIOProc) +{ + OSStatus theError = AudioDeviceRemoveIOProc(mAudioDeviceID, inIOProc); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::RemoveIOProc: got an error removing an IOProc"); +} + +void CAAudioHardwareDevice::StartIOProc(AudioDeviceIOProc inIOProc) +{ + OSStatus theError = AudioDeviceStart(mAudioDeviceID, inIOProc); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::StartIOProc: got an error starting an IOProc"); +} + +void CAAudioHardwareDevice::StartIOProcAtTime(AudioDeviceIOProc inIOProc, AudioTimeStamp& ioStartTime, bool inIsInput, bool inIgnoreHardware) +{ + UInt32 theFlags = 0; + if(inIsInput) + { + theFlags |= kAudioDeviceStartTimeIsInputFlag; + } + if(inIgnoreHardware) + { + theFlags |= kAudioDeviceStartTimeDontConsultDeviceFlag; + } + + OSStatus theError = AudioDeviceStartAtTime(mAudioDeviceID, inIOProc, &ioStartTime, theFlags); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::StartIOProcAtTime: got an error starting an IOProc"); +} + +void CAAudioHardwareDevice::StopIOProc(AudioDeviceIOProc inIOProc) +{ + OSStatus theError = AudioDeviceStop(mAudioDeviceID, inIOProc); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::StopIOProc: got an error stopping an IOProc"); +} + +void CAAudioHardwareDevice::GetIOProcStreamUsage(AudioDeviceIOProc inIOProc, CAAudioHardwareDeviceSectionID inSection, bool* outStreamUsage) const +{ + // make an AudioHardwareIOProcStreamUsage the right size + UInt32 theNumberStreams = GetNumberStreams(inSection); + UInt32 theSize = sizeof(void*) + sizeof(UInt32) + (theNumberStreams * sizeof(UInt32)); + CAAutoFree theStreamUsage(theSize); + + // set it up + theStreamUsage->mIOProc = (void*)inIOProc; + theStreamUsage->mNumberStreams = theNumberStreams; + + // get the property + GetPropertyData(0, inSection, kAudioDevicePropertyIOProcStreamUsage, theSize, theStreamUsage); + + // fill out the return value + for(UInt32 theIndex = 0; theIndex < theNumberStreams; ++theIndex) + { + outStreamUsage[theIndex] = (theStreamUsage->mStreamIsOn[theIndex] != 0); + } +} + +void CAAudioHardwareDevice::SetIOProcStreamUsage(AudioDeviceIOProc inIOProc, CAAudioHardwareDeviceSectionID inSection, const bool* inStreamUsage) +{ + // make an AudioHardwareIOProcStreamUsage the right size + UInt32 theNumberStreams = GetNumberStreams(inSection); + UInt32 theSize = sizeof(void*) + sizeof(UInt32) + (theNumberStreams * sizeof(UInt32)); + CAAutoFree theStreamUsage(theSize); + + // set it up + theStreamUsage->mIOProc = (void*)inIOProc; + theStreamUsage->mNumberStreams = theNumberStreams; + for(UInt32 theIndex = 0; theIndex < theNumberStreams; ++theIndex) + { + theStreamUsage->mStreamIsOn[theIndex] = (inStreamUsage[theIndex] ? 1 : 0); + } + + // set the property + SetPropertyData(0, inSection, kAudioDevicePropertyIOProcStreamUsage, theSize, theStreamUsage); +} + +void CAAudioHardwareDevice::GetCurrentTime(AudioTimeStamp& outTime) +{ + OSStatus theError = AudioDeviceGetCurrentTime(mAudioDeviceID, &outTime); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::GetCurrentTime: got an error retrieving the current time"); +} + +void CAAudioHardwareDevice::TranslateTime(const AudioTimeStamp& inTime, AudioTimeStamp& outTime) +{ + OSStatus theError = AudioDeviceTranslateTime(mAudioDeviceID, &inTime, &outTime); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::TranslateTime: got an error translating time"); +} + +void CAAudioHardwareDevice::GetNearestStartTime(AudioTimeStamp& ioTime, bool inIsInput, bool inIgnoreHardware) +{ + UInt32 theFlags = 0; + if(inIsInput) + { + theFlags |= kAudioDeviceStartTimeIsInputFlag; + } + if(inIgnoreHardware) + { + theFlags |= kAudioDeviceStartTimeDontConsultDeviceFlag; + } + + OSStatus theError = AudioDeviceGetNearestStartTime(mAudioDeviceID, &ioTime, theFlags); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::GetNearestStartTime: got an error getting the nearest start time"); +} + +UInt32 CAAudioHardwareDevice::GetNumberStreams(CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theSize = GetPropertyDataSize(0, inSection, kAudioDevicePropertyStreams); + return theSize / sizeof(AudioStreamID); +} + +void CAAudioHardwareDevice::GetStreams(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberStreams, AudioStreamID* outStreamList) const +{ + ioNumberStreams = std::min(GetNumberStreams(inSection), ioNumberStreams); + UInt32 theSize = ioNumberStreams * sizeof(AudioStreamID); + GetPropertyData(0, inSection, kAudioDevicePropertyStreams, theSize, outStreamList); + ioNumberStreams = theSize / sizeof(AudioStreamID); + AudioStreamID* theFirstItem = &(outStreamList[0]); + AudioStreamID* theLastItem = theFirstItem + ioNumberStreams; + std::sort(theFirstItem, theLastItem); +} + +AudioStreamID CAAudioHardwareDevice::GetStreamByIndex(CAAudioHardwareDeviceSectionID inSection, UInt32 inIndex) const +{ + AudioStreamID theAnswer = 0; + UInt32 theNumberStreams = GetNumberStreams(inSection); + if((theNumberStreams > 0) && (inIndex < theNumberStreams)) + { + CAAutoArrayDelete theStreamList(theNumberStreams); + GetStreams(inSection, theNumberStreams, theStreamList); + theAnswer = theStreamList[inIndex]; + } + return theAnswer; +} + +UInt32 CAAudioHardwareDevice::GetTotalNumberChannels(CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theAnswer = 0; + UInt32 theSize = GetPropertyDataSize(0, inSection, kAudioDevicePropertyStreamConfiguration); + CAAutoFree theBufferList(theSize); + GetPropertyData(0, inSection, kAudioDevicePropertyStreamConfiguration, theSize, theBufferList); + for(UInt32 theIndex = 0; theIndex < theBufferList->mNumberBuffers; ++theIndex) + { + theAnswer += theBufferList->mBuffers[theIndex].mNumberChannels; + } + return theAnswer; +} + +void CAAudioHardwareDevice::GetCurrentIOProcFormats(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const +{ + ioNumberStreams = std::min(ioNumberStreams, GetNumberStreams(inSection)); + for(UInt32 theIndex = 0; theIndex < ioNumberStreams; ++theIndex) + { + CAAudioHardwareStream theStream(GetStreamByIndex(inSection, theIndex)); + theStream.GetCurrentIOProcFormat(outFormats[theIndex]); + } +} + +void CAAudioHardwareDevice::GetCurrentPhysicalFormats(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const +{ + ioNumberStreams = std::min(ioNumberStreams, GetNumberStreams(inSection)); + for(UInt32 theIndex = 0; theIndex < ioNumberStreams; ++theIndex) + { + CAAudioHardwareStream theStream(GetStreamByIndex(inSection, theIndex)); + theStream.GetCurrentPhysicalFormat(outFormats[theIndex]); + } +} + +bool CAAudioHardwareDevice::HasVolumeControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return HasProperty(inChannel, inSection, kAudioDevicePropertyVolumeScalar); +} + +bool CAAudioHardwareDevice::VolumeControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return PropertyIsSettable(inChannel, inSection, kAudioDevicePropertyVolumeScalar); +} + +Float32 CAAudioHardwareDevice::GetVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + Float32 theValue = 0.0; + UInt32 theSize = sizeof(Float32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertyVolumeScalar, theSize, &theValue); + return theValue; +} + +Float32 CAAudioHardwareDevice::GetVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + Float32 theValue = 0.0; + UInt32 theSize = sizeof(Float32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertyVolumeDecibels, theSize, &theValue); + return theValue; +} + +void CAAudioHardwareDevice::SetVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) +{ + UInt32 theSize = sizeof(Float32); + SetPropertyData(inChannel, inSection, kAudioDevicePropertyVolumeScalar, theSize, &inValue); +} + +void CAAudioHardwareDevice::SetVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) +{ + UInt32 theSize = sizeof(Float32); + SetPropertyData(inChannel, inSection, kAudioDevicePropertyVolumeDecibels, theSize, &inValue); +} + +Float32 CAAudioHardwareDevice::GetVolumeControlScalarForDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const +{ + Float32 theValue = inValue; + UInt32 theSize = sizeof(Float32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertyVolumeDecibelsToScalar, theSize, &theValue); + return theValue; +} + +Float32 CAAudioHardwareDevice::GetVolumeControlDecibelForScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const +{ + Float32 theValue = inValue; + UInt32 theSize = sizeof(Float32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertyVolumeScalarToDecibels, theSize, &theValue); + return theValue; +} + +bool CAAudioHardwareDevice::HasMuteControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return HasProperty(inChannel, inSection, kAudioDevicePropertyMute); +} + +bool CAAudioHardwareDevice::MuteControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return PropertyIsSettable(inChannel, inSection, kAudioDevicePropertyMute); +} + +bool CAAudioHardwareDevice::GetMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theValue = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertyMute, theSize, &theValue); + return theValue != 0; +} + +void CAAudioHardwareDevice::SetMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, bool inValue) +{ + UInt32 theValue = (inValue ? 1 : 0); + UInt32 theSize = sizeof(UInt32); + SetPropertyData(inChannel, inSection, kAudioDevicePropertyMute, theSize, &theValue); +} + +bool CAAudioHardwareDevice::HasPlayThruControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return HasProperty(inChannel, inSection, kAudioDevicePropertyPlayThru); +} + +bool CAAudioHardwareDevice::PlayThruControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return PropertyIsSettable(inChannel, inSection, kAudioDevicePropertyPlayThru); +} + +bool CAAudioHardwareDevice::GetPlayThruControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theValue = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertyPlayThru, theSize, &theValue); + return theValue != 0; +} + +void CAAudioHardwareDevice::SetPlayThruControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, bool inValue) +{ + UInt32 theValue = (inValue ? 1 : 0); + UInt32 theSize = sizeof(UInt32); + SetPropertyData(inChannel, inSection, kAudioDevicePropertyPlayThru, theSize, &theValue); +} + +bool CAAudioHardwareDevice::HasISubOwnershipControl() const +{ + return HasProperty(0, kAudioDeviceSectionOutput, kAudioDevicePropertyDriverShouldOwniSub); +} + +bool CAAudioHardwareDevice::ISubOwnershipControlIsSettable() const +{ + return PropertyIsSettable(0, kAudioDeviceSectionOutput, kAudioDevicePropertyDriverShouldOwniSub); +} + +bool CAAudioHardwareDevice::GetISubOwnershipControlValue() const +{ + UInt32 theValue = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDeviceSectionOutput, kAudioDevicePropertyDriverShouldOwniSub, theSize, &theValue); + return theValue != 0; +} + +void CAAudioHardwareDevice::SetISubOwnershipControlValue(bool inValue) +{ + UInt32 theValue = (inValue ? 1 : 0); + UInt32 theSize = sizeof(UInt32); + SetPropertyData(0, kAudioDeviceSectionOutput, kAudioDevicePropertyDriverShouldOwniSub, theSize, &theValue); +} + +bool CAAudioHardwareDevice::HasSubMuteControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return HasProperty(inChannel, inSection, kAudioDevicePropertySubMute); +} + +bool CAAudioHardwareDevice::SubMuteControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return PropertyIsSettable(inChannel, inSection, kAudioDevicePropertySubMute); +} + +bool CAAudioHardwareDevice::GetSubMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + UInt32 theValue = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertySubMute, theSize, &theValue); + return theValue != 0; +} + +void CAAudioHardwareDevice::SetSubMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, bool inValue) +{ + UInt32 theValue = (inValue ? 1 : 0); + UInt32 theSize = sizeof(UInt32); + SetPropertyData(inChannel, inSection, kAudioDevicePropertySubMute, theSize, &theValue); +} + +bool CAAudioHardwareDevice::HasSubVolumeControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return HasProperty(inChannel, inSection, kAudioDevicePropertySubVolumeScalar); +} + +bool CAAudioHardwareDevice::SubVolumeControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + return PropertyIsSettable(inChannel, inSection, kAudioDevicePropertySubVolumeScalar); +} + +Float32 CAAudioHardwareDevice::GetSubVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + Float32 theValue = 0.0; + UInt32 theSize = sizeof(Float32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertySubVolumeScalar, theSize, &theValue); + return theValue; +} + +Float32 CAAudioHardwareDevice::GetSubVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const +{ + Float32 theValue = 0.0; + UInt32 theSize = sizeof(Float32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertySubVolumeDecibels, theSize, &theValue); + return theValue; +} + +void CAAudioHardwareDevice::SetSubVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) +{ + UInt32 theSize = sizeof(Float32); + SetPropertyData(inChannel, inSection, kAudioDevicePropertySubVolumeScalar, theSize, &inValue); +} + +void CAAudioHardwareDevice::SetSubVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) +{ + UInt32 theSize = sizeof(Float32); + SetPropertyData(inChannel, inSection, kAudioDevicePropertySubVolumeDecibels, theSize, &inValue); +} + +Float32 CAAudioHardwareDevice::GetSubVolumeControlScalarForDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const +{ + Float32 theValue = inValue; + UInt32 theSize = sizeof(Float32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertySubVolumeDecibelsToScalar, theSize, &theValue); + return theValue; +} + +Float32 CAAudioHardwareDevice::GetSubVolumeControlDecibelForScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const +{ + Float32 theValue = inValue; + UInt32 theSize = sizeof(Float32); + GetPropertyData(inChannel, inSection, kAudioDevicePropertySubVolumeScalarToDecibels, theSize, &theValue); + return theValue; +} + +bool CAAudioHardwareDevice::HasProperty(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID) const +{ + OSStatus theError = AudioDeviceGetPropertyInfo(mAudioDeviceID, inChannel, inSection, inPropertyID, NULL, NULL); + return theError == 0; +} + +bool CAAudioHardwareDevice::PropertyIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID) const +{ + Boolean isWritable = false; + OSStatus theError = AudioDeviceGetPropertyInfo(mAudioDeviceID, inChannel, inSection, inPropertyID, NULL, &isWritable); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::PropertyIsSettable: got an error getting info about a property"); + return isWritable != 0; +} + +UInt32 CAAudioHardwareDevice::GetPropertyDataSize(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID) const +{ + UInt32 theSize = 0; + OSStatus theError = AudioDeviceGetPropertyInfo(mAudioDeviceID, inChannel, inSection, inPropertyID, &theSize, NULL); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::GetPropertyDataSize: got an error getting info about a property"); + return theSize; +} + +void CAAudioHardwareDevice::GetPropertyData(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, UInt32& ioDataSize, void* outData) const +{ + OSStatus theError = AudioDeviceGetProperty(mAudioDeviceID, inChannel, inSection, inPropertyID, &ioDataSize, outData); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::GetPropertyData: got an error getting the value of a property"); +} + +void CAAudioHardwareDevice::SetPropertyData(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, UInt32 inDataSize, const void* inData, const AudioTimeStamp* inWhen) +{ + OSStatus theError = AudioDeviceSetProperty(mAudioDeviceID, inWhen, inChannel, inSection, inPropertyID, inDataSize, inData); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::SetPropertyData: got an error setting the value of a property"); +} + +void CAAudioHardwareDevice::AddPropertyListener(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, AudioDevicePropertyListenerProc inListenerProc, void* inClientData) +{ + OSStatus theError = AudioDeviceAddPropertyListener(mAudioDeviceID, inChannel, inSection, inPropertyID, inListenerProc, inClientData); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::AddPropertyListener: got an error adding a property listener"); +} + +void CAAudioHardwareDevice::RemovePropertyListener(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, AudioDevicePropertyListenerProc inListenerProc) +{ + OSStatus theError = AudioDeviceRemovePropertyListener(mAudioDeviceID, inChannel, inSection, inPropertyID, inListenerProc); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareDevice::RemovePropertyListener: got an error removing a property listener"); +} + +void CAAudioHardwareDevice::GetNameForTransportType(UInt32 inTransportType, char* outName) +{ + switch(inTransportType) + { + case 0: + strcpy(outName, "Unknown"); + break; + + case kIOAudioDeviceTransportTypeBuiltIn: + strcpy(outName, "Built-In"); + break; + + case kIOAudioDeviceTransportTypePCI: + strcpy(outName, "PCI"); + break; + + case kIOAudioDeviceTransportTypeUSB: + strcpy(outName, "USB"); + break; + + case kIOAudioDeviceTransportTypeFireWire: + strcpy(outName, "FireWire"); + break; + + case kIOAudioDeviceTransportTypeNetwork: + strcpy(outName, "Network"); + break; + + case kIOAudioDeviceTransportTypeWireless: + strcpy(outName, "Wireless"); + break; + + case kIOAudioDeviceTransportTypeOther: + strcpy(outName, "Other"); + break; + + default: + { + char* the4CC = (char*)&inTransportType; + outName[0] = the4CC[0]; + outName[1] = the4CC[1]; + outName[2] = the4CC[2]; + outName[3] = the4CC[3]; + outName[4] = 0; + } + break; + }; +} diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareDevice.h b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareDevice.h new file mode 100644 index 0000000000..4890e87817 --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareDevice.h @@ -0,0 +1,238 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAAudioHardwareDevice.h + +=============================================================================*/ +#if !defined(__CAAudioHardwareDevice_h__) +#define __CAAudioHardwareDevice_h__ + +//============================================================================= +// Includes +//============================================================================= + +// System Includes +#include +#include +#include + +//============================================================================= +// Types +//============================================================================= + +typedef UInt8 CAAudioHardwareDeviceSectionID; +#define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01) +#define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) +#define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) +#define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) + +//============================================================================= +// CAAudioHardwareDevice +//============================================================================= + +class CAAudioHardwareDevice +{ + +// Construction/Destruction +public: + CAAudioHardwareDevice(AudioDeviceID inAudioDeviceID); + ~CAAudioHardwareDevice(); + +// General Operations +public: + AudioDeviceID GetAudioDeviceID() const { return mAudioDeviceID; } + CFStringRef CopyName() const; + CFStringRef CopyManufacturer() const; + CFStringRef CopyUID() const; + CFStringRef CopyConfigurationApplicationBundleID() const; + UInt32 GetTransportType() const; + bool CanBeDefaultDevice(CAAudioHardwareDeviceSectionID inSection, bool inIsSystem = false) const; + + bool HasDevicePlugInStatus() const; + OSStatus GetDevicePlugInStatus() const; + + bool IsAlive() const; + bool IsRunning() const; + void SetIsRunning(bool inIsRunning); + bool IsRunningSomewhere() const; + + pid_t GetHogModeOwner() const; + bool TakeHogMode(); + void ReleaseHogMode(); + + bool SupportsChangingMixability() const; + bool IsMixable() const; + void SetIsMixable(bool inIsMixable); + + bool HasIsConnectedStatus(CAAudioHardwareDeviceSectionID inSection) const; + bool GetIsConnectedStatus(CAAudioHardwareDeviceSectionID inSection) const; + + bool HasPreferredStereoChannels(CAAudioHardwareDeviceSectionID inSection) const; + void GetPreferredStereoChannels(CAAudioHardwareDeviceSectionID inSection, UInt32& outLeft, UInt32& outRight) const; + void SetPreferredStereoChannels(CAAudioHardwareDeviceSectionID inSection, UInt32 inLeft, UInt32 inRight); + +// IO Operations +public: + UInt32 GetLatency(CAAudioHardwareDeviceSectionID inSection) const; + UInt32 GetSafetyOffset(CAAudioHardwareDeviceSectionID inSection) const; + + bool HasClockSourceControl() const; + bool ClockSourceControlIsSettable() const; + UInt32 GetCurrentClockSourceID() const; + void SetCurrentClockSourceByID(UInt32 inID); + UInt32 GetNumberAvailableClockSources() const; + UInt32 GetAvailableClockSourceByIndex(UInt32 inIndex) const; + void GetAvailableClockSources(UInt32& ioNumberSources, UInt32* outSources) const; + CFStringRef CopyClockSourceNameForID(UInt32 inID) const; + + bool HasDataSourceControl(CAAudioHardwareDeviceSectionID inSection) const; + bool DataSourceControlIsSettable(CAAudioHardwareDeviceSectionID inSection) const; + UInt32 GetCurrentDataSourceID(CAAudioHardwareDeviceSectionID inSection) const; + void SetCurrentDataSourceByID(CAAudioHardwareDeviceSectionID inSection, UInt32 inID); + UInt32 GetNumberAvailableDataSources(CAAudioHardwareDeviceSectionID inSection) const; + UInt32 GetAvailableDataSourceByIndex(CAAudioHardwareDeviceSectionID inSection, UInt32 inIndex) const; + void GetAvailableDataSources(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberSources, UInt32* outSources) const; + CFStringRef CopyDataSourceNameForID(CAAudioHardwareDeviceSectionID inSection, UInt32 inID) const; + + Float64 GetActualSampleRate() const; + Float64 GetNominalSampleRate() const; + void SetNominalSampleRate(Float64 inSampleRate); + bool IsValidNominalSampleRate(Float64 inSampleRate) const; + UInt32 GetNumberNominalSampleRateRanges() const; + void GetNominalSampleRateRanges(UInt32& ioNumberRanges, AudioValueRange* outRanges) const; + void GetNominalSampleRateRangeByIndex(UInt32 inIndex, Float64& outMinimum, Float64& outMaximum) const; + + UInt32 GetIOBufferSize() const; + void SetIOBufferSize(UInt32 inBufferSize); + bool UsesVariableIOBufferSizes() const; + UInt32 GetMaximumVariableIOBufferSize() const; + void GetIOBufferSizeRange(UInt32& outMinimum, UInt32& outMaximum) const; + + void AddIOProc(AudioDeviceIOProc inIOProc, void* inClientData); + void RemoveIOProc(AudioDeviceIOProc inIOProc); + + void StartIOProc(AudioDeviceIOProc inIOProc); + void StartIOProcAtTime(AudioDeviceIOProc inIOProc, AudioTimeStamp& ioStartTime, bool inIsInput, bool inIgnoreHardware); + void StopIOProc(AudioDeviceIOProc inIOProc); + + void GetIOProcStreamUsage(AudioDeviceIOProc inIOProc, CAAudioHardwareDeviceSectionID inSection, bool* outStreamUsage) const; + void SetIOProcStreamUsage(AudioDeviceIOProc inIOProc, CAAudioHardwareDeviceSectionID inSection, const bool* inStreamUsage); + +// Time Operations +public: + void GetCurrentTime(AudioTimeStamp& outTime); + void TranslateTime(const AudioTimeStamp& inTime, AudioTimeStamp& outTime); + void GetNearestStartTime(AudioTimeStamp& ioTime, bool inIsInput, bool inIgnoreHardware); + +// Stream Operations +public: + UInt32 GetNumberStreams(CAAudioHardwareDeviceSectionID inSection) const; + void GetStreams(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberStreams, AudioStreamID* outStreamList) const; + AudioStreamID GetStreamByIndex(CAAudioHardwareDeviceSectionID inSection, UInt32 inIndex) const; + + bool HasSection(CAAudioHardwareDeviceSectionID inSection) const { return GetNumberStreams(inSection) > 0; } + UInt32 GetTotalNumberChannels(CAAudioHardwareDeviceSectionID inSection) const; + +// Format Operations +public: + void GetCurrentIOProcFormats(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const; + void GetCurrentPhysicalFormats(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const; + +// Control Operations +public: + bool HasVolumeControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + bool VolumeControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + Float32 GetVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + Float32 GetVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + void SetVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue); + void SetVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue); + Float32 GetVolumeControlScalarForDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const; + Float32 GetVolumeControlDecibelForScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const; + + bool HasMuteControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + bool MuteControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + bool GetMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + void SetMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, bool inValue); + + bool HasPlayThruControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + bool PlayThruControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + bool GetPlayThruControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + void SetPlayThruControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, bool inValue); + + bool HasISubOwnershipControl() const; + bool ISubOwnershipControlIsSettable() const; + bool GetISubOwnershipControlValue() const; + void SetISubOwnershipControlValue(bool inValue); + + bool HasSubMuteControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + bool SubMuteControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + bool GetSubMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + void SetSubMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, bool inValue); + + bool HasSubVolumeControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + bool SubVolumeControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + Float32 GetSubVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + Float32 GetSubVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const; + void SetSubVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue); + void SetSubVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue); + Float32 GetSubVolumeControlScalarForDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const; + Float32 GetSubVolumeControlDecibelForScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const; + +// Property Operations +public: + bool HasProperty(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID) const; + bool PropertyIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID) const; + + UInt32 GetPropertyDataSize(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID) const; + void GetPropertyData(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, UInt32& ioDataSize, void* outData) const; + void SetPropertyData(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, UInt32 inDataSize, const void* inData, const AudioTimeStamp* inWhen = NULL); + + void AddPropertyListener(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, AudioDevicePropertyListenerProc inListenerProc, void* inClientData); + void RemovePropertyListener(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, AudioDevicePropertyListenerProc inListenerProc); + +// Utility Operations +public: + static void GetNameForTransportType(UInt32 inTransportType, char* outName); + +// Implementation +private: + AudioDeviceID mAudioDeviceID; + +}; + +#endif diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareStream.cpp b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareStream.cpp new file mode 100644 index 0000000000..4655e35b5d --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareStream.cpp @@ -0,0 +1,561 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAAudioHardwareStream.cpp + +=============================================================================*/ + +//============================================================================= +// Includes +//============================================================================= + +// Self Include +#include "CAAudioHardwareStream.h" + +// PublicUtility Includes +#include "CAAutoDisposer.h" +#include "CADebugMacros.h" +#include "CAException.h" + +// System Includes +#include +#include + +//============================================================================= +// CAAudioHardwareStream +//============================================================================= + +CAAudioHardwareStream::CAAudioHardwareStream(AudioStreamID inAudioStreamID) +: + mAudioStreamID(inAudioStreamID) +{ +} + +CAAudioHardwareStream::~CAAudioHardwareStream() +{ +} + +CFStringRef CAAudioHardwareStream::CopyName() const +{ + CFStringRef theAnswer = NULL; + UInt32 theSize = sizeof(CFStringRef); + GetPropertyData(0, kAudioDevicePropertyDeviceNameCFString, theSize, &theAnswer); + return theAnswer; +} + +AudioDeviceID CAAudioHardwareStream::GetOwningDevice() const +{ + AudioDeviceID theAnswer = 0; + UInt32 theSize = sizeof(AudioDeviceID); + GetPropertyData(0, kAudioStreamPropertyOwningDevice, theSize, &theAnswer); + return theAnswer; +} + +CAAudioHardwareDeviceSectionID CAAudioHardwareStream::GetSection() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioStreamPropertyDirection, theSize, &theAnswer); + return (theAnswer == 0) ? kAudioDeviceSectionOutput : kAudioDeviceSectionInput; +} + +UInt32 CAAudioHardwareStream::GetTerminalType() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioStreamPropertyTerminalType, theSize, &theAnswer); + return theAnswer; +} + +UInt32 CAAudioHardwareStream::GetStartingDeviceChannel() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioStreamPropertyStartingChannel, theSize, &theAnswer); + return theAnswer; +} + +bool CAAudioHardwareStream::HasIsConnectedStatus() const +{ + return HasProperty(0, kAudioDevicePropertyJackIsConnected); +} + +bool CAAudioHardwareStream::GetIsConnectedStatus() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDevicePropertyJackIsConnected, theSize, &theAnswer); + return theAnswer != 0; +} + +bool CAAudioHardwareStream::HasDataSourceControl() const +{ + return HasProperty(0, kAudioDevicePropertyDataSource); +} + +bool CAAudioHardwareStream::DataSourceControlIsSettable() const +{ + return PropertyIsSettable(0, kAudioDevicePropertyDataSource); +} + +UInt32 CAAudioHardwareStream::GetCurrentDataSourceID() const +{ + UInt32 theAnswer = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(0, kAudioDevicePropertyDataSource, theSize, &theAnswer); + return theAnswer; +} + +void CAAudioHardwareStream::SetCurrentDataSourceByID(UInt32 inID) +{ + UInt32 theSize = sizeof(UInt32); + SetPropertyData(0, kAudioDevicePropertyDataSource, theSize, &inID); +} + +UInt32 CAAudioHardwareStream::GetNumberAvailableDataSources() const +{ + UInt32 theAnswer = 0; + if(HasDataSourceControl()) + { + UInt32 theSize = GetPropertyDataSize(0, kAudioDevicePropertyDataSources); + theAnswer = theSize / sizeof(UInt32); + } + return theAnswer; +} + +UInt32 CAAudioHardwareStream::GetAvailableDataSourceByIndex(UInt32 inIndex) const +{ + AudioStreamID theAnswer = 0; + UInt32 theNumberSources = GetNumberAvailableDataSources(); + if((theNumberSources > 0) && (inIndex < theNumberSources)) + { + CAAutoArrayDelete theSourceList(theNumberSources); + GetAvailableDataSources(theNumberSources, theSourceList); + theAnswer = theSourceList[inIndex]; + } + return theAnswer; +} + +void CAAudioHardwareStream::GetAvailableDataSources(UInt32& ioNumberSources, UInt32* outSources) const +{ + UInt32 theNumberSources = std::min(GetNumberAvailableDataSources(), ioNumberSources); + UInt32 theSize = theNumberSources * sizeof(UInt32); + GetPropertyData(0, kAudioDevicePropertyDataSources, theSize, outSources); + ioNumberSources = theSize / sizeof(UInt32); + UInt32* theFirstItem = &(outSources[0]); + UInt32* theLastItem = theFirstItem + ioNumberSources; + std::sort(theFirstItem, theLastItem); +} + +CFStringRef CAAudioHardwareStream::CopyDataSourceNameForID(UInt32 inID) const +{ + CFStringRef theAnswer = NULL; + AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(CFStringRef) }; + UInt32 theSize = sizeof(AudioValueTranslation); + GetPropertyData(0, kAudioDevicePropertyDataSourceNameForIDCFString, theSize, &theTranslation); + return theAnswer; +} + +void CAAudioHardwareStream::GetCurrentIOProcFormat(AudioStreamBasicDescription& outFormat) const +{ + memset(&outFormat, 0, sizeof(AudioStreamBasicDescription)); + UInt32 theSize = sizeof(AudioStreamBasicDescription); + GetPropertyData(0, kAudioDevicePropertyStreamFormat, theSize, &outFormat); +} + +void CAAudioHardwareStream::SetCurrentIOProcFormat(const AudioStreamBasicDescription& inFormat) +{ + UInt32 theSize = sizeof(AudioStreamBasicDescription); + SetPropertyData(0, kAudioDevicePropertyStreamFormat, theSize, &inFormat); +} + +UInt32 CAAudioHardwareStream::GetNumberAvailableIOProcFormats() const +{ + UInt32 theAnswer = GetPropertyDataSize(0, kAudioDevicePropertyStreamFormats); + theAnswer /= sizeof(AudioStreamBasicDescription); + return theAnswer; +} + +void CAAudioHardwareStream::GetAvailableIOProcFormats(UInt32& ioNumberFormats, AudioStreamBasicDescription* outFormats) const +{ + UInt32 theSize = ioNumberFormats * sizeof(AudioStreamBasicDescription); + GetPropertyData(0, kAudioDevicePropertyStreamFormats, theSize, outFormats); + ioNumberFormats = theSize / sizeof(AudioStreamBasicDescription); +} + +void CAAudioHardwareStream::GetAvailableIOProcFormatByIndex(UInt32 inIndex, AudioStreamBasicDescription& outFormat) const +{ + UInt32 theNumberFormats = GetNumberAvailableIOProcFormats(); + ThrowIf(inIndex >= theNumberFormats, CAException(kAudioHardwareIllegalOperationError), "CAAudioHardwareStream::GetAvailableIOProcFormatByIndex: index out of range"); + CAAutoArrayDelete theFormats(theNumberFormats); + GetAvailableIOProcFormats(theNumberFormats, theFormats); + outFormat = theFormats[inIndex]; +} + +void CAAudioHardwareStream::GetCurrentPhysicalFormat(AudioStreamBasicDescription& outFormat) const +{ + memset(&outFormat, 0, sizeof(AudioStreamBasicDescription)); + UInt32 theSize = sizeof(AudioStreamBasicDescription); + GetPropertyData(0, kAudioStreamPropertyPhysicalFormat, theSize, &outFormat); +} + +void CAAudioHardwareStream::SetCurrentPhysicalFormat(const AudioStreamBasicDescription& inFormat) +{ + UInt32 theSize = sizeof(AudioStreamBasicDescription); + SetPropertyData(0, kAudioStreamPropertyPhysicalFormat, theSize, &inFormat); +} + +UInt32 CAAudioHardwareStream::GetNumberAvailablePhysicalFormats() const +{ + UInt32 theAnswer = GetPropertyDataSize(0, kAudioStreamPropertyPhysicalFormats); + theAnswer /= sizeof(AudioStreamBasicDescription); + return theAnswer; +} + +void CAAudioHardwareStream::GetAvailablePhysicalFormats(UInt32& ioNumberFormats, AudioStreamBasicDescription* outFormats) const +{ + UInt32 theSize = ioNumberFormats * sizeof(AudioStreamBasicDescription); + GetPropertyData(0, kAudioStreamPropertyPhysicalFormats, theSize, outFormats); + ioNumberFormats = theSize / sizeof(AudioStreamBasicDescription); +} + +void CAAudioHardwareStream::GetAvailablePhysicalFormatByIndex(UInt32 inIndex, AudioStreamBasicDescription& outFormat) const +{ + UInt32 theNumberFormats = GetNumberAvailablePhysicalFormats(); + ThrowIf(inIndex >= theNumberFormats, CAException(kAudioHardwareIllegalOperationError), "CAAudioHardwareStream::GetAvailablePhysicalFormatByIndex: index out of range"); + CAAutoArrayDelete theFormats(theNumberFormats); + GetAvailablePhysicalFormats(theNumberFormats, theFormats); + outFormat = theFormats[inIndex]; +} + +bool CAAudioHardwareStream::HasProperty(UInt32 inChannel, AudioHardwarePropertyID inPropertyID) const +{ + OSStatus theError = AudioStreamGetPropertyInfo(GetAudioStreamID(), inChannel, inPropertyID, NULL, NULL); + return theError == 0; +} + +bool CAAudioHardwareStream::PropertyIsSettable(UInt32 inChannel, AudioHardwarePropertyID inPropertyID) const +{ + Boolean isWritable = false; + OSStatus theError = AudioStreamGetPropertyInfo(GetAudioStreamID(), inChannel, inPropertyID, NULL, &isWritable); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareStream::PropertyIsSettable: got an error getting info about a property"); + return isWritable != 0; +} + +UInt32 CAAudioHardwareStream::GetPropertyDataSize(UInt32 inChannel, AudioHardwarePropertyID inPropertyID) const +{ + UInt32 theSize = 0; + OSStatus theError = AudioStreamGetPropertyInfo(GetAudioStreamID(), inChannel, inPropertyID, &theSize, NULL); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareStream::GetPropertyDataSize: got an error getting info about a property"); + return theSize; +} + +void CAAudioHardwareStream::GetPropertyData(UInt32 inChannel, AudioHardwarePropertyID inPropertyID, UInt32& ioDataSize, void* outData) const +{ + OSStatus theError = AudioStreamGetProperty(GetAudioStreamID(), inChannel, inPropertyID, &ioDataSize, outData); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareStream::GetPropertyData: got an error getting the value of a property"); +} + +void CAAudioHardwareStream::SetPropertyData(UInt32 inChannel, AudioHardwarePropertyID inPropertyID, UInt32 inDataSize, const void* inData, const AudioTimeStamp* inWhen) +{ + OSStatus theError = AudioStreamSetProperty(GetAudioStreamID(), inWhen, inChannel, inPropertyID, inDataSize, inData); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareStream::SetPropertyData: got an error setting the value of a property"); +} + +void CAAudioHardwareStream::AddPropertyListener(UInt32 inChannel, AudioHardwarePropertyID inPropertyID, AudioStreamPropertyListenerProc inListenerProc, void* inClientData) +{ + OSStatus theError = AudioStreamAddPropertyListener(GetAudioStreamID(), inChannel, inPropertyID, inListenerProc, inClientData); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareStream::AddPropertyListener: got an error adding a property listener"); +} + +void CAAudioHardwareStream::RemovePropertyListener(UInt32 inChannel, AudioHardwarePropertyID inPropertyID, AudioStreamPropertyListenerProc inListenerProc) +{ + OSStatus theError = AudioStreamRemovePropertyListener(GetAudioStreamID(), inChannel, inPropertyID, inListenerProc); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareStream::RemovePropertyListener: got an error removing a property listener"); +} + +void CAAudioHardwareStream::GetNameForTerminalType(UInt32 inTerminalType, char* outName) +{ + switch(inTerminalType) + { + // types that go nowhere + case OUTPUT_NULL: + strcpy(outName, "Null Output"); + break; + + case INPUT_NULL: + strcpy(outName, "Null Input"); + break; + + // Input terminal types + case INPUT_UNDEFINED: + strcpy(outName, "Undefined Input"); + break; + + case INPUT_MICROPHONE: + strcpy(outName, "Microphone"); + break; + + case INPUT_DESKTOP_MICROPHONE: + strcpy(outName, "Desktop Microphone"); + break; + + case INPUT_PERSONAL_MICROPHONE: + strcpy(outName, "Personal Microphone"); + break; + + case INPUT_OMNIDIRECTIONAL_MICROPHONE: + strcpy(outName, "Omnidirectional Microphone"); + break; + + case INPUT_MICROPHONE_ARRAY: + strcpy(outName, "Microphone Array"); + break; + + case INPUT_PROCESSING_MICROPHONE_ARRAY: + strcpy(outName, "Processing Microphone Array"); + break; + + case INPUT_MODEM_AUDIO: + strcpy(outName, "Modem"); + break; + + // Output terminal types + case OUTPUT_UNDEFINED: + strcpy(outName, "Undefined Output"); + break; + + case OUTPUT_SPEAKER: + strcpy(outName, "Speaker"); + break; + + case OUTPUT_HEADPHONES: + strcpy(outName, "Headphones"); + break; + + case OUTPUT_HEAD_MOUNTED_DISPLAY_AUDIO: + strcpy(outName, "Head-Monted Display"); + break; + + case OUTPUT_DESKTOP_SPEAKER: + strcpy(outName, "Desktop Speaker"); + break; + + case OUTPUT_ROOM_SPEAKER: + strcpy(outName, "Room Speaker"); + break; + + case OUTPUT_COMMUNICATION_SPEAKER: + strcpy(outName, "Communication Speaker"); + break; + + case OUTPUT_LOW_FREQUENCY_EFFECTS_SPEAKER: + strcpy(outName, "LFE Speaker"); + break; + + // Bi-directional terminal types + case BIDIRECTIONAL_UNDEFINED: + strcpy(outName, "Undefined Bidirectional"); + break; + + case BIDIRECTIONAL_HANDSET: + strcpy(outName, "Handset"); + break; + + case BIDIRECTIONAL_HEADSET: + strcpy(outName, "Headset"); + break; + + case BIDIRECTIONAL_SPEAKERPHONE_NO_ECHO_REDX: + strcpy(outName, "Speakerphone w/o Echo Reduction"); + break; + + case BIDIRECTIONAL_ECHO_SUPPRESSING_SPEAKERPHONE: + strcpy(outName, "Speakerphone w/ Echo Suppression"); + break; + + case BIDIRECTIONAL_ECHO_CANCELING_SPEAKERPHONE: + strcpy(outName, "Speakerphone w/ Echo Cacellation"); + break; + + // Telephony terminal types + case TELEPHONY_UNDEFINED: + strcpy(outName, "Undefined telephony"); + break; + + case TELEPHONY_PHONE_LINE: + strcpy(outName, "Telephone Line"); + break; + + case TELEPHONY_TELEPHONE: + strcpy(outName, "Telephone"); + break; + + case TELEPHONY_DOWN_LINE_PHONE: + strcpy(outName, "Down Line Telephone"); + break; + + // External terminal types + case EXTERNAL_UNDEFINED: + strcpy(outName, "Undefined External"); + break; + + case EXTERNAL_ANALOG_CONNECTOR: + strcpy(outName, "Analog"); + break; + + case EXTERNAL_DIGITAL_AUDIO_INTERFACE: + strcpy(outName, "Digital Interface"); + break; + + case EXTERNAL_LINE_CONNECTOR: + strcpy(outName, "Line"); + break; + + case EXTERNAL_LEGACY_AUDIO_CONNECTOR: + strcpy(outName, "Legacy"); + break; + + case EXTERNAL_SPDIF_INTERFACE: + strcpy(outName, "SPDIF"); + break; + + case EXTERNAL_1394_DA_STREAM: + strcpy(outName, "1394 Digital Audio"); + break; + + case EXTERNAL_1394_DV_STREAM_SOUNDTRACK: + strcpy(outName, "1394 Digital Video"); + break; + + // Embedded terminal types + case EMBEDDED_UNDEFINED: + strcpy(outName, "Undefined Embedded"); + break; + + case EMBEDDED_LEVEL_CALIBRATION_NOISE_SOURCE: + strcpy(outName, "Level Calibration Noise Source"); + break; + + case EMBEDDED_EQUALIZATION_NOISE: + strcpy(outName, "Equalization Noise"); + break; + + case EMBEDDED_CD_PLAYER: + strcpy(outName, "CD Player"); + break; + + case EMBEDDED_DAT: + strcpy(outName, "DAT"); + break; + + case EMBEDDED_DCC: + strcpy(outName, "DCC"); + break; + + case EMBEDDED_MINIDISK: + strcpy(outName, "Minidisk"); + break; + + case EMBEDDED_ANALOG_TAPE: + strcpy(outName, "Analog Tape"); + break; + + case EMBEDDED_PHONOGRAPH: + strcpy(outName, "Phonograph"); + break; + + case EMBEDDED_VCR_AUDIO: + strcpy(outName, "VCR"); + break; + + case EMBEDDED_VIDEO_DISC_AUDIO: + strcpy(outName, "Video Disc"); + break; + + case EMBEDDED_DVD_AUDIO: + strcpy(outName, "DVD"); + break; + + case EMBEDDED_TV_TUNER_AUDIO: + strcpy(outName, "TV Tuner"); + break; + + case EMBEDDED_SATELLITE_RECEIVER_AUDIO: + strcpy(outName, "Satellite Receiver"); + break; + + case EMBEDDED_CABLE_TUNER_AUDIO: + strcpy(outName, "Cable Tuner"); + break; + + case EMBEDDED_DSS_AUDIO: + strcpy(outName, "DSS"); + break; + + case EMBEDDED_RADIO_RECEIVER: + strcpy(outName, "Radio Receiver"); + break; + + case EMBEDDED_RADIO_TRANSMITTER: + strcpy(outName, "Radio Transmitter"); + break; + + case EMBEDDED_MULTITRACK_RECORDER: + strcpy(outName, "Mutitrack Recorder"); + break; + + case EMBEDDED_SYNTHESIZER: + strcpy(outName, "Synthesizer"); + break; + + // Processing terminal types + case PROCESSOR_UNDEFINED: + strcpy(outName, "Undefined Processor"); + break; + + case PROCESSOR_GENERAL: + strcpy(outName, "General Processor"); + break; + + default: + sprintf(outName, "0x%X", (unsigned int)inTerminalType); + break; + + }; +} diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareStream.h b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareStream.h new file mode 100644 index 0000000000..464abfb467 --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareStream.h @@ -0,0 +1,121 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAAudioHardwareStream.h + +=============================================================================*/ +#if !defined(__CAAudioHardwareStream_h__) +#define __CAAudioHardwareStream_h__ + +//============================================================================= +// Includes +//============================================================================= + +// Local Includes +#include "CAAudioHardwareDevice.h" + +//============================================================================= +// CAAudioHardwareStream +//============================================================================= + +class CAAudioHardwareStream +{ + +// Construction/Destruction +public: + CAAudioHardwareStream(AudioStreamID inAudioStreamID); + ~CAAudioHardwareStream(); + +// General Operations +public: + AudioStreamID GetAudioStreamID() const { return mAudioStreamID; } + CFStringRef CopyName() const; + AudioDeviceID GetOwningDevice() const; + CAAudioHardwareDeviceSectionID GetSection() const; + UInt32 GetTerminalType() const; + UInt32 GetStartingDeviceChannel() const; + + bool HasIsConnectedStatus() const; + bool GetIsConnectedStatus() const; + + bool HasDataSourceControl() const; + bool DataSourceControlIsSettable() const; + UInt32 GetCurrentDataSourceID() const; + void SetCurrentDataSourceByID(UInt32 inID); + UInt32 GetNumberAvailableDataSources() const; + UInt32 GetAvailableDataSourceByIndex(UInt32 inIndex) const; + void GetAvailableDataSources(UInt32& ioNumberSources, UInt32* outSources) const; + CFStringRef CopyDataSourceNameForID(UInt32 inID) const; + +// Format Operations +public: + void GetCurrentIOProcFormat(AudioStreamBasicDescription& outFormat) const; + void SetCurrentIOProcFormat(const AudioStreamBasicDescription& inFormat); + UInt32 GetNumberAvailableIOProcFormats() const; + void GetAvailableIOProcFormats(UInt32& ioNumberFormats, AudioStreamBasicDescription* outFormats) const; + void GetAvailableIOProcFormatByIndex(UInt32 inIndex, AudioStreamBasicDescription& outFormat) const; + + void GetCurrentPhysicalFormat(AudioStreamBasicDescription& outFormat) const; + void SetCurrentPhysicalFormat(const AudioStreamBasicDescription& inFormat); + UInt32 GetNumberAvailablePhysicalFormats() const; + void GetAvailablePhysicalFormats(UInt32& ioNumberFormats, AudioStreamBasicDescription* outFormats) const; + void GetAvailablePhysicalFormatByIndex(UInt32 inIndex, AudioStreamBasicDescription& outFormat) const; + +// Property Operations +public: + bool HasProperty(UInt32 inChannel, AudioHardwarePropertyID inPropertyID) const; + bool PropertyIsSettable(UInt32 inChannel, AudioHardwarePropertyID inPropertyID) const; + + UInt32 GetPropertyDataSize(UInt32 inChannel, AudioHardwarePropertyID inPropertyID) const; + void GetPropertyData(UInt32 inChannel, AudioHardwarePropertyID inPropertyID, UInt32& ioDataSize, void* outData) const; + void SetPropertyData(UInt32 inChannel, AudioHardwarePropertyID inPropertyID, UInt32 inDataSize, const void* inData, const AudioTimeStamp* inWhen = NULL); + + void AddPropertyListener(UInt32 inChannel, AudioHardwarePropertyID inPropertyID, AudioStreamPropertyListenerProc inListenerProc, void* inClientData); + void RemovePropertyListener(UInt32 inChannel, AudioHardwarePropertyID inPropertyID, AudioStreamPropertyListenerProc inListenerProc); + +// Utility Operations +public: + static void GetNameForTerminalType(UInt32 inTerminalType, char* outName); + +// Implementation +private: + AudioStreamID mAudioStreamID; + +}; + +#endif diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareSystem.cpp b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareSystem.cpp new file mode 100644 index 0000000000..e08c293405 --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareSystem.cpp @@ -0,0 +1,264 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAAudioHardwareSystem.cpp + +=============================================================================*/ + +//============================================================================= +// Includes +//============================================================================= + +// Self Include +#include "CAAudioHardwareSystem.h" + +// PublicUtility Includes +#include "CAAutoDisposer.h" +#include "CADebugMacros.h" +#include "CAException.h" + +//============================================================================= +// CAAudioHardwareSystem +//============================================================================= + +UInt32 CAAudioHardwareSystem::GetNumberDevices() +{ + UInt32 theAnswer = GetPropertyDataSize(kAudioHardwarePropertyDevices); + theAnswer /= sizeof(AudioDeviceID); + return theAnswer; +} + +AudioDeviceID CAAudioHardwareSystem::GetDeviceAtIndex(UInt32 inIndex) +{ + AudioDeviceID theAnswer = 0; + UInt32 theNumberDevices = GetNumberDevices(); + if((theNumberDevices > 0) && (inIndex < theNumberDevices)) + { + CAAutoArrayDelete theDeviceList(theNumberDevices); + UInt32 theSize = theNumberDevices * sizeof(AudioDeviceID); + GetPropertyData(kAudioHardwarePropertyDevices, theSize, theDeviceList); + theAnswer = theDeviceList[inIndex]; + } + return theAnswer; +} + +UInt32 CAAudioHardwareSystem::GetIndexForDevice(const AudioDeviceID inDevice) +{ + UInt32 theAnswer = 0xFFFFFFFF; + UInt32 theNumberDevices = GetNumberDevices(); + if(theNumberDevices > 0) + { + CAAutoArrayDelete theDeviceList(theNumberDevices); + UInt32 theSize = theNumberDevices * sizeof(AudioDeviceID); + GetPropertyData(kAudioHardwarePropertyDevices, theSize, theDeviceList); + for(UInt32 theIndex = 0; theIndex < theNumberDevices; ++theIndex) + { + if(inDevice == theDeviceList[theIndex]) + { + theAnswer = theIndex; + break; + } + } + } + return theAnswer; +} + +AudioDeviceID CAAudioHardwareSystem::GetDeviceForUID(CFStringRef inUID) +{ + AudioDeviceID theAnswer = 0; + AudioValueTranslation theValue = { &inUID, sizeof(CFStringRef), &theAnswer, sizeof(AudioDeviceID) }; + UInt32 theSize = sizeof(AudioValueTranslation); + GetPropertyData(kAudioHardwarePropertyDeviceForUID, theSize, &theValue); + return theAnswer; +} + +AudioDeviceID CAAudioHardwareSystem::GetDefaultDevice(bool inIsInput, bool inIsSystem) +{ + AudioDeviceID theAnswer = 0; + AudioHardwarePropertyID thePropertyID = 0; + if(inIsInput) + { + thePropertyID = kAudioHardwarePropertyDefaultInputDevice; + } + else if(inIsSystem) + { + thePropertyID = kAudioHardwarePropertyDefaultSystemOutputDevice; + } + else + { + thePropertyID = kAudioHardwarePropertyDefaultOutputDevice; + } + UInt32 theSize = sizeof(AudioDeviceID); + GetPropertyData(thePropertyID, theSize, &theAnswer); + return theAnswer; +} + +void CAAudioHardwareSystem::SetDefaultDevice(bool inIsInput, bool inIsSystem, AudioDeviceID inDevice) +{ + AudioHardwarePropertyID thePropertyID = 0; + if(inIsInput) + { + thePropertyID = kAudioHardwarePropertyDefaultInputDevice; + } + else if(inIsSystem) + { + thePropertyID = kAudioHardwarePropertyDefaultSystemOutputDevice; + } + else + { + thePropertyID = kAudioHardwarePropertyDefaultOutputDevice; + } + UInt32 theSize = sizeof(AudioDeviceID); + SetPropertyData(thePropertyID, theSize, &inDevice); +} + +bool CAAudioHardwareSystem::HasBootChimeVolumeControl() +{ + return HasProperty(kAudioHardwarePropertyBootChimeVolumeDecibels); +} + +Float32 CAAudioHardwareSystem::GetBootChimeVolumeControlValueAsScalar() +{ + Float32 theAnswer = 0; + UInt32 theSize = sizeof(Float32); + GetPropertyData(kAudioHardwarePropertyBootChimeVolumeScalar, theSize, &theAnswer); + return theAnswer; +} + +Float32 CAAudioHardwareSystem::GetBootChimeVolumeControlValueAsDB() +{ + Float32 theAnswer = 0; + UInt32 theSize = sizeof(Float32); + GetPropertyData(kAudioHardwarePropertyBootChimeVolumeDecibels, theSize, &theAnswer); + return theAnswer; +} + +void CAAudioHardwareSystem::GetBootChimeVolumeControlDBRange(Float32& outMinimum, Float32& outMaximum) +{ + AudioValueRange theRange = { 0, 0 }; + UInt32 theSize = sizeof(AudioValueRange); + GetPropertyData(kAudioHardwarePropertyBootChimeVolumeRangeDecibels, theSize, &theRange); + outMinimum = theRange.mMinimum; + outMaximum = theRange.mMaximum; +} + +void CAAudioHardwareSystem::SetBootChimeVolumeControlValueAsScalar(Float32 inScalarValue) +{ + UInt32 theSize = sizeof(Float32); + SetPropertyData(kAudioHardwarePropertyBootChimeVolumeScalar, theSize, &inScalarValue); +} + +void CAAudioHardwareSystem::SetBootChimeVolumeControlValueAsDB(Float32 inDBValue) +{ + UInt32 theSize = sizeof(Float32); + SetPropertyData(kAudioHardwarePropertyBootChimeVolumeDecibels, theSize, &inDBValue); +} + +Float32 CAAudioHardwareSystem::ConvertBootChimeVolumeControlScalarValueToDB(Float32 inScalarValue) +{ + UInt32 theSize = sizeof(Float32); + GetPropertyData(kAudioHardwarePropertyBootChimeVolumeScalarToDecibels, theSize, &inScalarValue); + return inScalarValue; +} + +Float32 CAAudioHardwareSystem::ConvertBootChimeVolumeControlDBValueToScalar(Float32 inDBValue) +{ + UInt32 theSize = sizeof(Float32); + GetPropertyData(kAudioHardwarePropertyBootChimeVolumeDecibelsToScalar, theSize, &inDBValue); + return inDBValue; +} + +bool CAAudioHardwareSystem::AllowsIdleSleepDuringIO() +{ + UInt32 theValue = 0; + UInt32 theSize = sizeof(UInt32); + GetPropertyData(kAudioHardwarePropertySleepingIsAllowed, theSize, &theValue); + return theValue != 0; +} + +void CAAudioHardwareSystem::SetAllowsIdleSleepDuringIO(bool inAllowIdleSleep) +{ + UInt32 theValue = inAllowIdleSleep ? 1 : 0; + SetPropertyData(kAudioHardwarePropertySleepingIsAllowed, sizeof(UInt32), &theValue); +} + +bool CAAudioHardwareSystem::HasProperty(AudioHardwarePropertyID inPropertyID) +{ + OSStatus theError = AudioHardwareGetPropertyInfo(inPropertyID, NULL, NULL); + return theError == 0; +} + +bool CAAudioHardwareSystem::PropertyIsSettable(AudioHardwarePropertyID inPropertyID) +{ + Boolean isWritable = false; + OSStatus theError = AudioHardwareGetPropertyInfo(inPropertyID, NULL, &isWritable); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareSystem::PropertyIsSettable: got an error getting info about a property"); + return isWritable != 0; +} + +UInt32 CAAudioHardwareSystem::GetPropertyDataSize(AudioHardwarePropertyID inPropertyID) +{ + UInt32 theSize = 0; + OSStatus theError = AudioHardwareGetPropertyInfo(inPropertyID, &theSize, NULL); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareSystem::GetPropertyDataSize: got an error getting info about a property"); + return theSize; +} + +void CAAudioHardwareSystem::GetPropertyData(AudioHardwarePropertyID inPropertyID, UInt32& ioDataSize, void* outData) +{ + OSStatus theError = AudioHardwareGetProperty(inPropertyID, &ioDataSize, outData); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareSystem::GetPropertyData: got an error getting the value of a property"); +} + +void CAAudioHardwareSystem::SetPropertyData(AudioHardwarePropertyID inPropertyID, UInt32 inDataSize, const void* inData) +{ + OSStatus theError = AudioHardwareSetProperty(inPropertyID, inDataSize, const_cast(inData)); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareSystem::SetPropertyData: got an error setting the value of a property"); +} + +void CAAudioHardwareSystem::AddPropertyListener(AudioHardwarePropertyID inPropertyID, AudioHardwarePropertyListenerProc inListenerProc, void* inClientData) +{ + OSStatus theError = AudioHardwareAddPropertyListener(inPropertyID, inListenerProc, inClientData); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareSystem::AddPropertyListener: got an error adding a property listener"); +} + +void CAAudioHardwareSystem::RemovePropertyListener(AudioHardwarePropertyID inPropertyID, AudioHardwarePropertyListenerProc inListenerProc) +{ + OSStatus theError = AudioHardwareRemovePropertyListener(inPropertyID, inListenerProc); + ThrowIfError(theError, CAException(theError), "CAAudioHardwareSystem::RemovePropertyListener: got an error removing a property listener"); +} diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareSystem.h b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareSystem.h new file mode 100644 index 0000000000..77372210b7 --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAAudioHardwareSystem.h @@ -0,0 +1,96 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAAudioHardwareSystem.h + +=============================================================================*/ +#if !defined(__CAAudioHardwareSystem_h__) +#define __CAAudioHardwareSystem_h__ + +//============================================================================= +// Includes +//============================================================================= + +// System Includes +#include +#include + +//============================================================================= +// CAAudioHardwareSystem +//============================================================================= + +class CAAudioHardwareSystem +{ + +// Operations +public: + static UInt32 GetNumberDevices(); + static AudioDeviceID GetDeviceAtIndex(UInt32 inIndex); + static UInt32 GetIndexForDevice(const AudioDeviceID inDevice); + static AudioDeviceID GetDeviceForUID(CFStringRef inUID); + + static AudioDeviceID GetDefaultDevice(bool inIsInput, bool inIsSystem); + static void SetDefaultDevice(bool inIsInput, bool inIsSystem, AudioDeviceID inDevice); + + static bool HasBootChimeVolumeControl(); + static Float32 GetBootChimeVolumeControlValueAsScalar(); + static Float32 GetBootChimeVolumeControlValueAsDB(); + static void GetBootChimeVolumeControlDBRange(Float32& outMinimum, Float32& outMaximum); + static void SetBootChimeVolumeControlValueAsScalar(Float32 inScalarValue); + static void SetBootChimeVolumeControlValueAsDB(Float32 inDBValue); + static Float32 ConvertBootChimeVolumeControlScalarValueToDB(Float32 inScalarValue); + static Float32 ConvertBootChimeVolumeControlDBValueToScalar(Float32 inDBValue); + + static bool AllowsIdleSleepDuringIO(); + static void SetAllowsIdleSleepDuringIO(bool inAllowIdleSleep); + +// Property Operations +public: + static bool HasProperty(AudioHardwarePropertyID inPropertyID); + static bool PropertyIsSettable(AudioHardwarePropertyID inPropertyID); + + static UInt32 GetPropertyDataSize(AudioHardwarePropertyID inPropertyID); + static void GetPropertyData(AudioHardwarePropertyID inPropertyID, UInt32& ioDataSize, void* outData); + static void SetPropertyData(AudioHardwarePropertyID inPropertyID, UInt32 inDataSize, const void* inData); + + static void AddPropertyListener(AudioHardwarePropertyID inPropertyID, AudioHardwarePropertyListenerProc inListenerProc, void* inClientData); + static void RemovePropertyListener(AudioHardwarePropertyID inPropertyID, AudioHardwarePropertyListenerProc inListenerProc); + +}; + +#endif diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAException.h b/stepmania/src/archutils/Darwin/PublicUtility/CAException.h new file mode 100644 index 0000000000..55ecd51bf7 --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAException.h @@ -0,0 +1,79 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAException.h + +=============================================================================*/ +#if !defined(__CAException_h__) +#define __CAException_h__ + +//============================================================================= +// Includes +//============================================================================= + +#include "CAConditionalMacros.h" + +#if CoreAudio_Use_Framework_Includes + #include +#else + #include "CoreAudioTypes.h" +#endif + +//============================================================================= +// CAException +//============================================================================= + +class CAException +{ + +public: + CAException(OSStatus inError) : mError(inError) {} + CAException(const CAException& inException) : mError(inException.mError) {} + CAException& operator=(const CAException& inException) { mError = inException.mError; return *this; } + ~CAException() {} + + OSStatus GetError() const { return mError; } + +protected: + OSStatus mError; +}; + +#define CATry try{ +#define CACatch }catch(const CAException& inException) {} catch(...) {} + +#endif diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAPrefix.h b/stepmania/src/archutils/Darwin/PublicUtility/CAPrefix.h new file mode 100644 index 0000000000..772c720511 --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAPrefix.h @@ -0,0 +1,83 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAPrefix.h + +=============================================================================*/ +#if !defined(__CAPrefix_h__) +#define __CAPrefix_h__ + +//============================================================================= +// Includes +//============================================================================= + +#include + +// MacTypes.h has the definitions of basic types like UInt32 and Float64 +#if TARGET_OS_MAC && TARGET_RT_MAC_MACHO + #include +#else + #include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(__cplusplus) + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +#endif + +#endif diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAStreamBasicDescription.cpp b/stepmania/src/archutils/Darwin/PublicUtility/CAStreamBasicDescription.cpp new file mode 100644 index 0000000000..a9e47c5468 --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAStreamBasicDescription.cpp @@ -0,0 +1,474 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAStreamBasicDescription.cpp + +=============================================================================*/ + +#include "CAConditionalMacros.h" + +#include "CAStreamBasicDescription.h" + +#if TARGET_OS_MAC && TARGET_RT_MAC_MACHO +#include +#else +#include +#endif + +const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags) +{ + mSampleRate = inSampleRate; + mFormatID = inFormatID; + mBytesPerPacket = inBytesPerPacket; + mFramesPerPacket = inFramesPerPacket; + mBytesPerFrame = inBytesPerFrame; + mChannelsPerFrame = inChannelsPerFrame; + mBitsPerChannel = inBitsPerChannel; + mFormatFlags = inFormatFlags; +} + +void CAStreamBasicDescription::PrintFormat(FILE *f, const char *indent, const char *name) const +{ + fprintf(f, "%s%s ", indent, name); + char formatID[5]; + *(UInt32 *)formatID = EndianU32_NtoB(mFormatID); + formatID[4] = '\0'; + fprintf(f, "%2ld ch, %6.0f Hz, '%-4.4s' (0x%08lX) ", + NumberChannels(), mSampleRate, formatID, + mFormatFlags); + if (mFormatID == kAudioFormatLinearPCM) { + bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat); + int wordSize = SampleWordSize(); + const char *endian = (wordSize > 1) ? + ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : ""; + const char *sign = isInt ? + ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : ""; + const char *floatInt = isInt ? "integer" : "float"; + char packed[32]; + if (PackednessIsSignificant()) { + if (mFormatFlags & kLinearPCMFormatFlagIsPacked) + sprintf(packed, "packed in %d bytes", wordSize); + else + sprintf(packed, "unpacked in %d bytes", wordSize); + } else + packed[0] = '\0'; + const char *align = AlignmentIsSignificant() ? + ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : ""; + const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : ""; + const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : ""; + + fprintf(f, "%ld-bit%s%s %s%s%s%s%s\n", + mBitsPerChannel, endian, sign, floatInt, + commaSpace, packed, align, deinter); + } else + fprintf(f, "%ld bits/channel, %ld bytes/packet, %ld frames/packet, %ld bytes/frame\n", + mBitsPerChannel, mBytesPerPacket, mFramesPerPacket, mBytesPerFrame); +} + +void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription) +{ + if(ioDescription.mFormatID == kAudioFormatLinearPCM) + { + // we have to doctor the linear PCM format because we always + // only export 32 bit, native endian, fully packed floats + ioDescription.mBitsPerChannel = sizeof(Float32) * 8; + ioDescription.mBytesPerFrame = sizeof(Float32) * ioDescription.mChannelsPerFrame; + ioDescription.mFramesPerPacket = 1; + ioDescription.mBytesPerPacket = ioDescription.mFramesPerPacket * ioDescription.mBytesPerFrame; + + ioDescription.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked; + ioDescription.mFormatFlags |= kAudioFormatFlagsNativeEndian; + } +} + +void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription) +{ + ioDescription.mSampleRate = 0; + ioDescription.mFormatID = 0; + ioDescription.mBytesPerPacket = 0; + ioDescription.mFramesPerPacket = 0; + ioDescription.mBytesPerFrame = 0; + ioDescription.mChannelsPerFrame = 0; + ioDescription.mBitsPerChannel = 0; + ioDescription.mFormatFlags = 0; +} + +void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription) +{ + if(ioDescription.mSampleRate == 0) + { + ioDescription.mSampleRate = inTemplateDescription.mSampleRate; + } + if(ioDescription.mFormatID == 0) + { + ioDescription.mFormatID = inTemplateDescription.mFormatID; + } + if(ioDescription.mFormatFlags == 0) + { + ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags; + } + if(ioDescription.mBytesPerPacket == 0) + { + ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket; + } + if(ioDescription.mFramesPerPacket == 0) + { + ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket; + } + if(ioDescription.mBytesPerFrame == 0) + { + ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame; + } + if(ioDescription.mChannelsPerFrame == 0) + { + ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame; + } + if(ioDescription.mBitsPerChannel == 0) + { + ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel; + } +} + +void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate) +{ + switch(inDescription.mFormatID) + { + case kAudioFormatLinearPCM: + { + const char* theEndianString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) + { + #if TARGET_RT_LITTLE_ENDIAN + theEndianString = "Big Endian"; + #endif + } + else + { + #if TARGET_RT_BIG_ENDIAN + theEndianString = "Little Endian"; + #endif + } + + const char* theKindString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0) + { + theKindString = (inAbbreviate ? "Float" : "Floating Point"); + } + else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) + { + theKindString = (inAbbreviate ? "SInt" : "Signed Integer"); + } + else + { + theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer"); + } + + const char* thePackingString = NULL; + if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0) + { + if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) + { + thePackingString = "High"; + } + else + { + thePackingString = "Low"; + } + } + + if(inAbbreviate) + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%d Ch %s %s %s%d/%s%d", (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%d Ch %s %s%d", (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel); + } + } + else + { + if(thePackingString != NULL) + { + sprintf(outName, "%d Ch %s %s%d/%s%d", (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8)); + } + else + { + sprintf(outName, "%d Ch %s%d", (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel); + } + } + } + else + { + if(theEndianString != NULL) + { + if(thePackingString != NULL) + { + sprintf(outName, "%d Channel %d Bit %s %s Aligned %s in %d Bits", (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%d Channel %d Bit %s %s", (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString); + } + } + else + { + sprintf(outName, "%d Channel %d Bit %s", (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString); + if(thePackingString != NULL) + { + sprintf(outName, "%d Channel %d Bit %s Aligned %s in %d Bits", (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); + } + else + { + sprintf(outName, "%d Channel %d Bit %s", (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString); + } + } + } + } + break; + + case kAudioFormatAC3: + strcpy(outName, "AC-3"); + break; + + case kAudioFormat60958AC3: + strcpy(outName, "AC-3 for SPDIF"); + break; + + default: + { + char* the4CCString = (char*)&inDescription.mFormatID; + outName[0] = the4CCString[0]; + outName[1] = the4CCString[1]; + outName[2] = the4CCString[2]; + outName[3] = the4CCString[3]; + outName[4] = 0; + } + break; + }; +} + +#if CoreAudio_Debug +#include "CALogMacros.h" + +void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc) +{ + PrintFloat (" Sample Rate: ", inDesc.mSampleRate); + Print4CharCode (" Format ID: ", inDesc.mFormatID); + PrintHex (" Format Flags: ", inDesc.mFormatFlags); + PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket); + PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket); + PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame); + PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame); + PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel); +} +#endif + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + bool theAnswer = false; + bool isDone = false; + + // note that if either side is 0, that field is skipped + + // format ID is the first order sort + if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0))) + { + if(x.mFormatID != y.mFormatID) + { + // formats are sorted numerically except that linear + // PCM is always first + if(x.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = true; + } + else if(y.mFormatID == kAudioFormatLinearPCM) + { + theAnswer = false; + } + else + { + theAnswer = x.mFormatID < y.mFormatID; + } + isDone = true; + } + } + + // floating point vs integer for linear PCM only + if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) + { + if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat)) + { + // floating point is better than integer + theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat; + isDone = true; + } + } + + // bit depth + if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0))) + { + if(x.mBitsPerChannel != y.mBitsPerChannel) + { + // deeper bit depths are higher quality + theAnswer = x.mBitsPerChannel < y.mBitsPerChannel; + isDone = true; + } + } + + // sample rate + if((!isDone) && ((x.mSampleRate != 0) && (y.mSampleRate != 0))) + { + if(x.mSampleRate != y.mSampleRate) + { + // higher sample rates are higher quality + theAnswer = x.mSampleRate < y.mSampleRate; + isDone = true; + } + } + + // number of channels + if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0))) + { + if(x.mChannelsPerFrame != y.mChannelsPerFrame) + { + // more channels is higher quality + theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame; + isDone = true; + } + } + + return theAnswer; +} + +static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + UInt32 xFlags = x.mFormatFlags; + UInt32 yFlags = y.mFormatFlags; + + // match wildcards + if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0) + return true; + + if (x.mFormatID == kAudioFormatLinearPCM) + { + // knock off the all clear flag + xFlags = xFlags & ~kAudioFormatFlagsAreAllClear; + yFlags = yFlags & ~kAudioFormatFlagsAreAllClear; + + // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit. + if (xFlags & yFlags & kAudioFormatFlagIsPacked) { + xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh; + yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh; + } + + // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit. + if (xFlags & yFlags & kAudioFormatFlagIsFloat) { + xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger; + yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger; + } + + // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness + if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + xFlags = xFlags & ~kAudioFormatFlagIsBigEndian; + } + if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) + { + yFlags = yFlags & ~kAudioFormatFlagIsBigEndian; + } + } + return xFlags == yFlags; +} + +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) +{ + // the semantics for equality are: + // 1) Values must match exactly + // 2) wildcard's are ignored in the comparison + +#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name)) + + return + // check the sample rate + MATCH(mSampleRate) + + // check the format ids + && MATCH(mFormatID) + + // check the format flags + && MatchFormatFlags(x, y) + + // check the bytes per packet + && MATCH(mBytesPerPacket) + + // check the frames per packet + && MATCH(mFramesPerPacket) + + // check the bytes per frame + && MATCH(mBytesPerFrame) + + // check the channels per frame + && MATCH(mChannelsPerFrame) + + // check the channels per frame + && MATCH(mBitsPerChannel) ; +} + +bool SanityCheck(const AudioStreamBasicDescription& x) +{ + // This function returns false if there are sufficiently insane values in any field. + // It is very conservative so even some very unlikely values will pass. + // This is just meant to catch the case where the data from a file is corrupted. + + return + (x.mSampleRate >= 0. && x.mSampleRate < 1e6) + && (x.mBytesPerPacket < 1000000) + && (x.mFramesPerPacket < 1000000) + && (x.mBytesPerFrame < 1000000) + && (x.mChannelsPerFrame <= 1024) + && (x.mBitsPerChannel <= 1024); +} diff --git a/stepmania/src/archutils/Darwin/PublicUtility/CAStreamBasicDescription.h b/stepmania/src/archutils/Darwin/PublicUtility/CAStreamBasicDescription.h new file mode 100644 index 0000000000..4a9093f104 --- /dev/null +++ b/stepmania/src/archutils/Darwin/PublicUtility/CAStreamBasicDescription.h @@ -0,0 +1,214 @@ +/* Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*============================================================================= + CAStreamBasicDescription.h + +=============================================================================*/ + +#ifndef __CAStreamBasicDescription_h__ +#define __CAStreamBasicDescription_h__ + +#include "CAConditionalMacros.h" + +#if CoreAudio_Use_Framework_Includes + #include + #include +#else + #include "CoreAudioTypes.h" + #include "CFPropertyList.h" +#endif + +#include "CADebugMacros.h" +#include // for memset, memcpy +#include // for FILE * + +//============================================================================= +// CAStreamBasicDescription +// +// This is a wrapper class for the AudioStreamBasicDescription struct. +// It adds a number of convenience routines, but otherwise adds nothing +// to the footprint of the original struct. +//============================================================================= +class CAStreamBasicDescription : + public AudioStreamBasicDescription +{ + +// Constants +public: + static const AudioStreamBasicDescription sEmpty; + +// Construction/Destruction +public: + CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); } + + CAStreamBasicDescription(const AudioStreamBasicDescription &desc) + { + SetFrom(desc); + } + + CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID, + UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, + UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, + UInt32 inBitsPerChannel, UInt32 inFormatFlags); + +// Assignment + CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; } + + void SetFrom(const AudioStreamBasicDescription &desc) + { + memcpy(this, &desc, sizeof(AudioStreamBasicDescription)); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // interrogation + + bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; } + + bool PackednessIsSignificant() const + { + Assert(IsPCM(), "PackednessIsSignificant only applies for PCM"); + return (SampleWordSize() << 3) != mBitsPerChannel; + } + + bool AlignmentIsSignificant() const + { + return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0; + } + + bool IsInterleaved() const + { + return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved); + } + + // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these: + UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; } + UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; } + UInt32 NumberChannels() const { return mChannelsPerFrame; } + UInt32 SampleWordSize() const { return (mBytesPerFrame > 0) ? mBytesPerFrame / NumberInterleavedChannels() : 0;} + + UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; } + UInt32 BytesToFrames(UInt32 nbytes) const { + Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames"); + return nbytes / mBytesPerFrame; + } + + bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const + { + return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved(); + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // manipulation + + void SetCanonical(UInt32 nChannels, bool interleaved) + // note: leaves sample rate untouched + { + mFormatID = kAudioFormatLinearPCM; + mFormatFlags = kAudioFormatFlagsNativeFloatPacked; + mBitsPerChannel = 32; + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) + mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(Float32); + else { + mBytesPerPacket = mBytesPerFrame = sizeof(Float32); + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + void ChangeNumberChannels(UInt32 nChannels, bool interleaved) + // alter an existing format + { + Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats"); + UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING + mChannelsPerFrame = nChannels; + mFramesPerPacket = 1; + if (interleaved) { + mBytesPerPacket = mBytesPerFrame = nChannels * wordSize; + mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved; + } else { + mBytesPerPacket = mBytesPerFrame = wordSize; + mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + } + + // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + // + // other + + void Print() const + { + Print (stdout); + } + + void Print(FILE* file) const + { + PrintFormat (file, "", "AudioStreamBasicDescription:"); + } + + void PrintFormat(FILE *f, const char *indent, const char *name) const; + + OSStatus Save(CFPropertyListRef *outData) const; + + OSStatus Restore(CFPropertyListRef &inData); + +// Operations + static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription); + static void ResetFormat(AudioStreamBasicDescription& ioDescription); + static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription); + static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate); +#if CoreAudio_Debug + static void PrintToLog(const AudioStreamBasicDescription& inDesc); +#endif +}; + +bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); +#if TARGET_OS_MAC +inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); } +inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); } +inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); } +inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); } +#endif + +bool SanityCheck(const AudioStreamBasicDescription& x); + + +#endif // __CAStreamBasicDescription_h__