Upto: Table of Contents of full book "Programming and Using Linux Sound"

Raspberry Pi

The Raspberry Pi (RPi) is a low cost Linux computer developed with the intention of improving the background of students entering university computer science courses by giving them a good, cheap environment in which to play. And its true! I've got a bunch of colleagues at work, well into middle-age who have leapt upon it to play with. So far their kids haven't had a look-in though...

Resources

Introduction

Hardware

The Raspberry Pi (RPi) Model B has 512Mb RAM, 2 USB ports and an Ethernet port. It has HDMI, and analogue audio and video outputs. From the FAQ

The SoC is a Broadcom BCM2835. This contains an ARM1176JZFS, with floating point, running at 700Mhz, and a Videocore 4 GPU. The GPU is capable of BluRay quality playback, using H.264 at 40MBits/s. It has a fast 3D core accessed using the supplied OpenGL ES2.0 and OpenVG libraries.

Graphically it looks like

and physically it looks like
.

The RPi has audio out through the HDMI port and also through an analogue 3.5 mm audio out. There is no audio in. However, there are USB ports, and a USB sound card can be plugged which is recognised by the Linux distros.

The CPU is an ARM CPU. A simple overview of the differences between ARM and Intel instruction sets is given by ARM vs x86 Processors: What's the Difference?

Alternative Single Board Computers

There are many single board computers. Wikipedia has a List of single-board computers . These are all potential alternatives to the RPi. Here is just a quick selection

Gumstix
This is a single board computer that has been around for many years (I got one in 2004). It isn't high powered, but isn't meant to be.
Arduino
The Arduino is designed as a micro-controller for electronic projects. It uses an ARM Cortec-M3 CPU which has even lower specs than the RPi
UDOO
UDOO attempts to marry the best of the RPi and Arduino with two CPUs into a single board computer
ODroid
The ODroid U2 is a higher powered system than the RPI, evaluated by Gigaom . It is about double the price.
BeagleBone
The BeagleBone Black has a slightly better CPU (ARM Cortex-A8) than the RPi, and is a bit more expensive
Wandboard
PandaBoard
CubieBoard

Distros

There are a number of Linux images available from the Raspberry Pi site, and others being developed elsewhere. I'm using the Debian-based image which essentially comes in two forms: with soft float using Debian and with hard float using the FPU, called Raspbian. The hard float image is required for decent sound processing which is heavily floating point dependent. There is a good article benchmarking these against each other: Raspbian Benchmarking – armel vs armhf . Another set of benchmarks is at RPi Performance . Basically, these show that you should use the hard float version if you want good floating point performance, and this is required for audio processing.

ELinux.org maintains a list of RPi Distributions There are many standard Linux distros included here, such as Fedora, Debian, Arch, SUSE, Gentoo and others. The RPi has gained traction as a media centre based on the XBMC media centre, and this is represented by distros such as Raspbmc and OpenElec.

So how does it go with the various audio tools we have been discussing so far? It's a mixed bag.

No sound

I plugged mine into a 29 inch ViewSonic monitor using the HDMI connectors. Initially I got no sound from either the 3.5mm analogue output or the HDMI monitor. This is explained at Why is my Audio (Sound) Output not working? I edited the file /boot/config.txt and uncommented the line "hdmi_drive=2". I also used the command

	
sudo amixer cset numid=3 <n>
	
      

where n is 0=auto, 1=headphones, 2=hdmi to toggle between outputs.

After that sound is fine.

ALSA

The Raspberry Pi uses the ALSA driver snd_bcm2835, and this can manage HDMI output. The command alsa-info is not present, but as this is a shell script it can be copied from elsewhere and will run on the RPi. Some of the usual configuration files and commands on a larger distro are missing, but it shows on the soft float Debian distro

	
upload=true&script=true&cardinfo=
!!################################
!!ALSA Information Script v 0.4.61
!!################################

!!Script ran on: Sun Nov  4 02:33:41 UTC 2012


!!Linux Distribution
!!------------------

Debian GNU/Linux wheezy/sid \n \l PRETTY_NAME="Debian GNU/Linux wheezy/sid" NAME="Debian GNU/Linux" ID=debian


!!DMI Information
!!---------------

Manufacturer:      
Product Name:      
Product Version:   
Firmware Version:  


!!Kernel Information
!!------------------

Kernel release:    3.1.9+
Operating System:  GNU/Linux
Architecture:      armv6l
Processor:         unknown
SMP Enabled:       No


!!ALSA Version
!!------------

Driver version:     1.0.24
Library version:    1.0.25
Utilities version:  1.0.25


!!Loaded ALSA modules
!!-------------------

snd_bcm2835


!!Sound Servers on this system
!!----------------------------

No sound servers found.


!!Soundcards recognised by ALSA
!!-----------------------------

 0 [ALSA           ]: BRCM bcm2835 ALSbcm2835 ALSA - bcm2835 ALSA
                      bcm2835 ALSA


!!PCI Soundcards installed in the system
!!--------------------------------------



!!Advanced information - PCI Vendor/Device/Subsystem ID's
!!-------------------------------------------------------



!!Modprobe options (Sound related)
!!--------------------------------

snd_atiixp_modem: index=-2
snd_intel8x0m: index=-2
snd_via82xx_modem: index=-2
snd_pcsp: index=-2
snd_usb_audio: index=-2


!!Loaded sound module options
!!---------------------------

!!Module: snd_bcm2835
	* : 


!!ALSA Device nodes
!!-----------------

crw-rw---T+ 1 root audio 116,  0 Nov  3 22:17 /dev/snd/controlC0
crw-rw---T+ 1 root audio 116, 16 Nov  3 22:17 /dev/snd/pcmC0D0p
crw-rw---T+ 1 root audio 116,  1 Nov  3 22:17 /dev/snd/seq
crw-rw---T+ 1 root audio 116, 33 Nov  3 22:17 /dev/snd/timer

/dev/snd/by-path:
total 0
drwxr-xr-x 2 root root  60 Nov  3 22:17 .
drwxr-xr-x 3 root root 140 Nov  3 22:17 ..
lrwxrwxrwx 1 root root  12 Nov  3 22:17 platform-bcm2835_AUD0.0 -gt; ../controlC0


!!Aplay/Arecord output
!!--------------------

APLAY

**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7

ARECORD

**** List of CAPTURE Hardware Devices ****

!!Amixer output
!!-------------

!!-------Mixer controls for card 0 [ALSA]

Card hw:0 'ALSA'/'bcm2835 ALSA'
  Mixer name	: 'Broadcom Mixer'
  Components	: ''
  Controls      : 3
  Simple ctrls  : 1
Simple mixer control 'PCM',0
  Capabilities: pvolume pvolume-joined pswitch pswitch-joined penum
  Playback channels: Mono
  Limits: Playback -10239 - 400
  Mono: Playback -1725 [80%] [-17.25dB] [on]


!!Alsactl output
!!--------------

--startcollapse--
state.ALSA {
	control.1 {
		iface MIXER
		name 'PCM Playback Volume'
		value -1725
		comment {
			access 'read write'
			type INTEGER
			count 1
			range '-10239 - 400'
			dbmin -9999999
			dbmax 400
			dbvalue.0 -1725
		}
	}
	control.2 {
		iface MIXER
		name 'PCM Playback Switch'
		value true
		comment {
			access 'read write'
			type BOOLEAN
			count 1
		}
	}
	control.3 {
		iface MIXER
		name 'PCM Playback Route'
		value 2
		comment {
			access 'read write'
			type INTEGER
			count 1
			range '0 - 2'
		}
	}
}
--endcollapse--


!!All Loaded Modules
!!------------------

Module
snd_bcm2835
snd_pcm
snd_seq
snd_timer
snd_seq_device
snd
snd_page_alloc
evdev


!!ALSA/HDA dmesg
!!--------------

[   16.369584] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
[   16.750460] ### snd_bcm2835_alsa_probe c05c88e0 ############### PROBING FOR bcm2835 ALSA device (0):(1) ###############
[   16.776071] Creating card...
--
[   16.834082] Registering card ....
[   16.853728] bcm2835 ALSA CARD CREATED!
[   16.883259] ### BCM2835 ALSA driver init OK ### 
[   23.608360] smsc95xx 1-1.1:1.0: eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
	
      

Sampled audio players

MPlayer

MPlayer plays fine on the default ALSA modules, for mp3, ogg and wav.

VLC

VLC attempts to play wav files, but it is very broken up on the soft float distro. CPU usage is up around 90% and it is quite unplayable. The hard float distro can play wav, mp3 and ogg.

Alsaplayer

The program alsaplayer can attempt to play files in formats such as Ogg-Vorbis and MP3. However, CPU usage hits as high as 80% on the soft float at which point the sound falls to pieces. The hard float distro is okay.

OmxPlayer

The RPi has GPU, and this can be used by omxplayer. It can play Ogg-Vorbis files with only 12% CPU usage and looks to be a good candidate for audio as well as video.

Is it X using the CPU?

Apparently not just X: gnome-player works fine.

Sampled audio capture

The RPi does not have an audio-in or line-in port. I connected my SoundBlaster USB card through a powered USB hub. It shows up with arecord -l as

	
**** List of CAPTURE Hardware Devices ****
card 1: Pro [SB X-Fi Surround 5.1 Pro], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
	
      

