• 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
My AUHAL AudioUnit Objective-C wrapper does not work with stereo line in
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

My AUHAL AudioUnit Objective-C wrapper does not work with stereo line in


  • Subject: My AUHAL AudioUnit Objective-C wrapper does not work with stereo line in
  • From: Marco Frisan <email@hidden>
  • Date: Tue, 14 Jun 2011 00:07:11 +0200

Hello all,

and thanks, in advance, for any help I will receive.

I am developing a wrapper for AUHAL AudioUnits. It is written in Objective-C.

Actually I had some problems to learn Core Audio, so there could be more errors then I can see. Documentation is not enough to really understand Core Audio and all examples are written in C++ (that does not help me) and use Core Audio SDK Public Utilities to achieve many tasks. But Core Audio SDK Public Utilities are not documented and poorly commented, therefore, to fully understand them is a really big job.

Though, I have been able to code this wrapper, that works with my LED Cinema Display microphone (apparently, a monophonic microphone, right?).

The problem is that it does not work with the Mac Pro jack line in (apparently, a stereophonic source, right?).

At this point, I don't know where to look for the cause of this problem.

What I can guess, is that the cause should not be a device/unit setup problem, since I check all the errors eventually produced by Core Audio calls and the wrapper should not initialize (neither starts rendering) if anything goes wrong.

But, when using line in jack, left and right buffer amplitudes are all zero. The buffer where I render is the _renderBuf member variable of the class.

This is the code (I pasted both header and source files here):

// Header file
#import <Foundation/Foundation.h>
#import <AudioUnit/AudioUnit.h>


@interface SpectreAUHALFromInputWrapper : NSObject {
@private
	AudioUnit _au;

	AudioStreamBasicDescription _in_format;
	AudioStreamBasicDescription _out_format;

	AudioBufferList * _renderBuf;

	UInt32 _framesNum;
}

@property (readonly) AudioUnit audioUnit;
@property (readonly) AudioStreamBasicDescription inputFormat;
@property (readonly) AudioStreamBasicDescription outputFormat;

- (OSStatus)start;
- (OSStatus)stop;

- (OSStatus)renderWithActionFlags:(AudioUnitRenderActionFlags *)flags
						timeStamp:(const AudioTimeStamp *)ts
							  bus:(UInt32)bus
					 framesNumber:(UInt32)framesNum;

- (OSStatus)readBuffer:(AudioBufferList **)bufList;

- (OSStatus)numberOfFrames:(UInt32 *)num;

@end


// Source file
#import "SpectreAUHALFromInputWrapper.h"

#import "SpectreMacros.h"


@interface SpectreAUHALFromInputWrapper (SpectreAUHALFromInputWrapperPrivate)
- (OSStatus)createAUHAL;
- (OSStatus)enableIO;
- (OSStatus)setDeviceTo:(AudioDeviceID)devID;
- (OSStatus)setAudioFormat;
- (OSStatus)setupCallback;
- (OSStatus)getInputFormat:(AudioStreamBasicDescription *)desc;
- (OSStatus)getOutputFormat:(AudioStreamBasicDescription *)desc;
- (BOOL)isRunning;
- (OSStatus)setupRenderBuffer;
@end


OSStatus SpectreInputProc(void							* inRefCon,
						  AudioUnitRenderActionFlags	* ioActionFlags,
						  const AudioTimeStamp			* inTimeStamp,
						  UInt32						  inBusNumber,
						  UInt32						  inNumberFrames,
						  AudioBufferList				* ioData)
{
	OSStatus err = noErr;
	SpectreAUHALFromInputWrapper * wrapper = (SpectreAUHALFromInputWrapper *)inRefCon;

	err = [wrapper renderWithActionFlags:ioActionFlags
							   timeStamp:inTimeStamp
									 bus:inBusNumber
							framesNumber:inNumberFrames];

	return err;
}


@implementation SpectreAUHALFromInputWrapper

@synthesize audioUnit = _au;
@synthesize inputFormat = _in_format;
@synthesize outputFormat = _out_format;

- (id)init {
	self = [super init];
	if (self) {
		OSStatus err = noErr;

		err = [self createAUHAL];
		spectreTestError2(err);
	}
	return self;
}

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

- (OSStatus)start {
	OSStatus err = noErr;

	if (![self isRunning]) {
		err = AudioOutputUnitStart(_au);
		spectreTestError(err);
	}

	return err;
}

- (OSStatus)stop {
	OSStatus err = noErr;

	if ([self isRunning]) {
		err = AudioOutputUnitStop(_au);
		spectreTestError(err);
	}

	return err;
}

