Re: ExtAudioFileSeek/ExtAudioFileRead issues in iOS4.2
Re: ExtAudioFileSeek/ExtAudioFileRead issues in iOS4.2
- Subject: Re: ExtAudioFileSeek/ExtAudioFileRead issues in iOS4.2
- From: Joel Pryde <email@hidden>
- Date: Wed, 12 Jan 2011 15:26:19 -0800
Yeah, I'm aware of both these issues and have coded around them for
the most part. There are a few workarounds for both the priming issue
as well as the packet size issue:
http://lists.apple.com/archives/coreaudio-api/2010/Sep/msg00063.html
http://lists.apple.com/archives/coreaudio-api/2010/Jan/msg00055.html
My issue is something a bit different though. The seeking to the
exact same spot twice and doing a read will not always return the same
results. As long as my seeks are to the end of my last read, I have
no problems. Seeking anywhere else however (including to the same
start of the last read) gives me noticeably different data. I'm not
sure how priming or packet sizes could account for this behaviour.
For instance, these two calls in succession occasionally return
different buffers for me:
result = ExtAudioFileSeek(mSoundBuffer->fileReference, 0);
result = ExtAudioFileRead(mSoundBuffer->fileReference, &numPackets, bufList1);
result = ExtAudioFileSeek(mSoundBuffer->fileReference, 0);
result = ExtAudioFileRead(mSoundBuffer->fileReference, &numPackets, bufList2);
Unfortunately uncompressing the entire file isn't an option for me. I
am dealing with very high bitrate files and I need to be able to open
them directly from mp3 very quickly (I'm using a circular buffer to
hold just my local frames).
Thanks to everyone for the explanations. It definitely helps clarify
things for me under the hood. Very frustrating that all this worked
fine in 3.2 and is very different in 4.2!
-joel
On Wed, Jan 12, 2011 at 3:09 PM, Brian Willoughby <email@hidden> wrote:
> Priming and blocking may appear similar from the outside, but they address
> different issues. There is some overlap, though.
>
> Priming is related to digital signal processing such as filters and sample
> rate conversion. Many processes involve a certain number of samples of
> latency. An FFT certainly requires a huge window, but even simple filters
> and SRC need several samples before you can get any output. In the specific
> case of ExtAudioFile, priming is primarily related to the fact that SRC may
> be necessary to convert the file from its native sample rate to your desired
> client sample rate. You cannot just start pulling sample frames out of a
> process without priming, because the operations involved in the process have
> latency. CoreAudio offers some control over this, but you always have to
> deal with the issue somewhere in your code (either by tossing the priming
> samples, or by shifting your entire timeline to account for the priming
> latency).
>
> But don't let priming confuse you about blocking. Every file format has a
> "packet" size, which I was calling blocking. For LPCM, the packet size is
> one frame (one sample per channel), and thus you can seek anywhere with
> ease. For compressed formats like MP3 or AAC, the packet is much larger -
> something like 1152 frames. If you seek to the middle of a packet, then
> ExtAudioFile will have to seek backwards to find the start of the packet,
> then decode and toss frames until your requested frame is ready. I agree
> with your assumption that it should work the same between iOS 3.2 and iOS
> 4.2, but perhaps you're asking too much.
>
> What's worse is that lossy file formats have both priming and blocking
> issues, because lossy formats involve complex filtering to reconstruct a
> facsimile of the original audio frames, and this filtering creates a latency
> between the input data and output data. Thus, you run into common issues
> where, e.g., MP3 does not have the same packet size as CD (an issue when
> burning MP3) or where seeking to random positions in an MP3 does not produce
> consistent results.
>
> I have a suspicion that you might need to convert active files from MP3 to
> LPCM so that random access with frame accuracy involves none of the extreme
> priming and blocking issues that lossy formats require. But I cannot say
> where in your code it would be most efficient to cache the LPCM, or whether
> memory constraints would cause tradeoff problems. If you are only accessing
> a couple of audio files at a time from a giant library, then perhaps
> converting and caching an LPCM copy would be prudent.
>
> Brian Willoughby
> Sound Consulting
>
>
> On Jan 12, 2011, at 14:47, Joel Pryde wrote:
>>
>> The strange thing is that setting the priming buffer size definitely
>> does /something/. If I don't set it, when I do my first read it will
>> skip the initial part of the file (even though I seeked to frame 0).
>> If I do set my priming sizes, it will at least do the first read
>> correctly (and then get screwed up if I try to jump anywhere in the
>> file).
>>
>> On Wed, Jan 12, 2011 at 12:52 PM, Ian Esten <email@hidden> wrote:
>>>
>>> My understanding of ExtAudioFileSeek is that it does not do what is
>>> claimed by the Apple docs - rather, it seeks to the requested sample
>>> location offset by the priming buffer size. If I remember correctly, the
>>> priming buffer size is a property of a compressed file. In other words, it
>>> is a read only property and cannot be set as you are trying to do. I know I
>>> am right about the seek location, but am less sure about the second
>>> statement, so you should check that. Also, you are not checking the return
>>> code of AudioConverterSetProperty - you may find it returns an error when
>>> trying to set the prime info for a read converter.
>>>
>>>
>>> On Jan 12, 2011, at 12:00 AM, Joel Pryde wrote:
>>>>
>>>> I've been experiencing a host of issues with the Extended File Audio
>>>> Services API in iOS4.2 (on iPad in my case). My app allows the user
>>>> to jump around the audio of a file and converts the localized area of
>>>> audio from MP3 to PCM using this API. This work great in iOS3.2 but
>>>> in iOS4.2 the ExtAudioFileSeek function does not reliably seek to the
>>>> frame I give it. If the audio is read sequentially through a series
>>>> of seeks (each seek is at the end of my last read) the API function
>>>> works fine. However if I ever jump to a new place in the file, the
>>>> audio read out is actually a small amount after where I seeked to
>>>> (usually around 2000 frames). This exact same code works fine in
>>>> iOS3.2 so I suspect it was a bug introduced in the audio framework in
>>>> iOS4.2.
>>>>
>>>> I've also had to set the following settings on my AudioConverter to
>>>> even reliably read the initial part of the file (even when doing
>>>> sequential seeks):
>>>>
>>>> UInt32 primeMethod = kConverterPrimeMethod_None;
>>>> err = AudioConverterSetProperty (acRef,
>>>>
>>>> kAudioConverterPrimeMethod,
>>>>
>>>> sizeof(primeMethod),
>>>>
>>>> &primeMethod);
>>>> AudioConverterPrimeInfo primeInfo;
>>>> primeInfo.leadingFrames = 0;
>>>> primeInfo.trailingFrames = 0;
>>>> err = AudioConverterSetProperty(acRef, kAudioConverterPrimeInfo,
>>>> sizeof(primeInfo), &primeInfo);
>
>
_______________________________________________
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