Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
alsa.c
Go to the documentation of this file.
1/*
2 ALSA - sound output backend using the Advanced Linux Sound Architecture
3
4 Copyright (C)
5 2011, Odin Omdal Hørthe <odin.omdal@gmail.com>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
14
20#include "alsa.h"
21
22#include <err.h>
23#include <alsa/asoundlib.h>
24
25static snd_pcm_t* playback_handle = 0;
26static snd_pcm_sw_params_t* sw_params = 0;
27static snd_pcm_hw_params_t* hw_params = 0;
28static snd_pcm_sframes_t buffer_size = 0;
29
30static snd_pcm_sframes_t written = 0;
31static snd_pcm_sframes_t delay = 0;
32
33static unsigned int rate = 44100;
34
35static int audio_initialised = 0;
36
37size_t
39{
40 snd_pcm_delay(playback_handle, &delay);
41
42 return written - delay;
43}
44
45void
47{
48 unsigned int buffer_time = 50000;
49 const char* device;
50 int err;
51
53 return;
54
56
57 device = getenv("ALSA_DEVICE");
58
59 if(!device)
60 device = "default";
61
62 if(0 > (err = snd_pcm_open(&playback_handle, device,
63 SND_PCM_STREAM_PLAYBACK, 0/*SND_PCM_NONBLOCK*/)))
64 errx(EXIT_FAILURE, "Audio: Cannot open device %s: %s", device, snd_strerror(err));
65
66 if(0 > (err = snd_pcm_sw_params_malloc(&sw_params)))
67 errx(EXIT_FAILURE, "Audio: Could not allocate software parameter structure: %s",
68 snd_strerror(err));
69
70 if(0 > (err = snd_pcm_hw_params_malloc(&hw_params)))
71 errx(EXIT_FAILURE, "Audio: Could not allocate hardware parameter structure: %s",
72 snd_strerror(err));
73
74 if(0 > (err = snd_pcm_hw_params_any(playback_handle, hw_params)))
75 errx(EXIT_FAILURE, "Audio: Could not initializa hardware parameters: %s",
76 snd_strerror(err));
77
78 if(0 > (err = snd_pcm_hw_params_set_access(playback_handle, hw_params,
79 SND_PCM_ACCESS_RW_INTERLEAVED)))
80 errx(EXIT_FAILURE, "Audio: Could not set access type: %s", snd_strerror(err));
81
82 if(0 > (err = snd_pcm_hw_params_set_format(playback_handle, hw_params,
83 SND_PCM_FORMAT_S16)))
84 errx(EXIT_FAILURE, "Audio: Could not set sample format to signed 16 bit "
85 "native endian: %s", snd_strerror(err));
86
87 if(0 > (err = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params,
88 &rate, 0)))
89 errx(EXIT_FAILURE, "Audio: Could not set sample rate %uHz: %s", rate,
90 snd_strerror(err));
91
92 if(0 > (err = snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2)))
93 errx(EXIT_FAILURE, "Audio: Could not set channel count to %u: %s",
94 2, snd_strerror(err));
95
96 snd_pcm_hw_params_set_buffer_time_near(playback_handle, hw_params, &buffer_time, 0);
97
98 if(0 > (err = snd_pcm_hw_params(playback_handle, hw_params)))
99 errx(EXIT_FAILURE, "Audio: Could not set hardware parameters: %s", snd_strerror(err));
100
101 fprintf(stderr, "Buffer time is %.3f seconds\n", buffer_time / 1.0e6);
102
103 if(0 > (err = snd_pcm_sw_params_current(playback_handle, sw_params)))
104 errx(EXIT_FAILURE, "Audio: Could not initialise software parameters: %s",
105 snd_strerror(err));
106
107 snd_pcm_sw_params_set_start_threshold(playback_handle, sw_params, 0);
108 snd_pcm_sw_params_set_avail_min(playback_handle, sw_params, 1024);
109
110 snd_pcm_uframes_t min;
111 snd_pcm_sw_params_get_avail_min(sw_params, &min);
112 fprintf(stderr, "Minimum %u\n", (unsigned) min);
113
114 if(0 > (err = snd_pcm_sw_params(playback_handle, sw_params)))
115 errx(EXIT_FAILURE, "Audio: Could not set software parameters: %s",
116 snd_strerror(err));
117
118 buffer_size = snd_pcm_avail_update(playback_handle);
119}
120
121size_t
122audio_write(const void* data, size_t amount)
123{
124 int err;
125
126 amount /= 4;
127
128 for(;;)
129 {
130 err = snd_pcm_writei(playback_handle, data, amount);
131
132 if(err == -EAGAIN)
133 return 0;
134
135 if(err < 0)
136 {
137 err = snd_pcm_recover(playback_handle, err, 0);
138
139 if(err < 0)
140 errx(EXIT_FAILURE, "Audio playback failed: %s", strerror(-err));
141 }
142
143
144 break;
145 }
146
147 written += err;
148
149 err *= 4;
150
151 return err;
152}
153
154void
155audio_start(unsigned int rate, unsigned int channel_count)
156{
157 audio_init();
158
159 snd_pcm_prepare(playback_handle);
160}
161
162void
164{
165 snd_pcm_drain(playback_handle);
166}
static snd_pcm_sframes_t written
Definition alsa.c:30
static snd_pcm_sframes_t buffer_size
Definition alsa.c:28
static int audio_initialised
Definition alsa.c:35
void audio_init()
Definition alsa.c:46
static snd_pcm_sw_params_t * sw_params
Definition alsa.c:26
void audio_start(unsigned int rate, unsigned int channel_count)
Definition alsa.c:155
size_t audio_offset()
Definition alsa.c:38
static snd_pcm_hw_params_t * hw_params
Definition alsa.c:27
void audio_stop()
Definition alsa.c:163
size_t audio_write(const void *data, size_t amount)
Definition alsa.c:122
static unsigned int rate
Definition alsa.c:33
static snd_pcm_sframes_t delay
Definition alsa.c:31
static snd_pcm_t * playback_handle
Definition alsa.c:25
Interfacing to ALSA sound output.