Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ALSA is not supporting 16 bits signed audio #173

Closed
adn770 opened this issue Apr 25, 2013 · 13 comments
Closed

ALSA is not supporting 16 bits signed audio #173

adn770 opened this issue Apr 25, 2013 · 13 comments

Comments

@adn770
Copy link

adn770 commented Apr 25, 2013

Using rpi-update with latest firmware in raspbian updated.

Running the following to produce audio 16 bits signed:

$ gst-launch-0.10 -v audiotestsrc ! audioconvert ! audio/x-raw-int, width=16, signed=true ! alsasink

I get choppy audio and high cpu consumption.

Although when producing unsigned 16 bits audio it's fine, like with the following pipeline.

gst-launch-0.10 -v audiotestsrc ! audioconvert ! audio/x-raw-int, width=16, signed=false ! alsasink

This issue is unfortunate as several software audio decoders produce signed 16 bits audio and additional conversion in software is required wasting cpu cycles.

@popcornmix
Copy link
Contributor

S16 is the default format of the alsa driver

Slave: Hardware PCM card 0 'bcm2835 ALSA' device 0 subdevice 0
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 2
  rate         : 44100
  exact rate   : 44100 (44100/1)
  msbits       : 16
  buffer_size  : 16384
  period_size  : 4096
  period_time  : 92879
  tstamp_mode  : NONE
  period_step  : 1
  avail_min    : 4096
  period_event : 0
  start_threshold  : 16384
  stop_threshold   : 16384
  silence_threshold: 0
  silence_size : 0
  boundary     : 1073741824
  appl_ptr     : 0
  hw_ptr       : 0

I think your problem is elsewhere.

@martinezjavier
Copy link

Hello Josep,

Currently RPi ALSA driver has no mmap support so ALSA's PCM mmap access emulation plugin is used (/etc/asound.conf):

pcm.mmap0 {
    type mmap_emul;
    slave {
      pcm "hw:0,0";
    }
}

pcm.!default {
  type plug;
  slave {
    pcm mmap0;
  }
}

But when trying to play S16LE PCM format with Gstreamer you get this choppy audio and a high CPU consumption (~90% on my tests). I couldn't dig further on this so I don't know if the bug is on alsasink gst element, libasound or somewhere else.

If you don't need mmap transfers method for PCM playback then you can just omit using the mmap emulation plug-in:

pcm.!default {
    type hw
    card 0
}

ctl.!default {
    type hw
    card 0
}

As popcornmix said, S16LE is the default format of the ALSA driver so you can play it without the need to audioconvert, e.g:

gst-launch-0.10 -v audiotestsrc ! queue ! audio/x-raw-int, width=16, signed=true ! alsasink

You won't be able to use U16LE of course since is not supported by the ALSA driver.

@martinezjavier
Copy link

By the way, if you don't use mmap emulation and you need mmap support, I added to the ALSA bcm2835 driver.

It is in this branch: https://github.com/martinezjavier/linux-rpi/tree/rpi-3.6.y-dev

I'll do a little more testing and send a pull request later today.

@popcornmix
Copy link
Contributor

@martinezjavier
Sounds interesting. Does this allow jack to work?
Can we remove /etc/asound.conf?
Is there anything else you think the alsa driver is missing?

@martinezjavier
Copy link

@popcornmix

Yes, I've tested mmap with both aplay and jackd with no /etc/asound.conf at all and both are working.

I can play wav files with aplay -M (using mmap stream):

$ aplay -vM /test.wav    
Playing WAVE '/test.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
Plug PCM: Hardware PCM card 0 'bcm2835 ALSA' device 0 subdevice 0
Its setup is:
  stream       : PLAYBACK
  access       : MMAP_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 1
  rate         : 48000
  exact rate   : 48000 (48000/1)
  msbits       : 16
  buffer_size  : 24000
  period_size  : 6000
  period_time  : 125000
  tstamp_mode  : NONE
  period_step  : 1
  avail_min    : 6000
  period_event : 0
  start_threshold  : 24000
  stop_threshold   : 24000
  silence_threshold: 0
  silence_size : 0
  boundary     : 1572864000
  appl_ptr     : 0
  hw_ptr       : 0
mmap_area[0] = 0xb6b73000,0,16 (16)

And also Jack2 + jack2_armel.diff patch works just fine. When I start with jackd I got this and I hear audio once the deamon is started and I run $ jack_simple_client

root@raspberrypi:~/jackd2-1.9.8~dfsg.4+20120529git007cdc37# jackd -r -d alsa
jackdmp 1.9.9
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2012 Grame.
jackdmp comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details
JACK server starting in non-realtime mode
control device hw:0
control device hw:0
audio_reservation_init
Acquire audio card Audio0
creating alsa driver ... hw:0|hw:0|1024|2|48000|0|0|nomon|swmeter|-|32bit
control device hw:0
ALSA: Cannot open PCM device alsa_pcm for capture. Falling back to playback-only mode
configuring for 48000Hz, period = 1024 frames (21.3 ms), buffer = 2 periods
ALSA: final selected sample format for playback: 16bit little-endian
ALSA: use 2 periods for playback

