Statistics
| Branch: | Revision:

root / audio / alsaaudio.c @ 22d948a2

History | View | Annotate | Download (31.7 kB)

1 1d14ffa9 bellard
/*
2 1d14ffa9 bellard
 * QEMU ALSA audio driver
3 1d14ffa9 bellard
 *
4 1d14ffa9 bellard
 * Copyright (c) 2005 Vassili Karpov (malc)
5 1d14ffa9 bellard
 *
6 1d14ffa9 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 1d14ffa9 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 1d14ffa9 bellard
 * in the Software without restriction, including without limitation the rights
9 1d14ffa9 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 1d14ffa9 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 1d14ffa9 bellard
 * furnished to do so, subject to the following conditions:
12 1d14ffa9 bellard
 *
13 1d14ffa9 bellard
 * The above copyright notice and this permission notice shall be included in
14 1d14ffa9 bellard
 * all copies or substantial portions of the Software.
15 1d14ffa9 bellard
 *
16 1d14ffa9 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 1d14ffa9 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 1d14ffa9 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 1d14ffa9 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 1d14ffa9 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 1d14ffa9 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 1d14ffa9 bellard
 * THE SOFTWARE.
23 1d14ffa9 bellard
 */
24 1d14ffa9 bellard
#include <alsa/asoundlib.h>
25 749bc4bf pbrook
#include "qemu-common.h"
26 8b438ba3 malc
#include "qemu-char.h"
27 749bc4bf pbrook
#include "audio.h"
28 1d14ffa9 bellard
29 2637872b malc
#if QEMU_GNUC_PREREQ(4, 3)
30 2637872b malc
#pragma GCC diagnostic ignored "-Waddress"
31 2637872b malc
#endif
32 2637872b malc
33 1d14ffa9 bellard
#define AUDIO_CAP "alsa"
34 1d14ffa9 bellard
#include "audio_int.h"
35 1d14ffa9 bellard
36 8b438ba3 malc
struct pollhlp {
37 8b438ba3 malc
    snd_pcm_t *handle;
38 8b438ba3 malc
    struct pollfd *pfds;
39 8b438ba3 malc
    int count;
40 b4f763b8 malc
    int mask;
41 8b438ba3 malc
};
42 8b438ba3 malc
43 1d14ffa9 bellard
typedef struct ALSAVoiceOut {
44 1d14ffa9 bellard
    HWVoiceOut hw;
45 541ba4e7 malc
    int wpos;
46 541ba4e7 malc
    int pending;
47 1d14ffa9 bellard
    void *pcm_buf;
48 1d14ffa9 bellard
    snd_pcm_t *handle;
49 8b438ba3 malc
    struct pollhlp pollhlp;
50 1d14ffa9 bellard
} ALSAVoiceOut;
51 1d14ffa9 bellard
52 1d14ffa9 bellard
typedef struct ALSAVoiceIn {
53 1d14ffa9 bellard
    HWVoiceIn hw;
54 1d14ffa9 bellard
    snd_pcm_t *handle;
55 1d14ffa9 bellard
    void *pcm_buf;
56 8b438ba3 malc
    struct pollhlp pollhlp;
57 1d14ffa9 bellard
} ALSAVoiceIn;
58 1d14ffa9 bellard
59 1d14ffa9 bellard
static struct {
60 1d14ffa9 bellard
    int size_in_usec_in;
61 1d14ffa9 bellard
    int size_in_usec_out;
62 1d14ffa9 bellard
    const char *pcm_name_in;
63 1d14ffa9 bellard
    const char *pcm_name_out;
64 1d14ffa9 bellard
    unsigned int buffer_size_in;
65 1d14ffa9 bellard
    unsigned int period_size_in;
66 1d14ffa9 bellard
    unsigned int buffer_size_out;
67 1d14ffa9 bellard
    unsigned int period_size_out;
68 1d14ffa9 bellard
    unsigned int threshold;
69 1d14ffa9 bellard
70 fe8f096b ths
    int buffer_size_in_overridden;
71 fe8f096b ths
    int period_size_in_overridden;
72 1d14ffa9 bellard
73 fe8f096b ths
    int buffer_size_out_overridden;
74 fe8f096b ths
    int period_size_out_overridden;
75 571ec3d6 bellard
    int verbose;
76 1d14ffa9 bellard
} conf = {
77 de2ca4fb malc
    .buffer_size_out = 4096,
78 de2ca4fb malc
    .period_size_out = 1024,
79 8ead62cf bellard
    .pcm_name_out = "default",
80 8ead62cf bellard
    .pcm_name_in = "default",
81 1d14ffa9 bellard
};
82 1d14ffa9 bellard
83 1d14ffa9 bellard
struct alsa_params_req {
84 ca9cc28c balrog
    int freq;
85 ca9cc28c balrog
    snd_pcm_format_t fmt;
86 ca9cc28c balrog
    int nchannels;
87 7a24c800 malc
    int size_in_usec;
88 64333899 malc
    int override_mask;
89 1d14ffa9 bellard
    unsigned int buffer_size;
90 1d14ffa9 bellard
    unsigned int period_size;
91 1d14ffa9 bellard
};
92 1d14ffa9 bellard
93 1d14ffa9 bellard
struct alsa_params_obt {
94 1d14ffa9 bellard
    int freq;
95 1d14ffa9 bellard
    audfmt_e fmt;
96 ca9cc28c balrog
    int endianness;
97 1d14ffa9 bellard
    int nchannels;
98 c0fe3827 bellard
    snd_pcm_uframes_t samples;
99 1d14ffa9 bellard
};
100 1d14ffa9 bellard
101 1d14ffa9 bellard
static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
102 1d14ffa9 bellard
{
103 1d14ffa9 bellard
    va_list ap;
104 1d14ffa9 bellard
105 1d14ffa9 bellard
    va_start (ap, fmt);
106 1d14ffa9 bellard
    AUD_vlog (AUDIO_CAP, fmt, ap);
107 1d14ffa9 bellard
    va_end (ap);
108 1d14ffa9 bellard
109 1d14ffa9 bellard
    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
110 1d14ffa9 bellard
}
111 1d14ffa9 bellard
112 1d14ffa9 bellard
static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
113 1d14ffa9 bellard
    int err,
114 1d14ffa9 bellard
    const char *typ,
115 1d14ffa9 bellard
    const char *fmt,
116 1d14ffa9 bellard
    ...
117 1d14ffa9 bellard
    )
118 1d14ffa9 bellard
{
119 1d14ffa9 bellard
    va_list ap;
120 1d14ffa9 bellard
121 c0fe3827 bellard
    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
122 1d14ffa9 bellard
123 1d14ffa9 bellard
    va_start (ap, fmt);
124 1d14ffa9 bellard
    AUD_vlog (AUDIO_CAP, fmt, ap);
125 1d14ffa9 bellard
    va_end (ap);
126 1d14ffa9 bellard
127 1d14ffa9 bellard
    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
128 1d14ffa9 bellard
}
129 1d14ffa9 bellard
130 6ebfda13 malc
static void alsa_fini_poll (struct pollhlp *hlp)
131 6ebfda13 malc
{
132 6ebfda13 malc
    int i;
133 6ebfda13 malc
    struct pollfd *pfds = hlp->pfds;
134 6ebfda13 malc
135 6ebfda13 malc
    if (pfds) {
136 6ebfda13 malc
        for (i = 0; i < hlp->count; ++i) {
137 6ebfda13 malc
            qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
138 6ebfda13 malc
        }
139 6ebfda13 malc
        qemu_free (pfds);
140 6ebfda13 malc
    }
141 6ebfda13 malc
    hlp->pfds = NULL;
142 6ebfda13 malc
    hlp->count = 0;
143 6ebfda13 malc
    hlp->handle = NULL;
144 6ebfda13 malc
}
145 6ebfda13 malc
146 6ebfda13 malc
static void alsa_anal_close1 (snd_pcm_t **handlep)
147 1d14ffa9 bellard
{
148 1d14ffa9 bellard
    int err = snd_pcm_close (*handlep);
149 1d14ffa9 bellard
    if (err) {
150 1d14ffa9 bellard
        alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
151 1d14ffa9 bellard
    }
152 1d14ffa9 bellard
    *handlep = NULL;
153 1d14ffa9 bellard
}
154 1d14ffa9 bellard
155 6ebfda13 malc
static void alsa_anal_close (snd_pcm_t **handlep, struct pollhlp *hlp)
156 6ebfda13 malc
{
157 6ebfda13 malc
    alsa_fini_poll (hlp);
158 6ebfda13 malc
    alsa_anal_close1 (handlep);
159 6ebfda13 malc
}
160 6ebfda13 malc
161 8b438ba3 malc
static int alsa_recover (snd_pcm_t *handle)
162 8b438ba3 malc
{
163 8b438ba3 malc
    int err = snd_pcm_prepare (handle);
164 8b438ba3 malc
    if (err < 0) {
165 8b438ba3 malc
        alsa_logerr (err, "Failed to prepare handle %p\n", handle);
166 8b438ba3 malc
        return -1;
167 8b438ba3 malc
    }
168 8b438ba3 malc
    return 0;
169 8b438ba3 malc
}
170 8b438ba3 malc
171 8b438ba3 malc
static int alsa_resume (snd_pcm_t *handle)
172 8b438ba3 malc
{
173 8b438ba3 malc
    int err = snd_pcm_resume (handle);
174 8b438ba3 malc
    if (err < 0) {
175 8b438ba3 malc
        alsa_logerr (err, "Failed to resume handle %p\n", handle);
176 8b438ba3 malc
        return -1;
177 8b438ba3 malc
    }
178 8b438ba3 malc
    return 0;
179 8b438ba3 malc
}
180 8b438ba3 malc
181 8b438ba3 malc
static void alsa_poll_handler (void *opaque)
182 8b438ba3 malc
{
183 8b438ba3 malc
    int err, count;
184 8b438ba3 malc
    snd_pcm_state_t state;
185 8b438ba3 malc
    struct pollhlp *hlp = opaque;
186 8b438ba3 malc
    unsigned short revents;
187 8b438ba3 malc
188 8b438ba3 malc
    count = poll (hlp->pfds, hlp->count, 0);
189 8b438ba3 malc
    if (count < 0) {
190 8b438ba3 malc
        dolog ("alsa_poll_handler: poll %s\n", strerror (errno));
191 8b438ba3 malc
        return;
192 8b438ba3 malc
    }
193 8b438ba3 malc
194 8b438ba3 malc
    if (!count) {
195 8b438ba3 malc
        return;
196 8b438ba3 malc
    }
197 8b438ba3 malc
198 8b438ba3 malc
    /* XXX: ALSA example uses initial count, not the one returned by
199 8b438ba3 malc
       poll, correct? */
200 8b438ba3 malc
    err = snd_pcm_poll_descriptors_revents (hlp->handle, hlp->pfds,
201 8b438ba3 malc
                                            hlp->count, &revents);
202 8b438ba3 malc
    if (err < 0) {
203 8b438ba3 malc
        alsa_logerr (err, "snd_pcm_poll_descriptors_revents");
204 8b438ba3 malc
        return;
205 8b438ba3 malc
    }
206 8b438ba3 malc
207 b4f763b8 malc
    if (!(revents & hlp->mask)) {
208 8b438ba3 malc
        if (conf.verbose) {
209 8b438ba3 malc
            dolog ("revents = %d\n", revents);
210 8b438ba3 malc
        }
211 8b438ba3 malc
        return;
212 8b438ba3 malc
    }
213 8b438ba3 malc
214 8b438ba3 malc
    state = snd_pcm_state (hlp->handle);
215 8b438ba3 malc
    switch (state) {
216 d9812b03 malc
    case SND_PCM_STATE_SETUP:
217 d9812b03 malc
        alsa_recover (hlp->handle);
218 d9812b03 malc
        break;
219 d9812b03 malc
220 8b438ba3 malc
    case SND_PCM_STATE_XRUN:
221 8b438ba3 malc
        alsa_recover (hlp->handle);
222 8b438ba3 malc
        break;
223 8b438ba3 malc
224 8b438ba3 malc
    case SND_PCM_STATE_SUSPENDED:
225 8b438ba3 malc
        alsa_resume (hlp->handle);
226 8b438ba3 malc
        break;
227 8b438ba3 malc
228 8b438ba3 malc
    case SND_PCM_STATE_PREPARED:
229 8b438ba3 malc
        audio_run ("alsa run (prepared)");
230 8b438ba3 malc
        break;
231 8b438ba3 malc
232 8b438ba3 malc
    case SND_PCM_STATE_RUNNING:
233 8b438ba3 malc
        audio_run ("alsa run (running)");
234 8b438ba3 malc
        break;
235 8b438ba3 malc
236 8b438ba3 malc
    default:
237 8b438ba3 malc
        dolog ("Unexpected state %d\n", state);
238 8b438ba3 malc
    }
239 8b438ba3 malc
}
240 8b438ba3 malc
241 b4f763b8 malc
static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
242 8b438ba3 malc
{
243 8b438ba3 malc
    int i, count, err;
244 8b438ba3 malc
    struct pollfd *pfds;
245 8b438ba3 malc
246 8b438ba3 malc
    count = snd_pcm_poll_descriptors_count (handle);
247 8b438ba3 malc
    if (count <= 0) {
248 8b438ba3 malc
        dolog ("Could not initialize poll mode\n"
249 8b438ba3 malc
               "Invalid number of poll descriptors %d\n", count);
250 8b438ba3 malc
        return -1;
251 8b438ba3 malc
    }
252 8b438ba3 malc
253 8b438ba3 malc
    pfds = audio_calloc ("alsa_poll_helper", count, sizeof (*pfds));
254 8b438ba3 malc
    if (!pfds) {
255 8b438ba3 malc
        dolog ("Could not initialize poll mode\n");
256 8b438ba3 malc
        return -1;
257 8b438ba3 malc
    }
258 8b438ba3 malc
259 8b438ba3 malc
    err = snd_pcm_poll_descriptors (handle, pfds, count);
260 8b438ba3 malc
    if (err < 0) {
261 8b438ba3 malc
        alsa_logerr (err, "Could not initialize poll mode\n"
262 8b438ba3 malc
                     "Could not obtain poll descriptors\n");
263 8b438ba3 malc
        qemu_free (pfds);
264 8b438ba3 malc
        return -1;
265 8b438ba3 malc
    }
266 8b438ba3 malc
267 8b438ba3 malc
    for (i = 0; i < count; ++i) {
268 8b438ba3 malc
        if (pfds[i].events & POLLIN) {
269 8b438ba3 malc
            err = qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler,
270 8b438ba3 malc
                                       NULL, hlp);
271 8b438ba3 malc
        }
272 8b438ba3 malc
        if (pfds[i].events & POLLOUT) {
273 8b438ba3 malc
            if (conf.verbose) {
274 8b438ba3 malc
                dolog ("POLLOUT %d %d\n", i, pfds[i].fd);
275 8b438ba3 malc
            }
276 8b438ba3 malc
            err = qemu_set_fd_handler (pfds[i].fd, NULL,
277 8b438ba3 malc
                                       alsa_poll_handler, hlp);
278 8b438ba3 malc
        }
279 8b438ba3 malc
        if (conf.verbose) {
280 8b438ba3 malc
            dolog ("Set handler events=%#x index=%d fd=%d err=%d\n",
281 8b438ba3 malc
                   pfds[i].events, i, pfds[i].fd, err);
282 8b438ba3 malc
        }
283 8b438ba3 malc
284 8b438ba3 malc
        if (err) {
285 8b438ba3 malc
            dolog ("Failed to set handler events=%#x index=%d fd=%d err=%d\n",
286 8b438ba3 malc
                   pfds[i].events, i, pfds[i].fd, err);
287 8b438ba3 malc
288 8b438ba3 malc
            while (i--) {
289 8b438ba3 malc
                qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
290 8b438ba3 malc
            }
291 8b438ba3 malc
            qemu_free (pfds);
292 8b438ba3 malc
            return -1;
293 8b438ba3 malc
        }
294 8b438ba3 malc
    }
295 8b438ba3 malc
    hlp->pfds = pfds;
296 8b438ba3 malc
    hlp->count = count;
297 8b438ba3 malc
    hlp->handle = handle;
298 b4f763b8 malc
    hlp->mask = mask;
299 8b438ba3 malc
    return 0;
300 8b438ba3 malc
}
301 8b438ba3 malc
302 8b438ba3 malc
static int alsa_poll_out (HWVoiceOut *hw)
303 8b438ba3 malc
{
304 8b438ba3 malc
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
305 8b438ba3 malc
306 b4f763b8 malc
    return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLOUT);
307 8b438ba3 malc
}
308 8b438ba3 malc
309 8b438ba3 malc
static int alsa_poll_in (HWVoiceIn *hw)
310 8b438ba3 malc
{
311 8b438ba3 malc
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
312 8b438ba3 malc
313 b4f763b8 malc
    return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN);
314 8b438ba3 malc
}
315 8b438ba3 malc
316 1d14ffa9 bellard
static int alsa_write (SWVoiceOut *sw, void *buf, int len)
317 1d14ffa9 bellard
{
318 1d14ffa9 bellard
    return audio_pcm_sw_write (sw, buf, len);
319 1d14ffa9 bellard
}
320 1d14ffa9 bellard
321 ca9cc28c balrog
static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt)
322 1d14ffa9 bellard
{
323 1d14ffa9 bellard
    switch (fmt) {
324 1d14ffa9 bellard
    case AUD_FMT_S8:
325 1d14ffa9 bellard
        return SND_PCM_FORMAT_S8;
326 1d14ffa9 bellard
327 1d14ffa9 bellard
    case AUD_FMT_U8:
328 1d14ffa9 bellard
        return SND_PCM_FORMAT_U8;
329 1d14ffa9 bellard
330 1d14ffa9 bellard
    case AUD_FMT_S16:
331 1d14ffa9 bellard
        return SND_PCM_FORMAT_S16_LE;
332 1d14ffa9 bellard
333 1d14ffa9 bellard
    case AUD_FMT_U16:
334 1d14ffa9 bellard
        return SND_PCM_FORMAT_U16_LE;
335 1d14ffa9 bellard
336 f941aa25 ths
    case AUD_FMT_S32:
337 f941aa25 ths
        return SND_PCM_FORMAT_S32_LE;
338 f941aa25 ths
339 f941aa25 ths
    case AUD_FMT_U32:
340 f941aa25 ths
        return SND_PCM_FORMAT_U32_LE;
341 f941aa25 ths
342 1d14ffa9 bellard
    default:
343 1d14ffa9 bellard
        dolog ("Internal logic error: Bad audio format %d\n", fmt);
344 1d14ffa9 bellard
#ifdef DEBUG_AUDIO
345 1d14ffa9 bellard
        abort ();
346 1d14ffa9 bellard
#endif
347 1d14ffa9 bellard
        return SND_PCM_FORMAT_U8;
348 1d14ffa9 bellard
    }
349 1d14ffa9 bellard
}
350 1d14ffa9 bellard
351 ca9cc28c balrog
static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
352 ca9cc28c balrog
                           int *endianness)
353 1d14ffa9 bellard
{
354 1d14ffa9 bellard
    switch (alsafmt) {
355 1d14ffa9 bellard
    case SND_PCM_FORMAT_S8:
356 1d14ffa9 bellard
        *endianness = 0;
357 1d14ffa9 bellard
        *fmt = AUD_FMT_S8;
358 1d14ffa9 bellard
        break;
359 1d14ffa9 bellard
360 1d14ffa9 bellard
    case SND_PCM_FORMAT_U8:
361 1d14ffa9 bellard
        *endianness = 0;
362 1d14ffa9 bellard
        *fmt = AUD_FMT_U8;
363 1d14ffa9 bellard
        break;
364 1d14ffa9 bellard
365 1d14ffa9 bellard
    case SND_PCM_FORMAT_S16_LE:
366 1d14ffa9 bellard
        *endianness = 0;
367 1d14ffa9 bellard
        *fmt = AUD_FMT_S16;
368 1d14ffa9 bellard
        break;
369 1d14ffa9 bellard
370 1d14ffa9 bellard
    case SND_PCM_FORMAT_U16_LE:
371 1d14ffa9 bellard
        *endianness = 0;
372 1d14ffa9 bellard
        *fmt = AUD_FMT_U16;
373 1d14ffa9 bellard
        break;
374 1d14ffa9 bellard
375 1d14ffa9 bellard
    case SND_PCM_FORMAT_S16_BE:
376 1d14ffa9 bellard
        *endianness = 1;
377 1d14ffa9 bellard
        *fmt = AUD_FMT_S16;
378 1d14ffa9 bellard
        break;
379 1d14ffa9 bellard
380 1d14ffa9 bellard
    case SND_PCM_FORMAT_U16_BE:
381 1d14ffa9 bellard
        *endianness = 1;
382 1d14ffa9 bellard
        *fmt = AUD_FMT_U16;
383 1d14ffa9 bellard
        break;
384 1d14ffa9 bellard
385 f941aa25 ths
    case SND_PCM_FORMAT_S32_LE:
386 f941aa25 ths
        *endianness = 0;
387 f941aa25 ths
        *fmt = AUD_FMT_S32;
388 f941aa25 ths
        break;
389 f941aa25 ths
390 f941aa25 ths
    case SND_PCM_FORMAT_U32_LE:
391 f941aa25 ths
        *endianness = 0;
392 f941aa25 ths
        *fmt = AUD_FMT_U32;
393 f941aa25 ths
        break;
394 f941aa25 ths
395 f941aa25 ths
    case SND_PCM_FORMAT_S32_BE:
396 f941aa25 ths
        *endianness = 1;
397 f941aa25 ths
        *fmt = AUD_FMT_S32;
398 f941aa25 ths
        break;
399 f941aa25 ths
400 f941aa25 ths
    case SND_PCM_FORMAT_U32_BE:
401 f941aa25 ths
        *endianness = 1;
402 f941aa25 ths
        *fmt = AUD_FMT_U32;
403 f941aa25 ths
        break;
404 f941aa25 ths
405 1d14ffa9 bellard
    default:
406 1d14ffa9 bellard
        dolog ("Unrecognized audio format %d\n", alsafmt);
407 1d14ffa9 bellard
        return -1;
408 1d14ffa9 bellard
    }
409 1d14ffa9 bellard
410 1d14ffa9 bellard
    return 0;
411 1d14ffa9 bellard
}
412 1d14ffa9 bellard
413 1d14ffa9 bellard
static void alsa_dump_info (struct alsa_params_req *req,
414 8bb414d2 malc
                            struct alsa_params_obt *obt,
415 8bb414d2 malc
                            snd_pcm_format_t obtfmt)
416 1d14ffa9 bellard
{
417 1d14ffa9 bellard
    dolog ("parameter | requested value | obtained value\n");
418 8bb414d2 malc
    dolog ("format    |      %10d |     %10d\n", req->fmt, obtfmt);
419 1d14ffa9 bellard
    dolog ("channels  |      %10d |     %10d\n",
420 1d14ffa9 bellard
           req->nchannels, obt->nchannels);
421 1d14ffa9 bellard
    dolog ("frequency |      %10d |     %10d\n", req->freq, obt->freq);
422 1d14ffa9 bellard
    dolog ("============================================\n");
423 1d14ffa9 bellard
    dolog ("requested: buffer size %d period size %d\n",
424 1d14ffa9 bellard
           req->buffer_size, req->period_size);
425 c0fe3827 bellard
    dolog ("obtained: samples %ld\n", obt->samples);
426 1d14ffa9 bellard
}
427 1d14ffa9 bellard
428 1d14ffa9 bellard
static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
429 1d14ffa9 bellard
{
430 1d14ffa9 bellard
    int err;
431 1d14ffa9 bellard
    snd_pcm_sw_params_t *sw_params;
432 1d14ffa9 bellard
433 1d14ffa9 bellard
    snd_pcm_sw_params_alloca (&sw_params);
434 1d14ffa9 bellard
435 1d14ffa9 bellard
    err = snd_pcm_sw_params_current (handle, sw_params);
436 1d14ffa9 bellard
    if (err < 0) {
437 c0fe3827 bellard
        dolog ("Could not fully initialize DAC\n");
438 1d14ffa9 bellard
        alsa_logerr (err, "Failed to get current software parameters\n");
439 1d14ffa9 bellard
        return;
440 1d14ffa9 bellard
    }
441 1d14ffa9 bellard
442 1d14ffa9 bellard
    err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
443 1d14ffa9 bellard
    if (err < 0) {
444 c0fe3827 bellard
        dolog ("Could not fully initialize DAC\n");
445 1d14ffa9 bellard
        alsa_logerr (err, "Failed to set software threshold to %ld\n",
446 1d14ffa9 bellard
                     threshold);
447 1d14ffa9 bellard
        return;
448 1d14ffa9 bellard
    }
449 1d14ffa9 bellard
450 1d14ffa9 bellard
    err = snd_pcm_sw_params (handle, sw_params);
451 1d14ffa9 bellard
    if (err < 0) {
452 c0fe3827 bellard
        dolog ("Could not fully initialize DAC\n");
453 1d14ffa9 bellard
        alsa_logerr (err, "Failed to set software parameters\n");
454 1d14ffa9 bellard
        return;
455 1d14ffa9 bellard
    }
456 1d14ffa9 bellard
}
457 1d14ffa9 bellard
458 1d14ffa9 bellard
static int alsa_open (int in, struct alsa_params_req *req,
459 1d14ffa9 bellard
                      struct alsa_params_obt *obt, snd_pcm_t **handlep)
460 1d14ffa9 bellard
{
461 1d14ffa9 bellard
    snd_pcm_t *handle;
462 1d14ffa9 bellard
    snd_pcm_hw_params_t *hw_params;
463 60fe76f3 ths
    int err;
464 7a24c800 malc
    int size_in_usec;
465 60fe76f3 ths
    unsigned int freq, nchannels;
466 1d14ffa9 bellard
    const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
467 1d14ffa9 bellard
    snd_pcm_uframes_t obt_buffer_size;
468 1d14ffa9 bellard
    const char *typ = in ? "ADC" : "DAC";
469 ca9cc28c balrog
    snd_pcm_format_t obtfmt;
470 1d14ffa9 bellard
471 1d14ffa9 bellard
    freq = req->freq;
472 1d14ffa9 bellard
    nchannels = req->nchannels;
473 7a24c800 malc
    size_in_usec = req->size_in_usec;
474 1d14ffa9 bellard
475 1d14ffa9 bellard
    snd_pcm_hw_params_alloca (&hw_params);
476 1d14ffa9 bellard
477 1d14ffa9 bellard
    err = snd_pcm_open (
478 1d14ffa9 bellard
        &handle,
479 1d14ffa9 bellard
        pcm_name,
480 1d14ffa9 bellard
        in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
481 1d14ffa9 bellard
        SND_PCM_NONBLOCK
482 1d14ffa9 bellard
        );
483 1d14ffa9 bellard
    if (err < 0) {
484 1d14ffa9 bellard
        alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
485 1d14ffa9 bellard
        return -1;
486 1d14ffa9 bellard
    }
487 1d14ffa9 bellard
488 1d14ffa9 bellard
    err = snd_pcm_hw_params_any (handle, hw_params);
489 1d14ffa9 bellard
    if (err < 0) {
490 1d14ffa9 bellard
        alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
491 1d14ffa9 bellard
        goto err;
492 1d14ffa9 bellard
    }
493 1d14ffa9 bellard
494 1d14ffa9 bellard
    err = snd_pcm_hw_params_set_access (
495 1d14ffa9 bellard
        handle,
496 1d14ffa9 bellard
        hw_params,
497 1d14ffa9 bellard
        SND_PCM_ACCESS_RW_INTERLEAVED
498 1d14ffa9 bellard
        );
499 1d14ffa9 bellard
    if (err < 0) {
500 1d14ffa9 bellard
        alsa_logerr2 (err, typ, "Failed to set access type\n");
501 1d14ffa9 bellard
        goto err;
502 1d14ffa9 bellard
    }
503 1d14ffa9 bellard
504 1d14ffa9 bellard
    err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
505 ca9cc28c balrog
    if (err < 0 && conf.verbose) {
506 1d14ffa9 bellard
        alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
507 1d14ffa9 bellard
    }
508 1d14ffa9 bellard
509 1d14ffa9 bellard
    err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
510 1d14ffa9 bellard
    if (err < 0) {
511 1d14ffa9 bellard
        alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
512 1d14ffa9 bellard
        goto err;
513 1d14ffa9 bellard
    }
514 1d14ffa9 bellard
515 1d14ffa9 bellard
    err = snd_pcm_hw_params_set_channels_near (
516 1d14ffa9 bellard
        handle,
517 1d14ffa9 bellard
        hw_params,
518 1d14ffa9 bellard
        &nchannels
519 1d14ffa9 bellard
        );
520 1d14ffa9 bellard
    if (err < 0) {
521 1d14ffa9 bellard
        alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
522 1d14ffa9 bellard
                      req->nchannels);
523 1d14ffa9 bellard
        goto err;
524 1d14ffa9 bellard
    }
525 1d14ffa9 bellard
526 1d14ffa9 bellard
    if (nchannels != 1 && nchannels != 2) {
527 1d14ffa9 bellard
        alsa_logerr2 (err, typ,
528 1d14ffa9 bellard
                      "Can not handle obtained number of channels %d\n",
529 1d14ffa9 bellard
                      nchannels);
530 1d14ffa9 bellard
        goto err;
531 1d14ffa9 bellard
    }
532 1d14ffa9 bellard
533 7a24c800 malc
    if (req->buffer_size) {
534 f3b52983 malc
        unsigned long obt;
535 f3b52983 malc
536 7a24c800 malc
        if (size_in_usec) {
537 7a24c800 malc
            int dir = 0;
538 7a24c800 malc
            unsigned int btime = req->buffer_size;
539 1d14ffa9 bellard
540 1d14ffa9 bellard
            err = snd_pcm_hw_params_set_buffer_time_near (
541 1d14ffa9 bellard
                handle,
542 1d14ffa9 bellard
                hw_params,
543 7a24c800 malc
                &btime,
544 7a24c800 malc
                &dir
545 c0fe3827 bellard
                );
546 f3b52983 malc
            obt = btime;
547 1d14ffa9 bellard
        }
548 1d14ffa9 bellard
        else {
549 7a24c800 malc
            snd_pcm_uframes_t bsize = req->buffer_size;
550 1d14ffa9 bellard
551 7a24c800 malc
            err = snd_pcm_hw_params_set_buffer_size_near (
552 7a24c800 malc
                handle,
553 7a24c800 malc
                hw_params,
554 7a24c800 malc
                &bsize
555 7a24c800 malc
                );
556 f3b52983 malc
            obt = bsize;
557 7a24c800 malc
        }
558 7a24c800 malc
        if (err < 0) {
559 7a24c800 malc
            alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
560 7a24c800 malc
                          size_in_usec ? "time" : "size", req->buffer_size);
561 7a24c800 malc
            goto err;
562 7a24c800 malc
        }
563 f3b52983 malc
564 64333899 malc
        if ((req->override_mask & 2) && (obt - req->buffer_size))
565 f3b52983 malc
            dolog ("Requested buffer %s %u was rejected, using %lu\n",
566 f3b52983 malc
                   size_in_usec ? "time" : "size", req->buffer_size, obt);
567 7a24c800 malc
    }
568 7a24c800 malc
569 7a24c800 malc
    if (req->period_size) {
570 f3b52983 malc
        unsigned long obt;
571 f3b52983 malc
572 7a24c800 malc
        if (size_in_usec) {
573 7a24c800 malc
            int dir = 0;
574 7a24c800 malc
            unsigned int ptime = req->period_size;
575 1d14ffa9 bellard
576 7a24c800 malc
            err = snd_pcm_hw_params_set_period_time_near (
577 7a24c800 malc
                handle,
578 1d14ffa9 bellard
                hw_params,
579 7a24c800 malc
                &ptime,
580 7a24c800 malc
                &dir
581 1d14ffa9 bellard
                );
582 f3b52983 malc
            obt = ptime;
583 7a24c800 malc
        }
584 7a24c800 malc
        else {
585 a7bb29ba malc
            int dir = 0;
586 7a24c800 malc
            snd_pcm_uframes_t psize = req->period_size;
587 1d14ffa9 bellard
588 a7bb29ba malc
            err = snd_pcm_hw_params_set_period_size_near (
589 1d14ffa9 bellard
                handle,
590 1d14ffa9 bellard
                hw_params,
591 a7bb29ba malc
                &psize,
592 a7bb29ba malc
                &dir
593 1d14ffa9 bellard
                );
594 f3b52983 malc
            obt = psize;
595 1d14ffa9 bellard
        }
596 7a24c800 malc
597 7a24c800 malc
        if (err < 0) {
598 7a24c800 malc
            alsa_logerr2 (err, typ, "Failed to set period %s to %d\n",
599 7a24c800 malc
                          size_in_usec ? "time" : "size", req->period_size);
600 7a24c800 malc
            goto err;
601 7a24c800 malc
        }
602 f3b52983 malc
603 541ba4e7 malc
        if (((req->override_mask & 1) && (obt - req->period_size)))
604 f3b52983 malc
            dolog ("Requested period %s %u was rejected, using %lu\n",
605 f3b52983 malc
                   size_in_usec ? "time" : "size", req->period_size, obt);
606 1d14ffa9 bellard
    }
607 1d14ffa9 bellard
608 1d14ffa9 bellard
    err = snd_pcm_hw_params (handle, hw_params);
609 1d14ffa9 bellard
    if (err < 0) {
610 1d14ffa9 bellard
        alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
611 1d14ffa9 bellard
        goto err;
612 1d14ffa9 bellard
    }
613 1d14ffa9 bellard
614 1d14ffa9 bellard
    err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
615 1d14ffa9 bellard
    if (err < 0) {
616 1d14ffa9 bellard
        alsa_logerr2 (err, typ, "Failed to get buffer size\n");
617 1d14ffa9 bellard
        goto err;
618 1d14ffa9 bellard
    }
619 1d14ffa9 bellard
620 ca9cc28c balrog
    err = snd_pcm_hw_params_get_format (hw_params, &obtfmt);
621 ca9cc28c balrog
    if (err < 0) {
622 ca9cc28c balrog
        alsa_logerr2 (err, typ, "Failed to get format\n");
623 ca9cc28c balrog
        goto err;
624 ca9cc28c balrog
    }
625 ca9cc28c balrog
626 ca9cc28c balrog
    if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
627 ca9cc28c balrog
        dolog ("Invalid format was returned %d\n", obtfmt);
628 ca9cc28c balrog
        goto err;
629 ca9cc28c balrog
    }
630 ca9cc28c balrog
631 1d14ffa9 bellard
    err = snd_pcm_prepare (handle);
632 1d14ffa9 bellard
    if (err < 0) {
633 c0fe3827 bellard
        alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
634 1d14ffa9 bellard
        goto err;
635 1d14ffa9 bellard
    }
636 1d14ffa9 bellard
637 1d14ffa9 bellard
    if (!in && conf.threshold) {
638 1d14ffa9 bellard
        snd_pcm_uframes_t threshold;
639 1d14ffa9 bellard
        int bytes_per_sec;
640 1d14ffa9 bellard
641 ca9cc28c balrog
        bytes_per_sec = freq << (nchannels == 2);
642 ca9cc28c balrog
643 ca9cc28c balrog
        switch (obt->fmt) {
644 ca9cc28c balrog
        case AUD_FMT_S8:
645 ca9cc28c balrog
        case AUD_FMT_U8:
646 ca9cc28c balrog
            break;
647 ca9cc28c balrog
648 ca9cc28c balrog
        case AUD_FMT_S16:
649 ca9cc28c balrog
        case AUD_FMT_U16:
650 ca9cc28c balrog
            bytes_per_sec <<= 1;
651 ca9cc28c balrog
            break;
652 ca9cc28c balrog
653 ca9cc28c balrog
        case AUD_FMT_S32:
654 ca9cc28c balrog
        case AUD_FMT_U32:
655 ca9cc28c balrog
            bytes_per_sec <<= 2;
656 ca9cc28c balrog
            break;
657 ca9cc28c balrog
        }
658 1d14ffa9 bellard
659 1d14ffa9 bellard
        threshold = (conf.threshold * bytes_per_sec) / 1000;
660 1d14ffa9 bellard
        alsa_set_threshold (handle, threshold);
661 1d14ffa9 bellard
    }
662 1d14ffa9 bellard
663 1d14ffa9 bellard
    obt->nchannels = nchannels;
664 1d14ffa9 bellard
    obt->freq = freq;
665 c0fe3827 bellard
    obt->samples = obt_buffer_size;
666 ca9cc28c balrog
667 1d14ffa9 bellard
    *handlep = handle;
668 1d14ffa9 bellard
669 ca9cc28c balrog
    if (conf.verbose &&
670 8bb414d2 malc
        (obtfmt != req->fmt ||
671 ca9cc28c balrog
         obt->nchannels != req->nchannels ||
672 ca9cc28c balrog
         obt->freq != req->freq)) {
673 f093feb7 Vagrant Cascadian
        dolog ("Audio parameters for %s\n", typ);
674 8bb414d2 malc
        alsa_dump_info (req, obt, obtfmt);
675 1d14ffa9 bellard
    }
676 1d14ffa9 bellard
677 1d14ffa9 bellard
#ifdef DEBUG
678 8bb414d2 malc
    alsa_dump_info (req, obt, obtfmt);
679 1d14ffa9 bellard
#endif
680 1d14ffa9 bellard
    return 0;
681 1d14ffa9 bellard
682 1d14ffa9 bellard
 err:
683 6ebfda13 malc
    alsa_anal_close1 (&handle);
684 1d14ffa9 bellard
    return -1;
685 1d14ffa9 bellard
}
686 1d14ffa9 bellard
687 571ec3d6 bellard
static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
688 571ec3d6 bellard
{
689 571ec3d6 bellard
    snd_pcm_sframes_t avail;
690 571ec3d6 bellard
691 571ec3d6 bellard
    avail = snd_pcm_avail_update (handle);
692 571ec3d6 bellard
    if (avail < 0) {
693 571ec3d6 bellard
        if (avail == -EPIPE) {
694 571ec3d6 bellard
            if (!alsa_recover (handle)) {
695 571ec3d6 bellard
                avail = snd_pcm_avail_update (handle);
696 571ec3d6 bellard
            }
697 571ec3d6 bellard
        }
698 571ec3d6 bellard
699 571ec3d6 bellard
        if (avail < 0) {
700 571ec3d6 bellard
            alsa_logerr (avail,
701 571ec3d6 bellard
                         "Could not obtain number of available frames\n");
702 571ec3d6 bellard
            return -1;
703 571ec3d6 bellard
        }
704 571ec3d6 bellard
    }
705 571ec3d6 bellard
706 571ec3d6 bellard
    return avail;
707 571ec3d6 bellard
}
708 571ec3d6 bellard
709 541ba4e7 malc
static void alsa_write_pending (ALSAVoiceOut *alsa)
710 1d14ffa9 bellard
{
711 541ba4e7 malc
    HWVoiceOut *hw = &alsa->hw;
712 1d14ffa9 bellard
713 541ba4e7 malc
    while (alsa->pending) {
714 541ba4e7 malc
        int left_till_end_samples = hw->samples - alsa->wpos;
715 541ba4e7 malc
        int len = audio_MIN (alsa->pending, left_till_end_samples);
716 541ba4e7 malc
        char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift);
717 1d14ffa9 bellard
718 571ec3d6 bellard
        while (len) {
719 541ba4e7 malc
            snd_pcm_sframes_t written;
720 541ba4e7 malc
721 541ba4e7 malc
            written = snd_pcm_writei (alsa->handle, src, len);
722 4787c71d bellard
723 571ec3d6 bellard
            if (written <= 0) {
724 4787c71d bellard
                switch (written) {
725 571ec3d6 bellard
                case 0:
726 571ec3d6 bellard
                    if (conf.verbose) {
727 571ec3d6 bellard
                        dolog ("Failed to write %d frames (wrote zero)\n", len);
728 4787c71d bellard
                    }
729 541ba4e7 malc
                    return;
730 4787c71d bellard
731 571ec3d6 bellard
                case -EPIPE:
732 571ec3d6 bellard
                    if (alsa_recover (alsa->handle)) {
733 571ec3d6 bellard
                        alsa_logerr (written, "Failed to write %d frames\n",
734 571ec3d6 bellard
                                     len);
735 541ba4e7 malc
                        return;
736 571ec3d6 bellard
                    }
737 571ec3d6 bellard
                    if (conf.verbose) {
738 571ec3d6 bellard
                        dolog ("Recovering from playback xrun\n");
739 571ec3d6 bellard
                    }
740 4787c71d bellard
                    continue;
741 4787c71d bellard
742 86635821 Bjรธrn Mork
                case -ESTRPIPE:
743 86635821 Bjรธrn Mork
                    /* stream is suspended and waiting for an
744 86635821 Bjรธrn Mork
                       application recovery */
745 86635821 Bjรธrn Mork
                    if (alsa_resume (alsa->handle)) {
746 86635821 Bjรธrn Mork
                        alsa_logerr (written, "Failed to write %d frames\n",
747 86635821 Bjรธrn Mork
                                     len);
748 541ba4e7 malc
                        return;
749 86635821 Bjรธrn Mork
                    }
750 86635821 Bjรธrn Mork
                    if (conf.verbose) {
751 86635821 Bjรธrn Mork
                        dolog ("Resuming suspended output stream\n");
752 86635821 Bjรธrn Mork
                    }
753 86635821 Bjรธrn Mork
                    continue;
754 86635821 Bjรธrn Mork
755 571ec3d6 bellard
                case -EAGAIN:
756 541ba4e7 malc
                    return;
757 571ec3d6 bellard
758 4787c71d bellard
                default:
759 541ba4e7 malc
                    alsa_logerr (written, "Failed to write %d frames from %p\n",
760 541ba4e7 malc
                                 len, src);
761 541ba4e7 malc
                    return;
762 1d14ffa9 bellard
                }
763 1d14ffa9 bellard
            }
764 1d14ffa9 bellard
765 541ba4e7 malc
            alsa->wpos = (alsa->wpos + written) % hw->samples;
766 541ba4e7 malc
            alsa->pending -= written;
767 571ec3d6 bellard
            len -= written;
768 4787c71d bellard
        }
769 1d14ffa9 bellard
    }
770 541ba4e7 malc
}
771 541ba4e7 malc
772 bdff253c malc
static int alsa_run_out (HWVoiceOut *hw, int live)
773 541ba4e7 malc
{
774 541ba4e7 malc
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
775 bdff253c malc
    int decr;
776 541ba4e7 malc
    snd_pcm_sframes_t avail;
777 541ba4e7 malc
778 541ba4e7 malc
    avail = alsa_get_avail (alsa->handle);
779 541ba4e7 malc
    if (avail < 0) {
780 541ba4e7 malc
        dolog ("Could not get number of available playback frames\n");
781 541ba4e7 malc
        return 0;
782 541ba4e7 malc
    }
783 541ba4e7 malc
784 541ba4e7 malc
    decr = audio_MIN (live, avail);
785 541ba4e7 malc
    decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending);
786 541ba4e7 malc
    alsa->pending += decr;
787 541ba4e7 malc
    alsa_write_pending (alsa);
788 1d14ffa9 bellard
    return decr;
789 1d14ffa9 bellard
}
790 1d14ffa9 bellard
791 1d14ffa9 bellard
static void alsa_fini_out (HWVoiceOut *hw)
792 1d14ffa9 bellard
{
793 1d14ffa9 bellard
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
794 1d14ffa9 bellard
795 1d14ffa9 bellard
    ldebug ("alsa_fini\n");
796 6ebfda13 malc
    alsa_anal_close (&alsa->handle, &alsa->pollhlp);
797 1d14ffa9 bellard
798 1d14ffa9 bellard
    if (alsa->pcm_buf) {
799 1d14ffa9 bellard
        qemu_free (alsa->pcm_buf);
800 1d14ffa9 bellard
        alsa->pcm_buf = NULL;
801 1d14ffa9 bellard
    }
802 1d14ffa9 bellard
}
803 1d14ffa9 bellard
804 1ea879e5 malc
static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
805 1d14ffa9 bellard
{
806 1d14ffa9 bellard
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
807 1d14ffa9 bellard
    struct alsa_params_req req;
808 1d14ffa9 bellard
    struct alsa_params_obt obt;
809 1d14ffa9 bellard
    snd_pcm_t *handle;
810 1ea879e5 malc
    struct audsettings obt_as;
811 1d14ffa9 bellard
812 c0fe3827 bellard
    req.fmt = aud_to_alsafmt (as->fmt);
813 c0fe3827 bellard
    req.freq = as->freq;
814 c0fe3827 bellard
    req.nchannels = as->nchannels;
815 1d14ffa9 bellard
    req.period_size = conf.period_size_out;
816 1d14ffa9 bellard
    req.buffer_size = conf.buffer_size_out;
817 23fb600b malc
    req.size_in_usec = conf.size_in_usec_out;
818 97f155dd Gerd Hoffmann
    req.override_mask =
819 97f155dd Gerd Hoffmann
        (conf.period_size_out_overridden ? 1 : 0) |
820 97f155dd Gerd Hoffmann
        (conf.buffer_size_out_overridden ? 2 : 0);
821 1d14ffa9 bellard
822 1d14ffa9 bellard
    if (alsa_open (0, &req, &obt, &handle)) {
823 1d14ffa9 bellard
        return -1;
824 1d14ffa9 bellard
    }
825 1d14ffa9 bellard
826 c0fe3827 bellard
    obt_as.freq = obt.freq;
827 c0fe3827 bellard
    obt_as.nchannels = obt.nchannels;
828 ca9cc28c balrog
    obt_as.fmt = obt.fmt;
829 ca9cc28c balrog
    obt_as.endianness = obt.endianness;
830 c0fe3827 bellard
831 d929eba5 bellard
    audio_pcm_init_info (&hw->info, &obt_as);
832 c0fe3827 bellard
    hw->samples = obt.samples;
833 1d14ffa9 bellard
834 c0fe3827 bellard
    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
835 1d14ffa9 bellard
    if (!alsa->pcm_buf) {
836 4787c71d bellard
        dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
837 4787c71d bellard
               hw->samples, 1 << hw->info.shift);
838 6ebfda13 malc
        alsa_anal_close1 (&handle);
839 1d14ffa9 bellard
        return -1;
840 1d14ffa9 bellard
    }
841 1d14ffa9 bellard
842 1d14ffa9 bellard
    alsa->handle = handle;
843 1d14ffa9 bellard
    return 0;
844 1d14ffa9 bellard
}
845 1d14ffa9 bellard
846 571ec3d6 bellard
static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
847 1d14ffa9 bellard
{
848 1d14ffa9 bellard
    int err;
849 571ec3d6 bellard
850 571ec3d6 bellard
    if (pause) {
851 571ec3d6 bellard
        err = snd_pcm_drop (handle);
852 571ec3d6 bellard
        if (err < 0) {
853 32d448c4 bellard
            alsa_logerr (err, "Could not stop %s\n", typ);
854 571ec3d6 bellard
            return -1;
855 571ec3d6 bellard
        }
856 571ec3d6 bellard
    }
857 571ec3d6 bellard
    else {
858 571ec3d6 bellard
        err = snd_pcm_prepare (handle);
859 571ec3d6 bellard
        if (err < 0) {
860 32d448c4 bellard
            alsa_logerr (err, "Could not prepare handle for %s\n", typ);
861 571ec3d6 bellard
            return -1;
862 571ec3d6 bellard
        }
863 571ec3d6 bellard
    }
864 571ec3d6 bellard
865 571ec3d6 bellard
    return 0;
866 571ec3d6 bellard
}
867 571ec3d6 bellard
868 571ec3d6 bellard
static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
869 571ec3d6 bellard
{
870 1d14ffa9 bellard
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
871 1d14ffa9 bellard
872 1d14ffa9 bellard
    switch (cmd) {
873 1d14ffa9 bellard
    case VOICE_ENABLE:
874 301901b5 malc
        {
875 301901b5 malc
            va_list ap;
876 301901b5 malc
            int poll_mode;
877 301901b5 malc
878 301901b5 malc
            va_start (ap, cmd);
879 301901b5 malc
            poll_mode = va_arg (ap, int);
880 301901b5 malc
            va_end (ap);
881 301901b5 malc
882 301901b5 malc
            ldebug ("enabling voice\n");
883 301901b5 malc
            if (poll_mode && alsa_poll_out (hw)) {
884 301901b5 malc
                poll_mode = 0;
885 301901b5 malc
            }
886 301901b5 malc
            hw->poll_mode = poll_mode;
887 301901b5 malc
            return alsa_voice_ctl (alsa->handle, "playback", 0);
888 8b438ba3 malc
        }
889 1d14ffa9 bellard
890 1d14ffa9 bellard
    case VOICE_DISABLE:
891 1d14ffa9 bellard
        ldebug ("disabling voice\n");
892 22d948a2 Jindrich Makovicka
        if (hw->poll_mode) {
893 22d948a2 Jindrich Makovicka
            hw->poll_mode = 0;
894 22d948a2 Jindrich Makovicka
            alsa_fini_poll (&alsa->pollhlp);
895 22d948a2 Jindrich Makovicka
        }
896 571ec3d6 bellard
        return alsa_voice_ctl (alsa->handle, "playback", 1);
897 1d14ffa9 bellard
    }
898 571ec3d6 bellard
899 571ec3d6 bellard
    return -1;
900 1d14ffa9 bellard
}
901 1d14ffa9 bellard
902 1ea879e5 malc
static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
903 1d14ffa9 bellard
{
904 1d14ffa9 bellard
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
905 1d14ffa9 bellard
    struct alsa_params_req req;
906 1d14ffa9 bellard
    struct alsa_params_obt obt;
907 1d14ffa9 bellard
    snd_pcm_t *handle;
908 1ea879e5 malc
    struct audsettings obt_as;
909 1d14ffa9 bellard
910 c0fe3827 bellard
    req.fmt = aud_to_alsafmt (as->fmt);
911 c0fe3827 bellard
    req.freq = as->freq;
912 c0fe3827 bellard
    req.nchannels = as->nchannels;
913 1d14ffa9 bellard
    req.period_size = conf.period_size_in;
914 1d14ffa9 bellard
    req.buffer_size = conf.buffer_size_in;
915 7a24c800 malc
    req.size_in_usec = conf.size_in_usec_in;
916 97f155dd Gerd Hoffmann
    req.override_mask =
917 97f155dd Gerd Hoffmann
        (conf.period_size_in_overridden ? 1 : 0) |
918 97f155dd Gerd Hoffmann
        (conf.buffer_size_in_overridden ? 2 : 0);
919 1d14ffa9 bellard
920 1d14ffa9 bellard
    if (alsa_open (1, &req, &obt, &handle)) {
921 1d14ffa9 bellard
        return -1;
922 1d14ffa9 bellard
    }
923 1d14ffa9 bellard
924 c0fe3827 bellard
    obt_as.freq = obt.freq;
925 c0fe3827 bellard
    obt_as.nchannels = obt.nchannels;
926 ca9cc28c balrog
    obt_as.fmt = obt.fmt;
927 ca9cc28c balrog
    obt_as.endianness = obt.endianness;
928 c0fe3827 bellard
929 d929eba5 bellard
    audio_pcm_init_info (&hw->info, &obt_as);
930 c0fe3827 bellard
    hw->samples = obt.samples;
931 c0fe3827 bellard
932 c0fe3827 bellard
    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
933 1d14ffa9 bellard
    if (!alsa->pcm_buf) {
934 4787c71d bellard
        dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
935 4787c71d bellard
               hw->samples, 1 << hw->info.shift);
936 6ebfda13 malc
        alsa_anal_close1 (&handle);
937 1d14ffa9 bellard
        return -1;
938 1d14ffa9 bellard
    }
939 1d14ffa9 bellard
940 1d14ffa9 bellard
    alsa->handle = handle;
941 1d14ffa9 bellard
    return 0;
