Statistics
| Branch: | Revision:

root / audio / alsaaudio.c @ 22d948a2

History | View | Annotate | Download (31.7 kB)

1
/*
2
 * QEMU ALSA audio driver
3
 *
4
 * Copyright (c) 2005 Vassili Karpov (malc)
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include <alsa/asoundlib.h>
25
#include "qemu-common.h"
26
#include "qemu-char.h"
27
#include "audio.h"
28

    
29
#if QEMU_GNUC_PREREQ(4, 3)
30
#pragma GCC diagnostic ignored "-Waddress"
31
#endif
32

    
33
#define AUDIO_CAP "alsa"
34
#include "audio_int.h"
35

    
36
struct pollhlp {
37
    snd_pcm_t *handle;
38
    struct pollfd *pfds;
39
    int count;
40
    int mask;
41
};
42

    
43
typedef struct ALSAVoiceOut {
44
    HWVoiceOut hw;
45
    int wpos;
46
    int pending;
47
    void *pcm_buf;
48
    snd_pcm_t *handle;
49
    struct pollhlp pollhlp;
50
} ALSAVoiceOut;
51

    
52
typedef struct ALSAVoiceIn {
53
    HWVoiceIn hw;
54
    snd_pcm_t *handle;
55
    void *pcm_buf;
56
    struct pollhlp pollhlp;
57
} ALSAVoiceIn;
58

    
59
static struct {
60
    int size_in_usec_in;
61
    int size_in_usec_out;
62
    const char *pcm_name_in;
63
    const char *pcm_name_out;
64
    unsigned int buffer_size_in;
65
    unsigned int period_size_in;
66
    unsigned int buffer_size_out;
67
    unsigned int period_size_out;
68
    unsigned int threshold;
69

    
70
    int buffer_size_in_overridden;
71
    int period_size_in_overridden;
72

    
73
    int buffer_size_out_overridden;
74
    int period_size_out_overridden;
75
    int verbose;
76
} conf = {
77
    .buffer_size_out = 4096,
78
    .period_size_out = 1024,
79
    .pcm_name_out = "default",
80
    .pcm_name_in = "default",
81
};
82

    
83
struct alsa_params_req {
84
    int freq;
85
    snd_pcm_format_t fmt;
86
    int nchannels;
87
    int size_in_usec;
88
    int override_mask;
89
    unsigned int buffer_size;
90
    unsigned int period_size;
91
};
92

    
93
struct alsa_params_obt {
94
    int freq;
95
    audfmt_e fmt;
96
    int endianness;
97
    int nchannels;
98
    snd_pcm_uframes_t samples;
99
};
100

    
101
static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
102
{
103
    va_list ap;
104

    
105
    va_start (ap, fmt);
106
    AUD_vlog (AUDIO_CAP, fmt, ap);
107
    va_end (ap);
108

    
109
    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
110
}
111

    
112
static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
113
    int err,
114
    const char *typ,
115
    const char *fmt,
116
    ...
117
    )
118
{
119
    va_list ap;
120

    
121
    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
122

    
123
    va_start (ap, fmt);
124
    AUD_vlog (AUDIO_CAP, fmt, ap);
125
    va_end (ap);
126

    
127
    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
128
}
129

    
130
static void alsa_fini_poll (struct pollhlp *hlp)
131
{
132
    int i;
133
    struct pollfd *pfds = hlp->pfds;
134

    
135
    if (pfds) {
136
        for (i = 0; i < hlp->count; ++i) {
137
            qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
138
        }
139
        qemu_free (pfds);
140
    }
141
    hlp->pfds = NULL;
142
    hlp->count = 0;
143
    hlp->handle = NULL;
144
}
145

    
146
static void alsa_anal_close1 (snd_pcm_t **handlep)
147
{
148
    int err = snd_pcm_close (*handlep);
149
    if (err) {
150
        alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
151
    }
152
    *handlep = NULL;
153
}
154

    
155
static void alsa_anal_close (snd_pcm_t **handlep, struct pollhlp *hlp)
156
{
157
    alsa_fini_poll (hlp);
158
    alsa_anal_close1 (handlep);
159
}
160

    
161
static int alsa_recover (snd_pcm_t *handle)
162
{
163
    int err = snd_pcm_prepare (handle);
164
    if (err < 0) {
165
        alsa_logerr (err, "Failed to prepare handle %p\n", handle);
166
        return -1;
167
    }
168
    return 0;
169
}
170

    
171
static int alsa_resume (snd_pcm_t *handle)
172
{
173
    int err = snd_pcm_resume (handle);
174
    if (err < 0) {
175
        alsa_logerr (err, "Failed to resume handle %p\n", handle);
176
        return -1;
177
    }
178
    return 0;
179
}
180

    
181
static void alsa_poll_handler (void *opaque)
182
{
183
    int err, count;
184
    snd_pcm_state_t state;
185
    struct pollhlp *hlp = opaque;
186
    unsigned short revents;
187

    
188
    count = poll (hlp->pfds, hlp->count, 0);
189
    if (count < 0) {
190
        dolog ("alsa_poll_handler: poll %s\n", strerror (errno));
191
        return;
192
    }
193

    
194
    if (!count) {
195
        return;
196
    }
197

    
198
    /* XXX: ALSA example uses initial count, not the one returned by
199
       poll, correct? */
