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: Thu, 10 Jul 2008 08:26:07 +1200
It looks like I finally have something that works. I made a better
queue and made sure it gets filled a little bit first (with silence)
to ensure that the audio callback always has something to process. I
do get some pops initially but then it comes right, at least a heck of
a lot more 'right' than what I was getting before. There is the odd
blemish every so often but I'll blame that on bad drivers.
For the sake of anyone else who is curious, I have posted some of the
relevant code below. I had to cut bits out because the moderators
rejected it the first time I sent it.
Once again, thanks for all the help and hopefully I needn't pursue
this small adventure further. Regardless, if someone wants to critique
the following code, then be my guest.
Glenn
*** snip ***
class AudioDataQueue
{
public:
AudioDataQueue() : mMaxSize(100), mWriteIndex(0), mReadIndex(0), mSize(0)
{
mDataByteSize = FRAME_SIZE * NUM_CHANNELS * sizeof(float);
mQueue = (Byte**)malloc(mMaxSize * sizeof(Byte*));
for (int i=0; i<mMaxSize; i++)
{
mQueue[i] = (Byte*)malloc(mDataByteSize);
}
};
virtual ~AudioDataQueue(){ };
void Queue(Byte *data)
{
memcpy(mQueue[mWriteIndex++], data, mDataByteSize);
if (mWriteIndex >= mMaxSize) mWriteIndex = 0;
mSize++;
};
void Dequeue(void *data)
{
//fill an AudioBuffer with bytes
memcpy(data, mQueue[mReadIndex++], mDataByteSize);
if (mReadIndex >= mMaxSize) mReadIndex = 0;
mSize--;
};
int Size() { return mSize };
public:
Byte **mQueue;
int mWriteIndex;
int mReadIndex;
int mSize;
int mDataByteSize;
int mMaxSize;
};
*** snip ***
// This is not for input-only streams, this is for streams where the
input device is different from the output device
OSStatus AudioInputProc( AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
const AudioTimeStamp* inInputTime,
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData)
{
if (state == 1) {
printf("%d: %d : The output hasn't been called yet\n",
++errorCount, adq.mSize);
}
state = 1;
adq.Queue( (Byte*)(inInputData->mBuffers[0].mData) );
return noErr;
}
// This is not for output-only streams, this is for streams where the
input device is different from the output device
OSStatus AudioOutputProc( AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
const AudioTimeStamp* inInputTime,
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData)
{
if (adq.Size() < 5)
{
//play some silence
memset(outOutputData->mBuffers[0].mData, 0, FRAME_SIZE
* NUM_CHANNELS * sizeof(float));
}
if (state == 2) {
printf("%d: %d : The input hasn't been called yet\n",
--errorCount, adq.mSize);
}
state = 2;
adq.Dequeue( outOutputData->mBuffers[0].mData );
return noErr;
}
On Wed, Jul 9, 2008 at 10:12 AM, Mikael Hakman <email@hidden> wrote:
> On July 04, 2008 5:41 AM, Glenn McCord wrote:
>>
>> Just to bring this thread full circle again, I was able to make a
>> console 'through' application by looking at the Portaudio source code.
>> They used to use a HAL implementation which is coded inside
>> pa_mac_core_old.cpp.
>>
>> With the help of that code and some other sources, I was able to make
>> a console application that plays through the inputs and straight to
>> the outputs. Unfortunately I get very regular, almost rhythmic popping
>> (imperfections in the audio) with frame sizes up to 2056 (I haven't
>> tried higher). This is despite being able to use Portaudio with a
>> frame size of 64 with no audio imperfections.
>>
>> As much as I don't want to, I have attached the code to this email
>> with the hope that something really really obvious is causing the
>> problems.
>> Essentially I'm using the following code flow
>> - Find the input and output ids of my device
>> - set the sample rates and frame buffer size for the device
>> - set up and input and output callback
>> - make a temporary AudioBufferList object to store the input data so
>> that it can be copied to the output
>>
>> Then the callbacks do their thing and data gets copied from input to
>> output.
>>
>> One of the guys suggested that Portaudio does some kind of extra
>> buffering, but that would have to be some significant buffering.
>>
>> Just a couple of points:
>> - My device is regarded as two devices, input and output.
>> - If I create a sine wave programatically and copy that data straight
>> to output, then I get no imperfections in playback.
>>
>> Hopefully my issue is relatively simple, but I've been at this all
>> week and need a bit of help.
>
> Here is good news. After reading through the thread "Programmatic Aggregate
> Device issue on Intel Mac" I decided to try to create an Aggregate Device
> out of my built-in input and output devices, not programmatically but using
> SAM panel. I did it once before and it didn't work - as soon as I checked
> input or output device, the other one was not selectable anymore. This time
> however it worked - now I have one device consisting of both input and
> output. I didn't actually play anything through it but HALLab shows clearly
> both its input and output sides. Perhaps it was fixed in the newest OS
> update. If you can do the same for your USB device then you could forget all
> about buffering and queues and use the aggregate device instead of separate
> input and output devices and have input delivered in the same IOProc and
> simultaneously with output.
>
> 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