942 1d14ffa9 bellard
}
943 1d14ffa9 bellard
944 1d14ffa9 bellard
static void alsa_fini_in (HWVoiceIn *hw)
945 1d14ffa9 bellard
{
946 1d14ffa9 bellard
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
947 1d14ffa9 bellard
948 6ebfda13 malc
    alsa_anal_close (&alsa->handle, &alsa->pollhlp);
949 1d14ffa9 bellard
950 1d14ffa9 bellard
    if (alsa->pcm_buf) {
951 1d14ffa9 bellard
        qemu_free (alsa->pcm_buf);
952 1d14ffa9 bellard
        alsa->pcm_buf = NULL;
953 1d14ffa9 bellard
    }
954 1d14ffa9 bellard
}
955 1d14ffa9 bellard
956 1d14ffa9 bellard
static int alsa_run_in (HWVoiceIn *hw)
957 1d14ffa9 bellard
{
958 1d14ffa9 bellard
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
959 1d14ffa9 bellard
    int hwshift = hw->info.shift;
960 1d14ffa9 bellard
    int i;
961 1d14ffa9 bellard
    int live = audio_pcm_hw_get_live_in (hw);
962 1d14ffa9 bellard
    int dead = hw->samples - live;
963 571ec3d6 bellard
    int decr;
964 1d14ffa9 bellard
    struct {
965 1d14ffa9 bellard
        int add;
966 1d14ffa9 bellard
        int len;
967 1d14ffa9 bellard
    } bufs[2] = {
968 98f9f48c malc
        { .add = hw->wpos, .len = 0 },
969 98f9f48c malc
        { .add = 0,        .len = 0 }
970 1d14ffa9 bellard
    };
971 571ec3d6 bellard
    snd_pcm_sframes_t avail;
972 1d14ffa9 bellard
    snd_pcm_uframes_t read_samples = 0;
973 1d14ffa9 bellard
974 1d14ffa9 bellard
    if (!dead) {
975 1d14ffa9 bellard
        return 0;
976 1d14ffa9 bellard
    }
977 1d14ffa9 bellard
978 571ec3d6 bellard
    avail = alsa_get_avail (alsa->handle);
979 571ec3d6 bellard
    if (avail < 0) {
980 571ec3d6 bellard
        dolog ("Could not get number of captured frames\n");
981 571ec3d6 bellard
        return 0;
982 571ec3d6 bellard
    }
983 571ec3d6 bellard
984 86635821 Bjรธrn Mork
    if (!avail) {
985 86635821 Bjรธrn Mork
        snd_pcm_state_t state;
986 86635821 Bjรธrn Mork
987 86635821 Bjรธrn Mork
        state = snd_pcm_state (alsa->handle);
988 86635821 Bjรธrn Mork
        switch (state) {
989 86635821 Bjรธrn Mork
        case SND_PCM_STATE_PREPARED:
990 86635821 Bjรธrn Mork
            avail = hw->samples;
991 86635821 Bjรธrn Mork
            break;
992 86635821 Bjรธrn Mork
        case SND_PCM_STATE_SUSPENDED:
993 86635821 Bjรธrn Mork
            /* stream is suspended and waiting for an application recovery */
994 86635821 Bjรธrn Mork
            if (alsa_resume (alsa->handle)) {
995 86635821 Bjรธrn Mork
                dolog ("Failed to resume suspended input stream\n");
996 86635821 Bjรธrn Mork
                return 0;
997 86635821 Bjรธrn Mork
            }
998 86635821 Bjรธrn Mork
            if (conf.verbose) {
999 86635821 Bjรธrn Mork
                dolog ("Resuming suspended input stream\n");
1000 86635821 Bjรธrn Mork
            }
1001 86635821 Bjรธrn Mork
            break;
1002 86635821 Bjรธrn Mork
        default:
1003 86635821 Bjรธrn Mork
            if (conf.verbose) {
1004 86635821 Bjรธrn Mork
                dolog ("No frames available and ALSA state is %d\n", state);
1005 86635821 Bjรธrn Mork
            }
1006 86635821 Bjรธrn Mork
            return 0;
1007 86635821 Bjรธrn Mork
        }
1008 571ec3d6 bellard
    }
1009 571ec3d6 bellard
1010 571ec3d6 bellard
    decr = audio_MIN (dead, avail);
1011 571ec3d6 bellard
    if (!decr) {
1012 571ec3d6 bellard
        return 0;
1013 571ec3d6 bellard
    }
1014 571ec3d6 bellard
1015 571ec3d6 bellard
    if (hw->wpos + decr > hw->samples) {
1016 1d14ffa9 bellard
        bufs[0].len = (hw->samples - hw->wpos);
1017 571ec3d6 bellard
        bufs[1].len = (decr - (hw->samples - hw->wpos));
1018 1d14ffa9 bellard
    }
1019 1d14ffa9 bellard
    else {
1020 571ec3d6 bellard
        bufs[0].len = decr;
1021 1d14ffa9 bellard
    }
1022 1d14ffa9 bellard
1023 1d14ffa9 bellard
    for (i = 0; i < 2; ++i) {
1024 1d14ffa9 bellard
        void *src;
1025 1ea879e5 malc
        struct st_sample *dst;
1026 1d14ffa9 bellard
        snd_pcm_sframes_t nread;
1027 1d14ffa9 bellard
        snd_pcm_uframes_t len;
1028 1d14ffa9 bellard
1029 1d14ffa9 bellard
        len = bufs[i].len;
1030 1d14ffa9 bellard
1031 1d14ffa9 bellard
        src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
1032 1d14ffa9 bellard
        dst = hw->conv_buf + bufs[i].add;
1033 1d14ffa9 bellard
1034 1d14ffa9 bellard
        while (len) {
1035 1d14ffa9 bellard
            nread = snd_pcm_readi (alsa->handle, src, len);
1036 1d14ffa9 bellard
1037 571ec3d6 bellard
            if (nread <= 0) {
1038 1d14ffa9 bellard
                switch (nread) {
1039 571ec3d6 bellard
                case 0:
1040 571ec3d6 bellard
                    if (conf.verbose) {
1041 571ec3d6 bellard
                        dolog ("Failed to read %ld frames (read zero)\n", len);
1042 1d14ffa9 bellard
                    }
1043 1d14ffa9 bellard
                    goto exit;
1044 1d14ffa9 bellard
1045 571ec3d6 bellard
                case -EPIPE:
1046 571ec3d6 bellard
                    if (alsa_recover (alsa->handle)) {
1047 571ec3d6 bellard
                        alsa_logerr (nread, "Failed to read %ld frames\n", len);
1048 571ec3d6 bellard
                        goto exit;
1049 571ec3d6 bellard
                    }
1050 571ec3d6 bellard
                    if (conf.verbose) {
1051 571ec3d6 bellard
                        dolog ("Recovering from capture xrun\n");
1052 571ec3d6 bellard
                    }
1053 1d14ffa9 bellard
                    continue;
1054 1d14ffa9 bellard
1055 571ec3d6 bellard
                case -EAGAIN:
1056 571ec3d6 bellard
                    goto exit;
1057 571ec3d6 bellard
1058 1d14ffa9 bellard
                default:
1059 1d14ffa9 bellard
                    alsa_logerr (
1060 1d14ffa9 bellard
                        nread,
1061 1d14ffa9 bellard
                        "Failed to read %ld frames from %p\n",
1062 1d14ffa9 bellard
                        len,
1063 1d14ffa9 bellard
                        src
1064 1d14ffa9 bellard
                        );
1065 1d14ffa9 bellard
                    goto exit;
1066 1d14ffa9 bellard
                }
1067 1d14ffa9 bellard
            }
1068 1d14ffa9 bellard
1069 1d14ffa9 bellard
            hw->conv (dst, src, nread, &nominal_volume);
1070 1d14ffa9 bellard
1071 1d14ffa9 bellard
            src = advance (src, nread << hwshift);
1072 1d14ffa9 bellard
            dst += nread;
1073 1d14ffa9 bellard
1074 1d14ffa9 bellard
            read_samples += nread;
1075 1d14ffa9 bellard
            len -= nread;
1076 1d14ffa9 bellard
        }
1077 1d14ffa9 bellard
    }
1078 1d14ffa9 bellard
1079 1d14ffa9 bellard
 exit:
1080 1d14ffa9 bellard
    hw->wpos = (hw->wpos + read_samples) % hw->samples;
1081 1d14ffa9 bellard
    return read_samples;
1082 1d14ffa9 bellard
}
1083 1d14ffa9 bellard
1084 1d14ffa9 bellard
static int alsa_read (SWVoiceIn *sw, void *buf, int size)
1085 1d14ffa9 bellard
{
1086 1d14ffa9 bellard
    return audio_pcm_sw_read (sw, buf, size);
1087 1d14ffa9 bellard
}
1088 1d14ffa9 bellard
1089 1d14ffa9 bellard
static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
1090 1d14ffa9 bellard
{
1091 571ec3d6 bellard
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
1092 571ec3d6 bellard
1093 571ec3d6 bellard
    switch (cmd) {
1094 571ec3d6 bellard
    case VOICE_ENABLE:
1095 a628b869 malc
        {
1096 a628b869 malc
            va_list ap;
1097 a628b869 malc
            int poll_mode;
1098 8b438ba3 malc
1099 a628b869 malc
            va_start (ap, cmd);
1100 a628b869 malc
            poll_mode = va_arg (ap, int);
1101 a628b869 malc
            va_end (ap);
1102 a628b869 malc
1103 a628b869 malc
            ldebug ("enabling voice\n");
1104 a628b869 malc
            if (poll_mode && alsa_poll_in (hw)) {
1105 a628b869 malc
                poll_mode = 0;
1106 a628b869 malc
            }
1107 a628b869 malc
            hw->poll_mode = poll_mode;
1108 a628b869 malc
1109 a628b869 malc
            return alsa_voice_ctl (alsa->handle, "capture", 0);
1110 a628b869 malc
        }
1111 571ec3d6 bellard
1112 571ec3d6 bellard
    case VOICE_DISABLE:
1113 571ec3d6 bellard
        ldebug ("disabling voice\n");
1114 8b438ba3 malc
        if (hw->poll_mode) {
1115 8b438ba3 malc
            hw->poll_mode = 0;
1116 8b438ba3 malc
            alsa_fini_poll (&alsa->pollhlp);
1117 8b438ba3 malc
        }
1118 571ec3d6 bellard
        return alsa_voice_ctl (alsa->handle, "capture", 1);
1119 571ec3d6 bellard
    }
1120 571ec3d6 bellard
1121 571ec3d6 bellard
    return -1;
1122 1d14ffa9 bellard
}
1123 1d14ffa9 bellard
1124 1d14ffa9 bellard
static void *alsa_audio_init (void)
1125 1d14ffa9 bellard
{
1126 1d14ffa9 bellard
    return &conf;
1127 1d14ffa9 bellard
}
1128 1d14ffa9 bellard
1129 1d14ffa9 bellard
static void alsa_audio_fini (void *opaque)
1130 1d14ffa9 bellard
{
1131 1d14ffa9 bellard
    (void) opaque;
1132 1d14ffa9 bellard
}
1133 1d14ffa9 bellard
1134 1d14ffa9 bellard
static struct audio_option alsa_options[] = {
1135 98f9f48c malc
    {
1136 98f9f48c malc
        .name        = "DAC_SIZE_IN_USEC",
1137 98f9f48c malc
        .tag         = AUD_OPT_BOOL,
1138 98f9f48c malc
        .valp        = &conf.size_in_usec_out,
1139 98f9f48c malc
        .descr       = "DAC period/buffer size in microseconds (otherwise in frames)"
1140 98f9f48c malc
    },
1141 98f9f48c malc
    {
1142 98f9f48c malc
        .name        = "DAC_PERIOD_SIZE",
1143 98f9f48c malc
        .tag         = AUD_OPT_INT,
1144 98f9f48c malc
        .valp        = &conf.period_size_out,
1145 98f9f48c malc
        .descr       = "DAC period size (0 to go with system default)",
1146 98f9f48c malc
        .overriddenp = &conf.period_size_out_overridden
1147 98f9f48c malc
    },
1148 98f9f48c malc
    {
1149 98f9f48c malc
        .name        = "DAC_BUFFER_SIZE",
1150 98f9f48c malc
        .tag         = AUD_OPT_INT,
1151 98f9f48c malc
        .valp        = &conf.buffer_size_out,
1152 98f9f48c malc
        .descr       = "DAC buffer size (0 to go with system default)",
1153 98f9f48c malc
        .overriddenp = &conf.buffer_size_out_overridden
1154 98f9f48c malc
    },
1155 98f9f48c malc
    {
1156 98f9f48c malc
        .name        = "ADC_SIZE_IN_USEC",
1157 98f9f48c malc
        .tag         = AUD_OPT_BOOL,
1158 98f9f48c malc
        .valp        = &conf.size_in_usec_in,
1159 98f9f48c malc
        .descr       =
1160 98f9f48c malc
        "ADC period/buffer size in microseconds (otherwise in frames)"
1161 98f9f48c malc
    },
1162 98f9f48c malc
    {
1163 98f9f48c malc
        .name        = "ADC_PERIOD_SIZE",
1164 98f9f48c malc
        .tag         = AUD_OPT_INT,
1165 98f9f48c malc
        .valp        = &conf.period_size_in,
1166 98f9f48c malc
        .descr       = "ADC period size (0 to go with system default)",
1167 98f9f48c malc
        .overriddenp = &conf.period_size_in_overridden
1168 98f9f48c malc
    },
1169 98f9f48c malc
    {
1170 98f9f48c malc
        .name        = "ADC_BUFFER_SIZE",
1171 98f9f48c malc
        .tag         = AUD_OPT_INT,
1172 98f9f48c malc
        .valp        = &conf.buffer_size_in,
1173 98f9f48c malc
        .descr       = "ADC buffer size (0 to go with system default)",
1174 98f9f48c malc
        .overriddenp = &conf.buffer_size_in_overridden
1175 98f9f48c malc
    },
1176 98f9f48c malc
    {
1177 98f9f48c malc
        .name        = "THRESHOLD",
1178 98f9f48c malc
        .tag         = AUD_OPT_INT,
1179 98f9f48c malc
        .valp        = &conf.threshold,
1180 98f9f48c malc
        .descr       = "(undocumented)"
1181 98f9f48c malc
    },
1182 98f9f48c malc
    {
1183 98f9f48c malc
        .name        = "DAC_DEV",
1184 98f9f48c malc
        .tag         = AUD_OPT_STR,
1185 98f9f48c malc
        .valp        = &conf.pcm_name_out,
1186 98f9f48c malc
        .descr       = "DAC device name (for instance dmix)"
1187 98f9f48c malc
    },
1188 98f9f48c malc
    {
1189 98f9f48c malc
        .name        = "ADC_DEV",
1190 98f9f48c malc
        .tag         = AUD_OPT_STR,
1191 98f9f48c malc
        .valp        = &conf.pcm_name_in,
1192 98f9f48c malc
        .descr       = "ADC device name"
1193 98f9f48c malc
    },
1194 98f9f48c malc
    {
1195 98f9f48c malc
        .name        = "VERBOSE",
1196 98f9f48c malc
        .tag         = AUD_OPT_BOOL,
1197 98f9f48c malc
        .valp        = &conf.verbose,
1198 98f9f48c malc
        .descr       = "Behave in a more verbose way"
1199 98f9f48c malc
    },
1200 2700efa3 Juan Quintela
    { /* End of list */ }
1201 1d14ffa9 bellard
};
1202 1d14ffa9 bellard
1203 35f4b58c blueswir1
static struct audio_pcm_ops alsa_pcm_ops = {
1204 1dd3e4d1 Juan Quintela
    .init_out = alsa_init_out,
1205 1dd3e4d1 Juan Quintela
    .fini_out = alsa_fini_out,
1206 1dd3e4d1 Juan Quintela
    .run_out  = alsa_run_out,
1207 1dd3e4d1 Juan Quintela
    .write    = alsa_write,
1208 1dd3e4d1 Juan Quintela
    .ctl_out  = alsa_ctl_out,
1209 1dd3e4d1 Juan Quintela
1210 1dd3e4d1 Juan Quintela
    .init_in  = alsa_init_in,
1211 1dd3e4d1 Juan Quintela
    .fini_in  = alsa_fini_in,
1212 1dd3e4d1 Juan Quintela
    .run_in   = alsa_run_in,
1213 1dd3e4d1 Juan Quintela
    .read     = alsa_read,
1214 8b438ba3 malc
    .ctl_in   = alsa_ctl_in,
1215 1d14ffa9 bellard
};
1216 1d14ffa9 bellard
1217 1d14ffa9 bellard
struct audio_driver alsa_audio_driver = {
1218 bee37f32 Juan Quintela
    .name           = "alsa",
1219 bee37f32 Juan Quintela
    .descr          = "ALSA http://www.alsa-project.org",
1220 bee37f32 Juan Quintela
    .options        = alsa_options,
1221 bee37f32 Juan Quintela
    .init           = alsa_audio_init,
1222 bee37f32 Juan Quintela
    .fini           = alsa_audio_fini,
1223 bee37f32 Juan Quintela
    .pcm_ops        = &alsa_pcm_ops,
1224 bee37f32 Juan Quintela
    .can_be_default = 1,
1225 bee37f32 Juan Quintela
    .max_voices_out = INT_MAX,
1226 bee37f32 Juan Quintela
    .max_voices_in  = INT_MAX,
1227 bee37f32 Juan Quintela
    .voice_size_out = sizeof (ALSAVoiceOut),
1228 bee37f32 Juan Quintela
    .voice_size_in  = sizeof (ALSAVoiceIn)
1229 1d14ffa9 bellard
};