Re: Problems when changing sample rate on a aggregate device
Re: Problems when changing sample rate on a aggregate device
- Subject: Re: Problems when changing sample rate on a aggregate device
- From: Stéphane Letz <email@hidden>
- Date: Tue, 4 Dec 2007 15:18:39 +0100
Message: 2
Date: Mon, 3 Dec 2007 11:31:27 -0800
From: Jeff Moore <email@hidden>
Subject: Re: Problems when changing sample rate on a aggregate device
(OSX 10.5.1)
To: CoreAudio API <email@hidden>
Message-ID: <email@hidden>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed; delsp=yes
To change the sample rate on any device, aggregate or otherwise, just
set the property, kAudioDevicePropertyNominalSampleRate. For an
aggregate device, this has the added benefit of changing the sample
rate of all the sub-devices in one call.
On Dec 3, 2007, at 8:18 AM, Stéphane Letz wrote:
We have code that use the AUHAL and possibly uses an aggregate
device. We sometime want to change the sample rate of the aggregate
device. We do that with the following code:
When actually changing the SR value, 1) succeed but 2) fails
already in " Check ouput sample rate" part: we get an
"kAudioHardwareUnknownPropertyError" error.
Is this a bug? Is this way of doing obsolete?
Thanks, this solved part of the problem, but we still have some weird
behavior related to SR changes when using the AUHAL. Our code does the
following scheme, so that is can be used with input, output, or duplex
devices:
// Get sample rate
outSize = sizeof(Float64);
err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal,
kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate);
if (err != noErr) {
....
}
// Set sample rate if needed
if (samplerate != (jack_nframes_t)sampleRate) {
sampleRate = (Float64)samplerate;
err = AudioDeviceSetProperty(fDeviceID, NULL, 0,
kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate,
outSize, &sampleRate);
if (err != noErr) {
....
}
}
ComponentDescription cd = {kAudioUnitType_Output,
kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
Component HALOutput = FindNextComponent(NULL, &cd);
err1 = OpenAComponent(HALOutput, &fAUHAL);
if (err1 != noErr) {
....
}
err1 = AudioUnitInitialize(fAUHAL);
if (err1 != noErr) {
....
}
// Enable IO
if (capturing && inchannels > 0) {
err1 = AudioUnitSetProperty(fAUHAL,
kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1,
&enableIO, sizeof(enableIO));
if (err1 != noErr) {
.....
}
}
if (playing && outchannels > 0) {
err1 = AudioUnitSetProperty(fAUHAL,
kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0,
&enableIO, sizeof(enableIO));
if (err1 != noErr) {
.....
}
}
// Setup up choosen device, in both input and output cases
err1 = AudioUnitSetProperty(fAUHAL,
kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0,
&fDeviceID, sizeof(AudioDeviceID));
if (err1 != noErr) {
.....
}
// Set buffer size
if (capturing && inchannels > 0) {
err1 = AudioUnitSetProperty(fAUHAL,
kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1,
(UInt32*)&nframes, sizeof(UInt32));
if (err1 != noErr) {
.....
}
}
if (playing && outchannels > 0) {
err1 = AudioUnitSetProperty(fAUHAL,
kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0,
(UInt32*)&nframes, sizeof(UInt32));
if (err1 != noErr) {
.....
}
}
// Setup channel map
if (capturing && inchannels > 0 && inchannels < in_nChannels) {
SInt32 chanArr[in_nChannels];
for (int i = 0; i < in_nChannels; i++) {
chanArr[i] = -1;
}
for (int i = 0; i < inchannels; i++) {
chanArr[i] = i;
}
AudioUnitSetProperty(fAUHAL,
kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1,
chanArr, sizeof(SInt32) * in_nChannels);
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty -
kAudioOutputUnitProperty_ChannelMap 1");
printError(err1);
}
}
if (playing && outchannels > 0 && outchannels < out_nChannels) {
SInt32 chanArr[out_nChannels];
for (int i = 0; i < out_nChannels; i++) {
chanArr[i] = -1;
}
for (int i = 0; i < outchannels; i++) {
chanArr[i] = i;
}
err1 = AudioUnitSetProperty(fAUHAL,
kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0,
chanArr, sizeof(SInt32) * out_nChannels);
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty -
kAudioOutputUnitProperty_ChannelMap 0");
printError(err1);
}
}
// Setup stream converters
if (capturing && inchannels > 0) {
srcFormat.mSampleRate = samplerate;
srcFormat.mFormatID = kAudioFormatLinearPCM;
srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked |
kLinearPCMFormatFlagIsNonInterleaved;
srcFormat.mBytesPerPacket = sizeof(float);
srcFormat.mFramesPerPacket = 1;
srcFormat.mBytesPerFrame = sizeof(float);
srcFormat.mChannelsPerFrame = outchannels;
srcFormat.mBitsPerChannel = 32;
err1 = AudioUnitSetProperty(fAUHAL,
kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat,
sizeof(AudioStreamBasicDescription));
if (err1 != noErr) {
.....
}
}
if (playing && outchannels > 0) {
dstFormat.mSampleRate = samplerate;
dstFormat.mFormatID = kAudioFormatLinearPCM;
dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked |
kLinearPCMFormatFlagIsNonInterleaved;
dstFormat.mBytesPerPacket = sizeof(float);
dstFormat.mFramesPerPacket = 1;
dstFormat.mBytesPerFrame = sizeof(float);
dstFormat.mChannelsPerFrame = inchannels;
dstFormat.mBitsPerChannel = 32;
err1 = AudioUnitSetProperty(fAUHAL,
kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1,
&dstFormat, sizeof(AudioStreamBasicDescription));
if (err1 != noErr) {
.....
}
}
.....
This works correctly when starting device with SR = 44100. As soon as
using other SR (like 48, or 96 k that are supported by the devices)
problems occurs:
- when application is started with 48k or 96k and input or output only
device => distorded sound
- when application is started with 48k or 96k an duplex device ==>
works OK
- when SR is changed externally (using AMS) ==> AUHAL audio callback
not be called anymore
- when SR is changed externally (using AMS) ==> distorded sound
Basically is seems that the problems is in the "Setup stream
converters" part. In some parameter choices we get error in
AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, 1, &dstFormat,
sizeof(AudioStreamBasicDescription)); line but not always... and
things still do not work, correctly even in the absence of errors..
Thanks
Stephane Letz
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden