-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Comments
S16 is the default format of the alsa driver
I think your problem is elsewhere. |
Hello Josep, Currently RPi ALSA driver has no mmap support so ALSA's PCM mmap access emulation plugin is used (/etc/asound.conf):
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:
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. |
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. |
@martinezjavier |
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):
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
When I run jackd without the mmap support (current snd-bcm2835.ko kernel module) I got this:
About how to improve the driver further, I was taking a look to issue raspberrypi/linux#194 ( 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. |
VC_AUDIO_MSG_TYPE_CLOSE should unconditionally send a response. |
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 :-) |
Closing, as "ALSA is not supporting 16 bits signed audio" is not true, and it's more likely a gstreamer issue. |
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. |
Maybe the bug should be retitled to '16-bit signed audio results in excessive CPU usage in connection with GStreamer alsasink' or so. |
But the ALSA driver's native format is signed 16-bit! |
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. |
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. |
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.
The text was updated successfully, but these errors were encountered: