PCM data format from audio flinger to Audio interface

752 views
Skip to first unread message

henry....@gmail.com

unread,
Feb 11, 2009, 1:03:39 AM2/11/09
to android-platform
Hi,

It looks like that audio flinger always sends 10240 bytes PCM data to
audio interface periodically(around every 32 ms for ring tone and
every 50 ms for mp3).

Just wondering what's the logic behind this. For 44.1k sampling
frequency, 16 bit per sample and 2 channels, it should be 44.1k * 2 *2
= 176.4kBytes per second. 10240 Bytes from audio flinger every
32~50ms doesn't seem to match 176.4kB/second.

Can anybody help to clarify what's the format the PCM data from audio
flinger? does that mean the sample size is not 16 bits, or any other
reason?

Thanks for clarification!
AndroidFan

Dave Sparks

unread,
Feb 11, 2009, 1:14:57 AM2/11/09
to android-platform
What platform are you testing on?

The software mixer buffers are sized to the value returned
AudioStreamOut.bufferSize(). The expectation is that the audio driver
is double buffering the audio, so AudioFlinger fills one buffer while
the other one is being streamed to the DAC.

On Feb 10, 10:03 pm, "henry.lon...@gmail.com" <henry.lon...@gmail.com>
wrote:

susanner

unread,
Feb 11, 2009, 1:22:09 AM2/11/09
to Dave Sparks, android-platform
" 2 channels" doesn't need sampling twice, it may puts data to one channel and copy it to the other.

免费送你钻戒作情人节礼物

Dave Sparks

unread,
Feb 11, 2009, 1:27:36 AM2/11/09
to android-platform
Oh forgot to mention, AudioFlinger output is always stereo 16-bit
linear PCM. There are some vestiges of mono-only in the code, but they
haven't been tested in a long time and I'm sure something would break
if you tried mono.

henry....@gmail.com

unread,
Feb 11, 2009, 1:38:49 AM2/11/09
to android-platform
I'm running over G1/ADP1, and playing with bluetooth bluez stack.
I mean the output from the mixer, to the bluez stack such as
a2dp_write.

How the AudioStreamOut.bufferSize() is determined for mp3/ring tone
for 44.1k sampling rate?

Thanks!

On Feb 10, 10:14 pm, Dave Sparks <davidspa...@android.com> wrote:

Dave Sparks

unread,
Feb 11, 2009, 4:33:59 AM2/11/09
to android-platform
That's the same situation, it uses whatever A2DP AudioStreamOut
interface returns from bufferSize().

The mix buffers are not affected by the source material at all.
Different audio sources will allocate different buffer sizes based on
their own requirements. Games typically use small buffers to keep
latency to a minimum. The media player tends to use larger buffers to
improve efficiency in the decoders.

On Feb 10, 10:38 pm, "henry.lon...@gmail.com" <henry.lon...@gmail.com>
wrote:

henry....@gmail.com

unread,
Feb 11, 2009, 10:44:58 PM2/11/09
to android-platform
The A2DP AudioStreamOut hard code the bufferSize() as 512*20. Could
you please clarify the logic? I mean how it's related to 44.1k
sampling rate.

Thanks!

Dave Sparks

unread,
Feb 12, 2009, 1:14:52 AM2/12/09
to android-platform
Why does it have to relate to the sample rate?

AFAIK, A2DP headsets are 44.1KHz or 48KHz, which is less than 10%
difference. As long as the buffer size is a multiple of the frame size
and big enough to prevent underruns when the CPU is busy, it should
work fine. There will be a small difference in latency over AD2P based
on the sample rate, but latency is already pretty bad when you
consider the SBC codecs on both ends, buffering through the audio
stack and bluez stack, and buffering in the headset.

On Feb 11, 7:44 pm, "henry.lon...@gmail.com" <henry.lon...@gmail.com>
wrote:

henry....@gmail.com

unread,
Feb 12, 2009, 1:44:31 AM2/12/09
to android-platform
Is the PCM data from audio flinger always sampled as 44.1kHz?

