[xiph-commits] r12394 - in trunk/xiph-qt: CAVorbis/src OggExport/src

arek at svn.xiph.org arek at svn.xiph.org
Mon Jan 29 17:21:27 PST 2007


Author: arek
Date: 2007-01-29 17:21:22 -0800 (Mon, 29 Jan 2007)
New Revision: 12394

Modified:
   trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.cpp
   trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.h
   trunk/xiph-qt/OggExport/src/OggExport.c
   trunk/xiph-qt/OggExport/src/exporter_types.h
   trunk/xiph-qt/OggExport/src/stream_audio.c
Log:
Added UI and configuration handling to Vorbis encoder, plus improved support for audio streams in exporter.

Modified: trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.cpp
===================================================================
--- trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.cpp	2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.cpp	2007-01-30 01:21:22 UTC (rev 12394)
@@ -44,10 +44,6 @@
 #include "debug.h"
 
 
-#if !defined(NO_ACS)
-#define NO_ACS 1
-#endif /* defined(NO_ACS) */
-
 #if !defined(NO_ADV_PROPS)
 #define NO_ADV_PROPS 1
 #endif /* defined(NO_ADV_PROPS) */
@@ -57,9 +53,19 @@
         (x)->mFormatFlags, (x)->mBytesPerPacket, (x)->mFramesPerPacket, (x)->mBytesPerPacket, \
         (x)->mChannelsPerFrame, (x)->mBitsPerChannel
 
+AudioChannelLayoutTag CAVorbisEncoder::gOutChannelLayouts[kVorbisEncoderOutChannelLayouts] = {
+    kAudioChannelLayoutTag_Mono,
+    kAudioChannelLayoutTag_Stereo,
+    //kAudioChannelLayoutTag_ITU_2_1, // there's no tag for [L, C, R] layout!! :(
+    kAudioChannelLayoutTag_Quadraphonic,
+    kAudioChannelLayoutTag_MPEG_5_0_C,
+    kAudioChannelLayoutTag_MPEG_5_1_C,
+};
+
 CAVorbisEncoder::CAVorbisEncoder() :
     mCookie(NULL), mCookieSize(0), mCompressionInitialized(false), mEOSHit(false),
-    last_granulepos(0), last_packetno(0), mVorbisFPList(), mProducedPList()
+    last_granulepos(0), last_packetno(0), mVorbisFPList(), mProducedPList(),
+    mCfgMode(kVorbisEncoderModeQuality), mCfgQuality(0.4), mCfgBitrate(128), mCfgDict(NULL)
 {
     CAStreamBasicDescription theInputFormat1(kAudioStreamAnyRate, kAudioFormatLinearPCM,
                                              0, 1, 0, 0, 32, kAudioFormatFlagsNativeFloatPacked);
@@ -109,6 +115,9 @@
 
         vorbis_info_clear(&mV_vi);
     }