When I run jackd without the mmap support (current snd-bcm2835.ko kernel module) I got this:

root@raspberrypi:~/jackd2-1.9.8~dfsg.4+20120529git007cdc37# jackd -r -d alsa
jackdmp 1.9.9
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2012 Grame.
jackdmp comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details
JACK server starting in non-realtime mode
control device hw:0
control device hw:0
audio_reservation_init
Acquire audio card Audio0
creating alsa driver ... hw:0|hw:0|1024|2|48000|0|0|nomon|swmeter|-|32bit
control device hw:0
ALSA: Cannot open PCM device alsa_pcm for capture. Falling back to playback-only mode
configuring for 48000Hz, period = 1024 frames (21.3 ms), buffer = 2 periods
ALSA: mmap-based access is not possible for the playback stream of this audio interface
ALSA: cannot configure playback channel
Cannot initialize driver
JackServer::Open failed with -1
Failed to open server

About how to improve the driver further, I was taking a look to issue raspberrypi/linux#194 (bcm2835_audio_close hangs randomly).

It seems to be some sort of race condition / deadlock on sound/arm/bcm2835-vchiq.c between audio_vchi_callback() and bcm2835_audio_close(). I'm still investigating this though.

The issue report says that it probably bcm2835_audio_close() hangs because someone is holding the "instance->vchi_mutex mutex" but from my tests it seems that is because of the even synchronization semaphore "instance->msg_avail_event"

I wonder if VC_AUDIO_MSG_TYPE_CLOSE message to videocore really expects a response in every case and maybe audio_vchi_callback() is not up'ing the semaphore.

I changed the driver to use the kernel wait completion facility instead of a semaphore for the synchronization but the semantics are the same so it shouldn't affect. Besides the bug happens on both cases.

@popcornmix
Copy link
Contributor

VC_AUDIO_MSG_TYPE_CLOSE should unconditionally send a response.
It's possible something has killed GPU or vchiq - do non-ALSA things still work? (e.g. hello_video?)

@martinezjavier
Copy link

@popcornmix

hello_audio.bin works well so doesn't seem to be a hardware issue.

I could reproduce raspberrypi/linux#194 by executing

$ aplay test.wav test2.wav

The first file is played correctly but the second hangs on an ioctl() call or close. From there any attempt to play a file is a hang on a ioctl() call which hangs on bcm2835_audio_set_ctls_chan().

Two interesting things I noticed:

1- executing hello_audio.bin makes the ioctl() call to return. So definitely the issue is that something is waiting for something from the video core and hello_audio.bin makes somehow this to happen.

2- even when aplay is killed, the my_queue workqueue kernel thread is still running. So is probably either sleeping on mutex_lock_interruptible(&instance->vchi_mutex) or on the call to vchi_msg_queue() since is using the VCHI_FLAGS_BLOCK_UNTIL_QUEUED flag.

Anyways, this has nothing to do with #173 so I should probably comment on raspberrypi/linux#194 instead.

Sorry for the noise :-)

@popcornmix
Copy link
Contributor

Closing, as "ALSA is not supporting 16 bits signed audio" is not true, and it's more likely a gstreamer issue.

@tp-m
Copy link

tp-m commented May 8, 2013

Well, there may also be a GStreamer issue of some sort, but it does look to me like something is not quite right in the lower layers somewhere.

GStreamer's audio sink and related base classes don't really care if the data being passed to ALSA is signed or not, they only care about number of bytes per sample. So GStreamer code should behave exactly the same for 16 bit unsigned audio and 16 bit signed audio. Yet only one of those causes problems. This to me strongly suggests an issue in the lower layers.

@tp-m
Copy link

tp-m commented May 8, 2013

Maybe the bug should be retitled to '16-bit signed audio results in excessive CPU usage in connection with GStreamer alsasink' or so.

@popcornmix
Copy link
Contributor

But the ALSA driver's native format is signed 16-bit!

@tp-m
Copy link

tp-m commented May 8, 2013

Well, it seems somewhere a different code path is taken, and one code path works fine, while the other doesn't. Make of that what you will. I have admittedly not investigated this in detail, but to me it does not seem "more likely" that it is a GStreamer issue than a driver or libasound issue. There are heaps of reports reporting abnormally high CPU usage when playing back FLAC, mp3 or AAC files on the raspberry pi via ALSA, which can't be explained by the CPU usage used for the decoding, and which don't use GStreamer.

@tp-m
Copy link

tp-m commented May 8, 2013

Anyway, I believe this issue is no longer hit with javier's mmap support patches, at least not with GStreamer's alsasink, so I guess this can stay closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants