Add wrapper for the CoreAudio care of Apple.
This commit is contained in:
@@ -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 <IOKit/audio/IOAudioTypes.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// Standard Library Includes
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// 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<UInt32> 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<UInt32> 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<AudioValueRange> 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<AudioValueRange> 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<UInt32>(theAnswer.mMinimum);
|
||||||
|
outMaximum = static_cast<UInt32>(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<AudioHardwareIOProcStreamUsage> 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<AudioHardwareIOProcStreamUsage> 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<AudioStreamID> 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<AudioBufferList> 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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 <CoreAudio/CoreAudio.h>
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// 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
|
||||||
@@ -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 <IOKit/audio/IOAudioTypes.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// 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<UInt32> 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<AudioStreamBasicDescription> 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<AudioStreamBasicDescription> 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;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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<AudioDeviceID> 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<AudioDeviceID> 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<void*>(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");
|
||||||
|
}
|
||||||
@@ -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 <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <CoreAudio/CoreAudio.h>
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// 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
|
||||||
@@ -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 <CoreAudio/CoreAudioTypes.h>
|
||||||
|
#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
|
||||||
@@ -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 <TargetConditionals.h>
|
||||||
|
|
||||||
|
// MacTypes.h has the definitions of basic types like UInt32 and Float64
|
||||||
|
#if TARGET_OS_MAC && TARGET_RT_MAC_MACHO
|
||||||
|
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
|
||||||
|
#else
|
||||||
|
#include <MacTypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
|
#include <IOKit/IOMessage.h>
|
||||||
|
#include <IOKit/audio/IOAudioDefines.h>
|
||||||
|
#include <IOKit/audio/IOAudioTypes.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <new>
|
||||||
|
#include <numeric>
|
||||||
|
#include <queue>
|
||||||
|
#include <set>
|
||||||
|
#include <stack>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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 <CoreServices/CoreServices.h>
|
||||||
|
#else
|
||||||
|
#include <Endian.h>
|
||||||
|
#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);
|
||||||
|
}
|
||||||
@@ -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 <CoreAudio/CoreAudioTypes.h>
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#else
|
||||||
|
#include "CoreAudioTypes.h"
|
||||||
|
#include "CFPropertyList.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "CADebugMacros.h"
|
||||||
|
#include <string.h> // for memset, memcpy
|
||||||
|
#include <stdio.h> // 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__
|
||||||
Reference in New Issue
Block a user