+
+    if (mCfgDict != NULL)
+        CFRelease(mCfgDict);
 }
 
 void CAVorbisEncoder::Initialize(const AudioStreamBasicDescription* inInputFormat,
@@ -171,18 +180,39 @@
     {
 
         /*
-    case kAudioCodecPropertyInputChannelLayout :
     case kAudioCodecPropertyOutputChannelLayout :
         // by default a codec doesn't support channel layouts.
         CODEC_THROW(kAudioCodecIllegalOperationError);
         break;
     case kAudioCodecPropertyAvailableInputChannelLayouts :
-    case kAudioCodecPropertyAvailableOutputChannelLayouts :
-        // by default a codec doesn't support channel layouts.
-        CODEC_THROW(kAudioCodecIllegalOperationError);
-        break;
 	*/
 
+    case kAudioCodecPropertyInputChannelLayout:
+        if (ioPropertyDataSize >= sizeof(AudioChannelLayout)) {
+            fill_channel_layout(mInputFormat.mChannelsPerFrame, reinterpret_cast<AudioChannelLayout*>(outPropertyData));
+        } else {
+            CODEC_THROW(kAudioCodecBadPropertySizeError);
+        }
+        break;
+
+    case kAudioCodecPropertyOutputChannelLayout:
+        if (ioPropertyDataSize >= sizeof(AudioChannelLayout)) {
+            fill_channel_layout(mOutputFormat.mChannelsPerFrame, reinterpret_cast<AudioChannelLayout*>(outPropertyData));
+        } else {
+            CODEC_THROW(kAudioCodecBadPropertySizeError);
+        }
+        break;
+
+    case kAudioCodecPropertyAvailableOutputChannelLayouts:
+        if (ioPropertyDataSize == sizeof(AudioChannelLayoutTag) * kVorbisEncoderOutChannelLayouts) {
+            for (int i = 0; i < kVorbisEncoderOutChannelLayouts; i++) {
+                (reinterpret_cast<AudioChannelLayoutTag*>(outPropertyData))[i] = gOutChannelLayouts[i];
+            }
+        } else {
+            CODEC_THROW(kAudioCodecBadPropertySizeError);
+        }
+        break;
+
     case kAudioCodecPropertyAvailableNumberChannels:
         if(ioPropertyDataSize == sizeof(UInt32) * 1) {
             (reinterpret_cast<UInt32*>(outPropertyData))[0] = 0xffffffff;
@@ -193,8 +223,8 @@
 
     case kAudioCodecPropertyAvailableBitRateRange:
         if (ioPropertyDataSize == sizeof(AudioValueRange) * 1) {
-            (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMinimum = 1.0;
-            (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 480.0;
+            (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMinimum = 8.0;
+            (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 384.0;
         } else {
             CODEC_THROW(kAudioCodecBadPropertySizeError);
         }
@@ -240,7 +270,7 @@
     case kAudioCodecPropertyAvailableInputSampleRates:
         if (ioPropertyDataSize == sizeof(AudioValueRange)) {
             (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMinimum = 0.0;
-            (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 0.0;
+            (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 200000.0;
         } else {
             CODEC_THROW(kAudioCodecBadPropertySizeError);
         }
@@ -249,23 +279,22 @@
     case kAudioCodecPropertyAvailableOutputSampleRates:
         if (ioPropertyDataSize == sizeof(AudioValueRange)) {
             (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMinimum = 0.0;
-            (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 0.0;
+            (reinterpret_cast<AudioValueRange*>(outPropertyData))->mMaximum = 200000.0;
         } else {
             CODEC_THROW(kAudioCodecBadPropertySizeError);
         }
         break;
 
-#if !defined(NO_ACS) || NO_ACS == 0
     case kAudioCodecPropertySettings:
         if (ioPropertyDataSize == sizeof(CFDictionaryRef)) {
             
-            BuildSettings(outPropertyData);
+            if (!BuildSettings(outPropertyData))
+                CODEC_THROW(kAudioCodecUnspecifiedError);
             
         } else {
             CODEC_THROW(kAudioCodecBadPropertySizeError);
         }
         break;
-#endif
 
         
     case kAudioCodecPropertyRequiresPacketDescription:
@@ -294,6 +323,8 @@
             } else {
                 *reinterpret_cast<UInt32*>(outPropertyData) = 0;
             }
+            dbg_printf("[  VE]   . [%08lx] :: GetProperty('%4.4s') = %ld\n", (UInt32) this, reinterpret_cast<char*> (&inPropertyID),
+                       *reinterpret_cast<UInt32*>(outPropertyData));
         }
         else
         {
@@ -384,17 +415,23 @@
     switch(inPropertyID)
     {
         /*
-    case kAudioCodecPropertyInputChannelLayout :
-    case kAudioCodecPropertyOutputChannelLayout :
-        // by default a codec doesn't support channel layouts.
-        CODEC_THROW(kAudioCodecIllegalOperationError);
-        break;
     case kAudioCodecPropertyAvailableInputChannelLayouts :
-    case kAudioCodecPropertyAvailableOutputChannelLayouts :
         // by default a codec doesn't support channel layouts.
         CODEC_THROW(kAudioCodecIllegalOperationError);
         break;
         */
+
+    case kAudioCodecPropertyOutputChannelLayout:
+    case kAudioCodecPropertyInputChannelLayout:
+        outPropertyDataSize = sizeof(AudioChannelLayout);
+        outWritable = false;
+        break;
+
+    case kAudioCodecPropertyAvailableOutputChannelLayouts:
+        outPropertyDataSize = sizeof(AudioChannelLayoutTag) * kVorbisEncoderOutChannelLayouts;
+        outWritable = false;
+        break;
+
     case kAudioCodecPropertyAvailableNumberChannels:
         outPropertyDataSize = sizeof(UInt32) * 1; // [0xffffffff - any number]
         outWritable = false;
@@ -420,12 +457,10 @@
         outWritable = false;
         break;
 
-#if !defined(NO_ACS) || NO_ACS == 0
     case kAudioCodecPropertySettings:
         outPropertyDataSize = sizeof(CFDictionaryRef);
         outWritable = true;
         break;
-#endif
 
         
     case kAudioCodecPropertyRequiresPacketDescription:
@@ -477,15 +512,14 @@
     dbg_printf("[  VE]  >> [%08lx] :: SetProperty('%4.4s')\n", (UInt32) this, reinterpret_cast<char*> (&inPropertyID));
 
     switch(inPropertyID) {
-#if !defined(NO_ACS) || NO_ACS == 0
     case kAudioCodecPropertySettings:
         if (inPropertyDataSize == sizeof(CFDictionaryRef)) {
-            ApplySettings(inPropertyData);
+            if (inPropertyData != NULL)
+                ApplySettings(*reinterpret_cast<const CFDictionaryRef*>(inPropertyData));
         } else {
             CODEC_THROW(kAudioCodecBadPropertySizeError);
         }
         break;
-#endif
 
     default:
         ACBaseCodec::SetProperty(inPropertyID, inPropertyDataSize, inPropertyData);
@@ -514,12 +548,12 @@
     if (!mIsInitialized) {
         //	check to make sure the input format is legal
         if ((inInputFormat.mFormatID != kAudioFormatLinearPCM) ||
+            (inInputFormat.mSampleRate > 200000.0) ||
             !(((inInputFormat.mFormatFlags == kAudioFormatFlagsNativeFloatPacked) &&
                (inInputFormat.mBitsPerChannel == 32)) ||
               ((inInputFormat.mFormatFlags == (kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked)) &&
                (inInputFormat.mBitsPerChannel == 16))))
         {
-            dbg_printf("CAVorbisEncoder::SetFormats: only supports either 16 bit native endian signed integer or 32 bit native endian Core Audio floats for input\n");
             CODEC_THROW(kAudioCodecUnsupportedFormatError);
         }
 
@@ -534,13 +568,19 @@
 {
     if (!mIsInitialized) {
         //	check to make sure the output format is legal
-        if (inOutputFormat.mFormatID != kAudioFormatXiphVorbis) {
-            dbg_printf("CAVorbisEncoder::SetFormats: only supports Xiph Vorbis for output\n");
+        if (inOutputFormat.mFormatID != kAudioFormatXiphVorbis ||
+            inOutputFormat.mSampleRate > 200000.0) {
             CODEC_THROW(kAudioCodecUnsupportedFormatError);
         }
 
         //	tell our base class about the new format
         XCACodec::SetCurrentOutputFormat(inOutputFormat);
+
+        // adjust the default config parameters
+        mCfgBitrate = BitrateMid();
+        if (mOutputFormat.mSampleRate < 8000.0 || mOutputFormat.mSampleRate > 50000.0)
+            mCfgMode = kVorbisEncoderModeQuality;
+        dbg_printf("[  VE]  of [%08lx] :: InitializeCompressionSettings() = br:%ld, m:%d\n", (UInt32) this, mCfgBitrate, mCfgMode);
     } else {
         CODEC_THROW(kAudioCodecStateError);
     }
@@ -600,210 +640,6 @@
     dbg_printf("[  VE] <.. [%08lx] :: FixFormats()\n", (UInt32) this);
 }
 
-
-Boolean CAVorbisEncoder::BuildSettings(void *outSettingsDict)
-{
-    const char *buffer = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-        "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
-        "<plist version=\"1.0\">"
-        "<dict>"
-        "	<key>name</key>"
-        "	<string>Xiph Vorbis Encoder</string>"
-        "	<key>parameters</key>"
-        "	<array>"
-        "		<dict>"
-        "			<key>available values</key>"
-        "			<array>"
-        "				<string>Variable Bit Rate (target quality)</string>"
-        "				<string>Average Bit Rate</string>"
-        "				<string>Variable Bit Rate (target bit rate)</string>"
-        "			</array>"
-        "			<key>current value</key>"
-        "			<integer>0</integer>"
-        "			<key>hint</key>"
-        "			<integer>5</integer>"
-        "			<key>key</key>"
-        "			<string>Target Format</string>"
-        "			<key>name</key>"
-        "			<string>Bit Rate Format</string>"
-        "			<key>summary</key>"
-        "			<string>Vorbis encoding bit rate management mode</string>"
-        "			<key>value type</key>"
-        "			<integer>10</integer>"
-        "		</dict>"
-        "		<dict>"
-        "			<key>available values</key>"
-        "			<array>"
-        "				<string>16</string>"
-        "				<string>20</string>"
-        "				<string>24</string>"
-        "				<string>28</string>"
-        "				<string>32</string>"
-        "				<string>40</string>"
-        "				<string>48</string>"
-        "				<string>56</string>"
-        "				<string>64</string>"
-        "				<string>80</string>"
-        "				<string>96</string>"
-        "				<string>112</string>"
-        "				<string>128</string>"
-        "				<string>160</string>"
-        "				<string>192</string>"
-        "				<string>224</string>"
-        "				<string>256</string>"
-        "				<string>320</string>"
-        "			</array>"
-        "			<key>current value</key>"
-        "			<integer>12</integer>"
-        "			<key>hint</key>"
-        "			<integer>4</integer>"
-        "			<key>key</key>"
-        "			<string>Bit Rate</string>"
-        "			<key>limited values</key>"
-        "			<array>"
-        "				<string>16</string>"
-        "				<string>20</string>"
-        "				<string>24</string>"
-        "				<string>28</string>"
-        "				<string>32</string>"
-        "				<string>40</string>"
-        "				<string>48</string>"
-        "				<string>56</string>"
-        "				<string>64</string>"
-        "				<string>80</string>"
-        "				<string>96</string>"
-        "				<string>112</string>"
-        "				<string>128</string>"
-        "				<string>160</string>"
-        "				<string>192</string>"
-        "				<string>224</string>"
-        "				<string>256</string>"
-        "				<string>320</string>"
-        "			</array>"
-        "			<key>name</key>"
-        "			<string>Target Bit Rate</string>"
-        "			<key>summary</key>"
-        "			<string>The bit rate of the Vorbis bitstream produced by the encoder</string>"
-        "			<key>unit</key>"
-        "			<string>kbps</string>"
-        "			<key>value type</key>"
-        "			<integer>10</integer>"
-        "		</dict>"
-        "		<dict>"
-        "			<key>available values</key>"
-        "			<array>"
-        "				<string>Recommended</string>"
-        "				<string>8.000</string>"
-        "				<string>11.025</string>"
-        "				<string>12.000</string>"
-        "				<string>16.000</string>"
-        "				<string>22.050</string>"
-        "				<string>24.000</string>"
-        "				<string>32.000</string>"
-        "				<string>44.100</string>"
-        "				<string>48.000</string>"
-        "				<string>52.000</string>"
-        "			</array>"
-        "			<key>current value</key>"
-        "			<integer>8</integer>"
-        "			<key>hint</key>"
-        "			<integer>6</integer>"
-        "			<key>key</key>"
-        "			<string>Sample Rate</string>"
-        "			<key>limited values</key>"
-        "			<array>"
-        "				<string>Recommended</string>"
-        "				<string>32.000</string>"
-        "				<string>44.100</string>"
-        "			</array>"
-        "			<key>name</key>"
-        "			<string>Sample Rate</string>"
-        "			<key>summary</key>"
-        "			<string>The sample rate of the Vorbis bitstream produced by the encoder</string>"
-        "			<key>unit</key>"
-        "			<string>kHz</string>"
-        "			<key>value type</key>"
-        "			<integer>10</integer>"
-        "		</dict>"
-        "		<dict>"
-        "			<key>available values</key>"
-        "			<array>"
-        "				<string>None</string>"
-        "				<string>Bit Rate</string>"
-        "				<string>Sample Rate</string>"
-        "			</array>"
-        "			<key>current value</key>"
-        "			<integer>1</integer>"
-        "			<key>hint</key>"
-        "			<integer>13</integer>"
-        "			<key>key</key>"
-        "			<string>Precedence</string>"
-        "			<key>name</key>"
-        "			<string>Precedence</string>"
-        "			<key>summary</key>"
-        "			<string>If either the bit rate or sample rate is allowed to override the other setting</string>"
-        "			<key>value type</key>"
-        "			<integer>10</integer>"
-        "		</dict>"
-        "		<dict>"
-        "			<key>available values</key>"
-        "			<array>"
-        "				<string>Good</string>"
-        "				<string>Better</string>"
-        "				<string>Best</string>"
-        "			</array>"
-        "			<key>current value</key>"
-        "			<integer>1</integer>"
-        "			<key>hint</key>"
-        "			<integer>1</integer>"
-        "			<key>key</key>"
-        "			<string>Quality</string>"
-        "			<key>name</key>"
-        "			<string>Quality</string>"
-        "			<key>summary</key>"
-        "			<string>The quality of the encoded Vorbis bitstream</string>"
-        "			<key>value type</key>"
-        "			<integer>10</integer>"
-        "		</dict>"
-        "		<dict>"
-        "			<key>available values</key>"
-        "			<array>"
-        "				<string>Mono</string>"
-        "				<string>Stereo</string>"
-        "				<string>2.0 (2.1?!)</string>"
-        "				<string>Quadraphonic</string>"
-        "				<string>5.0</string>"
-        "				<string>5.1</string>"
-        "			</array>"
-        "			<key>current value</key>"
-        "			<integer>1</integer>"
-        "			<key>hint</key>"
-        "			<integer>5</integer>"
-        "			<key>key</key>"
-        "			<string>Channel Configuration</string>"
-        "			<key>limited values</key>"
-        "			<array>"
-        "				<string>Stereo</string>"
-        "			</array>"
-        "			<key>name</key>"
-        "			<string>Channel Configuration</string>"
-        "			<key>summary</key>"
-        "			<string>The channel layout of the Vorbis bitstream produced by the encoder</string>"
-        "			<key>value type</key>"
-        "			<integer>10</integer>"
-        "		</dict>"
-        "	</array>"
-        "</dict>"
-        "</plist>";
-    CFDataRef data = CFDataCreate(NULL, (UInt8 *) buffer, strlen(buffer));
-    CFDictionaryRef dict = (CFDictionaryRef) CFPropertyListCreateFromXMLData(NULL, data, kCFPropertyListImmutable, NULL);
-    if (dict != NULL) {
-        *reinterpret_cast<CFDictionaryRef*>(outSettingsDict) = dict;
-        return true;
-    }
-    return false;
-}
-
 void CAVorbisEncoder::InitializeCompressionSettings()
 {
     int ret = 0;
@@ -825,10 +661,35 @@
 
     vorbis_info_init(&mV_vi);
 
-    ret = vorbis_encode_init_vbr(&mV_vi, mOutputFormat.mChannelsPerFrame, lround(mOutputFormat.mSampleRate), 0.4);
+    UInt32 sample_rate = lround(mOutputFormat.mSampleRate);
 
-    if (ret)
+    if (mCfgMode == kVorbisEncoderModeQuality) {
+        ret = vorbis_encode_init_vbr(&mV_vi, mOutputFormat.mChannelsPerFrame, sample_rate, mCfgQuality);
+    } else {
+        UInt32 total_bitrate = mCfgBitrate * 1000;
+        if (mOutputFormat.mChannelsPerFrame > 2)
+            total_bitrate *= mOutputFormat.mChannelsPerFrame;
+
+        dbg_printf("[  VE]  .? [%08lx] :: InitializeCompressionSettings() = br:%ld\n", (UInt32) this, total_bitrate);
+
+        if (mCfgMode == kVorbisEncoderModeAverage) {
+            ret = vorbis_encode_init(&mV_vi, mOutputFormat.mChannelsPerFrame, sample_rate, -1, total_bitrate, -1);
+        } else if (mCfgMode == kVorbisEncoderModeQualityByBitrate) {
+            ret = vorbis_encode_setup_managed(&mV_vi, mOutputFormat.mChannelsPerFrame, sample_rate, -1, total_bitrate, -1);
+            if (!ret)
+                ret = vorbis_encode_ctl(&mV_vi, OV_ECTL_RATEMANAGE2_SET, NULL);
+            if (!ret)
+                ret = vorbis_encode_setup_init(&mV_vi);
+        }
+        if (ret)
+            mCfgBitrate = 128;
+    }
+
+    if (ret) {
+        vorbis_info_clear(&mV_vi);
+        dbg_printf("[  VE] <!! [%08lx] :: InitializeCompressionSettings() = %ld\n", (UInt32) this, ret);
         CODEC_THROW(kAudioCodecUnspecifiedError);
+    }
 
     vorbis_comment_init(&mV_vc);
     vorbis_comment_add_tag(&mV_vc, "ENCODER", "XiphQT, CAVorbisEncoder.cpp $Rev$");
@@ -920,7 +781,6 @@
     if (!mIsInitialized)
         CODEC_THROW(kAudioCodecStateError);
 
-    UInt32 frames = 0;
     UInt32 fout = 0; //frames produced
     UInt32 bout = 0; //bytes produced
     UInt32 bspace = ioOutputDataByteSize;
@@ -1037,3 +897,413 @@
                (UInt32) this, ioNumberPackets, ioOutputDataByteSize, theAnswer);
     return theAnswer;
 }
+
+/* ======================== Settings ======================= */
+Boolean CAVorbisEncoder::BuildSettings(void *outSettingsDict)
+{
+    Boolean ret = false;
+    SInt32 n, ln;
+    CFNumberRef cf_n;
+    CFMutableDictionaryRef sd;
+    CFMutableDictionaryRef eltd;
+    CFMutableArrayRef params;
+
+    if (mCfgDict == NULL) {
+        sd = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        if (sd == NULL)
+            return ret;
+        CFDictionaryAddValue(sd, CFSTR(kAudioSettings_TopLevelKey), CFSTR("Xiph Vorbis Encoder"));
+    }
+
+    params = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+    {
+        eltd = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingKey), CFSTR("Encoding Mode"));
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingName), CFSTR("Encoding Mode"));
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Summary), CFSTR("Vorbis encoding mode."));
+        n = kAudioSettingsFlags_ExpertParameter | kAudioSettingsFlags_MetaParameter;
+        cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Hint), cf_n);
+        CFRelease(cf_n);
+        n = 0;
+        ln = 3;
+        if (mOutputFormat.mSampleRate >= 8000.0 && mOutputFormat.mSampleRate <= 50000.0) {
+            if (mCfgMode == kVorbisEncoderModeAverage)
+                n = 1;
+            else if (mCfgMode == kVorbisEncoderModeQualityByBitrate)
+                n = 2;
+        } else {
+            ln = 1;
+        }
+        cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_CurrentValue), cf_n);
+        CFRelease(cf_n);
+        n = kCFNumberLongType;
+        cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_ValueType), cf_n);
+        CFRelease(cf_n);
+
+        CFStringRef values[4] = {CFSTR("Target Quality"),
+                                 CFSTR("Average Bit Rate"),
+                                 CFSTR("Target Bit Rate Quality"),
+                                 CFSTR("Managed Bit Rate")};
+        CFArrayRef varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(&values), 4, &kCFTypeArrayCallBacks);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_AvailableValues), varr);
+        CFRelease(varr);
+
+        varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(&values), ln, &kCFTypeArrayCallBacks);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_LimitedValues), varr);
+        CFRelease(varr);
+
+        CFArrayAppendValue(params, eltd);
+        CFRelease(eltd);
+    }
+
+    if (mCfgMode == kVorbisEncoderModeQuality) {
+        eltd = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingKey), CFSTR("Encoding Quality"));
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingName), CFSTR("Encoding Quality"));
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Summary), CFSTR("Vorbis encoding quality."));
+        n = 0; // no flags - basic parameter
+        cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Hint), cf_n);
+        CFRelease(cf_n);
+
+        n = lroundf(mCfgQuality * 10.0) + 1;
+        if (n < 0)
+            n = 0;
+        else if (n > 11)
+            n = 11;
+        cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_CurrentValue), cf_n);
+        CFRelease(cf_n);
+
+        n = kCFNumberLongType;
+        cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_ValueType), cf_n);
+        CFRelease(cf_n);
+
+        CFNumberRef values[12];
+        for (UInt32 i = 0; i < 12; i++) {
+            n = i - 1;
+            values[i] = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        }
+        CFArrayRef varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(&values), 12, &kCFTypeArrayCallBacks);
+        for (UInt32 i = 0; i < 12; i++) {
+            CFRelease(values[i]);
+        }
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_AvailableValues), varr);
+        CFRelease(varr);
+
+        CFArrayAppendValue(params, eltd);
+        CFRelease(eltd);
+    } else {
+        eltd = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingKey), CFSTR("Target Bitrate"));
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_SettingName), CFSTR("Target Bitrate"));
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Summary), CFSTR("Target bitrate."));
+        n = 0; // no flags - basic parameter
+        cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Hint), cf_n);
+        CFRelease(cf_n);
+
+        n = ibrn(mCfgBitrate, kVorbisEncoderBitrateSeriesBase);
+        if (n < 0)
+            n = 0;
+        else if (n >= kVorbisEncoderBitrateSeriesLength)
+            n = kVorbisEncoderBitrateSeriesLength - 1;
+        cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_CurrentValue), cf_n);
+        CFRelease(cf_n);
+
+        n = kCFNumberLongType;
+        cf_n = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_ValueType), cf_n);
+        CFRelease(cf_n);
+
+        CFNumberRef values[kVorbisEncoderBitrateSeriesLength];
+        SInt32 brs_min = ibrn(BitrateMin(), kVorbisEncoderBitrateSeriesBase);
+        SInt32 brs_max = ibrn(BitrateMax(), kVorbisEncoderBitrateSeriesBase) - 1;
+        if (brs_max >= kVorbisEncoderBitrateSeriesLength)
+            brs_max = kVorbisEncoderBitrateSeriesLength - 1;
+        if (brs_max < brs_min) {
+            CFRelease(eltd);
+            CFRelease(params);
+            return false;
+        }
+
+        for (UInt32 i = 0; i < kVorbisEncoderBitrateSeriesLength; i++) {
+            n = brn(i, kVorbisEncoderBitrateSeriesBase);
+            values[i] = CFNumberCreate(NULL, kCFNumberLongType, &n);
+        }
+        CFArrayRef varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(&values), kVorbisEncoderBitrateSeriesLength, &kCFTypeArrayCallBacks);
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_AvailableValues), varr);
+        CFRelease(varr);
+
+        if (brs_min > 0 || brs_max < kVorbisEncoderBitrateSeriesLength - 1) {
+            CFNumberRef *limited = &values[brs_min];
+            brs_max = brs_max + 1 - brs_min;
+            if (brs_max > 0) {
+                varr = CFArrayCreate(NULL, reinterpret_cast<const void**>(limited), brs_max, &kCFTypeArrayCallBacks);
+                CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_LimitedValues), varr);
+                CFRelease(varr);
+            }
+        }
+        for (UInt32 i = 0; i < kVorbisEncoderBitrateSeriesLength; i++) {
+            CFRelease(values[i]);
+        }
+
+        CFDictionaryAddValue(eltd, CFSTR(kAudioSettings_Unit), mOutputFormat.mChannelsPerFrame > 2 ? CFSTR("kbps/chan.") : CFSTR("kbps"));
+
+        CFArrayAppendValue(params, eltd);
+        CFRelease(eltd);
+    }
+
+    CFDictionarySetValue(sd, CFSTR(kAudioSettings_Parameters), params);
+    CFRelease(params);
+
+    *reinterpret_cast<CFDictionaryRef*>(outSettingsDict) = sd;
+    ret = true;
+
+    return ret;
+}
+
+Boolean CAVorbisEncoder::ApplySettings(const CFDictionaryRef sd)
+{
+    Boolean ret = false;
+    CFArrayRef params = NULL;
+    CFStringRef name = NULL;
+    CFIndex i, cf_l;
+
+    dbg_printf("[  VE]  >> [%08lx] :: ApplySettings()\n", (UInt32) this);
+
+    name = (CFStringRef) CFDictionaryGetValue(sd, CFSTR(kAudioSettings_TopLevelKey));
+    if (name == NULL || CFStringCompare(name, CFSTR("Xiph Vorbis Encoder"), 0) != kCFCompareEqualTo)
+        return ret;
+
+    params = (CFArrayRef) CFDictionaryGetValue(sd, CFSTR(kAudioSettings_Parameters));
+    if (params == NULL)
+        return ret;
+
+    cf_l = CFArrayGetCount(params);
+    for (i = 0; i < cf_l; i++) {
+        CFDictionaryRef eltd = (CFDictionaryRef) CFArrayGetValueAtIndex(params, i);
+        CFStringRef key = (CFStringRef) CFDictionaryGetValue(eltd, CFSTR(kAudioSettings_SettingKey));
+        CFArrayRef available;
+        CFIndex current;
+        CFNumberRef nval;
+
+        if (key == NULL)
+            continue;
+
+        nval = (CFNumberRef) CFDictionaryGetValue(eltd, CFSTR(kAudioSettings_CurrentValue));
+        available = (CFArrayRef) CFDictionaryGetValue(eltd, CFSTR(kAudioSettings_AvailableValues));
+
+        if (nval == NULL || available == NULL)
+            continue;
+
+        if (!CFNumberGetValue(nval, kCFNumberLongType, &current))
+            continue;
+
+        if (CFStringCompare(key, CFSTR("Encoding Mode"), 0) == kCFCompareEqualTo) {
+            if (current == 0)
+                mCfgMode = kVorbisEncoderModeQuality;
+            else if (current == 1)
+                mCfgMode = kVorbisEncoderModeAverage;
+            else if (current == 2)
+                mCfgMode = kVorbisEncoderModeQualityByBitrate;
+            else
+                return ret;
+            dbg_printf("[  VE]   M [%08lx] :: ApplySettings() :: %d\n", (UInt32) this, mCfgMode);
+        } else if (CFStringCompare(key, CFSTR("Encoding Quality"), 0) == kCFCompareEqualTo) {
+            nval = (CFNumberRef) CFArrayGetValueAtIndex(available, current);
+            SInt32 q = 4;
+            CFNumberGetValue(nval, kCFNumberLongType, &q);
+            if (q < -1 || q > 10)
+                continue;
+            mCfgQuality = (float) q / 10.0;
+            dbg_printf("[  VE]   Q [%08lx] :: ApplySettings() :: %1.1f\n", (UInt32) this, mCfgQuality);
+        } else if (CFStringCompare(key, CFSTR("Target Bitrate"), 0) == kCFCompareEqualTo) {
+            nval = (CFNumberRef) CFArrayGetValueAtIndex(available, current);
+            SInt32 br = 4;
+            CFNumberGetValue(nval, kCFNumberLongType, &br);
+            if (br < BitrateMin())
+                br = BitrateMin();
+            else if (br > BitrateMax())
+                br = BitrateMax();
+            mCfgBitrate = br;
+            dbg_printf("[  VE]   B [%08lx] :: ApplySettings() :: %ld\n", (UInt32) this, mCfgBitrate);
+        }
+    }
+
+    if (mOutputFormat.mSampleRate < 8000.0 || mOutputFormat.mSampleRate > 50000.0)
+        mCfgMode = kVorbisEncoderModeQuality;
+    dbg_printf("[  VE]  !M [%08lx] :: ApplySettings() :: %d\n", (UInt32) this, mCfgMode);
+
+    ret = true;
+    dbg_printf("[  VE] <   [%08lx] :: ApplySettings() = %d\n", (UInt32) this, ret);
+    return ret;
+}
+
+
+UInt32 CAVorbisEncoder::ibrn(UInt32 br, UInt32 bs)
+{
+    UInt32 n = -3; // number of bits - 3
+    UInt32 bn = (br - 1) >> bs;
+    UInt32 _br = bn;
+
+    while (bn) {
+        n++;
+        bn >>= 1;
+    };
+
+    if (n < 0)
+        return 0;
+
+    return (n << 2) + ((_br >> n) & 0x03) + 1;
+}
+
+void CAVorbisEncoder::fill_channel_layout(UInt32 nch, AudioChannelLayout *acl)
+{
+    acl->mChannelBitmap = 0;
+    acl->mNumberChannelDescriptions = 0;
+    switch (nch) {
+    case 1:
+        acl->mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
+        break;
+    case 2:
+        acl->mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
+        break;
+    case 3:
+        /* ITU_2_1 used a.t.m, but 3-channel layout shouldn't be
+           accessible, as it's not the proper layout for vorbis */
+        acl->mChannelLayoutTag = kAudioChannelLayoutTag_ITU_2_1;
+        break;
+    case 4:
+        acl->mChannelLayoutTag = kAudioChannelLayoutTag_Quadraphonic;
+        break;
+    case 5:
+        acl->mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_0_C;
+        break;
+    case 6:
+        acl->mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_1_C;
+        break;
+    default:
+        acl->mChannelLayoutTag = kAudioChannelLayoutTag_DiscreteInOrder | nch;
+        break;
+    }
+}
+
+
+/*
+ * Vorbis bitrate limits depend on modes (sample rate + channel
+ * (un)coupling). The values in the following methods are taken from
+ * the current libvorbis sources, and may need to be changed if they
+ * change in libvorbis.
+ */
+
+SInt32 CAVorbisEncoder::BitrateMin()
+{
+    SInt32 br = -1;
+
+    if (mOutputFormat.mChannelsPerFrame == 2) {
+        if (mOutputFormat.mSampleRate < 9000.0)
+            br = 12;
+        else if (mOutputFormat.mSampleRate < 15000.0)
+            br = 16;
+        else if (mOutputFormat.mSampleRate < 19000.0)
+            br = 24;
+        else if (mOutputFormat.mSampleRate < 26000.0)
+            br = 30;
+        else if (mOutputFormat.mSampleRate < 40000.0)
+            br = 36;
+        else if (mOutputFormat.mSampleRate < 50000.0)
+            br = 45;
+    } else {
+        if (mOutputFormat.mSampleRate < 9000.0)
+            br = 8;
+        else if (mOutputFormat.mSampleRate < 15000.0)
+            br = 12;
+        else if (mOutputFormat.mSampleRate < 19000.0)
+            br = 16;
+        else if (mOutputFormat.mSampleRate < 26000.0)
+            br = 16;
+        else if (mOutputFormat.mSampleRate < 40000.0)
+            br = 30;
+        else if (mOutputFormat.mSampleRate < 50000.0)
+            br = 32;
+    }
+
+    return br;
+}
+
+SInt32 CAVorbisEncoder::BitrateMax()
+{
+    SInt32 br = 0;
+
+    if (mOutputFormat.mChannelsPerFrame == 2) {
+        if (mOutputFormat.mSampleRate < 9000.0)
+            br = 64;
+        else if (mOutputFormat.mSampleRate < 15000.0)
+            br = 88;
+        else if (mOutputFormat.mSampleRate < 19000.0)
+            br = 192;
+        else if (mOutputFormat.mSampleRate < 26000.0)
+            br = 192;
+        else if (mOutputFormat.mSampleRate < 40000.0)
+            br = 380;
+        else if (mOutputFormat.mSampleRate < 50000.0)
+            br = 500;
+    } else {
+        if (mOutputFormat.mSampleRate < 9000.0)
+            br = 42;
+        else if (mOutputFormat.mSampleRate < 15000.0)
+            br = 50;
+        else if (mOutputFormat.mSampleRate < 19000.0)
+            br = 100;
+        else if (mOutputFormat.mSampleRate < 26000.0)
+            br = 90;
+        else if (mOutputFormat.mSampleRate < 40000.0)
+            br = 190;
+        else if (mOutputFormat.mSampleRate < 50000.0)
+            br = 240;
+    }
+
+    return br;
+}
+
+SInt32 CAVorbisEncoder::BitrateMid()
+{
+    SInt32 br = 128;
+
+    if (mOutputFormat.mChannelsPerFrame == 2) {
+        if (mOutputFormat.mSampleRate < 9000.0)
+            br = 32;
+        else if (mOutputFormat.mSampleRate < 15000.0)
+            br = 48;
+        else if (mOutputFormat.mSampleRate < 19000.0)
+            br = 86;
+        else if (mOutputFormat.mSampleRate < 26000.0)
+            br = 86;
+        else if (mOutputFormat.mSampleRate < 40000.0)
+            br = 128;
+        else if (mOutputFormat.mSampleRate < 50000.0)
+            br = 128;
+    } else {
+        if (mOutputFormat.mSampleRate < 9000.0)
+            br = 20;
+        else if (mOutputFormat.mSampleRate < 15000.0)
+            br = 24;
+        else if (mOutputFormat.mSampleRate < 19000.0)
+            br = 48;
+        else if (mOutputFormat.mSampleRate < 26000.0)
+            br = 48;
+        else if (mOutputFormat.mSampleRate < 40000.0)
+            br = 96;
+        else if (mOutputFormat.mSampleRate < 50000.0)
+            br = 96;
+    }
+
+    return br;
+}

Modified: trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.h
===================================================================
--- trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.h	2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/CAVorbis/src/CAVorbisEncoder.h	2007-01-30 01:21:22 UTC (rev 12394)
@@ -89,8 +89,19 @@
 
     virtual void        FixFormats();
 
+    SInt32              BitrateMin();
+    SInt32              BitrateMax();
+    SInt32              BitrateMid();
+
+    /* bitrate-series generator and inverse generator functions */
+    static UInt32       brn(UInt32 n, UInt32 bs) { return (4 + n % 4) << ((n >> 2) + bs); };
+    static UInt32       ibrn(UInt32 br, UInt32 bs);
+
+    static void         fill_channel_layout(UInt32 nch, AudioChannelLayout *acl);
+
  private:
     Boolean             BuildSettings(void *outSettingsDict);
+    Boolean             ApplySettings(CFDictionaryRef sd);
 
  protected:
     Byte* mCookie;
@@ -136,8 +147,27 @@
         /* Just a funny number, and only roughly valid for the 'Xiph (Ogg-Framed) Vorbis'. */
         kVorbisFormatMaxBytesPerPacket = 255 * 255,
 
-        kVorbisEncoderBufferSize = 256 * 1024
+        kVorbisEncoderBufferSize = 256 * 1024,
+
+        kVorbisEncoderOutChannelLayouts = 5,
+
+        kVorbisEncoderBitrateSeriesLength = 23,
+        kVorbisEncoderBitrateSeriesBase = 1,
     };
+
+    static AudioChannelLayoutTag gOutChannelLayouts[kVorbisEncoderOutChannelLayouts];
+
+    /* settings */
+    enum VorbisEncoderMode {
+        kVorbisEncoderModeQuality = 0,
+        kVorbisEncoderModeAverage,
+        kVorbisEncoderModeQualityByBitrate,
+    };
+    VorbisEncoderMode mCfgMode;
+    float mCfgQuality; // [-0.1; 1.0] quality range
+    SInt32 mCfgBitrate; // in kbits
+
+    CFMutableDictionaryRef mCfgDict;
 };
 
 #endif /* __CAVorbisEncoder_h__ */

Modified: trunk/xiph-qt/OggExport/src/OggExport.c
===================================================================
--- trunk/xiph-qt/OggExport/src/OggExport.c	2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/OggExport/src/OggExport.c	2007-01-30 01:21:22 UTC (rev 12394)
@@ -128,10 +128,16 @@
 static ComponentResult mux_streams(OggExportGlobalsPtr globals, DataHandler data_h);
 
 static ComponentResult _setup_std_video(OggExportGlobalsPtr globals, ComponentInstance stdVideo);
+static ComponentResult _setup_std_audio(OggExportGlobalsPtr globals, ComponentInstance stdAudio);
 static ComponentResult _get_std_video_config(OggExportGlobalsPtr globals, ComponentInstance stdVideo);
