22 #include <alsa/asoundlib.h> 24 static snd_pcm_t* playback_handle = 0;
25 static snd_pcm_sw_params_t* sw_params = 0;
26 static snd_pcm_hw_params_t* hw_params = 0;
27 static snd_pcm_sframes_t buffer_size = 0;
29 static snd_pcm_sframes_t written = 0;
30 static snd_pcm_sframes_t delay = 0;
32 static unsigned int rate = 44100;
34 static int audio_initialised = 0;
39 snd_pcm_delay(playback_handle, &delay);
41 return written - delay;
47 unsigned int buffer_time = 50000;
54 audio_initialised = 1;
56 device = getenv(
"ALSA_DEVICE");
61 if(0 > (err = snd_pcm_open(&playback_handle, device,
62 SND_PCM_STREAM_PLAYBACK, 0)))
63 errx(EXIT_FAILURE,
"Audio: Cannot open device %s: %s", device, snd_strerror(err));
65 if(0 > (err = snd_pcm_sw_params_malloc(&sw_params)))
66 errx(EXIT_FAILURE,
"Audio: Could not allocate software parameter structure: %s",
69 if(0 > (err = snd_pcm_hw_params_malloc(&hw_params)))
70 errx(EXIT_FAILURE,
"Audio: Could not allocate hardware parameter structure: %s",
73 if(0 > (err = snd_pcm_hw_params_any(playback_handle, hw_params)))
74 errx(EXIT_FAILURE,
"Audio: Could not initializa hardware parameters: %s",
77 if(0 > (err = snd_pcm_hw_params_set_access(playback_handle, hw_params,
78 SND_PCM_ACCESS_RW_INTERLEAVED)))
79 errx(EXIT_FAILURE,
"Audio: Could not set access type: %s", snd_strerror(err));
81 if(0 > (err = snd_pcm_hw_params_set_format(playback_handle, hw_params,
83 errx(EXIT_FAILURE,
"Audio: Could not set sample format to signed 16 bit " 84 "native endian: %s", snd_strerror(err));
86 if(0 > (err = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params,
88 errx(EXIT_FAILURE,
"Audio: Could not set sample rate %uHz: %s", rate,
91 if(0 > (err = snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2)))
92 errx(EXIT_FAILURE,
"Audio: Could not set channel count to %u: %s",
93 2, snd_strerror(err));
95 snd_pcm_hw_params_set_buffer_time_near(playback_handle, hw_params, &buffer_time, 0);
97 if(0 > (err = snd_pcm_hw_params(playback_handle, hw_params)))
98 errx(EXIT_FAILURE,
"Audio: Could not set hardware parameters: %s", snd_strerror(err));
100 fprintf(stderr,
"Buffer time is %.3f seconds\n", buffer_time / 1.0e6);
102 if(0 > (err = snd_pcm_sw_params_current(playback_handle, sw_params)))
103 errx(EXIT_FAILURE,
"Audio: Could not initialise software parameters: %s",
106 snd_pcm_sw_params_set_start_threshold(playback_handle, sw_params, 0);
107 snd_pcm_sw_params_set_avail_min(playback_handle, sw_params, 1024);
109 snd_pcm_uframes_t min;
110 snd_pcm_sw_params_get_avail_min(sw_params, &min);
111 fprintf(stderr,
"Minimum %u\n", (
unsigned) min);
113 if(0 > (err = snd_pcm_sw_params(playback_handle, sw_params)))
114 errx(EXIT_FAILURE,
"Audio: Could not set software parameters: %s",
117 buffer_size = snd_pcm_avail_update(playback_handle);
121 audio_write(
const void* data,
size_t amount)
129 err = snd_pcm_writei(playback_handle, data, amount);
136 err = snd_pcm_recover(playback_handle, err, 0);
139 errx(EXIT_FAILURE,
"Audio playback failed: %s", strerror(-err));
154 audio_start(
unsigned int rate,
unsigned int channel_count)
158 snd_pcm_prepare(playback_handle);
164 snd_pcm_drain(playback_handle);
Interfacing to ALSA sound output.