Re: Monitoring input level
Re: Monitoring input level
- Subject: Re: Monitoring input level
- From: Neil Clayton <email@hidden>
- Date: Tue, 20 Jun 2006 08:13:11 +0100
OK. Thanks. I keep looking at the apple docs, rather than the
heads :-) (for error info, that is)
Make connections from the input/output unit's output scope, element
1 -- that's the device input.
Just took a look at the code, and unless I've misread how to make
connections, I thought I was already doing that....
// Connect the mixer to the output
OSStatus err = AUGraphConnectNodeInput(auGraph, mixerNode, 0,
inputNode, 0);
checkErr(err);
// Connect input to the mixer (same node, inputNode - using element
1 of that node)
err = AUGraphConnectNodeInput(auGraph, inputNode, 1, mixerNode, 0);
checkErr(err);
Karim mentioned a specific order for AU initialization, so I've gone
back and double checked that. I split out the 'getting references
to AU nodes' after I'd performed the AUGraphOpen(). Still, while
everything appears to initialize OK, I'm still getting inf as a value
for the levels.
I've assumed that no InputProc is required (no one's said that it is
yet :-).
Is it also possible that I DO have to setup volume levels on the
mixer? I've tried doing that (code is below), but to no effect. I
mention it because everything *seems* OK, but I have no readings.
---
Neil Clayton
I've included code again, because it has changed slightly (but I've
cut out meaningless stuff):
- (void) enableIO {
UInt32 enableIO;
//When using AudioUnitSetProperty the 4th parameter in the method
//refer to an AudioUnitElement. When using an AudioOutputUnit
//the input element will be '1' and the output element will be '0'.
enableIO = 1;
AudioUnitSetProperty(inputUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
1, // input element
&enableIO,
sizeof(enableIO));
enableIO = 0;
AudioUnitSetProperty(inputUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
0, //output element
&enableIO,
sizeof(enableIO));
}
- (void) createHALAU {
ComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_HALOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
OSStatus err = AUGraphNewNode(auGraph, &desc, 0, NULL, &inputNode);
checkErr(err);
}
- (void) createMixer {
OSStatus err = noErr;
ComponentDescription mixer;
mixer.componentType = kAudioUnitType_Mixer;
mixer.componentSubType = kAudioUnitSubType_MatrixMixer;
mixer.componentManufacturer = kAudioUnitManufacturer_Apple;
mixer.componentFlags = 0;
mixer.componentFlagsMask = 0;
err = AUGraphNewNode(auGraph, &mixer, 0, NULL, &mixerNode);
checkErr(err);
}
- (void) connectAUs {
// Connect the mixer to the output
OSStatus err = AUGraphConnectNodeInput(auGraph, mixerNode, 0,
inputNode, 0);
checkErr(err);
// Connect input to the mixer (same node, inputNode - using element
1 of that node)
err = AUGraphConnectNodeInput(auGraph, inputNode, 1, mixerNode, 0);
checkErr(err);
}
- (void) setDevice:(AudioDeviceID)deviceId {
UInt32 size;
OSStatus err = noErr;
size = sizeof(AudioDeviceID);
err = AudioUnitSetProperty(inputUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global,
0,
&deviceId,
sizeof(deviceId));
checkErr(err);
// Setup the StreamFormat for element 1 - the input element
CAStreamBasicDescription DeviceFormat;
CAStreamBasicDescription DesiredFormat;
size = sizeof(CAStreamBasicDescription);
//Get the input device format
err = AudioUnitGetProperty (inputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
1,
&DeviceFormat,
&size);
checkErr(err);
//set the desired format to the device's sample rate
DesiredFormat.mSampleRate = DeviceFormat.mSampleRate;
//set format to output scope
err = AudioUnitSetProperty(inputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
1,
&DesiredFormat,
sizeof(CAStreamBasicDescription));
checkErr(err);
}
- (void) enableMetering {
// turn on metering
UInt32 meteringMode = 1;
OSStatus err = AudioUnitSetProperty(mixerUnit,
kAudioUnitProperty_MeteringMode, kAudioUnitScope_Global, 0,
&meteringMode, sizeof(meteringMode) );
checkErr(err);
}
- (void) setVolumes {
// Not sure if I need to do this or not. It's had no effect so far,
but did within ComplexPlayThru (when I modified it to have a mixer)
// Enable the mixer input's and output's
OSStatus err = AudioUnitSetParameter(mixerUnit,
kMatrixMixerParam_Enable, kAudioUnitScope_Input, 0, 1, 0);
checkErr(err);
err = AudioUnitSetParameter(mixerUnit, kMatrixMixerParam_Enable,
kAudioUnitScope_Output, 0, 1, 0);
checkErr(err);
// Set global volume
err = AudioUnitSetParameter(mixerUnit, kMatrixMixerParam_Volume,
kAudioUnitScope_Global, 0, 1, 0);
checkErr(err);
// Set master volume
err = AudioUnitSetParameter(mixerUnit, kMatrixMixerParam_Volume,
kAudioUnitScope_Global, 0xFFFFFFFF, 1, 0);
checkErr(err);
// Set input and output volumes
err = AudioUnitSetParameter(mixerUnit, kMatrixMixerParam_Volume,
kAudioUnitScope_Input, 1, 1, 0);
checkErr(err);
err = AudioUnitSetParameter(mixerUnit, kMatrixMixerParam_Volume,
kAudioUnitScope_Output, 0, 1, 0);
checkErr(err);
}
- (void) getNodeReferences {
OSStatus err = AUGraphGetNodeInfo(auGraph, inputNode, NULL, NULL,
NULL, &inputUnit);
checkErr(err);
err = AUGraphGetNodeInfo(auGraph, mixerNode, NULL, NULL, NULL,
&mixerUnit);
checkErr(err);
}
- (void) monitorDevice:(MTCoreAudioDevice*)aDevice {
[self stopPreview];
NewAUGraph(&auGraph);
[self createHALAU];
[self createMixer];
[self connectAUs];
OSStatus err = AUGraphOpen(auGraph);
checkErr(err);
[self getNodeReferences];
[self enableMetering];
[self enableIO];
[self setDevice:[aDevice deviceID]];
err = AUGraphInitialize(auGraph);
checkErr(err);
[self setVolumes]; // doesn't do anything at present
[self startPreview];
}
- (void)idleTimer:(NSTimer*)timer {
OSStatus err;
float amps[2];
err = AudioUnitGetParameter(mixerUnit,
kMatrixMixerParam_PostAveragePower, kAudioUnitScope_Input, 0, &s[0]);
checkErr(err);
err = AudioUnitGetParameter(mixerUnit,
kMatrixMixerParam_PostPeakHoldLevel, kAudioUnitScope_Input, 0, &s
[1]);
checkErr(err);
currentAmps = amps[0];
peakAmps = amps[1];
NSLog(@"Got average power %f and peak power %f", currentAmps,
peakAmps);
}
- (void) stopPreview {
if(previewTimer) {
[previewTimer invalidate];
[previewTimer release];
previewTimer = nil;
OSStatus err = AUGraphStop(auGraph);
if(err != noErr) {
[self log:@"Error stopping AU graph, %d", err];
}
}
}
- (void) startPreview {
if (previewTimer == nil) {
previewTimer = [[NSTimer alloc] initWithFireDate:[NSDate date]
interval:.05
target:self
selector:@selector(idleTimer:)
userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:previewTimer
forMode:NSDefaultRunLoopMode];
OSStatus err = AUGraphStart(auGraph);
if(err != noErr) {
[self log:@"Error starting AU graph, %d", err];
}
}
}
@end
_______________________________________________
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