forked from nu774/qaac
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
53 changed files
with
1,583 additions
and
6,810 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#ifndef AudioCodec_H | ||
#define AudioCodec_H | ||
|
||
#include <Components.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
enum { | ||
kAudioCodecPropertyNameCFString = 'lnam', | ||
kAudioCodecPropertyManufacturerCFString = 'lmak', | ||
kAudioCodecPropertyFormatCFString = 'lfor', | ||
//kAudioCodecPropertyHasVariablePacketByteSizes = 'vpk?', | ||
kAudioCodecPropertySupportedInputFormats = 'ifm#', | ||
kAudioCodecPropertySupportedOutputFormats = 'ofm#', | ||
kAudioCodecPropertyAvailableInputSampleRates = 'aisr', | ||
kAudioCodecPropertyAvailableOutputSampleRates = 'aosr', | ||
kAudioCodecPropertyAvailableBitRateRange = 'abrt', | ||
kAudioCodecPropertyMinimumNumberInputPackets = 'mnip', | ||
kAudioCodecPropertyMinimumNumberOutputPackets = 'mnop', | ||
kAudioCodecPropertyAvailableNumberChannels = 'cmnc', | ||
kAudioCodecPropertyDoesSampleRateConversion = 'lmrc', | ||
kAudioCodecPropertyAvailableInputChannelLayoutTags = 'aicl', | ||
kAudioCodecPropertyAvailableOutputChannelLayoutTags = 'aocl', | ||
kAudioCodecPropertyInputFormatsForOutputFormat = 'if4o', | ||
kAudioCodecPropertyOutputFormatsForInputFormat = 'of4i', | ||
kAudioCodecPropertyFormatInfo = 'acfi', | ||
}; | ||
|
||
enum { | ||
kAudioCodecPropertyInputBufferSize = 'tbuf', | ||
kAudioCodecPropertyPacketFrameSize = 'pakf', | ||
kAudioCodecPropertyMaximumPacketByteSize = 'pakb', | ||
kAudioCodecPropertyCurrentInputFormat = 'ifmt', | ||
kAudioCodecPropertyCurrentOutputFormat = 'ofmt', | ||
kAudioCodecPropertyMagicCookie = 'kuki', | ||
kAudioCodecPropertyUsedInputBufferSize = 'ubuf', | ||
kAudioCodecPropertyIsInitialized = 'init', | ||
kAudioCodecPropertyCurrentTargetBitRate = 'brat', | ||
kAudioCodecPropertyCurrentInputSampleRate = 'cisr', | ||
kAudioCodecPropertyCurrentOutputSampleRate = 'cosr', | ||
kAudioCodecPropertyQualitySetting = 'srcq', | ||
kAudioCodecPropertyApplicableBitRateRange = 'brta', | ||
kAudioCodecPropertyApplicableInputSampleRates = 'isra', | ||
kAudioCodecPropertyApplicableOutputSampleRates = 'osra', | ||
kAudioCodecPropertyPaddedZeros = 'pad0', | ||
kAudioCodecPropertyPrimeMethod = 'prmm', | ||
kAudioCodecPropertyPrimeInfo = 'prim', | ||
kAudioCodecPropertyCurrentInputChannelLayout = 'icl ', | ||
kAudioCodecPropertyCurrentOutputChannelLayout = 'ocl ', | ||
kAudioCodecPropertySettings = 'acs ', | ||
kAudioCodecPropertyFormatList = 'acfl', | ||
kAudioCodecPropertyBitRateControlMode = 'acbf', | ||
kAudioCodecPropertySoundQualityForVBR = 'vbrq', | ||
kAudioCodecPropertyMinimumDelayMode = 'mdel' | ||
}; | ||
|
||
enum { | ||
kAudioCodecBitRateControlMode_Constant = 0, | ||
kAudioCodecBitRateControlMode_LongTermAverage = 1, | ||
kAudioCodecBitRateControlMode_VariableConstrained = 2, | ||
kAudioCodecBitRateControlMode_Variable = 3, | ||
}; | ||
|
||
typedef ComponentInstance AudioCodec; | ||
typedef UInt32 AudioCodecPropertyID; | ||
|
||
typedef struct AudioCodecPrimeInfo { | ||
UInt32 leadingFrames; | ||
UInt32 trailingFrames; | ||
} AudioCodecPrimeInfo; | ||
|
||
ComponentResult AudioCodecGetProperty ( | ||
AudioCodec inCodec, | ||
AudioCodecPropertyID inPropertyID, | ||
UInt32 *ioPropertyDataSize, | ||
void *outPropertyData); | ||
|
||
ComponentResult AudioCodecGetPropertyInfo ( | ||
AudioCodec inCodec, | ||
AudioCodecPropertyID inPropertyID, | ||
UInt32 *outSize, | ||
Boolean *outWritable); | ||
|
||
ComponentResult AudioCodecInitialize ( | ||
AudioCodec inCodec, | ||
const AudioStreamBasicDescription *inInputFormat, | ||
const AudioStreamBasicDescription *inOutputFormat, | ||
const void *inMagicCookie, | ||
UInt32 inMagicCookieByteSize); | ||
|
||
ComponentResult AudioCodecSetProperty ( | ||
AudioCodec inCodec, | ||
AudioCodecPropertyID inPropertyID, | ||
UInt32 inPropertyDataSize, | ||
const void *inPropertyData); | ||
|
||
ComponentResult AudioCodecUninitialize(AudioCodec inCodec); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
#ifndef AudioCodecX_H | ||
#define AudioCodecX_H | ||
|
||
#include "CoreAudioToolbox.h" | ||
|
||
class AudioCodecX { | ||
x::shared_ptr<ComponentInstanceRecord> m_codec; | ||
public: | ||
AudioCodecX() {} | ||
AudioCodecX(OSType codec) | ||
{ | ||
AudioComponentDescription desc = { 'aenc', codec, 0 }; | ||
AudioComponent component = AudioComponentFindNext(0, &desc); | ||
if (!component) { | ||
throw std::runtime_error(format( | ||
"AudioComponentFindNext: component %s not found", | ||
fourcc(codec).svalue)); | ||
} | ||
AudioComponentInstance aci; | ||
CHECKCA(AudioComponentInstanceNew(component, &aci)); | ||
attach(reinterpret_cast<AudioCodec>(aci), true); | ||
} | ||
AudioCodecX(AudioCodec codec, bool takeOwn) | ||
{ | ||
attach(codec, takeOwn); | ||
} | ||
void attach(AudioCodec codec, bool takeOwn) | ||
{ | ||
OSStatus (*dispose)(AudioCodec) = | ||
takeOwn ? reinterpret_cast<OSStatus (*)(AudioCodec)>( | ||
AudioComponentInstanceDispose) | ||
: fakeDispose; | ||
m_codec = x::shared_ptr<ComponentInstanceRecord>(codec, dispose); | ||
} | ||
operator AudioCodec() { return m_codec.get(); } | ||
|
||
// property accessor | ||
void getAvailableInputSampleRates(std::vector<AudioValueRange> *result) | ||
{ | ||
UInt32 size; | ||
Boolean writable; | ||
CHECKCA(AudioCodecGetPropertyInfo(m_codec.get(), | ||
kAudioCodecPropertyAvailableInputSampleRates, | ||
&size, &writable)); | ||
std::vector<AudioValueRange> vec(size / sizeof(AudioValueRange)); | ||
CHECKCA(AudioCodecGetProperty(m_codec.get(), | ||
kAudioCodecPropertyAvailableInputSampleRates, | ||
&size, &vec[0])); | ||
result->swap(vec); | ||
} | ||
void getAvailableOutputSampleRates(std::vector<AudioValueRange> *result) | ||
{ | ||
UInt32 size; | ||
Boolean writable; | ||
CHECKCA(AudioCodecGetPropertyInfo(m_codec.get(), | ||
kAudioCodecPropertyAvailableOutputSampleRates, | ||
&size, &writable)); | ||
std::vector<AudioValueRange> vec(size / sizeof(AudioValueRange)); | ||
CHECKCA(AudioCodecGetProperty(m_codec.get(), | ||
kAudioCodecPropertyAvailableOutputSampleRates, | ||
&size, &vec[0])); | ||
result->swap(vec); | ||
} | ||
void getAvailableOutputChannelLayoutTags(std::vector<UInt32> *result) | ||
{ | ||
UInt32 size; | ||
Boolean writable; | ||
CHECKCA(AudioCodecGetPropertyInfo(m_codec.get(), | ||
kAudioCodecPropertyAvailableOutputChannelLayoutTags, | ||
&size, &writable)); | ||
std::vector<UInt32> vec(size/sizeof(UInt32)); | ||
CHECKCA(AudioCodecGetProperty(m_codec.get(), | ||
kAudioCodecPropertyAvailableOutputChannelLayoutTags, | ||
&size, &vec[0])); | ||
result->swap(vec); | ||
} | ||
bool getIsInitialized() | ||
{ | ||
UInt32 value; | ||
UInt32 size = sizeof value; | ||
CHECKCA(AudioCodecGetProperty(m_codec.get(), | ||
kAudioCodecPropertyIsInitialized, &size, &value)); | ||
return !!value; | ||
} | ||
void getApplicableBitRateRange(std::vector<AudioValueRange> *result) | ||
{ | ||
UInt32 size; | ||
Boolean writable; | ||
CHECKCA(AudioCodecGetPropertyInfo(m_codec.get(), | ||
kAudioCodecPropertyApplicableBitRateRange, | ||
&size, &writable)); | ||
std::vector<AudioValueRange> vec(size / sizeof(AudioValueRange)); | ||
CHECKCA(AudioCodecGetProperty(m_codec.get(), | ||
kAudioCodecPropertyApplicableBitRateRange, &size, &vec[0])); | ||
result->swap(vec); | ||
} | ||
|
||
// helpers | ||
bool isAvailableOutputChannelLayout(UInt32 tag) | ||
{ | ||
std::vector<UInt32> tags; | ||
getAvailableOutputChannelLayoutTags(&tags); | ||
return std::find(tags.begin(), tags.end(), tag) != tags.end(); | ||
} | ||
|
||
double getClosestAvailableOutputSampleRate(double value) | ||
{ | ||
std::vector<AudioValueRange> rates; | ||
getAvailableOutputSampleRates(&rates); | ||
double distance = DBL_MAX; | ||
double pick = value; | ||
std::vector<AudioValueRange>::const_iterator it = rates.begin(); | ||
for (; it != rates.end(); ++it) { | ||
if (!it->mMinimum && !it->mMaximum) | ||
continue; | ||
if (it->mMinimum <= value && value <= it->mMaximum) | ||
return value; | ||
double ldiff = std::fabs(value - it->mMinimum), | ||
rdiff = std::fabs(value - it->mMaximum); | ||
double diff = std::min(ldiff, rdiff); | ||
if (distance > diff) { | ||
distance = diff; | ||
pick = ldiff > rdiff ? it->mMaximum : it->mMinimum; | ||
} | ||
} | ||
return pick; | ||
} | ||
private: | ||
static OSStatus fakeDispose(AudioCodec) { return 0; } | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#ifndef AudioComponent_H | ||
#define AudioComponent_H | ||
|
||
#include <CoreFoundation.h> | ||
#include <CoreAudioTypes.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
struct OpaqueAudioComponent; | ||
typedef struct OpaqueAudioComponent *AudioComponent; | ||
|
||
struct OpaqueAudioComponentInstance; | ||
typedef struct OpaqueAudioComponentInstance *AudioComponentInstance; | ||
|
||
typedef struct AudioComponentDescription { | ||
OSType componentType; | ||
OSType componentSubType; | ||
OSType componentManufacturer; | ||
UInt32 componentFlags; | ||
UInt32 componentFlagsMask; | ||
} AudioComponentDescription; | ||
|
||
AudioComponent AudioComponentFindNext( | ||
AudioComponent inAComponent, | ||
AudioComponentDescription *inDesc | ||
); | ||
|
||
OSStatus AudioComponentGetDescription( | ||
AudioComponent inComponent, | ||
AudioComponentDescription *outDesc | ||
); | ||
|
||
OSStatus AudioComponentGetVersion( | ||
AudioComponent inComponent, | ||
UInt32 *outVersion | ||
); | ||
|
||
OSStatus AudioComponentInstanceDispose( | ||
AudioComponentInstance inInstance | ||
); | ||
|
||
OSStatus AudioComponentInstanceNew( | ||
AudioComponent inComponent, | ||
AudioComponentInstance *outInstance | ||
); | ||
|
||
typedef void *CFPlugInFactoryFunction; // XXX | ||
|
||
AudioComponent AudioComponentRegister( | ||
const AudioComponentDescription *inDesc, | ||
CFStringRef inName, | ||
UInt32 inVersion, | ||
CFPlugInFactoryFunction inFactory | ||
); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
Oops, something went wrong.