• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Monitoring input level
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Monitoring input level


  • Subject: Re: Monitoring input level
  • From: Neil Clayton <email@hidden>
  • Date: Tue, 20 Jun 2006 00:33:22 +0100

Thanks for the tips.
I've written a spike, according to the link you mentioned.

I can get it to all start up OK (that is, no errors), but I'm not getting anything for my levels. Just 'infinity'.
I (perhaps wrongly) didn't setup a channel map (hoping the default is OK), or an input proc (as I don't want to actually DO anything with the data).
Is an input proc required, even if I'm not wanting to save/play the audio?


In the interest of keeping one thread only: Karim Morsy also replied with the idea that I might be able to setup a link from AUHAL (input) -> mixer -> AUHAL (output), but the docs say that you can only have one output unit in a graph. I tried to create another unit using the same component description, but got error -10862 (which I cannot see doco for).

I've posted the code below, for reference. Hope it's not too much to wade through. If you're looking for where I start things rolling, it's at a method called monitorDevice.

---
Neil Clayton





//
//  AudioPreview.m
//  iShowU
//
//  Created by Neil Clayton on 18/06/2006.
//  Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import "AudioPreview.h"
#import "DebugMacros.h"
#import "NSUtils.h"
#import "AudioToolbox/AudioFormat.h"
#import <AudioUnit/AudioUnitParameters.h>
#import <AudioUnit/AudioUnitProperties.h>
#import "CAStreamBasicDescription.h"

#define checkErr( err) \
if(err) {\
	OSStatus error = static_cast<OSStatus>(err);\
		fprintf(stderr, "Error: %ld ->  %s:  %d\n",  error,\
				__FILE__, \
				__LINE__\
				);\
					fflush(stdout);\
}


@implementation AudioPreview

- (id) init {
	self = [super init];
	return self;
}

- (void) dealloc {
	[self stopPreview];
	[super dealloc];
}

- (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);
// err = AUGraphNewNode(auGraph, &desc, 0, NULL, &outputNode);
// checkErr(err);
err = AUGraphGetNodeInfo(auGraph, inputNode, NULL, NULL, NULL, &inputUnit);
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);
err = AUGraphGetNodeInfo(auGraph, mixerNode, NULL, NULL, NULL, &mixerUnit);
checkErr(err);
}


- (void) connectAUs {
OSStatus err = AUGraphConnectNodeInput(auGraph, mixerNode, 0, inputNode, 0);
checkErr(err);
err = AUGraphConnectNodeInput(auGraph, inputNode, 1, mixerNode, 0);
checkErr(err);
err = AUGraphUpdate(auGraph, NULL);
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) monitorDevice:(MTCoreAudioDevice*)aDevice {
	[self stopPreview];

	NewAUGraph(&auGraph);
	OSStatus err = AUGraphOpen(auGraph);
	checkErr(err);

	[self createHALAU];
	[self createMixer];
	[self connectAUs];	

	err = AUGraphInitialize(auGraph);
	checkErr(err);

	[self enableIO];
	[self setDevice:[aDevice deviceID]];
	[self setVolumes]; // doesn't do anything at present
	[self enableMetering];

	[self startPreview];
}

- (void)idleTimer:(NSTimer*)timer {
OSStatus err;

float amps[2];
err = AudioUnitGetParameter(mixerUnit, kMatrixMixerParam_PostAveragePower, kAudioUnitScope_Input, 0, &amps[0]);
checkErr(err);

err = AudioUnitGetParameter(mixerUnit, kMatrixMixerParam_PostPeakHoldLevel, kAudioUnitScope_Input, 0, &amps [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


  • Follow-Ups:
    • Re: Monitoring input level
      • From: Doug Wyatt <email@hidden>
References: 
 >Monitoring input level (From: Neil Clayton <email@hidden>)
 >Re: Monitoring input level (From: Neil Clayton <email@hidden>)
 >Re: Monitoring input level (From: Jeff Moore <email@hidden>)

  • Prev by Date: AU instrument on top of complete MIDI synth
  • Next by Date: Re: Monitoring input level
  • Previous by thread: Re: Monitoring input level
  • Next by thread: Re: Monitoring input level
  • Index(es):
    • Date
    • Thread