200
    err = snd_pcm_poll_descriptors_revents (hlp->handle, hlp->pfds,
201
                                            hlp->count, &revents);
202
    if (err < 0) {
203
        alsa_logerr (err, "snd_pcm_poll_descriptors_revents");
204
        return;
205
    }
206

    
207
    if (!(revents & hlp->mask)) {
208
        if (conf.verbose) {
209
            dolog ("revents = %d\n", revents);
210
        }
211
        return;
212
    }
213

    
214
    state = snd_pcm_state (hlp->handle);
215
    switch (state) {
216
    case SND_PCM_STATE_SETUP:
217
        alsa_recover (hlp->handle);
218
        break;
219

    
220
    case SND_PCM_STATE_XRUN:
221
        alsa_recover (hlp->handle);
222
        break;
223

    
224
    case SND_PCM_STATE_SUSPENDED:
225
        alsa_resume (hlp->handle);
226
        break;
227

    
228
    case SND_PCM_STATE_PREPARED:
229
        audio_run ("alsa run (prepared)");
230
        break;
231

    
232
    case SND_PCM_STATE_RUNNING:
233
        audio_run ("alsa run (running)");
234
        break;
235

    
236
    default:
237
        dolog ("Unexpected state %d\n", state);
238
    }
239
}
240

    
241
static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
242
{
243
    int i, count, err;
244
    struct pollfd *pfds;
245

    
246
    count = snd_pcm_poll_descriptors_count (handle);
247
    if (count <= 0) {
248
        dolog ("Could not initialize poll mode\n"
249
               "Invalid number of poll descriptors %d\n", count);
250
        return -1;
251
    }
252

    
253
    pfds = audio_calloc ("alsa_poll_helper", count, sizeof (*pfds));
254
    if (!pfds) {
255
        dolog ("Could not initialize poll mode\n");
256
        return -1;
257
    }
258

    
259
    err = snd_pcm_poll_descriptors (handle, pfds, count);
260
    if (err < 0) {
261
        alsa_logerr (err, "Could not initialize poll mode\n"
262
                     "Could not obtain poll descriptors\n");
263
        qemu_free (pfds);
264
        return -1;
265
    }
266

    
267
    for (i = 0; i < count; ++i) {
268
        if (pfds[i].events & POLLIN) {
269
            err = qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler,
270
                                       NULL, hlp);
271
        }
272
        if (pfds[i].events & POLLOUT) {
273
            if (conf.verbose) {
274
                dolog ("POLLOUT %d %d\n", i, pfds[i].fd);
275
            }
276
            err = qemu_set_fd_handler (pfds[i].fd, NULL,
277
                                       alsa_poll_handler, hlp);
278
        }
279
        if (conf.verbose) {
280
            dolog ("Set handler events=%#x index=%d fd=%d err=%d\n",
281
                   pfds[i].events, i, pfds[i].fd, err);
282
        }
283

    
284
        if (err) {
285
            dolog ("Failed to set handler events=%#x index=%d fd=%d err=%d\n",
286
                   pfds[i].events, i, pfds[i].fd, err);
287

    
288
            while (i--) {
289
                qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
290
            }
291
            qemu_free (pfds);
292
            return -1;
293
        }
294
    }
295
    hlp->pfds = pfds;
296
    hlp->count = count;
297
    hlp->handle = handle;
298
    hlp->mask = mask;
299
    return 0;
300
}
301

    
302
static int alsa_poll_out (HWVoiceOut *hw)
303
{
304
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
305

    
306
    return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLOUT);
307
}
308

    
309
static int alsa_poll_in (HWVoiceIn *hw)
310
{
311
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
312

    
313
    return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN);
314
}
315

    
316
static int alsa_write (SWVoiceOut *sw, void *buf, int len)
317
{
318
    return audio_pcm_sw_write (sw, buf, len);
319
}
320

    
321
static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt)
322
{
323
    switch (fmt) {
324
    case AUD_FMT_S8:
325
        return SND_PCM_FORMAT_S8;
326

    
327
    case AUD_FMT_U8:
328
        return SND_PCM_FORMAT_U8;
329

    
330
    case AUD_FMT_S16:
331
        return SND_PCM_FORMAT_S16_LE;
332

    
333
    case AUD_FMT_U16:
334
        return SND_PCM_FORMAT_U16_LE;
335

    
336
    case AUD_FMT_S32:
337
        return SND_PCM_FORMAT_S32_LE;
338

    
339
    case AUD_FMT_U32:
340
        return SND_PCM_FORMAT_U32_LE;
341

    
342
    default:
343
        dolog ("Internal logic error: Bad audio format %d\n", fmt);
344
#ifdef DEBUG_AUDIO
345
        abort ();
346
#endif
347
        return SND_PCM_FORMAT_U8;
348
    }
349
}
350

    
351
static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
352
                           int *endianness)
353
{
354
    switch (alsafmt) {
355
    case SND_PCM_FORMAT_S8:
356
        *endianness = 0;
357
        *fmt = AUD_FMT_S8;
358
        break;
359

    
360
    case SND_PCM_FORMAT_U8:
361
        *endianness = 0;
362
        *fmt = AUD_FMT_U8;
363
        break;
364

    
365
    case SND_PCM_FORMAT_S16_LE:
366
        *endianness = 0;
367
        *fmt = AUD_FMT_S16;
368
        break;
369

    
370
    case SND_PCM_FORMAT_U16_LE:
371
        *endianness = 0;
372
        *fmt = AUD_FMT_U16;
373
        break;
374

    
375
    case SND_PCM_FORMAT_S16_BE:
376
        *endianness = 1;
377
        *fmt = AUD_FMT_S16;
378
        break;
379

    
380
    case SND_PCM_FORMAT_U16_BE:
381
        *endianness = 1;
382
        *fmt = AUD_FMT_U16;
383
        break;
384

    
385
    case SND_PCM_FORMAT_S32_LE:
386
        *endianness = 0;
387
        *fmt = AUD_FMT_S32;
388
        break;
389

    
390
    case SND_PCM_FORMAT_U32_LE:
391
        *endianness = 0;
392
        *fmt = AUD_FMT_U32;
393
        break;
394

    
395
    case SND_PCM_FORMAT_S32_BE:
396
        *endianness = 1;
397
        *fmt = AUD_FMT_S32;
398
        break;
399

    
400
    case SND_PCM_FORMAT_U32_BE:
401
        *endianness = 1;
402
        *fmt = AUD_FMT_U32;
403
        break;
404

    
405
    default:
406
        dolog ("Unrecognized audio format %d\n", alsafmt);
407
        return -1;
408
    }
409

    
410
    return 0;
411
}
412

    
413
static void alsa_dump_info (struct alsa_params_req *req,
414
                            struct alsa_params_obt *obt,
415
                            snd_pcm_format_t obtfmt)
416
{
417
    dolog ("parameter | requested value | obtained value\n");
418
    dolog ("format    |      %10d |     %10d\n", req->fmt, obtfmt);
419
    dolog ("channels  |      %10d |     %10d\n",
420
           req->nchannels, obt->nchannels);
421
    dolog ("frequency |      %10d |     %10d\n", req->freq, obt->freq);
422
    dolog ("============================================\n");
423
    dolog ("requested: buffer size %d period size %d\n",
424
           req->buffer_size, req->period_size);
425
    dolog ("obtained: samples %ld\n", obt->samples);
426
}
427

    
428
static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
429
{
430
    int err;
431
    snd_pcm_sw_params_t *sw_params;
432

    
433
    snd_pcm_sw_params_alloca (&sw_params);
434

    
435
    err = snd_pcm_sw_params_current (handle, sw_params);
436
    if (err < 0) {
437
        dolog ("Could not fully initialize DAC\n");
438
        alsa_logerr (err, "Failed to get current software parameters\n");
439
        return;
440
    }
441

    
442
    err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
443
    if (err < 0) {
444
        dolog ("Could not fully initialize DAC\n");
445
        alsa_logerr (err, "Failed to set software threshold to %ld\n",
446
                     threshold);
447
        return;
448
    }
449

    
450
    err = snd_pcm_sw_params (handle, sw_params);
451
    if (err < 0) {
452
        dolog ("Could not fully initialize DAC\n");
453
        alsa_logerr (err, "Failed to set software parameters\n");
454
        return;
455
    }
456
}
457

    
458
static int alsa_open (int in, struct alsa_params_req *req,
459
                      struct alsa_params_obt *obt, snd_pcm_t **handlep)
460
{
461
    snd_pcm_t *handle;
462
    snd_pcm_hw_params_t *hw_params;
463
    int err;
464
    int size_in_usec;
465
    unsigned int freq, nchannels;
466
    const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
467
    snd_pcm_uframes_t obt_buffer_size;
468
    const char *typ = in ? "ADC" : "DAC";
469
    snd_pcm_format_t obtfmt;
470

    
471
    freq = req->freq;
472
    nchannels = req->nchannels;
473
    size_in_usec = req->size_in_usec;
474

    
475
    snd_pcm_hw_params_alloca (&hw_params);
476

    
477
    err = snd_pcm_open (
478
        &handle,
479
        pcm_name,
480
        in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
481
        SND_PCM_NONBLOCK
482
        );
483
    if (err < 0) {
484
        alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
485
        return -1;
486
    }
487

    
488
    err = snd_pcm_hw_params_any (handle, hw_params);
489
    if (err < 0) {
490
        alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
491
        goto err;
492
    }
493

    
494
    err = snd_pcm_hw_params_set_access (
495
        handle,
496
        hw_params,
497
        SND_PCM_ACCESS_RW_INTERLEAVED
498
        );
499
    if (err < 0) {
500
        alsa_logerr2 (err, typ, "Failed to set access type\n");
501
        goto err;
502
    }
503

    
504
    err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
505
    if (err < 0 && conf.verbose) {
506
        alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
507
    }
508

    
509
    err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
510
    if (err < 0) {
511
        alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
512
        goto err;
513
    }
514

    
515
    err = snd_pcm_hw_params_set_channels_near (
516
        handle,
517
        hw_params,
518
        &nchannels
519
        );
520
    if (err < 0) {
521
        alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
522
                      req->nchannels);
523
        goto err;
524
    }
525

    
526
    if (nchannels != 1 && nchannels != 2) {
527
        alsa_logerr2 (err, typ,
528
                      "Can not handle obtained number of channels %d\n",
529
                      nchannels);
530
        goto err;
531
    }
532

    
533
    if (req->buffer_size) {
534
        unsigned long obt;
535

    
536
        if (size_in_usec) {
537
            int dir = 0;
538
            unsigned int btime = req->buffer_size;
539

    
540
            err = snd_pcm_hw_params_set_buffer_time_near (
541
                handle,
542
                hw_params,
543
                &btime,
544
                &dir
545
                );
546
            obt = btime;
547
        }
548
        else {
549
            snd_pcm_uframes_t bsize = req->buffer_size;
550

    
551
            err = snd_pcm_hw_params_set_buffer_size_near (
552
                handle,
553
                hw_params,
554
                &bsize
555
                );
556
            obt = bsize;
557
        }
558
        if (err < 0) {
559
            alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
560
                          size_in_usec ? "time" : "size", req->buffer_size);
561
            goto err;
562
        }
563

    
564
        if ((req->override_mask & 2) && (obt - req->buffer_size))
565
            dolog ("Requested buffer %s %u was rejected, using %lu\n",
566
                   size_in_usec ? "time" : "size", req->buffer_size, obt);
567
    }
568

    
569
    if (req->period_size) {
570
        unsigned long obt;
571

    
572
        if (size_in_usec) {
573
            int dir = 0;
574
            unsigned int ptime = req->period_size;
575

    
576
            err = snd_pcm_hw_params_set_period_time_near (
577
                handle,
578
                hw_params,
579
                &ptime,
580
                &dir
581
                );
582
            obt = ptime;
583
        }
584
        else {
585
            int dir = 0;
586
            snd_pcm_uframes_t psize = req->period_size;
587

    
588
            err = snd_pcm_hw_params_set_period_size_near (
589
                handle,
590
                hw_params,
591
                &psize,
592
                &dir
593
                );
594
            obt = psize;
595
        }
596

    
597
        if (err < 0) {
598
            alsa_logerr2 (err, typ, "Failed to set period %s to %d\n",
599
                          size_in_usec ? "time" : "size", req->period_size);
600
            goto err;
601
        }
602

    
603
        if (((req->override_mask & 1) && (obt - req->period_size)))
604
            dolog ("Requested period %s %u was rejected, using %lu\n",
605
                   size_in_usec ? "time" : "size", req->period_size, obt);
606
    }
607

    
608
    err = snd_pcm_hw_params (handle, hw_params);
609
    if (err < 0) {
610
        alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
611
        goto err;
612
    }
613

    
614
    err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
615
    if (err < 0) {
616
        alsa_logerr2 (err, typ, "Failed to get buffer size\n");
617
        goto err;
618
    }
619

    
620
    err = snd_pcm_hw_params_get_format (hw_params, &obtfmt);
621
    if (err < 0) {
622
        alsa_logerr2 (err, typ, "Failed to get format\n");
623
        goto err;
624
    }
625

    
626
    if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
627
        dolog ("Invalid format was returned %d\n", obtfmt);
628
        goto err;
629
    }
630

    
631
    err = snd_pcm_prepare (handle);
632
    if (err < 0) {
633
        alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
634
        goto err;
635
    }
636

    
637
    if (!in && conf.threshold) {
638
        snd_pcm_uframes_t threshold;
639
        int bytes_per_sec;
640

    
641
        bytes_per_sec = freq << (nchannels == 2);
642

    
643
        switch (obt->fmt) {
644
        case AUD_FMT_S8:
645
        case AUD_FMT_U8:
646
            break;
647

    
648
        case AUD_FMT_S16:
649
        case AUD_FMT_U16:
650
            bytes_per_sec <<= 1;
651
            break;
652

    
653
        case AUD_FMT_S32:
654
        case AUD_FMT_U32:
655
            bytes_per_sec <<= 2;
656
            break;
657
        }
658

    
659
        threshold = (conf.threshold * bytes_per_sec) / 1000;
660
        alsa_set_threshold (handle, threshold);
661
    }
662

    
663
    obt->nchannels = nchannels;
664
    obt->freq = freq;
665
    obt->samples = obt_buffer_size;
666

    
667
    *handlep = handle;
668

    
669
    if (conf.verbose &&
670
        (obtfmt != req->fmt ||
671
         obt->nchannels != req->nchannels ||
672
         obt->freq != req->freq)) {
673
        dolog ("Audio parameters for %s\n", typ);
674
        alsa_dump_info (req, obt, obtfmt);
675
    }
676

    
677
#ifdef DEBUG
678
    alsa_dump_info (req, obt, obtfmt);
679
#endif
680
    return 0;
681

    
682
 err:
683
    alsa_anal_close1 (&handle);
684
    return -1;
685
}
686

    
687
static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
688
{
689
    snd_pcm_sframes_t avail;
690

    
691
    avail = snd_pcm_avail_update (handle);
692
    if (avail < 0) {
693
        if (avail == -EPIPE) {
694
            if (!alsa_recover (handle)) {
695
                avail = snd_pcm_avail_update (handle);
696
            }
697
        }
698

    
699
        if (avail < 0) {
700
            alsa_logerr (avail,
701
                         "Could not obtain number of available frames\n");
702
            return -1;
703
        }
704
    }
705

    
706
    return avail;
707
}
708

    
709
static void alsa_write_pending (ALSAVoiceOut *alsa)
710
{
711
    HWVoiceOut *hw = &alsa->hw;
712

    
713
    while (alsa->pending) {
714
        int left_till_end_samples = hw->samples - alsa->wpos;
715
        int len = audio_MIN (alsa->pending, left_till_end_samples);
716
        char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift);
717

    
718
        while (len) {
719
            snd_pcm_sframes_t written;
720

    
721
            written = snd_pcm_writei (alsa->handle, src, len);
722

    
723
            if (written <= 0) {
724
                switch (written) {
725
                case 0:
726
                    if (conf.verbose) {
727
                        dolog ("Failed to write %d frames (wrote zero)\n", len);
728
                    }
729
                    return;
730

    
731
                case -EPIPE:
732
                    if (alsa_recover (alsa->handle)) {
733
                        alsa_logerr (written, "Failed to write %d frames\n",
734
                                     len);
735
                        return;
736
                    }
737
                    if (conf.verbose) {
738
                        dolog ("Recovering from playback xrun\n");
739
                    }
740
                    continue;
741

    
742
                case -ESTRPIPE:
743
                    /* stream is suspended and waiting for an
744
                       application recovery */
745
                    if (alsa_resume (alsa->handle)) {
746
                        alsa_logerr (written, "Failed to write %d frames\n",
747
                                     len);
748
                        return;
749
                    }
750
                    if (conf.verbose) {
751
                        dolog ("Resuming suspended output stream\n");
752
                    }
753
                    continue;
754

    
755
                case -EAGAIN:
756
                    return;
757

    
758
                default:
759
                    alsa_logerr (written, "Failed to write %d frames from %p\n",
760
                                 len, src);
761
                    return;
762
                }
763
            }
764

    
765
            alsa->wpos = (alsa->wpos + written) % hw->samples;
766
            alsa->pending -= written;
767
            len -= written;
768
        }
769
    }
770
}
771

    
772
static int alsa_run_out (HWVoiceOut *hw, int live)
773
{
774
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
775
    int decr;
776
    snd_pcm_sframes_t avail;
777

    
778
    avail = alsa_get_avail (alsa->handle);
779
    if (avail < 0) {
780
        dolog ("Could not get number of available playback frames\n");
781
        return 0;
782
    }
783

    
784
    decr = audio_MIN (live, avail);
785
    decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending);
786
    alsa->pending += decr;
787
    alsa_write_pending (alsa);
788
    return decr;
789
}
790

    
791
static void alsa_fini_out (HWVoiceOut *hw)
792
{
793
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
794

    
795
    ldebug ("alsa_fini\n");
796
    alsa_anal_close (&alsa->handle, &alsa->pollhlp);
797

    
798
    if (alsa->pcm_buf) {
799
        qemu_free (alsa->pcm_buf);
800
        alsa->pcm_buf = NULL;
801
    }
802
}
803

    
804
static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
805
{
806
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
807
    struct alsa_params_req req;
808
    struct alsa_params_obt obt;
809
    snd_pcm_t *handle;
810
    struct audsettings obt_as;
811

    
812
    req.fmt = aud_to_alsafmt (as->fmt);
813
    req.freq = as->freq;
814
    req.nchannels = as->nchannels;
815
    req.period_size = conf.period_size_out;
816
    req.buffer_size = conf.buffer_size_out;
817
    req.size_in_usec = conf.size_in_usec_out;
818
    req.override_mask =
819
        (conf.period_size_out_overridden ? 1 : 0) |
820
        (conf.buffer_size_out_overridden ? 2 : 0);
821

    
822
    if (alsa_open (0, &req, &obt, &handle)) {
823
        return -1;
824
    }
825

    
826
    obt_as.freq = obt.freq;
827
    obt_as.nchannels = obt.nchannels;
828
    obt_as.fmt = obt.fmt;
829
    obt_as.endianness = obt.endianness;
830

    
831
    audio_pcm_init_info (&hw->info, &obt_as);
832
    hw->samples = obt.samples;
833

    
834
    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
835
    if (!alsa->pcm_buf) {
836
        dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
837
               hw->samples, 1 << hw->info.shift);
838
        alsa_anal_close1 (&handle);
839
        return -1;
840
    }
841

    
842
    alsa->handle = handle;
843
    return 0;
844
}
845

    
846
static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
847
{
848
    int err;
849

    
850
    if (pause) {
851
        err = snd_pcm_drop (handle);
852
        if (err < 0) {
853
            alsa_logerr (err, "Could not stop %s\n", typ);
854
            return -1;
855
        }
856
    }
857
    else {
858
        err = snd_pcm_prepare (handle);
859
        if (err < 0) {
860
            alsa_logerr (err, "Could not prepare handle for %s\n", typ);
861
            return -1;
862
        }
863
    }
864

    
865
    return 0;
866
}
867

    
868
static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
869
{
870
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
871

    
872
    switch (cmd) {
873
    case VOICE_ENABLE:
874
        {
875
            va_list ap;
876
            int poll_mode;
877

    
878
            va_start (ap, cmd);
879
            poll_mode = va_arg (ap, int);
880
            va_end (ap);
881

    
882
            ldebug ("enabling voice\n");
883
            if (poll_mode && alsa_poll_out (hw)) {
884
                poll_mode = 0;
885
            }
886
            hw->poll_mode = poll_mode;
887
            return alsa_voice_ctl (alsa->handle, "playback", 0);
888
        }
889

    
890
    case VOICE_DISABLE:
891
        ldebug ("disabling voice\n");
892
        if (hw->poll_mode) {
893
            hw->poll_mode = 0;
894
            alsa_fini_poll (&alsa->pollhlp);
895
        }
896
        return alsa_voice_ctl (alsa->handle, "playback", 1);
897
    }
898

    
899
    return -1;
900
}
901

    
902
static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
903
{
904
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
905
    struct alsa_params_req req;
906
    struct alsa_params_obt obt;
907
    snd_pcm_t *handle;
908
    struct audsettings obt_as;
909

    
910
    req.fmt = aud_to_alsafmt (as->fmt);
911
    req.freq = as->freq;
912
    req.nchannels = as->nchannels;
913
    req.period_size = conf.period_size_in;
914
    req.buffer_size = conf.buffer_size_in;
915
    req.size_in_usec = conf.size_in_usec_in;
916
    req.override_mask =
917
        (conf.period_size_in_overridden ? 1 : 0) |
918
        (conf.buffer_size_in_overridden ? 2 : 0);
919

    
920
    if (alsa_open (1, &req, &obt, &handle)) {
921
        return -1;
922
    }
923

    
924
    obt_as.freq = obt.freq;
925
    obt_as.nchannels = obt.nchannels;
926
    obt_as.fmt = obt.fmt;
927
    obt_as.endianness = obt.endianness;
928

    
929
    audio_pcm_init_info (&hw->info, &obt_as);
930
    hw->samples = obt.samples;
931

    
932
    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
933
    if (!alsa->pcm_buf) {
934
        dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
935
               hw->samples, 1 << hw->info.shift);
936
        alsa_anal_close1 (&handle);
937
        return -1;
938
    }
939

    
940
    alsa->handle = handle;
941
    return 0;
