Introduction to Sound Programming with ALSA
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. Simple Sound Recording
/*
This example reads from the default PCM device
and writes to standard output for 5 seconds of data.
*/
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
int main() {
long loops;
int rc;
int size;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val;
int dir;
snd_pcm_uframes_t frames;
char *buffer;
/* Open PCM device for recording (capture). */
rc = snd_pcm_open(&handle, "default",
SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0) {
fprintf(stderr,
"unable to open pcm device: %s\n",
snd_strerror(rc));
exit(1);
}
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(¶ms);
/* Fill it in with default values. */
snd_pcm_hw_params_any(handle, params);
/* Set the desired hardware parameters. */
/* Interleaved mode */
snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
/* Signed 16-bit little-endian format */
snd_pcm_hw_params_set_format(handle, params,
SND_PCM_FORMAT_S16_LE);
/* Two channels (stereo) */
snd_pcm_hw_params_set_channels(handle, params, 2);
/* 44100 bits/second sampling rate (CD quality) */
val = 44100;
snd_pcm_hw_params_set_rate_near(handle, params,
&val, &dir);
/* Set period size to 32 frames. */
frames = 32;
snd_pcm_hw_params_set_period_size_near(handle,
params, &frames, &dir);
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
fprintf(stderr,
"unable to set hw parameters: %s\n",
snd_strerror(rc));
exit(1);
}
/* Use a buffer large enough to hold one period */
snd_pcm_hw_params_get_period_size(params,
&frames, &dir);
size = frames * 4; /* 2 bytes/sample, 2 channels */
buffer = (char *) malloc(size);
/* We want to loop for 5 seconds */
snd_pcm_hw_params_get_period_time(params,
&val, &dir);
loops = 5000000 / val;
while (loops > 0) {
loops--;
rc = snd_pcm_readi(handle, buffer, frames);
if (rc == -EPIPE) {
/* EPIPE means overrun */
fprintf(stderr, "overrun occurred\n");
snd_pcm_prepare(handle);
} else if (rc < 0) {
fprintf(stderr,
"error from read: %s\n",
snd_strerror(rc));
} else if (rc != (int)frames) {
fprintf(stderr, "short read, read %d frames\n", rc);
}
rc = write(1, buffer, size);
if (rc != size)
fprintf(stderr,
"short write: wrote %d bytes\n", rc);
}
snd_pcm_drain(handle);
snd_pcm_close(handle);
free(buffer);
return 0;
}
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.
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.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- New Products
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Nice article, thanks for the
4 hours 46 min ago - I once had a better way I
10 hours 32 min ago - Not only you I too assumed
10 hours 49 min ago - another very interesting
12 hours 42 min ago - Reply to comment | Linux Journal
14 hours 36 min ago - Reply to comment | Linux Journal
21 hours 30 min ago - Reply to comment | Linux Journal
21 hours 46 min ago - Favorite (and easily brute-forced) pw's
23 hours 37 min ago - Have you tried Boxen? It's a
1 day 5 hours ago - seo services in india
1 day 10 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
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 |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




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.
jamie@goonathon.net
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
santosh.pattar@gmail.com
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!