Re: HALOutputUnit (Pt 2)
Re: HALOutputUnit (Pt 2)
- Subject: Re: HALOutputUnit (Pt 2)
- From: Doug Wyatt <email@hidden>
- Date: Tue, 24 Feb 2004 17:38:41 -0800
On Feb 24, 2004, at 15:16, Bob Stuller wrote:
Aaron, Greetings!
At 11:33 AM -0800 2/24/04, Aaron Eppolito wrote:
>> This sounds like the same problem I was having. You must set the
sample rate of the OutputScope of the InputBus equal to the
InputScope of the InputBus, otherwise, you'll get the CannotDo
error.
How is the sample rate of the InputScope of the InputBus set? When
I
do a AUSetProperty-SampleRate on the input side of the HALAU, i.e.
the
side the device is hooked up to, I get a
kAudioUnitErr_PropertyNotWritable error. Going to Global scope
(still
on the input element) gives a kAudioUnitErr_InvalidElement error.
Here's what I did:
// get the "input of input" stream description
AudioStreamBasicDescription asbd;
size = sizeof(asbd);
result = AudioUnitGetProperty (unit, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, 1, &asbd, &size);
THROW_RESULT ("AudioUnitGetProperty");
// get the "output of input" stream description
AudioStreamBasicDescription outputOfInput;
size = sizeof(outputOfInput);
result = AudioUnitGetProperty (unit, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, 1, &outputOfInput, &size);
THROW_RESULT ("AudioUnitGetProperty");
// set the output of the input to be the right sample rate
// as well as the number of channels
outputOfInput.mSampleRate = asbd.mSampleRate;
if(asbd.mChannelsPerFrame == 1) outputOfInput.mChannelsPerFrame = 1;
result = AudioUnitSetProperty (unit, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, 1, &outputOfInput, size);
THROW_RESULT ("AudioUnitSetProperty");
Better to do would be to skip the second chunk and instead explicitly
set the stream format you want.
I'd assumed that setting the device's format via the HALAU would set
both the device's sample rate &, necessarily, that of the HALAU's
input side (of element == 1).
I assumed that too. Alas, it is an incorrect assumption. All Audio
Units initialize to 44.1kHz de-interleaved stereo float.
Aaron -- that is true in general, but not for the output(/input) unit,
which fetches the format from the hardware. I see the line of code that
should be doing it ...
(I should also pick a nit and clarify -- all units *default* to 44.1,
but in most if not all, the stream format can be changed before
initialization -- except on the converter and I/O units, which allow
the format to be changed after initialization)
Ouch! Reviewing the situation (all references are to the input bus,
element #1):
1) The input (device) scope is a read-only property for format in
general and sample rate in particular.
2) The input & output ends of the bus must match on sample rates &
number of channels.
3) I'm always going to find the output end's sample rate to be 44.1kHz.
Therefore, I can _only_ get 44.1kHz out of the HALAU.
So I simply cannot do what I feel I need to do using the HALAU.
Bummer!
I guess the thing to do now is to advocate to the wider set of Core
Audio engineers to have this change sometime soon. Look at it from
our point of view: We have plenty to do with the processor and,
especially, with memory bandwidth once the sample have been sent to
the speech-recognition engine. This is not to speak of the processing
involved by the target application, e.g. Word doing on-the-fly spell
checking.
Secondly, I am concerned about down-sampling artifacts & was figuring
to use the fancier converter whenever a microphone couldn't be
throttled down to 16kHz. Most speech-oriented hardware can, however.
Aaron, thank you for passing along your no-doubt hard-won experience.
I don't want you to think that you are a target of my current
disappointed state. Fact is, all the CA engineers are
super-helpful...
Hi Bob,
Ah, now that I see what's going on. We don't (currently) allow sample
rate conversion on input. The constraint in the current design is that
the client must pull *all* of the input from the unit during each I/O
cycle, and I guess there was some sense that it was too tricky to
describe how to do this in the presence of an SRC.
That said:
[a] if you do have hardware that runs at 16K, you should be able to run
the AUHAL at 16K too. I'm sure I've successfully recorded from it at
48K... it should be a matter of making sure you set the element
1/output scope to match the hardware sample rate, which should be
readable from element 1/input scope.
[b] you could pull all the data out into a ring buffer and do the
downsampling on another thread. The I/O unit uses an AudioConverter to
do rate conversions internally, but you can also use your own converter
externally.
hth,
Doug
--
Doug Wyatt
Core Audio, Apple
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.