- (BOOL)isRunning {
	OSStatus err = noErr;
	UInt32 isRunning = 0;
	UInt32 size = 0;

	size = sizeof(isRunning);

	if (_au) {
		err = AudioUnitGetProperty(_au,
								   kAudioOutputUnitProperty_IsRunning,
								   kAudioUnitScope_Global,
								   0,
								   &isRunning,
								   &size);
	}

	return isRunning;
}

- (OSStatus)createAUHAL {
	OSStatus err = noErr;
	AudioComponent comp;
	AudioComponentDescription desc;

	desc.componentType = kAudioUnitType_Output;
	desc.componentSubType = kAudioUnitSubType_HALOutput;
	desc.componentManufacturer = kAudioUnitManufacturer_Apple;
	desc.componentFlags = 0;
	desc.componentFlagsMask = 0;

	comp = AudioComponentFindNext(NULL, &desc);
	if (!comp) {
		NSLog(@"No AudioComponent found for the AUHAL unit description.");
		return -1;
	}

	err = AudioComponentInstanceNew(comp, &_au);
	spectreTestError(err);

	err = AudioUnitInitialize(_au);
	spectreTestError(err);

	err = [self enableIO];
	spectreTestError(err);

	err = [self setDeviceTo:kAudioDeviceUnknown];
	spectreTestError(err);

	err = [self setupCallback];
	spectreTestError(err);

	err = [self getInputFormat:&_in_format];
	spectreTestError(err);

	err = [self getOutputFormat:&_out_format];
	spectreTestError(err);

	err = [self setAudioFormat];
	spectreTestError(err);

	err = [self setupRenderBuffer];
	spectreTestError(err);

	err = AudioUnitInitialize(_au);

	return err;
}

- (OSStatus)enableIO {
	OSStatus err = noErr;
	UInt32 enableIO = 1;

	err = AudioUnitSetProperty(_au,
							   kAudioOutputUnitProperty_EnableIO,
							   kAudioUnitScope_Input,
							   kSpectreInputBus, // input element
							   &enableIO,
							   sizeof(enableIO));
	spectreTestError(err);

	enableIO = 0;
	err = AudioUnitSetProperty(_au,
							   kAudioOutputUnitProperty_EnableIO,
							   kAudioUnitScope_Output,
							   kSpectreOutputBus, //output element
							   &enableIO,
							   sizeof(enableIO));
	return err;
}

- (OSStatus)setDeviceTo:(AudioDeviceID)devID {
	OSStatus err = noErr;
	UInt32 size = sizeof(AudioDeviceID);

	if(devID == kAudioDeviceUnknown) {
		err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
									   &size,
									   &devID);
		spectreTestError(err);
	}

	/* ================================ DEBUG =============================== */
	err = AudioDeviceGetPropertyInfo(devID, 0, YES, kAudioDevicePropertyDeviceName, &size, NULL);
	spectreTestError(err);

	char * name = (char *)malloc(size);

	err = AudioDeviceGetProperty(devID, 0, YES, kAudioDevicePropertyDeviceName, &size, name);
	spectreTestError(err);

	NSLog(@"Input device name: %s", name);
	/* ================================ DEBUG =============================== */

	err = AudioUnitSetProperty(_au,
							   kAudioOutputUnitProperty_CurrentDevice,
							   kAudioUnitScope_Global,
							   0,
							   &devID,
							   sizeof(devID));

	return err;
}

- (OSStatus)setupCallback {
	OSStatus err = noErr;
	AURenderCallbackStruct cbs;

	cbs.inputProc = SpectreInputProc;
	cbs.inputProcRefCon = self;

	// Setup the input callback.
	err = AudioUnitSetProperty(_au,
							   kAudioOutputUnitProperty_SetInputCallback,
							   kAudioUnitScope_Global,
							   0,
							   &cbs,
							   sizeof(cbs));

	return err;
}

- (OSStatus)getInputFormat:(AudioStreamBasicDescription *)desc {
	OSStatus err = noErr;
	UInt32 size = sizeof(AudioStreamBasicDescription);

	err = AudioUnitGetProperty(_au,
							   kAudioUnitProperty_StreamFormat,
							   kAudioUnitScope_Input,
							   kSpectreInputBus,
							   desc,
							   &size);

	return err;
}

- (OSStatus)getOutputFormat:(AudioStreamBasicDescription *)desc {
	OSStatus err = noErr;
	UInt32 size = sizeof(AudioStreamBasicDescription);

	err = AudioUnitGetProperty(_au,
							   kAudioUnitProperty_StreamFormat,
							   kAudioUnitScope_Output,
							   kSpectreInputBus,
							   desc,
							   &size);

	return err;
}

