Re: Reduce Audio Time Latency
Re: Reduce Audio Time Latency
- Subject: Re: Reduce Audio Time Latency
- From: Jeff Moore <email@hidden>
- Date: Tue, 23 Jun 2009 14:11:18 -0700
I'm sorry, but this still doesn't make sense. I don't understand why
you are jumping through all these hoops just to play some audio. I'm
pretty sure that most of your problems stem from the fact that you are
combining Python with ObjC and real-time requirements of the HAL. As I
said previously, none of these things play nice together. Almost
certainly, your threading problems stem directly from your attempts to
mash these things together.
Further, I see a call to gettimeofday() in your IOProc. Let me
reiterate what I said about not calling blocking APIs from inside your
IOProc.
So, I think you really need to simplify this if you want to get some
help here. You need to separate the Python/ObjC stuff from the audio
stuff. There is no way you are going to get them to work together
anyway. Then we can talk about any audio problems you have after that.
I suspect that your picture of things will clear up tremendously after
this simplification too.
--
Jeff Moore
Core Audio
Apple
On Jun 23, 2009, at 1:36 PM, Ravneet Kaur wrote:
Hello Jeff,
Sorry for the confusion. I am writing a Python application that has
to report exact callback time of audio on Mac machine. I wrote a
CoreAudio SDK (using Audio Units) based program in Objective-C that
is invoked by my python code for playing Audio.
When my python code invokes this objective-c program, it creates a
new thread and within this thread I create Audio Unit, converter,
register callback and Initialize the audio unit. All this code I
posted on my first post.
I am mainly interested in the exact playback time and I was not
getting from Audio Units) . I fetched machine latency and steam
latency but their sum was also not matching up with external
hardware testing device (which is accurate).
So I registered an IOProc with my device through MTCoreAudio which
gets invoked immediately after my Callback method associated with
Audio Unit. From this IOProc, as suggested by you I used the
InInputData and OutputData Audio time Stamps.
The InInputData Time from the IOProc is consistent with the time
reported by external hardware testing device with 1ms precision.
This time also takes care of latency.
But if python code after invoking play method gets into doing any
other thing (UI stuff) then it seems that the time received in
IOProc is completely off. If I sleep this python thread after
invoking the play method i.e. while new thread gets created and
audio is getting rendered then time reported is correct.
My last post was showing code of the play method and thread created.
This puts a strong limitation on my application as I can not present
any other stimulus while playing audio and I do not understand
reasoning behind this behavior.
My understanding is that thread created for my audio playback gets
terminated after initializing the Audio Unit (as I do not put into
while loop to check if sound is still being rendered) and this makes
Callback and IOProc to be called on main python thread. Is this right?
I do not like the idea of staying in while loop to keep checking is
audio is still being rendered as I felt this will be managed by
Audio device and callback.
Below is code for easy reference
OSStatus mySimpleIOProc (
AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
const AudioTimeStamp* inInputTime,
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData)
{
if(rendererFlag==1)
{
rendererFlag++;
soundStartTime = inOutputTime->mHostTime;
gettimeofday(&audioTimeOfDay, NULL);
double timeOffsetInMilliseconds= ((double)(inOutputTime->
mHostTime-nowTimeRenderProc))*1E-6;
double timeOffsetInMilliseconds2= ((double)(inNow->mHostTime-
nowTimeRenderProc))*1E-6;
}
return 0;
}
- (void) play:(char *) fileName:(int) volumeValue
{
volume = volumeValue;
pthread_attr_t theThreadAttributes;
int ret;
ret = pthread_attr_init(&theThreadAttributes);
ret = pthread_create(&tid, &theThreadAttributes, playThread,
fileName);
nowTime = mach_absolute_time();
while(rendererFlag<2)
{
usleep(2000);
}
}
The PlayThread
void playThread(char* fileName)
{
AURenderCallbackStruct renderCallback;
OSStatus err = noErr;
AudioStreamBasicDescription fileASBD, outputASBD;
FSRef fileRef;
err = setupAudioUnit(&theOutputUnit);
err = MatchAUFormats(&theOutputUnit,&outputASBD, 0); //"0" is the
output bus, use "1" for the input bus
err = getFileInfo(&fileRef, &musicFileID, &fileASBD, fileName);
err = MakeAUConverter(&musicFileID, &converter,&fileASBD,
&outputASBD );
err = setupCallbacks(&theOutputUnit, &renderCallback);
outputUnit = theOutputUnit;
uint64_t nowTime = mach_absolute_time();
// printf("calling audio unit start -------------------------->
\n");
err =AudioOutputUnitStart(theOutputUnit);
// printf("after call audio unit start
-------------------------->%lld\n", (mach_absolute_time()-nowTime));
checkStatus(err);
gIsPlaying=TRUE;
}
_______________________________________________
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