so that to ALSA it is device hw:1,0.

ALSA

The standard program arecord works if you get the options correct:

	
arecord -D hw:1,0 -f S16_LE -c 2 -r 48000 tmp.s16
Recording WAVE 'tmp.s16' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
	
      

The resulting file can be played back using

	
aplay -D hw:1,1 -c 2 -r 48000 -f S16_LE tmp.s16
	
      

In the chapter on ALSA I gave the source for a program alsa_capture.c. When run by

	
alsa_capture hw:1,0 tmp.s16
	
      

it records PCM data in stereo at 48,000hz.

MIDI players

Timidity

Timidity hits upto 90% CPU. It can't play MIDI files on the RPi properly using the soft float dsitro, but is just about okay on the hard float distro.

To make the RPi usable, in the timidity.cfg file uncomment the lines

	
## If you have a slow CPU, uncomment these:
#opt EFresamp=d         #disable resampling
#opt EFvlpf=d           #disable VLPF
#opt EFreverb=d         #disable reverb
#opt EFchorus=d         #disable chorus
#opt EFdelay=d          #disable delay
#opt anti-alias=d       #disable sample anti-aliasing
#opt EWPVSETOZ          #disable all Midi Controls
#opt p32a               #default to 32 voices with auto reduction
#opt s32kHz             #default sample frequency to 32kHz
#opt fast-decay         #fast decay notes
	
      

This brings the CPU usage down to about 30%. (Thanks to Chivalry Timber).

PyKaraoke

This only uses 40% of the CPU and plays okay, even giving a GUI on the soft float distro.

Fluidsynth/Qsynth

This just sat there doing not very at all using soft float Debian wheezy out of the box. I spent some time with the FluidSynth team investigating possibilities.

Images

The soft float image is unusable. You need to use the hard float image.

Scheduling

Sometimes fluidsynth complains about not being able to reset the scheduler. Aere Greenway suggests making the following security changes:

You need to create a file (whose name starts with your user-ID) in the following folder: /etc/security/limits.d For example, my user-ID is aere, so the filename I use is: aere.conf The file needs to contain the following lines:
	  
aere - rtprio 85
aere - memlock unlimited
	  
	

Except, substitute your user-ID in place of "aere".

This is necessary, but not sufficient It did help with the Raspbian hard-float image, but only a little: some MIDI files played fine while others broke up badly.

Analysis tools

The simplest tool to analyse performance is perf. This will give a breakdown of the percentage of CPU usage for the function calls within a program.

perf averages the results over an execution period. The MIDI songs I tried only misplayed in parts, not over the whole song. perf can however be run as a separate process to sample every second by the command

	
perf top -d 1
	
      

You can then observe function calls over one second periods.

This didn't reveal much in this instance, but may be helpful in other cases.

The command pidstat can be run by e.g.

	
pidstat -C fluidsynth -r -u 5
	
      