- (OSStatus)renderWithActionFlags:(AudioUnitRenderActionFlags *)flags
						timeStamp:(const AudioTimeStamp *)ts
							  bus:(UInt32)bus
					 framesNumber:(UInt32)framesNum
{
	//NSLog(@"Render input audio with time stamp: %f; bus number: %u; number of frames: %u", ts->mSampleTime, bus, framesNum);
	OSStatus err = noErr;

	@synchronized(self) {
		err = AudioUnitRender(_au,
							  flags,
							  ts,
							  bus,
							  framesNum,
							  _renderBuf);

		_framesNum = framesNum;
	}

	return err;
}

- (OSStatus)readBuffer:(AudioBufferList **)bufList {
//	NSLog(@"\tnumber of buffers = %u", _renderBuf->mNumberBuffers);
//	for (UInt32 i = 0; i < _renderBuf->mNumberBuffers; i++) {
//		NSLog(@"\tbuffer %u = (number of channels = %u; bytes number = %u)", i, _renderBuf->mBuffers[i].mNumberChannels, _renderBuf->mBuffers[i].mDataByteSize);
//
//		Float32 * data = (Float32 *)_renderBuf->mBuffers[i].mData;
//		NSMutableString * seq = [NSMutableString string];
//		//for (UInt32 f = 0; f < _framesNum; f++) {
//			[seq appendFormat:@"%f ", data[0]];
//		//}
//		NSLog(@"\t\tdata = %@", seq);
//	}

	OSStatus err = noErr;

	@synchronized(self) {
		if (_renderBuf) {
			if (*bufList)
				free(bufList);

			size_t bufListSize;

			bufListSize = offsetof(AudioBufferList, mBuffers[0]) + (sizeof(AudioBuffer) * _renderBuf->mNumberBuffers);

			*bufList = (AudioBufferList *)malloc(bufListSize);

			(*bufList)->mNumberBuffers = _renderBuf->mNumberBuffers;

			for (UInt32 i = 0; i < _renderBuf->mNumberBuffers; i++) {
				(*bufList)->mBuffers[i].mNumberChannels = _renderBuf->mBuffers[i].mNumberChannels;
				(*bufList)->mBuffers[i].mDataByteSize = _renderBuf->mBuffers[i].mDataByteSize;

				(*bufList)->mBuffers[i].mData = malloc((*bufList)->mBuffers[i].mDataByteSize);

				memcpy((*bufList)->mBuffers[i].mData, _renderBuf->mBuffers[i].mData, (*bufList)->mBuffers[i].mDataByteSize);
			}
		}
	}

	return err;
}

- (OSStatus)numberOfFrames:(UInt32 *)num {
	OSStatus err = noErr;

	@synchronized(self) {
		*num = _framesNum;
	}

	return err;
}

- (OSStatus)setAudioFormat {
	OSStatus err = noErr;

	_out_format = _in_format;

	err = AudioUnitSetProperty(_au,
							   kAudioUnitProperty_StreamFormat,
							   kAudioUnitScope_Output,
							   kSpectreInputBus,
							   &_out_format,
							   sizeof(_out_format));

	return err;
}

- (OSStatus)setupRenderBuffer {
	OSStatus err = noErr;
	UInt32 size;
	UInt32 bufFrameNum;
	UInt32 bufSize;

	size = offsetof(AudioBufferList, mBuffers[0]) + (sizeof(AudioBuffer) * _in_format.mChannelsPerFrame);

	_renderBuf = (AudioBufferList *)malloc(size);

	_renderBuf->mNumberBuffers = _in_format.mChannelsPerFrame;

	size = sizeof(UInt32);
	err = AudioUnitGetProperty(_au,
							   kAudioDevicePropertyBufferFrameSize,
							   kAudioUnitScope_Global,
							   0,
							   &bufFrameNum,
							   &size);
	spectreTestError(err);

	bufSize = bufFrameNum * sizeof(Float32);

	for(UInt32 i = 0; i < _renderBuf->mNumberBuffers; i++) {
		_renderBuf->mBuffers[i].mNumberChannels = 1;
		_renderBuf->mBuffers[i].mDataByteSize = bufSize;
		_renderBuf->mBuffers[i].mData = malloc(bufSize);
	}

	return 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: My AUHAL AudioUnit Objective-C wrapper does not work with stereo line in
      • From: Daniel Mack <email@hidden>
  • Prev by Date: Re: Newbie iOS Audio Unit question
  • Next by Date: Configuring RemoteIO Audio unit to play and record iLBC on the iPhone
  • Previous by thread: Re: Coreaudio-api Digest, Vol 8, Issue 178
  • Next by thread: Re: My AUHAL AudioUnit Objective-C wrapper does not work with stereo line in
  • Index(es):
    • Date
    • Thread