PulseAudio: Difference between revisions

From OLPC
Jump to navigation Jump to search
No edit summary
Line 54: Line 54:
fragments can be used to save power and smaller ones when low-latency applications are
fragments can be used to save power and smaller ones when low-latency applications are
running. Unfortunately ALSA cannot do this as of now.
running. Unfortunately ALSA cannot do this as of now.

== Pulseaudio and Csound5 ==
Since Csound5 has a modular IO architecture, making it work natively (ie. not through an ALSA plugin) with pulseaudio it is just a matter of adding an IO module to it. The code for the rtpulse module is already in CVS[http://csound.cvs.sourceforge.net/csound/csound5/]. This module will be added to the next release of the software. This will hopefully then be included in future OLPC builds.


== Tests ==
== Tests ==

Revision as of 23:25, 27 March 2008

PulseAudio is a sound server for POSIX and Win32 systems. A sound server is basically a proxy for your sound applications. It allows you to do advanced operations on your sound data as it passes between your application and your hardware. Things like transferring the audio to a different machine, changing the sample format or channel count and mixing several sounds into one are easily achieved using a sound server.

Pulseaudio on the XO

- XO version: B1
- Build: 406
- pulseaudio version: 0.9.6
- more info: pulseaudio

Install

Basic

These are the basic packages you need to install to run pulseaudio on the XO. The zeroconf module is needed if you want to enable networking of the sound server. zeroconf is used to announce the sound servers on the network.

 pulseaudio pulseaudio-lib-zeroconf pulseaudio-module-zeroconf
 deps: libsamplerate libtool-ltdl

Extra packages

The utils package contains tools like a soundfile player which is a native pulseaudio client.

 pulseaudio-utils

The lib package is needed when you want to run alsa applications (see what else you need in section Pulseaudio#ALSA Applications)

pulseaudio-lib

To configure pulseaudio you may want to install these X tools. You will need them to setup the networking part.

 padevchooser pavucontrol pavumeter paman

Configuration

You can configure pulseaudio using the files /etc/pulse/daemon.conf and /etc/pulse/default.pa and run pulseaudio without any arguments.

To run pulseaudio with a higher priority you have to add yourself to the group pulse-rt (you may have to log out before these changes take effect).

/usr/sbin/usermod -a -G pulse-rt olpc

You can start pulseaudio with the high priority option to prevent clicks when doing UI stuff

pulseaudio --high-priority=1

You will see the following output when pulseaudio succesfully gained the priority.

      I: core-util.c: Successfully gained nice level -15.                                                   
      I: core-util.c: Successfully enabled SCHED_FIFO scheduling.

Open Issues

These are some known issues with the current pulseaudio version running on the XO. The list is based on this thread on the pulseaudio list: http://www.mail-archive.com/pulseaudio-discuss@mail.0pointer.de/msg00405.html

a) The audio device is not released when PA is idle which will shorten the battery time.

   Should be fixed in the latest pulse release.
b) Pulseaudio requires FP for resampling calculations. At the moment 
   libsamplerate is used for this task. An option might 
   be speex which offers a resampling library which can 
   do the calculations using integers.
   
   This has been changed in the 0.9.7 release. Pulse is using the speex resampler by default which allows to 
   configure pulse's resampler to do either float or fixed.

c) PA should be able to change the fragment size dynamically during playback, so that large 
   fragments can be used to save power and smaller ones when low-latency applications are 
   running. Unfortunately ALSA cannot do this as of now.

Pulseaudio and Csound5

Since Csound5 has a modular IO architecture, making it work natively (ie. not through an ALSA plugin) with pulseaudio it is just a matter of adding an IO module to it. The code for the rtpulse module is already in CVS[1]. This module will be added to the next release of the software. This will hopefully then be included in future OLPC builds.

Tests

Start pulseaudio

pulseaudio -v
pulseaudio --high-priority=1 -v

Native pulseaudio client

In the first test we use a native pulseaudio client to play a sound (paplay is included in pulseaudio-utils)

paplay soundfile.wav

Some rather bad numbers:

  • top shows a cpu usage of ~2.6% and a memory usage of ~1.2 when not in use
  • when playing a soundfile with paplay, cpu usage is 7% to 10% and memory usage 1.7

In this case, the pulseaudio server is running using a sampling rate of only 44100 Hz.

In other words, it sucks up resources when not doing anything and it sucks up even more when asked to do something.

Gstreamer Applications

Applications using the GStreamer media framework can make use of the PulseAudio through gst-pulse, the PulseAudio plugin for GStreamer. You need to install the gstreamer-plugins-pulse in order to use them. Otherwise applications based on the gstreamer framework will be using the alsa plugin in pulseaudio. You will have to enable it as default sink after installing it using the GConf[GConf] keys.

gconftool -t string --set /system/gstreamer/0.10/default/audiosink pulsesink
gconftool -t string --set /system/gstreamer/0.10/default/audiosrc pulsesrc

You can use the python gstreamer bindings to play a soundfile on the pulseaudio server. Since clicks where noticed I went through the following setups.

- gst-launch | wav with 44k and 22k | no pulseaudio     | no noticable clicks  
- gst-launch | wav with 44k         | pulseaudio at 44k | sounds stops during playback, gst-launch stops
- gst-launch | wav with 22k         | pulseaudio at 44k | sounds interrupts during playback, gst-launch finishs 
                                                          after some time
- gst-launch | wav with 44k         | pulseaudio at 22k | clicks, pulseaudio terminates, gst-launch-0.10: 
                                                          pcm_pulse.c:193: pulse_pointer: Assertion `pcm->stream' 
                                                          failed.
- aplay      | wav with 44k         | pulseaudio at 22k | no clicks but gets pulseaudio to terminate after some 
                                                          seconds
- gst-launch | wav with 22k         | pulseaudio at 22k | small clicks, most of the times at the beginning
- aplay      | wav with 22k         | pulseaudio at 22k | without any problem

Another test was to play an ogg vorbis file with the gstreamer faclities.

gst-launch | ogg with 22k         | pulseaudio at 22k | same as with wav files - small clicks, most of 
                                                        the times at the beginning

command used:

gst-launch-0.10 filesrc location=/home/olpc/tone.ogg ! oggdemux ! vorbisdec ! audioconvert ! alsasink
gst-launch-0.10 filesrc location=/home/olpc/tone.ogg ! oggdemux ! vorbisdec ! audioconvert ! pulsesink
gst-launch filesrc location=guitcello.wav ! wavparse ! alsasink 

I tried to changing the buffer settings of pulseaudio (i.e. to the default ones):

add-autoload-sink output module-alsa-sink device=plughw:0,0 rate=22050 sink_name=output 
fragments=12 fragment_size=1024

and was playing with the buffer sizes of gstreamer but had no luck on getting a result without clicks.

ALSA Applications

To setup pulseaudio to work for alsa applications you have to put these lines into /etc/asound.conf.

   # This following device can fool some applications into using pulseaudio                                 
   pcm.dsp2 {                                                                                               
   type plug                                                                                                
   slave.pcm "pulse"                                                                                        
   }                                                                                                        
                                                                                                            
   pcm.pulse {                                                                                              
   type pulse                                                                                               
   }                                                                                                        
                                                                                                            
   ctl.pulse {                                                                                              
   type pulse                                                                                               
   }                                                                                                        
                                                                                                            
   pcm.!default {                                                                                           
   type pulse                                                                                               
   }                                                                                                        
                                                                                                            
   ctl.!default {                                                                                           
   type pulse                                                                                               
   }                                                                                                        
   

and you need to install the alsa-plugins. I could not find an rpm for Fedora that is why I build and installed the plugins by hand. You can find the sources here: alsa-plugins To test the result I used aplay.

aplay -Dpulse soundfile.wav

The pulseaudio server is running using a sampling rate of 44100Hz.

Csound

You can run csound as a pulseaudio client as well. To make this work on the XO you have to use big enough buffer sizes (-b -B options).

csound -+rtaudio=alsa -odac:plug:pulse -m0 -d -b1024 -B4096 bilbar.csd

The one channel piece bilbar.csd does run (without using pulseaudio) on the XO when bringing the sampling rate of csound down. When running at 44100Hz we get some 'hickups'. It runs fine at a sr of 22050Hz. Playing the piece while csound is connected to the pulseaudio server (the server is running at 44100Hz) csound glitches and hungs so that you have to kill it manually. This is csound using sr=44100 and sr=22050.

When running csound with 22k and pulseaudio with 44k resampling is needed which I found out to be problematic on the XO - at least with csound. Playing a soundfile of 22kHz using aplay while the server is running at 44kHz is fine. When csound and the pulseaudio server using sr=22050 it will play fine as well.

Memosono

Another test was to run memosono (which uses csound to play soundfiles) as a pulseaudio client. The csound instance of memosono runs at 22050Hz. When running the pulseaudio server at 44100Hz I got clicks, that is why I run the server at 22050Hz as well. I guess resampling is the bottle neck here. You can do this by adding these two lines into your default.pa and uncommenting the HAL detection.

add-autoload-sink output module-alsa-sink device=plughw:0,0 rate=22050 sink_name=output
set-default-sink output

Running pulseaudio without the high-priority option resulted in clicks when moving the mouse over the window while sound was playing. With the option enabled I could switch back and forth between views without interruption.

Pygame (sdl_mixer)

You can play back an ogg vorbis file and many other formats using the sdl_mixer of pygame [, pygame]. As seen in other tests you should run pulseaudio and the client at the same sampling rate. And in this case you had to trim them down to 22k in order to make it sound good. You avoid some small clicks if you set the buffersize to 2048 samples. Now when running the pulseaudio server with higher priority we do not get any clicks.

import time
import pygame.mixer
pygame.mixer.init(22050, -16, True, 2048)
sound = pygame.mixer.Sound('/home/olpc/guitcello.ogg')
sound.play()
time.sleep(6)
pygame.mixer.quit()

More on the sdl_mixer can be found here: [, pygame mixer]

Networking

I was able to send audio data to the XO and from the XO to another machine running the pulseaudio server.

XO aplay file 44k | -> | laptop pulseaudio 44k | result=good
XO aplay file 22k | -> | laptop pulseaudio 44k | result=good
XO paplay 44k | -> | laptop pulseaudio 44k | result=good
XO paplay 22k | -> | laptop pulseaudio 44k | result=good
XO csound 44k | -> | laptop pulseaudio 44k | result=unacceptable
XO csound 44k | -> | laptop pulseaudio 44k | result=a bit glitchy
XO pulseaudio 44k | <- | laptop aplay 44k | result=good
XO pulseaudio 44k | <- | laptop aplay 22k | result=good
XO pulseaudio 44k | <- | laptop paplay 44k | result=good
XO pulseaudio 44k | <- | laptop paplay 22k | result=good

To stream audio data from one machine running pulseaudio to another machine you need to setup a few things. To be anounced of available pulseaudio servers on the network you need to install the pulseaudio-module-zeroconf and enable it in your pulseaudio configuration. Add the following line to /etc/pulse/default.pa to do so.

load-module module-zeroconf-publish

You need to enable those two modules in your /etc/pulse/default.pa (of the machine you want to send to) as well. Otherwise you might be prompted for "Connection failure: Connection refused" when trying to send audio data with paplay for example. These settings can be done with the configuration tool parefs as well.

load-module module-esound-protocol-tcp
load-module module-native-protocol-tcp

You can run padevchooser to control the pulseaudio server. This tool will prompt you when a new server on the network has been discovered. You can set the Default Sink and the Default Source here. The discovered pulseaudio servers will be listed in the list of available Sinks and Sources.

Once you selected your Sink you can try to play a sound. It is likely that you will be prompted for an "access denied error". With aplay you get the following error.

*** PULSEAUDIO: Unable to connect: Access denied                                                             
aplay: main:545: audio open error: Connection refused                                                        

This happens because pulseaudio requires authentication before accepting connections to prevent random people from playing audio on your computer. Pulseaudio places a cookie in the home directories of the user running the server. Copy the cookie of the machine you want to send the audio data to, to the home directory of the sender machine. (Alternatively, you may add auth-anonymous=1 to the end of the load-module module-native-protocol-tcp line to disable authentication). You are ready to play networked audio using pulseaudio.