Re: HALOutputUnit (Pt 1)
Re: HALOutputUnit (Pt 1)
- Subject: Re: HALOutputUnit (Pt 1)
- From: Robert Grant <email@hidden>
- Date: Thu, 5 Feb 2004 12:33:40 -0500
It's good to see there's others now getting involved with this...
I'm still able to reliably lock up my machine trying to capture input
from an Edirol USB audio interface. Of course all the HAL demos work
fine. :-)
So I thought I'd spell out what I'm doing to see if there's some
obvious.
I first check if the Output device can do input. If it can't I then go
about setting up a HALOutputUnit to do input.
(I'm using Default input and output devices which both point to the
Edirol - I will switch to code that gets the related device, though I
don't think it will guarantee that USB devices will have sync'd input
and output clocks correct?)
// Here's the code to find out if the Input HALOutputDevice can
actually do input:
ComponentDescription cd;
Component auComp;
// construct output unit
cd.componentFlags = 0;
cd.componentFlagsMask = 0;
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_HALOutput;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
auComp = FindNextComponent (NULL, &cd);
OpenAComponent (auComp, &m_inputUnit);
// disable the output bus
UInt32 enableIO = 0;
OSStatus status = AudioUnitSetProperty(m_inputUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
0,
&enableIO,
sizeof(enableIO) );
if (status) NSLog(@"AudioUnitSetProperty
kAudioOutputUnitProperty_EnableIO status: %ld", status);
// enable the input bus - is the scope correct for this (I'm confused
now that I'm looking at it)?
enableIO = 1;
status = AudioUnitSetProperty(m_inputUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
1,
&enableIO,
sizeof(enableIO) );
if (status) NSLog(@"AudioUnitSetProperty
kAudioOutputUnitProperty_EnableIO status: %ld", status);
// now the busses are enabled set the device - as recommended by Apple
AudioDeviceID deviceID;
UInt32 dataSize;
dataSize = sizeof (AudioDeviceID);
AudioHardwareGetProperty
(kAudioHardwarePropertyDefaultInputDevice, &dataSize, &deviceID);
status = AudioUnitSetProperty(m_inputUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global,
0,
&deviceID,
sizeof(deviceID) );
if (status) NSLog(@"AudioUnitSetProperty
kAudioOutputUnitProperty_CurrentDevice status: %ld", status);
// Now find out if it actually can do input.
UInt32 hasInput = 0;
dataSize = sizeof(hasInput);
status = AudioUnitGetProperty(m_inputUnit,
kAudioOutputUnitProperty_HasIO,
kAudioUnitScope_Input,
1,
&hasInput,
&dataSize);
if (status) NSLog(@"AudioUnitGetProperty
kAudioOutputUnitProperty_HasIO status: %ld", status);
// If it can do input then set up the buffers and callback:
if (hasInput) {
// Ready a BufferList - I know this isn't generalized just trying to
get it to work at the moment!
m_bufferList =
(AudioBufferList*)calloc(sizeof(AudioBufferList)+sizeof(AudioBuffer),
0);
m_bufferList->mNumberBuffers = 2;
m_bufferList->mBuffers[0].mNumberChannels = 1;
m_bufferList->mBuffers[1].mNumberChannels = 1;
// Set up the input callback
AURenderCallbackStruct callback = {
InputRenderCallbackDispatch, self };
OSStatus status = AudioUnitSetProperty(m_inputUnit,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
1,
&callback,
sizeof(AURenderCallbackStruct));
status = AudioUnitInitialize (m_inputUnit);
if (status) NSLog(@"AudioUnitInitialize status: %ld",
status);
status = AudioOutputUnitStart(m_inputUnit);
if (status) NSLog(@"AudioOutputUnitStart status: %ld",
status);
}
// Freeze!!!
// Here's the callback that's probably causing the trouble. I'd just
like it to render
// successfully - I'll worry about copying the buffers once it stops
freezing.
OSStatus AURenderNotificationCallback ( void *inRefCon,
AudioUnitRenderActionFlags
*ioActionFlags,
const AudioTimeStamp
*inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
// It just struck me that I'm not checking the actionFlags - could I be
asking it to render on a PreRenderNotification? I'll check the next
time I have the courage to crash my computer! :-)
// ioData is apparently not a valid AudioBufferList in this context
// Make sure the AudioUnitRender sets the mData pointers rather than
copies. I wasn't clearing these in my earlier efforts but it doesn't
seem to be making a difference.
m_bufferList->mBuffers[0].mData = 0;
m_bufferList->mBuffers[1].mData = 0;
// Do the render
OSStatus status = AudioUnitRender(m_inputUnit,
ioActionFlags,
inTimeStamp,
1,
inNumberFrames,
m_bufferList);
if (status) NSLog(@"AudioUnitRender status: %ld", status);
return status;
}
Hopefully someone can post the d'oh mistake :-)
Robert.
_______________________________________________
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.