Re: Ring buffer design for MP3 (et. al.) playback
Re: Ring buffer design for MP3 (et. al.) playback
- Subject: Re: Ring buffer design for MP3 (et. al.) playback
- From: "Andreas Falkenhahn" <email@hidden>
- Date: Sun, 14 Oct 2007 23:48:49 +0200
I've now dropped the ring buffer approach, and adopted a double
buffering mechanism as shown in the AudioFilePlayImpl example in
the CoreAudio SDK. This works fine.
One problem remains, though: How can I monitor how long the
audio file has been playing? Previously, this was possible by
simply using a frame counter in the ACComplexInputProc()
because buffer sizes were very small. But now I'm using buffers
which have space for about a second of audio data. Therefore,
ACComplexInputProc() is only called at intervals of about 1
second. But I want to be able to get much more precise information
about how many frames of an audio file were already played.
This is crucial information because my player needs to implement
a pause/resume feature, a time line, etc.
So my current solution to get the playback time position of the
audio file is to record a time stamp in the kAudioUnitRenderAction_PreRender
part of a notification callback, and use this time as the base
value for computing the current audio file playback position
later.
While this works fine, I'm still wondering if that's the way one
should do this, or is there a better way to get the information about
how long an audio file has been playing?
Tks
Andreas
On 13.10.2007 at 16:14 Andreas Falkenhahn wrote:
>Hi,
>
>I've some problems devising an appropriate ring buffer design to use for
>playing several audio formats using the AudioFile API. The data is streamed
>in using the AudioFileReadPackets() function.
>
>Set up is like the following:
>1) CoreAudio calls MixerInputCallback()
>2) AudioConverterFillComplexBuffer() runs user callback function
>3) User callback function copies data from ring buffer to a private buffer
>which is
>then passed on to the audio converter
>4) After copying data from the ring buffer, the user callback function
>signals
>the feeder thread using pthread_cond_signal() to read in the next chunk
>if there's enough room for it in the ring buffer
>5) and so on...
>
>This ring buffer design would be fairly easy and straight-forward if I
>were to play
>standard PCM data with a fixed byte rate only, e.g. 4 bytes per frame for
>16-bit
>stereo PCM data. In that case, I could for instance set up a ring buffer
>containing
>8 chunks with room for 2048 frames per chunk. The ring buffer size would
>be
>2048 * 8 * 8 = 128 kb then.
>
>So far so good. The problems begin as soon as the ring buffer shall be able
>to handle compressed audio formats as well, because now I have to deal
>with "packets" and the byte sizes of these vary. With PCM data one frame
>would equal one packet and would have a fixed byte size. Now things are
>much more complex. I tested my routines with a random MP3 on my hard
>disk and got the following information:
>
>1 packet = 1152 frames
>
>When I used AudioFileReadPackets() to read 1 packet from the stream, it
>returned that it read 626 bytes. But of course this information is only
>valid for
>this very packet. An other packet will be of a different byte size,
>because we're
>dealing with compressed data here.
>
>Well, to cut a long story short: The major problem is how could I read the
>requested number of packets from the ring buffer? My ACComplexInputProc()
>requests me to return ioNumberDataPackets in a memory buffer. So I would
>need to copy this data from my ring buffer into a new buffer so that the
>AudioConverter can access and convert it.
>But how do I know how much bytes I need to read from the ring buffer? I
>really
>can't imagine where I can get this information from. Let's suppose the
>feeder
>thread reads 20 packets from the file and these 20 packets equal some
>15 kb. Now the my ACComplexInputProc() requests me to return 10
>packets to the AudioConverter. How do I know how much bytes these
>10 packets occupy in the ring buffer? I need to know this because I have
>to read the 10 packets from the ring buffer!
>
>I would really need some help here. I hope someone has understood what
>I mean and can help me out here.
>
>Thanks very much!
>
>Andreas
>--
>"Remember: It's nice to be important but it's more important to be nice!"
>
>
> _______________________________________________
>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
--
"Remember: It's nice to be important but it's more important to be nice!"
_______________________________________________
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