Re: A simple 'Device Through' app (need some help).
Re: A simple 'Device Through' app (need some help).
- Subject: Re: A simple 'Device Through' app (need some help).
- From: "Glenn McCord" <email@hidden>
- Date: Mon, 7 Jul 2008 14:50:23 +1200
Thanks, that clarifies a few things.
On further playing around, it seems that both Portaudio's old HAL
implementation and consequently my HAL through code is still popping.
Portaudio's newer AUHAL implementation is fine though.
I'm trying to add input AudioBufferLists to a queue for the output
callback to work its way through, but it has proved unsuccessful so
far. I still get lots of popping.
Glenn
On Sun, Jul 6, 2008 at 12:27 AM, Mikael Hakman <email@hidden> wrote:
> On Saturday, July 05, 2008 12:30 PM, Glenn McCord wrote:
>>
>> On Fri, Jul 4, 2008 at 12:04 PM, Mikael Hakman <email@hidden> wrote:
>>>
>>> On Friday, July 04, 2008 5:41 AM, Glenn McCord wrote:
>>>
>>> If I understand your code correctly then in your AudioInputProc, the
>>> statement:
>>>
>>> (*savedAudioBufferList) = (*inInputData);
>>>
>>> copies contents of inInputData structure to savedAudioBufferList
>>> structure,
>>> both of which are of AudioBufferList type. AudioBufferList is defined as:
>>>
>>> struct AudioBufferList {
>>> UInt32 mNumberBuffers;
>>> AudioBuffer mBuffers[kVariableLengthArray];
>>> };
>>>
>>> Constant kVariableLengthArray is defined as:
>>>
>>> enum {
>>> kVariableLengthArray = 1
>>> };
>>>
>>> This means that the copy operation copies entire inInputData->mBuffers[0]
>>> including its mData member over to savedAudioBufferList. After copy,
>>> savedAudioBufferList->mBuffers[0].mData will point to the same area as
>>> inInputData->mBuffers[0].mData. Which means that nothing will be buffered
>>> and your original in Start() allocated buffer area is lost. In your data
>>> copy loop latter on, you "copy" the contents to itself. Your
>>> AudioOutputProc
>>> works therefore on the original data address passed to your
>>> AudioInputProc
>>> by your audio driver which at that time was returned to your driver and
>>> probably is reused again for new samples.
>>
>>
>> Is making a copy of the inInputBuffer going to copy the AudioBuffer
>> array called inInputBuffer->mBuffers[0] or is it going to copy an
>> address?
>> Should I memcpy mBuffers[0] with:
>>
>> memcpy(savedAudioBufferList->mBuffers, inInputBuffer->mBuffers,
>> sizeof(AudioBuffer)) ?
>>
>>
>>>
>>> BTW, why do you use a loop and copy each sample separately? Why not use
>>> memcpy and copy the whole shebang at once?
>>
>> I was trying to use memcpy initially but for some reason I couldn't
>> get the application to work. I can't remember the details now, so
>> maybe it was some other code that was causing the grief.
>>
>> I'm assuming I can only memcpy that void * mData array by itself and
>> not the AudioBufferList struct in its entirety.
>>
>> memcpy( savedBuffer->mData, savedBuffer->mData,
>> inputBuffer->mDataByteSize);
>>
>> My code is at work and I don't have a mac, so I can't test things until
>> Monday.
>
> Making copy of inInputBuffer will copy entire inInputBuffer structure - i.e.
> entire memory area taken up by inInputBuffer. As seen by the compiler, this
> area consists of the following:
>
> struct AudioBufferList {
> UInt32 mNumberBuffers;
> AudioBuffer mBuffers[1];
> };
>
> It will therefore copy both mNumberBuffers field, and array of mBuffers
> field consisting of one AudioBuffer element. This array is not an array of
> pointers but an array of AudioBuffer structures:
>
> struct AudioBuffer {
> UInt32 mNumberChannels;
> UInt32 mDataByteSize;
> void* mData;
> };
>
> It will therefore copy mNumberChannels, mDataByteSize and mData fields. Now,
> mData is a pointer and therefore it will copy this pointer but not the data
> it points to. Laying out things sequentially, it will copy the following:
>
> mNumberBuffers mNumberChannels mDataByteSize mData
>
> On a 32 bit machine it will copy 16 bytes.
>
> In general, copy by assignment operation will (recursively) copy everything
> including any contained structures, arrays, and pointers but it will not
> deference pointers.
>
> Assuming your input and output consists of one stream only (there could be
> more and different counts for input and output, and the numbers could change
> dynamically), and that it uses only one buffer (= interleaved data or one
> channel only), and following your framework, I would setup things in Start:
>
> UInt32 dataByteSize = sizeof(float) * FRAME_SIZE * NUM_CHANNELS;
>
> savedAudioBufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList));
> savedAudioBufferList-> mNumberBuffers = 1;
> savedAudioBufferList->mBuffers[0].mNumberChannels = NUM_CHANNELS;
> savedAudioBufferList-> mBuffers[0].mDataByteSize = dataByteSize;
> savedAudioBufferList->mBuffers[0].mData = malloc(dataByteSize);
>
> Then in AudioInputProc, the _only_ thing that needs to be done is:
>
> memcpy (savedAudioBufferList-> mBuffers[0].mData,inInputData->
> mBuffers[0].mData, inInputData-> mBuffers[0]. mDataByteSize);
>
> Regards/Mikael
>
>
>
_______________________________________________
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