to give CPU and memory usage every 5 seconds. it is similar to top but just writes figures for the command to stdout. The output can be massaged using shell scripts and shown as a histogram using GNU octave. This shows that the distortion occurs when CPU usage hits over 100% (don't ask me how!). Memory usage is fine, around 40%.

Non-causes

The following were suggested as causes of the problems, but ultimately discarded

Solutions

The two solutions that I have found are

JavaSound

I installed OpenJDK version 6, the default Java install at present. The program DeviceInfo was given in the JavaSound Sampled chapter The output from this on the RPi is

	
Mixers:
   PulseAudio Mixer, version 0.02
    Mixer: org.classpath.icedtea.pulseaudio.PulseAudioMixer@1d05c81
      Source lines
        interface SourceDataLine supporting 42 audio formats, and buffers of 0 to 1000000 bytes
        interface Clip supporting 42 audio formats, and buffers of 0 to 1000000 bytes
      Target lines
        interface TargetDataLine supporting 42 audio formats, and buffers of 0 to 1000000 bytes
   ALSA [default], version 1.0.24
    Mixer: com.sun.media.sound.DirectAudioDevice@12558d6
      Source lines
        interface SourceDataLine supporting 84 audio formats, and buffers of at least 32 bytes
        interface Clip supporting 84 audio formats, and buffers of at least 32 bytes
      Target lines
   ALSA [plughw:0,0], version 1.0.24
    Mixer: com.sun.media.sound.DirectAudioDevice@eb7859
      Source lines
        interface SourceDataLine supporting 8 audio formats, and buffers of at least 32 bytes
        interface Clip supporting 8 audio formats, and buffers of at least 32 bytes
      Target lines
   Port ALSA [hw:0], version 1.0.24
    Mixer: com.sun.media.sound.PortMixer@fd54d6
      Source lines
      Target lines
        PCM target port
	
      

Althjough this is using the PulseAudio mixer, pulse audio isn't actually running (at this stage)! So it can only use the ALSA interface.

The program PlayAudioFile was given in the JavaSound Sampled chapter. This can play .wav files okay. But it can't play Ogg-Vorbis or MP3 files and throws anUnsupportedAudioFileException.

PulseAudio

PulseAudio installs okay from the repositories and runs with no problems. The output from pulsedevlist is

	
=======[ Output Device #1 ]=======
Description: bcm2835 ALSA Analog Stereo
Name: alsa_output.platform-bcm2835_AUD0.0.analog-stereo
Index: 0

=======[ Input Device #1 ]=======
Description: Monitor of bcm2835 ALSA Analog Stereo
Name: alsa_output.platform-bcm2835_AUD0.0.analog-stereo.monitor
Index: 0
	
      

Java MIDI

openJDK supports the Java MIDI devices. The program DeviceInfo reports

	
MIDI devices:
    Name: Gervill, Decription: Software MIDI Synthesizer, Vendor: OpenJDK
        Device is a synthesizer
        Open receivers:

        Default receiver: com.sun.media.sound.SoftReceiver@10655dd

        Open receivers now:
            com.sun.media.sound.SoftReceiver@10655dd

        Open transmitters:
        No default transmitter
    Name: Real Time Sequencer, Decription: Software sequencer, Vendor: Sun Microsystems
        Device is a sequencer
        Open receivers:

        Default receiver: com.sun.media.sound.RealTimeSequencer$SequencerReceiver@12f0999

        Open receivers now:
            com.sun.media.sound.RealTimeSequencer$SequencerReceiver@12f0999

        Open transmitters:

        Default transmitter: com.sun.media.sound.RealTimeSequencer$SequencerTransmitter@65a77f

        Open transmitters now:
            com.sun.media.sound.RealTimeSequencer$SequencerTransmitter@65a77f
Default system sequencer is Real Time Sequencer
Default system synthesizer is Gervill

	
      

Programs like DumpSequence work okay. But the SimpleMidiPlayer hits 80% CPU usage and is unusable. So any idea of a Karaoke player using Java on the RPi is simply not on :-(. There is a thread on the Raspberry Pi site discussing problems with sound .

OpenMAX

Audio and video can be played on the Raspberry Pi using the OpenMAX IL toolkit. This has been implemented by Broadcom for their GPU used by the RPi. This is partly covered in the chapter OpenMAX and and OpenSL . More examples will be explored in later editions of this book.

Displaying images

As a step in using the RPi, I decided to try drawing JPEG images into the GPU using OpenMAX. As with all things related to OpenMAX this is far too hard - OpenMAX is one of the worst APIs I have ever had to deal with, and the version on the RPi brings its own set of problems.

The directory /opt/vc/src/hello_pi/hello_jpeg contains an example to read in a JPEG file and resize the image. This program works. But it uses the Broadcom convenience functions such as ilclient_create_component and I don't want to use those just in case they aen't available elsewhere.

I adapted their code, and it didn't work. Digging deep with the debugger showed a bizarre set of values:

Duh!

The problem was the type OMX_TICKS. In a 64-bit environment it is a 64-bit integer, otherwise it is a struct of two 32-bit values. I used one version, the Broadcom code on the RPi is using the other.

By looking at the compile environment for the Broadcom example, it uses the defines

	
-DSTANDALONE -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -DTARGET_POSIX\
-D_LINUX -fPIC -DPIC -D_REENTRANT -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64\
-U_FORTIFY_SOURCE -Wall -g -DHAVE_LIBOPENMAX=2 -DOMX -DOMX_SKIP64BIT\
-ftree-vectorize -pipe -DUSE_EXTERNAL_OMX -DHAVE_LIBBCM_HOST\
-DUSE_EXTERNAL_LIBBCM_HOST -DUSE_VCHIQ_ARM
	
      

The OMX_SKIP64BIT flag is needed to choose the right value for the RPi type. What else is needed for what, I don't know yet :-(

Conclusion

The Raspberry Pi is an exciting new toy to play with. There are many competitors on the block but it has still sold over one million devices. This chapter has covered some of the audio aspects of the device.



Copyright © Jan Newmarch, jan@newmarch.name
Creative Commons License
"Programming and Using Linux Sound - in depth" by Jan Newmarch is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License .
Based on a work at https://jan.newmarch.name/LinuxSound/ .

If you like this book, please contribute using PayPal

Or Flattr me:
Flattr this book