+static ComponentResult _get_std_audio_config(OggExportGlobalsPtr globals, ComponentInstance stdAudio);
 static ComponentResult _video_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings);
+static ComponentResult _audio_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings);
 static ComponentResult _ac_to_video_settings(OggExportGlobalsPtr globals, QTAtomContainer settings);
+static ComponentResult _ac_to_audio_settings(OggExportGlobalsPtr globals, QTAtomContainer settings);
 
+static ComponentResult _preconfig_stdaudio(ComponentInstance stdAudio);
+
 static ComponentResult _movie_fps(Movie theMovie, Fixed *fps);
 
 
@@ -181,10 +187,16 @@
         globals->set_v_custom = NULL;
         globals->set_v_ci = NULL;
 
-        globals->set_a_quality = codecNormalQuality;
-        globals->set_a_bitrate = 0;
-        globals->set_a_samplerate = 0;
+        globals->set_a_rquality = 0x40; //!kRenderQuality_Medium;
+        globals->set_a_settings = NULL;
+        globals->set_a_custom = NULL;
+        globals->set_a_ci = NULL;
 
+        memset(&globals->set_a_asbd, 0, sizeof(AudioStreamBasicDescription));
+        globals->set_a_asbd.mFormatID = kAudioFormatXiphVorbis;
+        globals->set_a_asbd.mChannelsPerFrame = 6;
+
+
         globals->setdlg_a_allow = true;
         globals->setdlg_v_allow = true;
 
@@ -226,6 +238,15 @@
         if (globals->set_v_settings)
             QTDisposeAtomContainer(globals->set_v_settings);
 
+        if (globals->set_a_ci)
+            CloseComponent(globals->set_a_ci);
+
+        if (globals->set_a_custom)
+            CFRelease(globals->set_a_custom);
+
+        if (globals->set_a_settings)
+            QTDisposeAtomContainer(globals->set_a_settings);
+
         DisposePtr((Ptr) globals);
     }
 
@@ -301,13 +322,19 @@
             break;
 
         default:
-            err = kQTPropertyNotSupportedErr;
+            //err = kQTPropertyNotSupportedErr;
+            err = QTSetComponentProperty(globals->quickTimeMovieExporter, inPropClass,
+                                         inPropID, inPropValueSize, inPropValueAddress);
+
             break;
         }
         break;
 
     default:
-        err = kQTPropertyNotSupportedErr;
+        //err = kQTPropertyNotSupportedErr;
+        err = QTSetComponentProperty(globals->quickTimeMovieExporter, inPropClass,
+                                     inPropID, inPropValueSize, inPropValueAddress);
+
         break;
     }
 
@@ -384,7 +411,7 @@
 
     dbg_printf("[  OE]  >> [%08lx] :: ToDataRef(%d, %ld, %ld)\n", (UInt32) globals, onlyThisTrack != NULL, startTime, duration);
 
-    // TODO: loop for all tracks
+    // TODO: loop for all tracks...?
 
     if (globals->set_v_disable != 1) {
         err = MovieExportNewGetDataAndPropertiesProcs(globals->quickTimeMovieExporter, VideoMediaType, &scale, theMovie,
@@ -570,7 +597,6 @@
             err = SCRequestSequenceSettings(stdVideo);
 
         if (!err) {
-            /* TODO: get config from the stdComp and store it */
             if (globals->set_v_settings) {
                 QTDisposeAtomContainer(globals->set_v_settings);
                 globals->set_v_settings = NULL;
@@ -582,7 +608,8 @@
             }
         }
 
-        //CloseComponent(stdVideo);
+        if (globals->set_v_ci == NULL)
+            CloseComponent(stdVideo);
 
         if (ph != NULL)
             DisposeHandle((Handle) ph);
@@ -592,6 +619,116 @@
     return err;
 }
 
+ComponentResult ConfigAndShowStdAudioDlg(OggExportGlobalsPtr globals, WindowRef window)
+{
+    ComponentResult err = noErr;
+    ComponentInstance stdAudio = globals->set_a_ci;
+    SCExtendedProcs xProcs;
+
+    dbg_printf("[  OE]  >> [%08lx] :: ConfigAndShowStdAudioDlg() [%08lx, %08lx]\n", (UInt32) globals, (UInt32) stdAudio, (UInt32) globals->set_a_settings);
+
+    if (stdAudio == NULL) {
+        err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudio);
+        dbg_printf("[  OE]  !a [%08lx] :: ConfigAndShowStdAudioDlg() = %ld [%08lx]\n", (UInt32) globals, err, (UInt32) stdAudio);
+    }
+
+    if (!err) {
+        memset(&xProcs, 0, sizeof(xProcs));
+        strcpy((char*)xProcs.customName + 1, "Select Output Format");
+        xProcs.customName[0] = (unsigned char) strlen((char*) xProcs.customName + 1);
+        (void) QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                      kQTSCAudioPropertyID_ExtendedProcs,
+                                      sizeof(xProcs), &xProcs);
+
+        if (globals->set_a_settings == NULL) {
+            err = _setup_std_audio(globals, stdAudio);
+            dbg_printf("[  OE]  ?' [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+        }
+
+        if (!err && globals->setdlg_movie != NULL) {
+            SoundDescriptionHandle sdh = (SoundDescriptionHandle) NewHandle(0);
+            Media media;
+            Track track = globals->setdlg_track;
+            if (track == NULL)
+                track = GetMovieIndTrackType(globals->setdlg_movie, 1, AudioMediaCharacteristic,
+                                             movieTrackCharacteristic | movieTrackEnabledOnly);
+            if (track != NULL)
+                media = GetTrackMedia(track);
+
+            if (media != NULL)
+                GetMediaSampleDescription(media, 1, (SampleDescriptionHandle) sdh);
+
+            if (GetHandleSize((Handle) sdh) > 0) {
+                /*
+                SoundDescriptionV2Handle sd2h;
+                QTSoundDescriptionConvert(kQTSoundDescriptionKind_Movie_AnyVersion,
+                                          (SoundDescriptionHandle) sdh,
+                                          kQTSoundDescriptionKind_Movie_Version2,
+                                          &sdh);
+                */
+                err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                             kQTSCAudioPropertyID_InputSoundDescription,
+                                             sizeof(SoundDescriptionHandle), &sdh);
+                dbg_printf("[  OE]  sd [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+            }
+            DisposeHandle((Handle) sdh);
+        } else {
+            /*
+            AudioStreamBasicDescription asbd = { 44100.0, kAudioFormatLinearPCM, kAudioFormatFlagsNativeFloatPacked, 24, 1, 24, 6, 32, 0 };
+
+            err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                         kQTSCAudioPropertyID_InputBasicDescription,
+                                         sizeof(AudioStreamBasicDescription), &asbd);
+            */
+            err = _preconfig_stdaudio(stdAudio);
+            dbg_printf("[  OE]  bd [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+        }
+
+        if (globals->set_a_settings != NULL) {
+            err = SCSetSettingsFromAtomContainer(stdAudio, globals->set_a_settings);
+            dbg_printf("[  OE]  ?\" [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+        }
+
+        if (!err) {
+            OSType formats[1] = { kAudioFormatXiphVorbis };
+            err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                         kQTSCAudioPropertyID_ClientRestrictedCompressionFormatList,
+                                         sizeof(OSType) * 1, formats);
+            dbg_printf("[  OE]  fl [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+        }
+
+        if (!err) {
+            QTAtomContainer std_a_settings = NULL;
+            err = SCGetSettingsAsAtomContainer(stdAudio, &std_a_settings);
+            dbg_printf("[  OE]  ?S [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+            if (!err) {
+                err = SCSetSettingsFromAtomContainer(stdAudio, std_a_settings);
+                dbg_printf("[  OE]  !S [%08lx] :: ConfigAndShowStdAudioDlg() = %ld\n", (UInt32) globals, err);
+            }
+        }
+
+        if (!err)
+            err = SCRequestImageSettings(stdAudio);
+
+        if (!err) {
+            if (globals->set_a_settings) {
+                QTDisposeAtomContainer(globals->set_a_settings);
+                globals->set_a_settings = NULL;
+            }
+            err = SCGetSettingsAsAtomContainer(stdAudio, &globals->set_a_settings);
+            if (err && globals->set_a_settings) {
+                QTDisposeAtomContainer(globals->set_a_settings);
+                globals->set_a_settings = NULL;
+            }
+        }
+
+        if (globals->set_a_ci == NULL)
+            CloseComponent(stdAudio);
+    }
+
+    return err;
+}
+
 #if USE_NIB_FILE
 static pascal OSStatus SettingsWindowEventHandler(EventHandlerCallRef inHandler, EventRef inEvent, void *inUserData)
 {
@@ -644,6 +781,14 @@
             //globals->set_v_settings = NULL;
         }
 
+        if (globals->set_a_ci != NULL) {
+            /* result = */ _get_std_audio_config(globals, globals->set_a_ci);
+        } else if (globals->set_a_settings != NULL) {
+            /* result = */ _ac_to_audio_settings(globals, globals->set_a_settings);
+            //QTDisposeAtomContainer(globals->set_v_settings);
+            //globals->set_v_settings = NULL;
+        }
+
         QuitAppModalLoopForWindow(window);
         result = noErr;
         break;
@@ -662,26 +807,10 @@
         break;
 
     case 'OEca':                /* O(gg)E(xport)c(onfigure)a(udio) */
-        {
-            SCExtendedProcs xProcs;
-            ComponentInstance stdAudio;
+        result = ConfigAndShowStdAudioDlg(globals, window);
+        if (result == userCanceledErr || result == scUserCancelled)
+            result = noErr;
 
-            result = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudio);
-            if (result == noErr) {
-                memset(&xProcs, 0, sizeof(xProcs));
-                strcpy((char*)xProcs.customName + 1, "Select Output Format");
-                xProcs.customName[0] = (unsigned char) strlen((char*) xProcs.customName + 1);
-                (void) QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
-                                              kQTSCAudioPropertyID_ExtendedProcs,
-                                              sizeof(xProcs), &xProcs);
-
-                result = SCRequestImageSettings(stdAudio);
-                if (result == userCanceledErr)
-                    result = noErr; // User cancelling is ok.
-                CloseComponent(stdAudio);
-            }
-        }
-
         break;
 
     case 'OEea':                /* O(gg)E(xport)e(nable)a(udio) */
@@ -936,6 +1065,30 @@
             goto bail;
     }
 
+    if (globals->set_a_disable == 0) {
+        QTAtomContainer as = NULL;
+        err = noErr;
+        if (globals->set_a_settings != NULL) {
+            as = globals->set_a_settings;
+        } else {
+            err = QTNewAtomContainer(&as);
+            if (!err)
+                err = _audio_settings_to_ac(globals, &as);
+        }
+
+        if (!err) {
+            dbg_printf("[  OE] aAC [%08lx] :: GetSettingsAsAtomContainer() = %ld %ld\n", (UInt32) globals, err, GetHandleSize(as));
+
+            err = QTInsertChildren(ac, kParentAtomIsContainer, as);
+
+            if (globals->set_a_settings == NULL)
+                QTDisposeAtomContainer(as);
+        }
+
+        if (err)
+            goto bail;
+    }
+
  bail:
     if (err && ac) {
         QTDisposeAtomContainer(ac);
@@ -1001,6 +1154,24 @@
             goto bail;
     }
 
+    atom = QTFindChildByID(settings, kParentAtomIsContainer, kQTSettingsSound, 1, NULL);
+    if (atom) {
+        if (globals->set_a_settings) {
+            QTDisposeAtomContainer(globals->set_a_settings);
+            globals->set_a_settings = NULL;
+        }
+        err = QTCopyAtom(settings, atom, &globals->set_a_settings);
+        if (err)
+            goto bail;
+        err = _ac_to_audio_settings(globals, globals->set_a_settings);
+
+        //QTDisposeAtomContainer(globals->set_a_settings);
+        //globals->set_a_settings = NULL;
+
+        if (err)
+            goto bail;
+    }
+
  bail:
     dbg_printf("[  OE] <   [%08lx] :: SetSettingsFromAtomContainer() = %d\n", (UInt32) globals, err);
     return err;
@@ -1051,55 +1222,36 @@
 
 static OSErr ConfigureQuickTimeMovieExporter(OggExportGlobalsPtr globals)
 {
-    ComponentInstance  stdComp = NULL;
-    QTAtomContainer    movieExporterSettings = NULL;
+    QTAtomContainer    settings = NULL;
     OSErr              err;
 
     dbg_printf("[  OE]  >> [%08lx] :: ConfigureQuickTimeMovieExporter()\n", (UInt32) globals);
 
-    /* TODO: make this function do something */
+    err = MovieExportGetSettingsAsAtomContainer(globals->self, &settings);
+    dbg_printf("[  OE]  gO [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
+    if (!err) {
+        /* quicktime movie exporter seems to have problems with 0.0/recommended sample rates in output -
+           removing all the audio atoms for now */
+        QTAtom atom = QTFindChildByID(settings, kParentAtomIsContainer, kQTSettingsSound, 1, NULL);
+        if (atom) {
+            QTRemoveAtom(settings, atom);
+        }
 
-    /*
-    // Open the Standard Compression component
-    err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudioCompression);
-    if (err)
-        goto bail;
+        err = MovieExportSetSettingsFromAtomContainer(globals->quickTimeMovieExporter, settings);
+        dbg_printf("[  OE]  sE [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
 
-    // Get the settings atom
-    err = SCGetSettingsAsAtomContainer(stdAudioCompression, &movieExporterSettings);
-    if (err)
-        goto bail;
-
-    // Set the compression settings for the QT Movie Exporter
-    //err = MovieExportSetSettingsFromAtomContainer(globals->quickTimeMovieExporter, movieExporterSettings);
-    */
-
-    /*
-    if (globals->set_v_settings) {
-        err = MovieExportSetSettingsFromAtomContainer(globals->quickTimeMovieExporter, globals->set_v_settings);
-        dbg_printf("[  OE]  =S [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
-    } else {
-        err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubType, &stdComp);
         if (!err) {
+            err = QTSetComponentProperty(globals->quickTimeMovieExporter, kQTPropertyClass_SCAudio,
+                                         kQTSCAudioPropertyID_RenderQuality,
+                                         sizeof(UInt32), &globals->set_a_rquality);
+            dbg_printf("[  OE]  Rq [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld [%08lx]\n", (UInt32) globals, err, (UInt32) globals->set_a_rquality);
+            err = noErr;
         }
     }
-    */
 
-    err = MovieExportGetSettingsAsAtomContainer(globals->self, &movieExporterSettings);
-    dbg_printf("[  OE]  gO [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
-    if (!err) {
-        err = MovieExportSetSettingsFromAtomContainer(globals->quickTimeMovieExporter, movieExporterSettings);
-        dbg_printf("[  OE]  sE [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
-    }
+    if (settings)
+        DisposeHandle(settings);
 
-
- bail:
-    if (stdComp)
-        CloseComponent(stdComp);
-
-    if (movieExporterSettings)
-        DisposeHandle(movieExporterSettings);
-
     dbg_printf("[  OE] <   [%08lx] :: ConfigureQuickTimeMovieExporter() = %ld\n", (UInt32) globals, err);
     return err;
 }
@@ -1449,7 +1601,9 @@
 
     if (!err) {
         *(OSType *)*codec_types = kXiphComponentsManufacturer;
-        err = SCSetInfo(stdVideo, scCodecManufacturerType, &codec_types);
+        HLock(codec_types);
+        err = SCSetInfo(stdVideo, scCodecManufacturerType, *codec_types);
+        HUnlock(codec_types);
     }
 
     DisposeHandle(codec_types);
@@ -1467,6 +1621,46 @@
     return err;
 }
 
+static ComponentResult _setup_std_audio(OggExportGlobalsPtr globals, ComponentInstance stdAudio)
+{
+    ComponentResult err = noErr;
+    /* isbd's mChannelsPerFrame should be set to the highest number of
+       channels supported by the supported audio encoder, and mSampleRate should be non-zero */
+    AudioStreamBasicDescription isbd = { 44100.0, kAudioFormatLinearPCM, kAudioFormatFlagsNativeFloatPacked, 24, 1, 24, 6, 32, 0 };
+
+    dbg_printf("[  OE]  >> [%08lx] :: _setup_std_audio()\n", (UInt32) globals);
+
+    /* Can't set output description (if it contains 0.0 samplerate?) without input format set :( */
+    err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                 kQTSCAudioPropertyID_InputBasicDescription,
+                                 sizeof(isbd), &isbd);
+    dbg_printf("[  OE]  i? [%08lx] :: _setup_std_audio() = %ld\n", (UInt32) globals, err);
+
+    if (!err) {
+        err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                     kQTSCAudioPropertyID_BasicDescription,
+                                     sizeof(AudioStreamBasicDescription), &globals->set_a_asbd);
+        dbg_printf("[  OE]  o! [%08lx] :: _setup_std_audio() = %ld\n", (UInt32) globals, err);
+    }
+
+    if (!err) {
+        err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                     kQTSCAudioPropertyID_RenderQuality,
+                                     sizeof(UInt32), &globals->set_a_rquality);
+        dbg_printf("[  OE]  rq [%08lx] :: _setup_std_audio() = %ld [%08lx]\n", (UInt32) globals, err, (UInt32) globals->set_a_rquality);
+    }
+
+    if (!err && globals->set_a_custom != NULL) {
+        err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                     kQTSCAudioPropertyID_CodecSpecificSettingsArray,
+                                     sizeof(CFArrayRef), &globals->set_a_custom);
+        dbg_printf("[  OE]  cs [%08lx] :: _setup_std_audio() = %ld\n", (UInt32) globals, err);
+    }
+
+    dbg_printf("[  OE] <   [%08lx] :: _setup_std_audio() = %ld [%08lx]\n", (UInt32) globals, err, (UInt32) stdAudio);
+    return err;
+}
+
 static ComponentResult _get_std_video_config(OggExportGlobalsPtr globals, ComponentInstance stdVideo)
 {
     ComponentResult err = noErr;
@@ -1506,6 +1700,53 @@
     return err;
 }
 
+static ComponentResult _get_std_audio_config(OggExportGlobalsPtr globals, ComponentInstance stdAudio)
+{
+    ComponentResult err = noErr;
+    Boolean tmpbool = false;
+
+    err = QTGetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                 kQTSCAudioPropertyID_BasicDescription,
+                                 sizeof(AudioStreamBasicDescription),
+                                 &globals->set_a_asbd, NULL);
+
+    if (!err) {
+        err = QTGetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                     kQTSCAudioPropertyID_SampleRateIsRecommended,
+                                     sizeof(Boolean),
+                                     &tmpbool, NULL);
+        if (!err && tmpbool)
+            globals->set_a_asbd.mSampleRate = 0.0;
+        dbg_printf("[  OE] rec [%08lx] :: _get_std_audio_config() = %ld, %d\n", (UInt32) globals, err, tmpbool);
+    }
+
+    if (!err) {
+        err = QTGetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                     kQTSCAudioPropertyID_RenderQuality,
+                                     sizeof(UInt32),
+                                     &globals->set_a_rquality, NULL);
+    }
+
+    if (!err) {
+        if (globals->set_a_custom != NULL) {
+            CFRelease(globals->set_a_custom);
+            globals->set_a_custom = NULL;
+        }
+        err = QTGetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                     kQTSCAudioPropertyID_CodecSpecificSettingsArray,
+                                     sizeof(CFArrayRef),
+                                     &globals->set_a_custom, NULL);
+        if (err && globals->set_a_custom != NULL) {
+            CFRelease(globals->set_a_custom);
+            globals->set_a_custom = NULL;
+        } else if (!err) {
+            CFRetain(globals->set_a_custom);
+        }
+    }
+
+    return err;
+}
+
 static ComponentResult _video_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings)
 {
     ComponentResult err = noErr;
@@ -1528,6 +1769,29 @@
     return err;
 }
 