Let's go back to my original question, audio flinger seems always
sends 10240 bytes PCM data to
audio interface periodically(around every 32 ms for ring tone), which
is more than what the 44.1k sampling frequency can consume(for 44.1k
sampling frequency, 16 bit per sample and 2 channels, it should be
44.1k * 2 *2
= 176.4kBytes per second.). Does that mean the sbc encoder will
discard some of the payload from audio flinger?

Thanks!

Dave Sparks

unread,
Feb 12, 2009, 10:23:21 PM2/12/09
to android-platform
The A2dpAudioInterface is responsible for pacing the audio through
blocking writes, so that should not be the case. However, I know there
are bugs in the A2DP implementation, so it might be that's what you
are seeing.

On Feb 11, 10:44 pm, "henry.lon...@gmail.com" <henry.lon...@gmail.com>

henry....@gmail.com

unread,
Feb 13, 2009, 12:35:27 AM2/13/09
to android-platform
For the ring tone(.ogg file), it's mono 44.1K. Does audio flinger
converts it into stereo samples by simple copy?

I analyzed the Audio Flinger output for ring tone. It looks like there
are a lot of zeros. Just wondering how the media player/audio flinger
decide to send bufferSize() bytes at which kind of frequency. If it's
keep sending through blocking write, then the output from local speaker
(if not a2dp) will not be 44.1k frequency, right? Somebody must keep
the timing.

Nick Pelly

unread,
Feb 13, 2009, 10:55:21 AM2/13/09
to android-...@googlegroups.com
Hi Henry,

Audioflinger does not keep the timing (but it does pay attention for AV sync etc). It calls a blocking write() to the audio hardware interface and it is the responsibility of the audio hardware to keep timing. For example in A2DP you will see some code in liba2dp.c to sleep in order to keep timing. Dave will correct me if i'm wrong.

Nick

Dave Sparks

unread,
Feb 13, 2009, 11:13:42 AM2/13/09
to android-platform
I'm pretty sure you're right, although I haven't looked at that code
myself.

My understanding is that A2DP does not have flow control (what were
they thinking?), so we just present the data based on our clock. I
assume that A2DP playback devices must do some block-based clock
recovery or just live with the fact that they are going to underrun or
overrun periodically.

And yes Henry, all output is mixed to stereo, so you're mono ringtone
is going to be mixed to stereo in AudioFlinger.

On Feb 13, 7:55 am, Nick Pelly <npe...@google.com> wrote:
> Hi Henry,
> Audioflinger does not keep the timing (but it does pay attention for AV sync
> etc). It calls a blocking write() to the audio hardware interface and it is
> the responsibility of the audio hardware to keep timing. For example in A2DP
> you will see some code in liba2dp.c to sleep in order to keep timing. Dave
> will correct me if i'm wrong.
>
> Nick
>
> On Thu, Feb 12, 2009 at 9:35 PM, henry.lon...@gmail.com <

Mike Lockwood

unread,
Feb 13, 2009, 11:31:33 AM2/13/09
to android-...@googlegroups.com
On Fri, Feb 13, 2009 at 11:13 AM, Dave Sparks <david...@android.com> wrote:
>
> I'm pretty sure you're right, although I haven't looked at that code
> myself.
>
> My understanding is that A2DP does not have flow control (what were
> they thinking?), so we just present the data based on our clock. I
> assume that A2DP playback devices must do some block-based clock
> recovery or just live with the fact that they are going to underrun or
> overrun periodically.

It seems to depend on the device you are talking to. While developing
A2DP I noticed that some headsets could manage fine if we sent the
audio data as fast as possible. So there must be some flow control
going on at the lower level. But other headsets do not behave well if
you do not send the data at exactly the right speed. For example, the
Jabra BT8010 will start playing at 48Khz instead of the negotiated
rate 44.1Khz if the we send the packets too fast.

Maybe someone with more A2DP experience can chime in, but that is what
I saw while working on the A2DP support in android.

--
Mike Lockwood
Google android team

Reply all
Reply to author
Forward
0 new messages