Re: Offline rendering difficulty
Re: Offline rendering difficulty
- Subject: Re: Offline rendering difficulty
- From: dct <email@hidden>
- Date: Wed, 17 Jun 2009 14:10:25 -0700
Doug,
Thanks for the reply.
It does raise a few questions:
a. Is the latency (from push to ready-to-pull) predictable?
b, Will AudioConverter complete the push for all but the last packet -
and-
c. Is there a built-in way with AudioQueueOfflineRender and/or
AudioConverter to push in some number of packets and then simply wait
for the process to complete before pulling the output?
Don
On Jun 16, 2009, at 11:36 PM, Doug Wyatt wrote:
This algorithm is flawed in that it expects to be able, given a
single MP3 packet, to use AudioQueueOfflineRender to immedately
produce exactly the PCM frames corresponding to that packet.
Neither MP3 decoders nor AudioQueueOfflineRender work that way.
Both, for pretty different reasons, require that you "push" the
encoded input at a significantly in advance of where you try to
"pull" decoded output.
You might study the example for AudioQueueOfflineRender carefully
and get a feel for how the example decouples its pushes and pulls.
You might also experiment with using a software MP3 decoder via
AudioConverter, for the same purpose. You might notice that with
AudioConverter you can never pull quite as much as you've pushed.
The horrible difference with AudioQueueOfflineRender is that it's
emulating the realtime playback path too well -- it dutifully
generates as many samples as you ask for, even if not that many have
been decoded yet.
Doug
On Jun 10, 2009, at 13:28 , dct wrote:
(This was sent earlier but I received no receipt reply.)
I am having difficuty with offline rendering to linear pcm.
With an mp3 music input, the rendering operation produces a
properly sized output
but one that is very "spikey" and (more or less) repeating--
certainly not music.
A histogram of the SInt16 output (channel 1 ) shows:
- ~60% zeros,
- ~ one very distinctive spike at about +5652 (~6%) and about 10
lesser ones.
Autocorrelation of channel 1 output shows a very distictive
structure with sharp
spikes at multiples of ~0.02612 sec ( = 1152 / 44100 = output
packet time span).
The 2nd channel shows similar, non-music characteristics.
The input is definitely music--it plays very nicely through iTunes.
My processing goes as follows:
1. In a controlling Obj-C object:
a. Open an audio file parser,
err = AudioFileStreamOpen(self, propertyCallback,
packetCallback, 0, &aFileParserID);
b. Run the parser:
err = AudioFileStreamParseBytes(aFileParserID, inBufSize,
inBuffer, kAudioFileStreamParseFlag_Discontinuity);
2. In the propertyCallback function --
if(inPropertyID==kAudioFileStreamProperty_ReadyToProducePackets):
a. Get properties:
err = AudioFileStreamGetProperty( inAudioFileStream,
kAudioFileStreamProperty_DataFormat, &asbdSize, &asbdX);
b. Set out-format for linear pcm (AudioStreamBasicDescription
asbdY):
asbdY.mSampleRate = asbdX.mSampleRate;
asbdY.mFormatID = kAudioFormatLinearPCM;
asbdY.mFormatFlags = kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kAudioFormatFlagIsPacked;
asbdY.mFramesPerPacket = 1;
asbdY.mChannelsPerFrame = asbdX.mChannelsPerFrame;
asbdY.mBitsPerChannel = 16;
asbdY.mBytesPerFrame = sizeof(SInt16)*asbdY.mChannelsPerFrame;
asbdY.mBytesPerPacket = asbdY.mBytesPerFrame;
c. Create an audio queue:
err = AudioQueueNewOutput(&asbdX, audioQueueCallback,
inBuffer, NULL, NULL, 0,
&queue);
d. Establish a queue buffer (sized to handle one packet at a time):
err = AudioQueueAllocateBuffer( queue, outPcktSize, &ioBuffer );
e. Set queue for offline rendering:
chLayout.mChannelLayoutTag = (asbdX.mChannelsPerFrame==1) ?
kAudioChannelLayoutTag_Mono :
kAudioChannelLayoutTag_Stereo;
chLayout.mChannelBitmap = 0;
chLayout.mNumberChannelDescriptions = 1;
err = AudioQueueSetOfflineRenderFormat( queue, &asbdY,
&chLayout );
3. In the packetCallback function --
once each loop: for(ii=0;ii<inNPackets;ii++)
a. Copy input block to queue buffer
memcpy((char *)ioBuffer, (const char *)inInputData+pcktOffset,
inPcktSz);
b. Generate time stamp, ts
ts.mSampleTime = 0;
ts.mHostTime = (UInt64)startT; (startT derived from
Microseconds() )
ts.mRateScalar = 0;
ts.mWordClockTime = 0;
memset (&ts.mSMPTETime, 0, sizeof(SMPTETime));
ts.mFlags = kAudioTimeStampSampleTimeValid |
kAudioTimeStampHostTimeValid;
c. Render to pcm
nn = asbdX.mFramesPerPacket;
err = AudioQueueOfflineRender( queue, &ts, ioBuffer, nn );
d. Copy queue buffer to output
memcpy((char *)outBuffer+fillOffset, (const char *)ioBuffer,
outPcktSz);
e. Update the fillOffset value
_______________________________________________
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