+static ComponentResult _audio_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings)
+{
+    ComponentResult err = noErr;
+    ComponentInstance stdAudio = NULL;
+
+    dbg_printf("[  OE]  >> [%08lx] :: _audio_settings_to_ac()\n", (UInt32) globals);
+
+    err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudio);
+
+    if (!err) {
+        err = _setup_std_audio(globals, stdAudio);
+        dbg_printf("[  OE]  .? [%08lx] :: _audio_settings_to_ac() = %ld\n", (UInt32) globals, err);
+
+        if (!err)
+            err = SCGetSettingsAsAtomContainer(stdAudio, settings);
+
+        CloseComponent(stdAudio);
+    }
+
+    dbg_printf("[  OE] <   [%08lx] :: _audio_settings_to_ac() = %d [%ld]\n", (UInt32) globals, err, GetHandleSize(*settings));
+    return err;
+}
+
 static ComponentResult _ac_to_video_settings(OggExportGlobalsPtr globals, QTAtomContainer settings)
 {
     ComponentResult err = noErr;
@@ -1551,6 +1815,45 @@
     return err;
 }
 
+static ComponentResult _ac_to_audio_settings(OggExportGlobalsPtr globals, QTAtomContainer settings)
+{
+    ComponentResult err = noErr;
+    ComponentInstance stdAudio = NULL;
+
+    dbg_printf("[  OE]  >> [%08lx] :: _ac_to_audio_settings() [%ld]\n", (UInt32) globals, GetHandleSize(settings));
+
+    err = OpenADefaultComponent(StandardCompressionType, StandardCompressionSubTypeAudio, &stdAudio);
+
+    if (!err)
+        err = _preconfig_stdaudio(stdAudio);
+
+    if (!err) {
+        err = SCSetSettingsFromAtomContainer(stdAudio, settings);
+
+        if (!err)
+            err = _get_std_audio_config(globals, stdAudio);
+
+        CloseComponent(stdAudio);
+    }
+
+    dbg_printf("[  OE] <   [%08lx] :: _ac_to_audio_settings() = %ld\n", (UInt32) globals, err);
+    return err;
+}
+
+static ComponentResult _preconfig_stdaudio(ComponentInstance stdAudio)
+{
+    ComponentResult err = noErr;
+    /* Can't set output description (if it contains 0.0 samplerate?) without input format set :( */
+    AudioStreamBasicDescription isbd = { 44100.0, kAudioFormatLinearPCM, kAudioFormatFlagsNativeFloatPacked, 24, 1, 24, 6, 32, 0 };
+
+    err = QTSetComponentProperty(stdAudio, kQTPropertyClass_SCAudio,
+                                 kQTSCAudioPropertyID_InputBasicDescription,
+                                 sizeof(isbd), &isbd);
+
+    dbg_printf("[  OE]   = [%08lx] :: _preconfig_stdaudio() = %ld\n", (UInt32) -1, err);
+    return err;
+}
+
 static ComponentResult _movie_fps(Movie theMovie, Fixed *fps)
 {
     ComponentResult err = noErr;

Modified: trunk/xiph-qt/OggExport/src/exporter_types.h
===================================================================
--- trunk/xiph-qt/OggExport/src/exporter_types.h	2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/OggExport/src/exporter_types.h	2007-01-30 01:21:22 UTC (rev 12394)
@@ -136,9 +136,11 @@
     Handle             set_v_custom;
     ComponentInstance  set_v_ci;
 
-    CodecQ             set_a_quality;
-    UInt32             set_a_bitrate;
-    Float64            set_a_samplerate;
+    CodecQ             set_a_rquality;        /**< processing chain's render quality */
+    AudioStreamBasicDescription set_a_asbd;   /**< audio codec's target output format settings */
+    QTAtomContainer    set_a_settings;        /**< all audio codec's settings */
+    CFArrayRef         set_a_custom;          /**< specific codec-only settings */
+    ComponentInstance  set_a_ci;
 
     /* settings dialog vars */
     Boolean            setdlg_a_allow;

Modified: trunk/xiph-qt/OggExport/src/stream_audio.c
===================================================================
--- trunk/xiph-qt/OggExport/src/stream_audio.c	2007-01-29 22:37:46 UTC (rev 12393)
+++ trunk/xiph-qt/OggExport/src/stream_audio.c	2007-01-30 01:21:22 UTC (rev 12394)
@@ -37,6 +37,9 @@
 
 #include "debug.h"
 
+extern ComponentResult _audio_settings_to_ac(OggExportGlobalsPtr globals, QTAtomContainer *settings);
+
+
 static ComponentResult
 _flush_ogg(StreamInfoPtr si, DataHandler data_h, wide *offset)
 {
@@ -114,7 +117,7 @@
     StreamInfoPtr si = (StreamInfoPtr) inRefCon;
     ComponentResult err = noErr;
 
-    dbg_printf("[  OE]  >> [%08lx] :: _InputDataProc__audio(%ld)\n",
+    dbg_printf("[ aOE]  >> [%08lx] :: _InputDataProc__audio(%ld)\n",
                (UInt32) -1, *ioNumberDataPackets);
 
     *ioNumberDataPackets = 0;
@@ -138,7 +141,7 @@
 
             err = InvokeMovieExportGetDataUPP(si->refCon, &si->gdp,
                                               si->getDataProc);
-            dbg_printf("[  OE]  <  [%08lx] :: _InputDataProc__audio() = %ld; "
+            dbg_printf("[ aOE]  <  [%08lx] :: _InputDataProc__audio() = %ld; "
                        "%ld, %ld, %ld, %ld, %ld)\n",
                        (UInt32) -1, err, *ioNumberDataPackets, si->gdp.dataSize,
                        si->gdp.requestedTime, si->gdp.actualTime, ioData->mNumberBuffers);
@@ -172,7 +175,7 @@
         si->gdp.requestedTime = si->gdp.actualTime = 0;
     }
 
-    dbg_printf("[  OE] <   [%08lx] :: _InputDataProc__audio(%ld, "
+    dbg_printf("[ aOE] <   [%08lx] :: _InputDataProc__audio(%ld, "
                "%ld, %ld, %ld, %ld, %d) = %ld\n",
                (UInt32) -1, *ioNumberDataPackets, si->gdp.dataSize,
                si->gdp.requestedTime, si->gdp.actualTime, ioData->mNumberBuffers,
@@ -332,7 +335,7 @@
 
         if (!err) {
             sd = (SoundDescriptionV2Ptr) *sdh;
-            dbg_printf("[  OE]   i [%08lx] :: configure_stream__audio() = %ld, '%4.4s' ('%4.4s', %d, %d, '%4.4s', [%ld, %ld, %lf] [%ld, %ld, %ld, %ld])\n",
+            dbg_printf("[ aOE]   i [%08lx] :: configure_stream__audio() = %ld, '%4.4s' ('%4.4s', %d, %d, '%4.4s', [%ld, %ld, %lf] [%ld, %ld, %ld, %ld])\n",
                        (UInt32) globals, err, (char *) &si->gdp.descType,
                        (char *) &sd->dataFormat, sd->version, sd->revlevel, (char *) &sd->vendor,
                        sd->numAudioChannels, sd->constBitsPerChannel, sd->audioSampleRate,
@@ -359,14 +362,14 @@
                 err = QTSoundDescriptionGetPropertyInfo(sdh, kQTPropertyClass_SoundDescription,
                                                         kQTSoundDescriptionPropertyID_AudioChannelLayout,
                                                         NULL, &acl_size, NULL);
-                dbg_printf("[  OE]  cl [%08lx] :: configure_stream__audio() = %ld, %ld\n",
+                dbg_printf("[ aOE]  cl [%08lx] :: configure_stream__audio() = %ld, %ld\n",
                            (UInt32) globals, err, acl_size);
                 if (!err) {
                     acl = (AudioChannelLayout *) calloc(1, acl_size);
                     err = QTSoundDescriptionGetProperty(sdh, kQTPropertyClass_SoundDescription,
                                                         kQTSoundDescriptionPropertyID_AudioChannelLayout,
                                                         acl_size, acl, NULL);
-                    dbg_printf("[  OE]  CL [%08lx] :: configure_stream__audio() = %ld, {0x%08lx, %ld, %ld}\n",
+                    dbg_printf("[ aOE]  CL [%08lx] :: configure_stream__audio() = %ld, {0x%08lx, %ld, %ld}\n",
                                (UInt32) globals, err, acl->mChannelLayoutTag,
                                acl->mChannelBitmap, acl->mNumberChannelDescriptions);
                 } else {
@@ -376,6 +379,7 @@
 
             DisposeHandle((Handle) sdh);
 
+#if 0
             if (!acl) {
                 acl_size = sizeof(AudioChannelLayout);
                 acl = (AudioChannelLayout *) calloc(1, acl_size);
@@ -385,20 +389,21 @@
                 acl->mChannelBitmap = 0;
                 acl->mNumberChannelDescriptions = 0;
             }
+#endif
 
             err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_InputBasicDescription,
                                          sizeof(si->si_a.qte_out_asbd), &si->si_a.qte_out_asbd);
-            dbg_printf("[  OE]  iD [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+            dbg_printf("[ aOE]  iD [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
             {
                 AudioStreamBasicDescription *asbd = &si->si_a.qte_out_asbd;
-                dbg_printf("[  OE]  iD [%08lx] :: configure_stream__audio() = %ld, {%lf, '%4.4s', %04lx, %ld, %ld, %ld, %ld, %ld}\n", (UInt32) globals, err,
+                dbg_printf("[ aOE]  iD [%08lx] :: configure_stream__audio() = %ld, {%lf, '%4.4s', %04lx, %ld, %ld, %ld, %ld, %ld}\n", (UInt32) globals, err,
                            asbd->mSampleRate, (char *) &asbd->mFormatID, asbd->mFormatFlags, asbd->mBytesPerPacket, asbd->mFramesPerPacket,
                            asbd->mBytesPerFrame, asbd->mChannelsPerFrame, asbd->mBitsPerChannel);
             }
-            if (!err) {
+            if (!err && acl != NULL && false) {
                 err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio, kQTSCAudioPropertyID_InputChannelLayout,
                                              acl_size, acl);
-                dbg_printf("[  OE]  iL [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+                dbg_printf("[ aOE]  iL [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
                 if (err)
                     err = noErr;
             }
@@ -406,18 +411,33 @@
     }
 
     if (!err) {
-        /* TODO: this config should be taken from saved settings or user
-         * dialog (efectively, that's saved settings as well)
-         */
-        AudioStreamBasicDescription asbd = {si->si_a.qte_out_asbd.mSampleRate,
-                                            kAudioFormatXiphVorbis, 0, 0, 0, 0,
-                                            si->si_a.qte_out_asbd.mChannelsPerFrame, 0};
+        AudioStreamBasicDescription asbd = {globals->set_a_asbd.mSampleRate, globals->set_a_asbd.mFormatID,
+                                            globals->set_a_asbd.mFormatFlags, globals->set_a_asbd.mBytesPerPacket,
+                                            globals->set_a_asbd.mFramesPerPacket, globals->set_a_asbd.mBytesPerFrame,
+                                            //si->si_a.qte_out_asbd.mChannelsPerFrame,
+                                            globals->set_a_asbd.mChannelsPerFrame,
+                                            0};
+
         err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
                                      kQTSCAudioPropertyID_BasicDescription,
                                      sizeof(asbd), &asbd);
-        dbg_printf("[  OE]  iO [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+        dbg_printf("[  aOE]  iO [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
 
         if (!err) {
+            err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
+                                         kQTSCAudioPropertyID_RenderQuality,
+                                         sizeof(UInt32), &globals->set_a_rquality);
+            dbg_printf("[ aOE]  rq [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+        }
+
+        if (!err && globals->set_a_custom != NULL) {
+            err = QTSetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
+                                         kQTSCAudioPropertyID_CodecSpecificSettingsArray,
+                                         sizeof(CFArrayRef), &globals->set_a_custom);
+            dbg_printf("[ aOE]  cs [%08lx] :: configure_stream__audio() = %ld\n", (UInt32) globals, err);
+        }
+
+        if (!err) {
             err = QTGetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
                                          kQTSCAudioPropertyID_BasicDescription,
                                          sizeof(si->si_a.stda_asbd), &si->si_a.stda_asbd, NULL);
@@ -425,7 +445,7 @@
 
         if (!err) {
             if (si->si_a.stda_asbd.mBytesPerPacket) {
-                si->si_a.max_packet_size = asbd.mBytesPerPacket;
+                si->si_a.max_packet_size = si->si_a.stda_asbd.mBytesPerPacket;
             } else {
                 err = QTGetComponentProperty(si->si_a.stdAudio, kQTPropertyClass_SCAudio,
                                              kQTSCAudioPropertyID_MaximumOutputPacketSize,
@@ -433,7 +453,7 @@
                                              &si->si_a.max_packet_size, NULL);
             }
         }
-        dbg_printf("[  OE]  xp [%08lx] :: configure_stream__audio()  (%ld)\n", (UInt32) globals, si->si_a.max_packet_size);
+        dbg_printf("[ aOE]  xp [%08lx] :: configure_stream__audio()  (%ld)\n", (UInt32) globals, si->si_a.max_packet_size);
     }
 
     if (acl) {
@@ -460,7 +480,7 @@
     UInt32 max_page_duration = (UInt32) (max_duration *
                                          si->si_a.stda_asbd.mSampleRate);
 
-    dbg_printf("[  OE]  >> [%08lx] :: fill_page__audio(%lf)\n",
+    dbg_printf("[ aOE]  >> [%08lx] :: fill_page__audio(%lf)\n",
                (UInt32) globals, max_duration);
 
     if (ogg_stream_pageout(&si->os, &si->og) > 0) {
@@ -514,7 +534,7 @@
             err = SCAudioFillBuffer(si->si_a.stdAudio, _InputDataProc__audio,
                                     (void *) si, (UInt32 *) &pull_packets,
                                     abl, aspds);
-            dbg_printf("[  OE]  .  [%08lx] :: fill_page__audio(): "
+            dbg_printf("[ aOE]  .  [%08lx] :: fill_page__audio(): "
                        "SCAudioFillBuffer(%ld) = %ld, eos: %d\n",
                        (UInt32) globals, pull_packets, err,
                        pull_packets == 0 &&
@@ -540,7 +560,7 @@
                 si->acc_packets++;
                 si->acc_duration += si->si_a.op_duration;
                 result = ogg_stream_packetin(&si->os, &si->si_a.op);
-                dbg_printf("[  OE] _i  [%08lx] :: fill_page__audio(): "
+                dbg_printf("[ aOE] _i  [%08lx] :: fill_page__audio(): "
                            "ogg_stream_packetin(%lld, %ld, %lld) = %d\n",
                            (UInt32) globals, si->si_a.op.packetno,
                            si->si_a.op.bytes, si->si_a.op.granulepos,
@@ -563,7 +583,7 @@
                     si->si_a.op.packet = (UInt8 *) abl->mBuffers[0].mData +
                         aspds[i].mStartOffset;
                     result = ogg_stream_packetin(&si->os, &si->si_a.op);
-                    dbg_printf("[  OE]  i  [%08lx] :: fill_page__audio(): "
+                    dbg_printf("[ aOE]  i  [%08lx] :: fill_page__audio(): "
                                "ogg_stream_packetin(%lld, %ld, %lld) = %d\n",
                                (UInt32) globals, si->si_a.op.packetno,
                                si->si_a.op.bytes, si->si_a.op.granulepos,
@@ -600,7 +620,7 @@
         }
     }
 
-    dbg_printf("[  OE] <   [%08lx] :: fill_page__audio() = %ld (%ld, %lf)\n",
+    dbg_printf("[ aOE] <   [%08lx] :: fill_page__audio() = %ld (%ld, %lf)\n",
                (UInt32) globals, err, si->og_ts_sec, si->og_ts_subsec);
     return err;
 }



More information about the commits mailing list