[Audio] Programmation Input - Recuperer les buffers

nartu

Membre enregistré
5 Octobre 2005
5
0
44
salut tout l'monde !

je travaille en ce moment sur la programmation d'un module pour gérer le son sur Mac OS X : Lire des buffers sur le Micro et Ecrire des buffers sur les hauts-parleurs.

j'ai essayé de suivre ce tuto sur la gestion de l'input audio pour récupérer les buffers du microphone, mais sans succes : http://developer.apple.com/technotes/tn2002/tn2091.html

j'ai un Bus error quand la fonction InitAndStartAUHAL() est executée... Est-ce qu'il y aurait un moyen plus simple d'ouvrir le driver audio ? ou une autre façon de recupérer les buffers sur l'input audio ?
 
J'ai un plantage au niveau de AudioUnitInitialize... Voici mon code :

Component comp;
ComponentDescription desc;

//There are several different types of Audio Units.
//Some audio units serve as Outputs, Mixers, or DSP
//units. See AUComponent.h for listing
desc.componentType = kAudioUnitType_Output;

//Every Component has a subType, which will give a clearer picture
//of what this components function will be.
desc.componentSubType = kAudioUnitSubType_HALOutput;

//all Audio Units in AUComponent.h must use
//"kAudioUnitManufacturer_Apple" as the Manufacturer
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;

//Finds a component that meets the desc spec's
comp = FindNextComponent(NULL, &desc);
if (comp == NULL) exit (-1);

//gains access to the services provided by the component
err = OpenAComponent(comp, &theInputUnit);
checkError("opening audio component", err);
checkStatus(err);

UInt32 enableIO;
size=0;

//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;
err = AudioUnitSetProperty(theInputUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
1, // input element
&enableIO,
sizeof(enableIO));
checkError("opening audio component", err);
checkStatus(err);

enableIO = 0;
err = AudioUnitSetProperty(theInputUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
0, //output element
&enableIO,
sizeof(enableIO));
checkError("opening audio component", err);
checkStatus(err);

/****/

size = sizeof(AudioDeviceID);

AudioDeviceID inputDevice;
err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
&size,
&inputDevice);
checkError("opening audio component", err);
checkStatus(err);

err =AudioUnitSetProperty(theInputUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global,
0,
&inputDevice,
sizeof(inputDevice));
checkError("opening audio component", err);
checkStatus(err);

/****/

AudioStreamBasicDescription DeviceFormat;
AudioStreamBasicDescription DesiredFormat;
//Use CAStreamBasicDescriptions instead of 'naked'
//AudioStreamBasicDescription to minimize errors.
//CAStreamBasicDescription.h can be found in the CoreAudio SDK.

size = sizeof(AudioStreamBasicDescription);

//Get the input device format
err = AudioUnitGetProperty (theInputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
1,
&DeviceFormat,
&size);
checkError("opening audio component", err);
checkStatus(err);

//set the desired format to the device's sample rate
DesiredFormat.mSampleRate = DeviceFormat.mSampleRate;

//set format to output scope
err = AudioUnitSetProperty(
theInputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
1,
&DesiredFormat,
sizeof(AudioStreamBasicDescription));
checkError("opening audio component", err);
checkStatus(err);

/****/

SInt32 *channelMap =NULL;
UInt32 numOfChannels = DesiredFormat.mChannelsPerFrame; //2 channels
UInt32 mapSize = numOfChannels *sizeof(SInt32);
channelMap = (SInt32 *)malloc(mapSize);

//for each channel of desired input, map the channel from
//the device's output channel.
for(UInt32 i=0;i<numOfChannels;i++)
{
channelMap=-1;
}
//channelMap[desiredInputChannel] = deviceOutputChannel;
channelMap[0] = 2;
channelMap[1] = 3;
err = AudioUnitSetProperty(theInputUnit,
kAudioOutputUnitProperty_ChannelMap,
kAudioUnitScope_Output,
1,
channelMap,
size);
checkError("opening audio component", err);
checkStatus(err);

free(channelMap);

/****/

err = AudioUnitInitialize(theInputUnit);
checkError("opening audio component", err);
checkStatus(err);

err = AudioOutputUnitStart(theInputUnit);
checkError("opening audio component", err);
checkStatus(err);
 
bon j'ai résolu pas mal de problemes, j'ai reussi à lancer le thread pour attrapper les buffers sur l'Output Scope du Bus Input. Mais le seul hic est que l'AudioUnitRender me rend à chaque appel 512 frames alors que je ne souhaite que 160 frames, et évidemment l'AudioUnitRender plante si je le set à 160 frames. Une idée ?

mon code :

Bloc de code:
flags = 0;
kNumChannels = 160;

theAudioData = (AudioBufferList *)malloc(offsetof(AudioBufferList, mBuffers[kNumChannels]));

theAudioData->mNumberBuffers = kNumChannels;

for (int i = 0; i < kNumChannels; i++)
{
   theAudioData->mBuffers[i].mNumberChannels = 1;
   theAudioData->mBuffers[i].mDataByteSize = 2;
   theAudioData->mBuffers[i].mData = NULL;
}

OSStatus err = [B]AudioUnitRender[/B](theInputUnit, &flags, &myTimeStamp, 1, numberOfFrames, theAudioData); // plante si numberOfFrames=160...

myTimeStamp.mSampleTime += kNumFramesPerSlice;

mon Output Scope du Bus Input est configuré de cette façon :
Bloc de code:
output.mSampleRate = 8000;

output.mBytesPerPacket = 2;

output.mFramesPerPacket = 1;

output.mBytesPerFrame = 2;

output.mChannelsPerFrame = 1;

output.mBitsPerChannel = 16;