Introduction to Sound Programming with ALSA
ALSA stands for the Advanced Linux Sound Architecture. It consists of a set of kernel drivers, an application programming interface (API) library and utility programs for supporting sound under Linux. In this article, I present a brief overview of the ALSA Project and its software components. The focus is on programming the PCM interfaces of ALSA, including programming examples with which you can experiment.
You may want to explore ALSA simply because it is new, but it is not the only sound API available. ALSA is a good choice if you are performing low-level audio functions for maximum control and performance or want to make use of special features not supported by other sound APIs. If you already have written an audio application, you may want to add native support for the ALSA sound drivers. If your primary interest isn't audio and you simply want to play sound files, using one of the higher-level sound toolkits, such as SDL, OpenAL or those provided in desktop environments, may be a better choice. By using ALSA you are restricted to using systems running a Linux kernel with ALSA support.
The ALSA Project was started because the sound drivers in the Linux kernel (OSS/Free drivers) were not being maintained actively and were lagging behind the capabilities of new sound technology. Jaroslav Kysela, who previously had written a sound card driver, started the project. Over time, more developers joined, support for many sound cards was added and the structure of the API was refined.
During development of the 2.5 series of Linux kernel, ALSA was merged into the official kernel source. With the release of the 2.6 kernel, ALSA will be part of the stable Linux kernel and should be in wide use.
Sound, consisting of waves of varying air pressure, is converted to its electrical form by a transducer, such as a microphone. An analog-to-digital converter (ADC) converts the analog voltages into discrete values, called samples, at regular intervals in time, known as the sampling rate. By sending the samples to a digital-to-analog converter and an output transducer, such as a loudspeaker, the original sound can be reproduced.
The size of the samples, expressed in bits, is one factor that determines how accurately the sound is represented in digital form. The other major factor affecting sound quality is the sampling rate. The Nyquist Theorem states that the highest frequency that can be represented accurately is at most one-half the sampling rate.
ALSA consists of a series of kernel device drivers for many different sound cards, and it also provides an API library, libasound. Application developers are encouraged to program using the library API and not the kernel interface. The library provides a higher-level and more developer-friendly programming interface along with a logical naming of devices so that developers do not need to be aware of low-level details such as device files.
In contrast, OSS/Free drivers are programmed at the kernel system call level and require the developer to specify device filenames and perform many functions using ioctl calls. For backward compatibility, ALSA provides kernel modules that emulate the OSS/Free sound drivers, so most existing sound applications continue to run unchanged. An emulation wrapper library, libaoss, is available to emulate the OSS/Free API without kernel modules.
ALSA has a capability called plugins that allows extension to new devices, including virtual devices implemented entirely in software. ALSA provides a number of command-line utilities, including a mixer, sound file player and tools for controlling special features of specific sound cards.
The ALSA API can be broken down into the major interfaces it supports:
Control interface: a general-purpose facility for managing registers of sound cards and querying the available devices.
PCM interface: the interface for managing digital audio capture and playback. The rest of this article focuses on this interface, as it is the one most commonly used for digital audio applications.
Raw MIDI interface: supports MIDI (Musical Instrument Digital Interface), a standard for electronic musical instruments. This API provides access to a MIDI bus on a sound card. The raw interface works directly with the MIDI events, and the programmer is responsible for managing the protocol and timing.
Timer interface: provides access to timing hardware on sound cards used for synchronizing sound events.
Sequencer interface: a higher-level interface for MIDI programming and sound synthesis than the raw MIDI interface. It handles much of the MIDI protocol and timing.
Mixer interface: controls the devices on sound cards that route signals and control volume levels. It is built on top of the control interface.
Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.
Sponsored by Red Hat
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
Best. Cake. Ever. | Dec 18, 2013 |
AIDE—Developing for Android on Android | Dec 18, 2013 |
Two Pi R | Dec 17, 2013 |
A Handy U-Boot Trick | Dec 16, 2013 |
GIMP Shmimp, Give Me a Browser | Dec 13, 2013 |
Tinker with Molecular Dynamics for Fun and Profit | Dec 12, 2013 |
- Two Pi R
- Readers' Choice Awards 2013
- AIDE—Developing for Android on Android
- Best. Cake. Ever.
- The Geek's Guide to the Coolest 2013 Holiday Gifts
- A Handy U-Boot Trick
- Sublime Text: One Editor to Rule Them All?
- RSS Feeds
- Raspberry Pi: the Perfect Home Server
- Tech Tip: Really Simple HTTP Server with Python
- Nice coding on the cake. I
1 hour 11 min ago - Baker's identity
6 hours 44 sec ago - Uber jealous
10 hours 58 min ago - Reality is disapointing
21 hours 30 min ago - Máy sấy quần áo
1 day 16 min ago - Services on GlusterFS
1 day 26 min ago - Reply to comment | Linux Journal
1 day 2 hours ago - Definitely cool stuff here
1 day 3 hours ago - thanks for the information
1 day 4 hours ago - nice information thanks
1 day 4 hours ago
Featured Jobs
Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
Senior Perl Developer | Austin, Texas | Host Gator |
Technical Support Rep | Houston and Austin, Texas | Host Gator |
UX Designer | Austin, Texas | Host Gator |
Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Comments
CROSS_COMPILE
Hi,
I compile the source codes on my pc(ubuntu) with gcc play.c -o play -lasound and test with ./play < sample.raw. It works properly. But i want to use it on my beagleboarg(ARM platform). I tried to compile with
arm-none-linux-gcc play.c -o play -lasound
it doesn't work. It gives
/opt/arm-2009q1/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -lasound
collect2: ld returned 1 exit status
what is my mistake? Please help me.
Fatih
CROSS_COMPILE
try: "strace ./play < sample.raw"
or "ldd play" and view if the correct path of library is linking
Volume needs to increase
It is brilliant tutorial for beginners.I have run the capture and playback code.I noticed my volume level is very low when I capture my voice followed by playback code.But if I playback http://freewavesamples.com/files/Roland-JD-990-Windchimes.wav file, the sound volume is very good.I have followed a code to get the Capability of /dev/dsp from: http://www.oreilly.de/catalog/multilinux/excerpt/ch14-09.htm .
Here is the output :
Information on /dev/dsp:
Defaults:
sampling rate: 8000 Hz
channels: 1
sample size: 8 bits
block size: 4097 bytes
Supported Formats:
mu-law
unsigned 8-bit (default)
signed 16-bit little-endian
signed 16-bit big-endian
signed 8-bit
unsigned 16-bit little-endian
unsigned 16-bit big-endian
Capabilities:
revision: 1
full duplex: yes
real-time: yes
batch: no
coprocessor: no
trigger: yes
mmap: yes
Modes and Limits:
Device Sample Minimum Maximum
Channels Size Rate Rate
-------- -------- -------- --------
1 8 1000 100000
1 16 1000 100000
2 8 1000 100000
2 16 1000 100000
Please let me know how do I increase volume while capturing from /dev/dsp.
With regards,
-- Guha.
Example 3
Hi to all.... Very good article for ALSA bigginers. I was trying to run this example on my PC. I want to play my .wav file (I will use file bugs_bye.wav as my input) and to hear that. When I run this example ./example3 bugs_bye.wav program executes but I can't hear anything. I am using file descriptor of this file insted of 0 (stdin) when I call function read like this:
int fd = open( argv[1] , O_RDONLY );
......
rc = read(fd, buffer, size);
The rest is same as example 3. What am I wrong??? Can someone help??? I am little bit confused.
Milos
Very Much informative
Thanks for this article
listing3
hi,i have a problem,i'm verry new to alsa programming,i didn't understand exactly how listing3 works.how do i put data into application buffer,to be transmitted to the sound card???i assume that the program is running correctly,but i don't know what to do after i run the program.Can anyone help me??
Re: Listing 3
Hello,
The program allocates a buffer,
buffer = (char *) malloc(size);
then in the loop it fills it from file descriptor 0,
i.e. stdin,
rc = read(0, buffer, size);
so to test, you could feed it something from the
command line.
It is set up for "CD" audio, 44100Hz, 2ch. I grabbed a sample here,
$ wget http://freewavesamples.com/files/Roland-JD-990-Windchimes.wav
I saved listing 3 as "listing3.c" and compiled,
$ gcc $(pkg-config --cflags --libs alsa) listing3.c -o listing3
Then to test,
$ cat Roland-JD-990-Windchimes.wav | ./listing3
If you wanted to generate your own sound, you could fill the buffer programmatically instead of reading from stdin.
Hope this helps.
[email protected]
Kudoos and hats off for the Article
Hi
I had been ssearching on net just to know how to start about with ALSA.
This article is simply great, starts from scratch building foundation and then takes you as far as you want to go..
Great work..
Regards
samir
question about one command of the program
hello,
I run your 4 programs coding in C with linux but i don't understand how does it work the next command :
snd_pcm_hw_params_get_period_time(params, &Val, &dir) who is used like that in Example 3 for example:
/* We want to loop for 5 seconds */
snd_pcm_hw_params_get_period_time(params,
&val, &dir);
/* 5 seconds in microseconds divided by
* period time */
loops = 5000000 / val;
If I add some lines of code, I can read the value of the variable "val" after and before the function " snd_pcm_hw_params_get_period_time(params, &val, &dir); ".
I can read that "val" before this function as a value 44099 (sample frequency minus 1), and after, "val" has the value 21333 at each time, whatever the others values enter as a parameters.
I don't understand how this function works and i would to know.
Would someone help me?
Thanks
Manu
5 sec
/* 5 seconds in microseconds divided by
* period time */
loops = 5000000 / val;
How did he calculate this?
how to read & play a sound file
hi,
I am new to ALSA programing. Could anyone tell how i can read & play a sound file using above example code for playback?
how to read & play a sound file
You complie the example Listing 4 then plug the Headpone in the system.firsly check that your headphone is properly working by running the sound recorder program.after compiling code some output file is generated in the particular folder.
just start recording by typing ./.outfile name > sound.raw and record your voice through headphone for 5 sec.
For plaback compile code for playback in the seprate folder and run
./.outfile name
Converting to ALSA
Firstly, this article is really good.
I need to write an application for FXS interface. the drivers are implements using ioctl system calls. How difficult is it to convert to ALSA API.
Or the otherway, what is to be done if i need to access these drivers in an application which is already supporting ALSA.
ok I just found it. for code
ok I just found it. for code called 'alsa.c' it's
gcc alsa.c -lasound
Linking Libraries
Umm... what libraries do i need to link? I tried the code (listings 3 & 4) and it compiled but didn't link. What gcc parameters need to be added?
(currently using Ubuntu Feisty 7.04)
undocumented bs wtf!
your second piece of example code has the following funciton call..
rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
looking at the API reference for this call we see that the last parameter in this call is int mode. Mode may be one of the following values.
SND_PCM_NONBLOCK or SND_PCM_ASYNC. The first of these is equal to 0x01 and the second is equal to 0x02. WHAT is this undocumented mode zero that your example code AND the alsa example code uses.
undocumented == BAD MOJO!
great article tho :)
i am working on a project
i am working on a project that needs a simple voice recording to be saved to a file, before further processing can be done on it... i am new to alsa (sound programming in general).
i believe alsa and oss can accomplish what i want but i need further guidance.
thanks.
ALSA Duplex Working code
Does any body tested ALSA duplex (Record and playback)? Can you please point the place where i can get some reference source code?
Thank you,
Santosh
[email protected]
Updated code for FC6?
I read this article and tried to run the sample code. It did compile and run but the record program produces garbage/noise. Is there an update for a Fedora Core 6 kernel? What kind of sound file does this code produce, wav, au, etc?
I don't know if anyone is
I don't know if anyone is reading this.
But there are a few problems.
It records as far as I can see, but I get a lot of random garbage data which I don't want when recording. Anything I record is messed up in random data.
I´ve tried Sound
I´ve tried Sound Programming with ALSA in a seminar, but i´m afraid, it is just too difficult for me. But i have to point out that i´m progging since one year, so i think i need just a bit more time. patience is all :-)
in listing 2, dir should be initialized
Very useful article.
In listing 2, you should replace
int dir;
by
int dir = 0;
or replace &dir by NULL later
In my first test case, dir was randomly initialized to a negative
value, giving as a result
rate = 44099 bps
Actually, the snd_pcm_hw_params_set_rate_near function is poorly documented.
Display format
It would be nice if the (fixed) page width were a little greater, without having to shrink the browser text size.
Hard to read code that's full of line wraps.
Problem in opening default device in listing2 of this article
Hi guys am new to this ALSA, I downloaded all driver, library utils from www.alsa-project.com and i installed.
when i run the listing1 of this doc it went fine and when i tried to run the second listing it says like this.
Unable to open the default device No such file.And i am using slackware with linux 2.4.22
Please help me out guys.
Thanx in advance for help
Re: Introduction to Sound Programming with ALSA
Great article. I tried the first source and it worked fine, but the second bombed:
Any idea why this would be? I didn't modify the source.
-Jeff
Problem in listing2 program Unable to open default device
Hi guys am new to this ALSA, I downloaded all driver, library utils from www.alsa-project.com and i installed.
when i run the listing1 of this doc it went fine and when i tried to run the second listing it says like this.
Unable to open the default device No such file.And i am using slackware with linux 2.4.22
Please help me out guys.
Thanx in advance for help
Re: Introduction to Sound Programming with ALSA
It happened the same to me. When I change the sampling frequency value to 48 kHz then I got the error message:
unable to set hw parameters: Invalid argument
For any other sampling frequency it works ok.
Pablo
It happened the same to me. W
It happened the same to me. When I change the sampling frequency value to 48 kHz then I got the error message:
unable to set hw parameters: Invalid argument
For any other sampling frequency it works ok.
Pablo
Re: Introduction to Sound Programming with ALSA
Someone has posted a note at the Resources page
,
saying that the variable "dir" needs to be initialized to 0 (zero).
That seemed to solve my problems, at least.
Re: Introduction to Sound Programming with ALSA
I am having the same problems with listing 4. (And it seems that others have too, see the Resources page.) In my case the problem seems to be the sampling frequency, if I change 44100 til 88200 the program will run.
What I really would like to know is whether this is a problem with the example program from the article (I did not modify it), a problem with ALSA (I use Debian Sarge with 2.6-kernel) or a problem with my sound card (SoundBlaster Live).
problem
Hi,
I tried to run the codes under beagleboard. I got the error message:
unable to set hw parameters: Invalid argument
I change the sampling frequency from 44100 to 88200 even to 132300 as you said. This time it works but when i run
./example3 < /dev/urandom
this command it gives me veri bad sound like "CCcczzZZZZzzzrrttTtTT".
My beagleboards parameters are this : //my pc(ubuntu)
PCM handle name = 'default'
PCM state = PREPARED
access type = RW_INTERLEAVED
format = 'S16_LE' (Signed 16 bit Little Endian)
subformat = 'STD' (Standard)
channels = 2
rate = 44100 bps
period time = 5804 us //23219
period size = 256 frames //1024
buffer time = 743038 us //23219
buffer size = 32768 frames //1048576
periods per buffer = 128 frames //1024
exact rate = 44100/1 bps
significant bits = 16
tick time = 16 us
is batch = 0
is block transfer = 0 //1
is double = 0
is half duplex = 0
is joint duplex = 0
can overrange = 0
can mmap = 1 //0
can pause = 1
can resume = 1 //0
can sync start = 0
The parameters which are bold are difference between my pc(ubuntu).
Please Can you give me a suggestion how to modify the code?
Thx in Advance.
Fatih
problem
Hi,
I tried to run the codes under beagleboard. I got the error message:
unable to set hw parameters: Invalid argument
I change the sampling frequency from 44100 to 88200 even to 132300 as you said. This time it works but when i run
./example3 < /dev/urandom
this command it gives me veri bad sound like "CCcczzZZZZzzzrrttTtTT".
My beagleboards parameters are this : //my pc(ubuntu)
PCM handle name = 'default'
PCM state = PREPARED
access type = RW_INTERLEAVED
format = 'S16_LE' (Signed 16 bit Little Endian)
subformat = 'STD' (Standard)
channels = 2
rate = 44100 bps
period time = 5804 us //23219
period size = 256 frames //1024
buffer time = 743038 us //23219
buffer size = 32768 frames //1048576
periods per buffer = 128 frames //1024
exact rate = 44100/1 bps
significant bits = 16
tick time = 16 us
is batch = 0
is block transfer = 0 //1
is double = 0
is half duplex = 0
is joint duplex = 0
can overrange = 0
can mmap = 1 //0
can pause = 1
can resume = 1 //0
can sync start = 0
The parameters which are bold are difference between my pc(ubuntu).
Please Can you give me a suggestion how to modify the code?
Thx in Advance.
Fatih
Re: Introduction to Sound Programming with ALSA
A simple question: Why can't the ALSA developers make sure that ALSA provides sound support at least as good as OSS? After having tested it on a number of boards, it was always a pain in the neck to configure properly, and getting it to work, an adventure. I will stay with OSS until ALSA becomes much more user-friendly.
Re: Introduction to Sound Programming with ALSA
Excellent informatiom. Now lets have a simple real time mixer with chnangeable effect to really show what ALSA + 2.6 Linux can do
Re: Introduction to Sound Programming with ALSA
Yes, I agree, excellent article and a brilliant introduction to ALSA.
Keep up the good work!
Re: Introduction to Sound Programming with ALSA
Informative article. More intros to popular or obscure libraries please!