Introduction to Sound Programming with ALSA

Make maximum use of all the functionality in the new 2.6 kernel sound architecture using a simple API.

The random data should produce white noise for five seconds.

Next, try redirecting the input to /dev/null or /dev/zero and compare the results. Change some parameters, such as the sampling rate and data format, and see how it affects the results.

Listing 4 is much like Listing 3, except that we perform PCM capture (recording). When we open the PCM stream, we specify the mode as SND_PCM_STREAM_CAPTURE. In the main processing loop, we read the samples from the sound hardware using snd_pcm_readi and write it to standard output using write. We check for overrun and handle it in the same manner as we did underrun in Listing 3.

Running Listing 4 records approximately five seconds of data and sends it to standard out; you should redirect it to a file. If you have a microphone connected to your sound card, use a mixer program to set the recording source and level. Alternatively, you can run a CD player program and set the recording source to CD. Try running Listing 4 and redirecting the output to a file. You then can run Listing 3 to play back the data:


./listing4 > sound.raw
./listing3 < sound.raw

If your sound card supports full duplex sound, you should be able to pipe the programs together and hear the recorded sound coming out of the sound card by typing: ./listing4 | ./listing3. By changing the PCM parameters you can experiment with the effect of sampling rates and formats.

Advanced Features

In the previous examples, the PCM streams were operating in blocking mode, that is, the calls would not return until the data had been transferred. In an interactive event-driven application, this situation could lock up the application for unacceptably long periods of time. ALSA allows opening a stream in nonblocking mode where the read and write functions return immediately. If data transfers are pending and the calls cannot be processed, ALSA returns an error code of EBUSY.

Many graphical applications use callbacks to handle events. ALSA supports opening a PCM stream in asynchronous mode. This allows registering a callback function to be called when a period of sample data has been transferred.

The snd_pcm_readi and snd_pcm_writei calls used here are similar to the Linux read and write system calls. The letter i indicates that the frames are interleaved; corresponding functions exist for non-interleaved mode. Many devices under Linux also support the mmap system call, which maps them into memory where they can be manipulated with pointers. Finally, ALSA supports opening a PCM channel in mmap mode, which allows efficient zero copy access to sound data.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

CROSS_COMPILE

Anonymous's picture

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

rangel's picture

try: "strace ./play < sample.raw"
or "ldd play" and view if the correct path of library is linking

Volume needs to increase

djguha's picture

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

Milos's picture

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

Anonymous's picture

Thanks for this article

listing3

Anonymous's picture

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

Anonymous's picture

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.

jamie@goonathon.net

Kudoos and hats off for the Article

Anonymous's picture

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

manu's picture

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

MK's picture

/* 5 seconds in microseconds divided by
* period time */
loops = 5000000 / val;

How did he calculate this?

how to read & play a sound file

Shubham's picture

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

Anonymous's picture

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

Anonymous's picture

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

Elie's picture

ok I just found it. for code called 'alsa.c' it's

gcc alsa.c -lasound

Linking Libraries

Elie's picture

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!

mark manning's picture

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

Anonymous's picture

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

Santoshkumar's picture

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
santosh.pattar@gmail.com

Updated code for FC6?

William Estrada's picture

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

Anonymous's picture

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

David's picture

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

Fabrice Pardo's picture

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

MikeW's picture

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

Nagaraja S's picture

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

JKCunningham's picture

Great article. I tried the first source and it worked fine, but the second bombed:

> ./listing_2
unable to set hw parameters: Invalid argument

Any idea why this would be? I didn't modify the source.

-Jeff

Problem in listing2 program Unable to open default device

Nagaraja's picture

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

Pablo's picture

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

Pablo's picture

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

Anonymous's picture

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

Anonymous's picture

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

Anonymous's picture

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

Anonymous's picture

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

Anonymous's picture

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

Anonymous's picture

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

Anonymous's picture

Yes, I agree, excellent article and a brilliant introduction to ALSA.

Keep up the good work!

Re: Introduction to Sound Programming with ALSA

Anonymous's picture

Informative article. More intros to popular or obscure libraries please!

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

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.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

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.

Learn More

Sponsored by ActiveState