942
}
943

    
944
static void alsa_fini_in (HWVoiceIn *hw)
945
{
946
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
947

    
948
    alsa_anal_close (&alsa->handle, &alsa->pollhlp);
949

    
950
    if (alsa->pcm_buf) {
951
        qemu_free (alsa->pcm_buf);
952
        alsa->pcm_buf = NULL;
953
    }
954
}
955

    
956
static int alsa_run_in (HWVoiceIn *hw)
957
{
958
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
959
    int hwshift = hw->info.shift;
960
    int i;
961
    int live = audio_pcm_hw_get_live_in (hw);
962
    int dead = hw->samples - live;
963
    int decr;
964
    struct {
965
        int add;
966
        int len;
967
    } bufs[2] = {
968
        { .add = hw->wpos, .len = 0 },
969
        { .add = 0,        .len = 0 }
970
    };
971
    snd_pcm_sframes_t avail;
972
    snd_pcm_uframes_t read_samples = 0;
973

    
974
    if (!dead) {
975
        return 0;
976
    }
977

    
978
    avail = alsa_get_avail (alsa->handle);
979
    if (avail < 0) {
980
        dolog ("Could not get number of captured frames\n");
981
        return 0;
982
    }
983

    
984
    if (!avail) {
985
        snd_pcm_state_t state;
986

    
987
        state = snd_pcm_state (alsa->handle);
988
        switch (state) {
989
        case SND_PCM_STATE_PREPARED:
990
            avail = hw->samples;
991
            break;
992
        case SND_PCM_STATE_SUSPENDED:
993
            /* stream is suspended and waiting for an application recovery */
994
            if (alsa_resume (alsa->handle)) {
995
                dolog ("Failed to resume suspended input stream\n");
996
                return 0;
997
            }
998
            if (conf.verbose) {
999
                dolog ("Resuming suspended input stream\n");
1000
            }
1001
            break;
1002
        default:
1003
            if (conf.verbose) {
1004
                dolog ("No frames available and ALSA state is %d\n", state);
1005
            }
1006
            return 0;
1007
        }
1008
    }
1009

    
1010
    decr = audio_MIN (dead, avail);
1011
    if (!decr) {
1012
        return 0;
1013
    }
1014

    
1015
    if (hw->wpos + decr > hw->samples) {
1016
        bufs[0].len = (hw->samples - hw->wpos);
1017
        bufs[1].len = (decr - (hw->samples - hw->wpos));
1018
    }
1019
    else {
1020
        bufs[0].len = decr;
1021
    }
1022

    
1023
    for (i = 0; i < 2; ++i) {
1024
        void *src;
1025
        struct st_sample *dst;
1026
        snd_pcm_sframes_t nread;
1027
        snd_pcm_uframes_t len;
1028

    
1029
        len = bufs[i].len;
1030

    
1031
        src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
1032
        dst = hw->conv_buf + bufs[i].add;
1033

    
1034
        while (len) {
1035
            nread = snd_pcm_readi (alsa->handle, src, len);
1036

    
1037
            if (nread <= 0) {
1038
                switch (nread) {
1039
                case 0:
1040
                    if (conf.verbose) {
1041
                        dolog ("Failed to read %ld frames (read zero)\n", len);
1042
                    }
1043
                    goto exit;
1044

    
1045
                case -EPIPE:
1046
                    if (alsa_recover (alsa->handle)) {
1047
                        alsa_logerr (nread, "Failed to read %ld frames\n", len);
1048
                        goto exit;
1049
                    }
1050
                    if (conf.verbose) {
1051
                        dolog ("Recovering from capture xrun\n");
1052
                    }
1053
                    continue;
1054

    
1055
                case -EAGAIN:
1056
                    goto exit;
1057

    
1058
                default:
1059
                    alsa_logerr (
1060
                        nread,
1061
                        "Failed to read %ld frames from %p\n",
1062
                        len,
1063
                        src
1064
                        );
1065
                    goto exit;
1066
                }
1067
            }
1068

    
1069
            hw->conv (dst, src, nread, &nominal_volume);
1070

    
1071
            src = advance (src, nread << hwshift);
1072
            dst += nread;
1073

    
1074
            read_samples += nread;
1075
            len -= nread;
1076
        }
1077
    }
1078

    
1079
 exit:
1080
    hw->wpos = (hw->wpos + read_samples) % hw->samples;
1081
    return read_samples;
1082
}
1083

    
1084
static int alsa_read (SWVoiceIn *sw, void *buf, int size)
1085
{
1086
    return audio_pcm_sw_read (sw, buf, size);
1087
}
1088

    
1089
static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
1090
{
1091
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
1092

    
1093
    switch (cmd) {
1094
    case VOICE_ENABLE:
1095
        {
1096
            va_list ap;
1097
            int poll_mode;
1098

    
1099
            va_start (ap, cmd);
1100
            poll_mode = va_arg (ap, int);
1101
            va_end (ap);
1102

    
1103
            ldebug ("enabling voice\n");
1104
            if (poll_mode && alsa_poll_in (hw)) {
1105
                poll_mode = 0;
1106
            }
1107
            hw->poll_mode = poll_mode;
1108

    
1109
            return alsa_voice_ctl (alsa->handle, "capture", 0);
1110
        }
1111

    
1112
    case VOICE_DISABLE:
1113
        ldebug ("disabling voice\n");
1114
        if (hw->poll_mode) {
1115
            hw->poll_mode = 0;
1116
            alsa_fini_poll (&alsa->pollhlp);
1117
        }
1118
        return alsa_voice_ctl (alsa->handle, "capture", 1);
1119
    }
1120

    
1121
    return -1;
1122
}
1123

    
1124
static void *alsa_audio_init (void)
1125
{
1126
    return &conf;
1127
}
1128

    
1129
static void alsa_audio_fini (void *opaque)
1130
{
1131
    (void) opaque;
1132
}
1133

    
1134
static struct audio_option alsa_options[] = {
1135
    {
1136
        .name        = "DAC_SIZE_IN_USEC",
1137
        .tag         = AUD_OPT_BOOL,
1138
        .valp        = &conf.size_in_usec_out,
1139
        .descr       = "DAC period/buffer size in microseconds (otherwise in frames)"
1140
    },
1141
    {
1142
        .name        = "DAC_PERIOD_SIZE",
1143
        .tag         = AUD_OPT_INT,
1144
        .valp        = &conf.period_size_out,
1145
        .descr       = "DAC period size (0 to go with system default)",
1146
        .overriddenp = &conf.period_size_out_overridden
1147
    },
1148
    {
1149
        .name        = "DAC_BUFFER_SIZE",
1150
        .tag         = AUD_OPT_INT,
1151
        .valp        = &conf.buffer_size_out,
1152
        .descr       = "DAC buffer size (0 to go with system default)",
1153
        .overriddenp = &conf.buffer_size_out_overridden
1154
    },
1155
    {
1156
        .name        = "ADC_SIZE_IN_USEC",
1157
        .tag         = AUD_OPT_BOOL,
1158
        .valp        = &conf.size_in_usec_in,
1159
        .descr       =
1160
        "ADC period/buffer size in microseconds (otherwise in frames)"
1161
    },
1162
    {
1163
        .name        = "ADC_PERIOD_SIZE",
1164
        .tag         = AUD_OPT_INT,
1165
        .valp        = &conf.period_size_in,
1166
        .descr       = "ADC period size (0 to go with system default)",
1167
        .overriddenp = &conf.period_size_in_overridden
1168
    },
1169
    {
1170
        .name        = "ADC_BUFFER_SIZE",
1171
        .tag         = AUD_OPT_INT,
1172
        .valp        = &conf.buffer_size_in,
1173
        .descr       = "ADC buffer size (0 to go with system default)",
1174
        .overriddenp = &conf.buffer_size_in_overridden
1175
    },
1176
    {
1177
        .name        = "THRESHOLD",
1178
        .tag         = AUD_OPT_INT,
1179
        .valp        = &conf.threshold,
1180
        .descr       = "(undocumented)"
1181
    },
1182
    {
1183
        .name        = "DAC_DEV",
1184
        .tag         = AUD_OPT_STR,
1185
        .valp        = &conf.pcm_name_out,
1186
        .descr       = "DAC device name (for instance dmix)"
1187
    },
1188
    {
1189
        .name        = "ADC_DEV",
1190
        .tag         = AUD_OPT_STR,
1191
        .valp        = &conf.pcm_name_in,
1192
        .descr       = "ADC device name"
1193
    },
1194
    {
1195
        .name        = "VERBOSE",
1196
        .tag         = AUD_OPT_BOOL,
1197
        .valp        = &conf.verbose,
1198
        .descr       = "Behave in a more verbose way"
1199
    },
1200
    { /* End of list */ }
1201
};
1202

    
1203
static struct audio_pcm_ops alsa_pcm_ops = {
1204
    .init_out = alsa_init_out,
1205
    .fini_out = alsa_fini_out,
1206
    .run_out  = alsa_run_out,
1207
    .write    = alsa_write,
1208
    .ctl_out  = alsa_ctl_out,
1209

    
1210
    .init_in  = alsa_init_in,
1211
    .fini_in  = alsa_fini_in,
1212
    .run_in   = alsa_run_in,
1213
    .read     = alsa_read,
1214
    .ctl_in   = alsa_ctl_in,
1215
};
1216

    
1217
struct audio_driver alsa_audio_driver = {
1218
    .name           = "alsa",
1219
    .descr          = "ALSA http://www.alsa-project.org",
1220
    .options        = alsa_options,
1221
    .init           = alsa_audio_init,
1222
    .fini           = alsa_audio_fini,
1223
    .pcm_ops        = &alsa_pcm_ops,
1224
    .can_be_default = 1,
1225
    .max_voices_out = INT_MAX,
1226
    .max_voices_in  = INT_MAX,
1227
    .voice_size_out = sizeof (ALSAVoiceOut),
1228
    .voice_size_in  = sizeof (ALSAVoiceIn)
1229
};