|
Q: I want to use the StdAudio dialog to configure an AudioConverter but I'm not sure what to do with the |
Standard Audio (QuickTimeComponents.h) | Audio Converter (AudioConverter.h) |
---|---|
kQTSCAudioPropertyID_CodecSpecificSettingsArray | kAudioConverterPropertySettings |
Some (but not all) audio codecs publish settings as a CFDictionaryRef
describing various parameters that are only specific to the codec being configured.
Additionally, every subconverter used by an Audio Converter can potentially have a CFDictionaryRef
of settings. For example, when performing a sample rate conversion from PCM to PCM there will be a dictionary exposed by a rate converter subconverter. The Audio Converter used in such a conversion operation will conglomerate the various CFDictionaryRef
's exposed by its subconverters in the CFArrayRef
returned as the CodecSpecificSettingsArray
property.
When working with Standard Audio, this property is retrieved and set by calling the QTGetComponentProperty
/ QTSetComponentProperty
API pair using the kQTSCAudioPropertyID_CodecSpecificSettingsArray
property ID.
When configuring an audio converter, the codec specific settings array retrieved from StdAudio is set by calling AudioConverterSetProperty
using the kAudioConverterPropertySettings
property ID.
Applications wishing to provide a custom user interface for audio codecs supporting this property may parse the returned CFArrayRef
using the Audio Codec Property Settings keys available in AudioCodec.h
.
When individual values in this array are modified, a client must call QTSetComponentProperty
and pass in the entire array.
Table 2:
Standard Audio (QuickTimeComponents.h) | Audio Converter (AudioConverter.h) |
---|---|
kQTSCAudioPropertyID_MagicCookie | kAudioConverterCompressionMagicCookie |
Some (but not all) audio codecs provide a variable sized "blob" of untyped (void *
) configuration data. This "out of band" data is required to process the stream of encoded audio correctly. This data is considered private to the codec.
When working with Standard Audio this property is retrieved and set by calling the QTGetComponentProperty
/ QTSetComponentProperty
API pair using the kQTSCAudioPropertyID_MagicCookie
property ID. You need to allocate a buffer to hold this data, therefore before calling QTGetComponentProperty
to retrieve the magic cookie a call to QTGetComponentPropertyInfo
is required to get the size, allocate a buffer of the specified size then call QTGetComponentProperty
passing in the newly allocated buffer (see Listing 1).
When configuring an audio converter the magic cookie retrieved from StdAudio is set by calling AudioConverterSetProperty
using the kAudioConverterCompressionMagicCookie
property ID.
Note: An audio converter may require further setup depending on the format conversion being performed, for example a kAudioConverterDecompressionMagicCookie
property may be required. For more information refer to the Core Audio documentation and sample code provided in the Core Audio SDK.
The rules for using the above two properties to configure a Core Audio AudioConverter
are straight forward:
When querying StdAudio, applications should always ask for both the CodecSpecificSettingsArray
and the MagicCookie
.
When configuring a Core Audio AudioConverter
, the CodecSpecificSettingsArray
should be preferred if both properties are available.
If the CodecSpecificSettingsArray
is NOT available use the MagicCookie
if available.
IMPORTANT: If a MagicCookie
is available, it will always be required when creating a Sound Description (using QTSoundDescriptionCreate
) or when using the AudioFile API if the intent is to write the converted audio data to a file, for example a QuickTime movie file (.mov) or a Core Audio file (.caf) and so on.
Listing 1: Snippet for getting and setting properties discussed.
ComponentInstance ci = 0; AudioConverterRef myAudioConverter = NULL; CFArrayRef codecSpecificSettings = NULL; UInt32 magicCookieSize = 0; void * magicCookie = NULL; UInt32 flags; // open StdAudio (added in QuickTime 7.0) err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &ci); if (err) goto bail; // set some configuration properties before bringing up the dialog // such as input ASBD, input channel layout and so on ... // show the dialog (this call blocks until the dialog is finished) err = SCRequestImageSettings(ci); if (err) goto bail; // get the configuration properties specified in the dialog ... // get the codec specific settings if available if (noErr == QTGetComponentPropertyInfo(ci, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_CodecSpecificSettingsArray, NULL, NULL, &flags) && (flags & kComponentPropertyFlagCanGetNow)) { err = QTGetComponentProperty(ci, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_CodecSpecificSettingsArray, sizeof(CFArrayRef), &mCodecSpecificSettings, NULL); if (err) goto bail; } // get the magic cookie if available if (noErr == QTGetComponentPropertyInfo(ci, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_MagicCookie, NULL, &magicCookieSize, NULL) && magicCookieSize) { magicCookie = calloc(1, magicCookieSize); if (NULL == mMagicCookie) { err = memFullErr; goto bail; } err = QTGetComponentProperty(ci, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_MagicCookie, magicCookieSize, magicCookie, &magicCookieSize); if (err) goto bail; } // get more properties as appropriate ... // once we have all the required properties close StdAudio CloseComponent(ci); ci = 0; // create an AudioConverter err = AudioConverterNew(&myInputASBD, &myOutputASBD, &myAudioConverter); if (err) goto bail; // set other Audio Converter properties such as channel layout and so on ... // a codec that has CodecSpecificSettings may have a MagicCookie // prefer the CodecSpecificSettingsArray if you have both if (NULL != codecSpecificSettings) { err = AudioConverterSetProperty(myAudioConverter, kAudioConverterPropertySettings, sizeof(CFArray), codecSpecificSettings); if (err) goto bail; CFRelease(codecSpecificSettings); } else if (NULL != magicCookie) { err = AudioConverterSetProperty(myAudioConverter, kAudioConverterCompressionMagicCookie, magicCookieSize, magicCookie); if (err) goto bail; // we may need the magic cookie later if we're going to write the data to a file // but make sure and remember to free it when we're done! } // continue with any other required setup ... bail: if (err) { If (codecSpecificSettings) CFRelease(codecSpecificSettings); if (magicCookie) free(magicCookie); if (ci) CloseComponent(ci); if (myAudioConverter) AudioConverterDispose(myAudioConverter); // clean up as required ... } return err;
Date | Notes |
---|---|
2006-11-16 | First Version |
Posted: 2006-11-16
|