Statistics
| Branch: | Revision:

root / audio / alsaaudio.c @ 98f9f48c

History | View | Annotate | Download (26.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 "audio.h"
27

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

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

    
35
typedef struct ALSAVoiceOut {
36
    HWVoiceOut hw;
37
    void *pcm_buf;
38
    snd_pcm_t *handle;
39
} ALSAVoiceOut;
40

    
41
typedef struct ALSAVoiceIn {
42
    HWVoiceIn hw;
43
    snd_pcm_t *handle;
44
    void *pcm_buf;
45
} ALSAVoiceIn;
46

    
47
static struct {
48
    int size_in_usec_in;
49
    int size_in_usec_out;
50
    const char *pcm_name_in;
51
    const char *pcm_name_out;
52
    unsigned int buffer_size_in;
53
    unsigned int period_size_in;
54
    unsigned int buffer_size_out;
55
    unsigned int period_size_out;
56
    unsigned int threshold;
57

    
58
    int buffer_size_in_overridden;
59
    int period_size_in_overridden;
60

    
61
    int buffer_size_out_overridden;
62
    int period_size_out_overridden;
63
    int verbose;
64
} conf = {
65
    .buffer_size_out = 1024,
66
    .pcm_name_out = "default",
67
    .pcm_name_in = "default",
68
};
69

    
70
struct alsa_params_req {
71
    int freq;
72
    snd_pcm_format_t fmt;
73
    int nchannels;
74
    int size_in_usec;
75
    int override_mask;
76
    unsigned int buffer_size;
77
    unsigned int period_size;
78
};
79

    
80
struct alsa_params_obt {
81
    int freq;
82
    audfmt_e fmt;
83
    int endianness;
84
    int nchannels;
85
    snd_pcm_uframes_t samples;
86
};
87

    
88
static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
89
{
90
    va_list ap;
91

    
92
    va_start (ap, fmt);
93
    AUD_vlog (AUDIO_CAP, fmt, ap);
94
    va_end (ap);
95

    
96
    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
97
}
98

    
99
static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
100
    int err,
101
    const char *typ,
102
    const char *fmt,
103
    ...
104
    )
105
{
106
    va_list ap;
107

    
108
    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
109

    
110
    va_start (ap, fmt);
111
    AUD_vlog (AUDIO_CAP, fmt, ap);
112
    va_end (ap);
113

    
114
    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
115
}
116

    
117
static void alsa_anal_close (snd_pcm_t **handlep)
118
{
119
    int err = snd_pcm_close (*handlep);
120
    if (err) {
121
        alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
122
    }
123
    *handlep = NULL;
124
}
125

    
126
static int alsa_write (SWVoiceOut *sw, void *buf, int len)
127
{
128
    return audio_pcm_sw_write (sw, buf, len);
129
}
130

    
131
static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt)
132
{
133
    switch (fmt) {
134
    case AUD_FMT_S8:
135
        return SND_PCM_FORMAT_S8;
136

    
137
    case AUD_FMT_U8:
138
        return SND_PCM_FORMAT_U8;
139

    
140
    case AUD_FMT_S16:
141
        return SND_PCM_FORMAT_S16_LE;
142

    
143
    case AUD_FMT_U16:
144
        return SND_PCM_FORMAT_U16_LE;
145

    
146
    case AUD_FMT_S32:
147
        return SND_PCM_FORMAT_S32_LE;
148

    
149
    case AUD_FMT_U32:
150
        return SND_PCM_FORMAT_U32_LE;
151

    
152
    default:
153
        dolog ("Internal logic error: Bad audio format %d\n", fmt);
154
#ifdef DEBUG_AUDIO
155
        abort ();
156
#endif
157
        return SND_PCM_FORMAT_U8;
158
    }
159
}
160

    
161
static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
162
                           int *endianness)
163
{
164
    switch (alsafmt) {
165
    case SND_PCM_FORMAT_S8:
166
        *endianness = 0;
167
        *fmt = AUD_FMT_S8;
168
        break;
169

    
170
    case SND_PCM_FORMAT_U8:
171
        *endianness = 0;
172
        *fmt = AUD_FMT_U8;
173
        break;
174

    
175
    case SND_PCM_FORMAT_S16_LE:
176
        *endianness = 0;
177
        *fmt = AUD_FMT_S16;
178
        break;
179

    
180
    case SND_PCM_FORMAT_U16_LE:
181
        *endianness = 0;
182
        *fmt = AUD_FMT_U16;
183
        break;
184

    
185
    case SND_PCM_FORMAT_S16_BE:
186
        *endianness = 1;
187
        *fmt = AUD_FMT_S16;
188
        break;
189

    
190
    case SND_PCM_FORMAT_U16_BE:
191
        *endianness = 1;
192
        *fmt = AUD_FMT_U16;
193
        break;
194

    
195
    case SND_PCM_FORMAT_S32_LE:
196
        *endianness = 0;
197
        *fmt = AUD_FMT_S32;
198
        break;
199

    
200
    case SND_PCM_FORMAT_U32_LE:
201
        *endianness = 0;
202
        *fmt = AUD_FMT_U32;
203
        break;
204

    
205
    case SND_PCM_FORMAT_S32_BE:
206
        *endianness = 1;
207
        *fmt = AUD_FMT_S32;
208
        break;
209

    
210
    case SND_PCM_FORMAT_U32_BE:
211
        *endianness = 1;
212
        *fmt = AUD_FMT_U32;
213
        break;
214

    
215
    default:
216
        dolog ("Unrecognized audio format %d\n", alsafmt);
217
        return -1;
218
    }
219

    
220
    return 0;
221
}
222

    
223
static void alsa_dump_info (struct alsa_params_req *req,
224
                            struct alsa_params_obt *obt)
225
{
226
    dolog ("parameter | requested value | obtained value\n");
227
    dolog ("format    |      %10d |     %10d\n", req->fmt, obt->fmt);
228
    dolog ("channels  |      %10d |     %10d\n",
229
           req->nchannels, obt->nchannels);
230
    dolog ("frequency |      %10d |     %10d\n", req->freq, obt->freq);
231
    dolog ("============================================\n");
232
    dolog ("requested: buffer size %d period size %d\n",
233
           req->buffer_size, req->period_size);
234
    dolog ("obtained: samples %ld\n", obt->samples);
235
}
236

    
237
static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
238
{
239
    int err;
240
    snd_pcm_sw_params_t *sw_params;
241

    
242
    snd_pcm_sw_params_alloca (&sw_params);
243

    
244
    err = snd_pcm_sw_params_current (handle, sw_params);
245
    if (err < 0) {
246
        dolog ("Could not fully initialize DAC\n");
247
        alsa_logerr (err, "Failed to get current software parameters\n");
248
        return;
249
    }
250

    
251
    err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
252
    if (err < 0) {
253
        dolog ("Could not fully initialize DAC\n");
254
        alsa_logerr (err, "Failed to set software threshold to %ld\n",
255
                     threshold);
256
        return;
257
    }
258

    
259
    err = snd_pcm_sw_params (handle, sw_params);
260
    if (err < 0) {
261
        dolog ("Could not fully initialize DAC\n");
262
        alsa_logerr (err, "Failed to set software parameters\n");
263
        return;
264
    }
265
}
266

    
267
static int alsa_open (int in, struct alsa_params_req *req,
268
                      struct alsa_params_obt *obt, snd_pcm_t **handlep)
269
{
270
    snd_pcm_t *handle;
271
    snd_pcm_hw_params_t *hw_params;
272
    int err;
273
    int size_in_usec;
274
    unsigned int freq, nchannels;
275
    const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
276
    snd_pcm_uframes_t obt_buffer_size;
277
    const char *typ = in ? "ADC" : "DAC";
278
    snd_pcm_format_t obtfmt;
279

    
280
    freq = req->freq;
281
    nchannels = req->nchannels;
282
    size_in_usec = req->size_in_usec;
283

    
284
    snd_pcm_hw_params_alloca (&hw_params);
285

    
286
    err = snd_pcm_open (
287
        &handle,
288
        pcm_name,
289
        in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
290
        SND_PCM_NONBLOCK
291
        );
292
    if (err < 0) {
293
        alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
294
        return -1;
295
    }
296

    
297
    err = snd_pcm_hw_params_any (handle, hw_params);
298
    if (err < 0) {
299
        alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
300
        goto err;
301
    }
302

    
303
    err = snd_pcm_hw_params_set_access (
304
        handle,
305
        hw_params,
306
        SND_PCM_ACCESS_RW_INTERLEAVED
307
        );
308
    if (err < 0) {
309
        alsa_logerr2 (err, typ, "Failed to set access type\n");
310
        goto err;
311
    }
312

    
313
    err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
314
    if (err < 0 && conf.verbose) {
315
        alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
316
    }
317

    
318
    err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
319
    if (err < 0) {
320
        alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
321
        goto err;
322
    }
323

    
324
    err = snd_pcm_hw_params_set_channels_near (
325
        handle,
326
        hw_params,
327
        &nchannels
328
        );
329
    if (err < 0) {
330
        alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
331
                      req->nchannels);
332
        goto err;
333
    }
334

    
335
    if (nchannels != 1 && nchannels != 2) {
336
        alsa_logerr2 (err, typ,
337
                      "Can not handle obtained number of channels %d\n",
338
                      nchannels);
339
        goto err;
340
    }
341

    
342
    if (req->buffer_size) {
343
        unsigned long obt;
344

    
345
        if (size_in_usec) {
346
            int dir = 0;
347
            unsigned int btime = req->buffer_size;
348

    
349
            err = snd_pcm_hw_params_set_buffer_time_near (
350
                handle,
351
                hw_params,
352
                &btime,
353
                &dir
354
                );
355
            obt = btime;
356
        }
357
        else {
358
            snd_pcm_uframes_t bsize = req->buffer_size;
359

    
360
            err = snd_pcm_hw_params_set_buffer_size_near (
361
                handle,
362
                hw_params,
363
                &bsize
364
                );
365
            obt = bsize;
366
        }
367
        if (err < 0) {
368
            alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
369
                          size_in_usec ? "time" : "size", req->buffer_size);
370
            goto err;
371
        }
372

    
373
        if ((req->override_mask & 2) && (obt - req->buffer_size))
374
            dolog ("Requested buffer %s %u was rejected, using %lu\n",
375
                   size_in_usec ? "time" : "size", req->buffer_size, obt);
376
    }
377

    
378
    if (req->period_size) {
379
        unsigned long obt;
380

    
381
        if (size_in_usec) {
382
            int dir = 0;
383
            unsigned int ptime = req->period_size;
384

    
385
            err = snd_pcm_hw_params_set_period_time_near (
386
                handle,
387
                hw_params,
388
                &ptime,
389
                &dir
390
                );
391
            obt = ptime;
392
        }
393
        else {
394
            int dir = 0;
395
            snd_pcm_uframes_t psize = req->period_size;
396

    
397
            err = snd_pcm_hw_params_set_period_size_near (
398
                handle,
399
                hw_params,
400
                &psize,
401
                &dir
402
                );
403
            obt = psize;
404
        }
405

    
406
        if (err < 0) {
407
            alsa_logerr2 (err, typ, "Failed to set period %s to %d\n",
408
                          size_in_usec ? "time" : "size", req->period_size);
409
            goto err;
410
        }
411

    
412
        if ((req->override_mask & 1) && (obt - req->period_size))
413
            dolog ("Requested period %s %u was rejected, using %lu\n",
414
                   size_in_usec ? "time" : "size", req->period_size, obt);
415
    }
416

    
417
    err = snd_pcm_hw_params (handle, hw_params);
418
    if (err < 0) {
419
        alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
420
        goto err;
421
    }
422

    
423
    err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
424
    if (err < 0) {
425
        alsa_logerr2 (err, typ, "Failed to get buffer size\n");
426
        goto err;
427
    }
428

    
429
    err = snd_pcm_hw_params_get_format (hw_params, &obtfmt);
430
    if (err < 0) {
431
        alsa_logerr2 (err, typ, "Failed to get format\n");
432
        goto err;
433
    }
434

    
435
    if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
436
        dolog ("Invalid format was returned %d\n", obtfmt);
437
        goto err;
438
    }
439

    
440
    err = snd_pcm_prepare (handle);
441
    if (err < 0) {
442
        alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
443
        goto err;
444
    }
445

    
446
    if (!in && conf.threshold) {
447
        snd_pcm_uframes_t threshold;
448
        int bytes_per_sec;
449

    
450
        bytes_per_sec = freq << (nchannels == 2);
451

    
452
        switch (obt->fmt) {
453
        case AUD_FMT_S8:
454
        case AUD_FMT_U8:
455
            break;
456

    
457
        case AUD_FMT_S16:
458
        case AUD_FMT_U16:
459
            bytes_per_sec <<= 1;
460
            break;
461

    
462
        case AUD_FMT_S32:
463
        case AUD_FMT_U32:
464
            bytes_per_sec <<= 2;
465
            break;
466
        }
467

    
468
        threshold = (conf.threshold * bytes_per_sec) / 1000;
469
        alsa_set_threshold (handle, threshold);
470
    }
471

    
472
    obt->nchannels = nchannels;
473
    obt->freq = freq;
474
    obt->samples = obt_buffer_size;
475

    
476
    *handlep = handle;
477

    
478
    if (conf.verbose &&
479
        (obt->fmt != req->fmt ||
480
         obt->nchannels != req->nchannels ||
481
         obt->freq != req->freq)) {
482
        dolog ("Audio paramters for %s\n", typ);
483
        alsa_dump_info (req, obt);
484
    }
485

    
486
#ifdef DEBUG
487
    alsa_dump_info (req, obt);
488
#endif
489
    return 0;
490

    
491
 err:
492
    alsa_anal_close (&handle);
493
    return -1;
494
}
495

    
496
static int alsa_recover (snd_pcm_t *handle)
497
{
498
    int err = snd_pcm_prepare (handle);
499
    if (err < 0) {
500
        alsa_logerr (err, "Failed to prepare handle %p\n", handle);
501
        return -1;
502
    }
503
    return 0;
504
}
505

    
506
static int alsa_resume (snd_pcm_t *handle)
507
{
508
    int err = snd_pcm_resume (handle);
509
    if (err < 0) {
510
        alsa_logerr (err, "Failed to resume handle %p\n", handle);
511
        return -1;
512
    }
513
    return 0;
514
}
515

    
516
static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
517
{
518
    snd_pcm_sframes_t avail;
519

    
520
    avail = snd_pcm_avail_update (handle);
521
    if (avail < 0) {
522
        if (avail == -EPIPE) {
523
            if (!alsa_recover (handle)) {
524
                avail = snd_pcm_avail_update (handle);
525
            }
526
        }
527

    
528
        if (avail < 0) {
529
            alsa_logerr (avail,
530
                         "Could not obtain number of available frames\n");
531
            return -1;
532
        }
533
    }
534

    
535
    return avail;
536
}
537

    
538
static int alsa_run_out (HWVoiceOut *hw)
539
{
540
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
541
    int rpos, live, decr;
542
    int samples;
543
    uint8_t *dst;
544
    struct st_sample *src;
545
    snd_pcm_sframes_t avail;
546

    
547
    live = audio_pcm_hw_get_live_out (hw);
548
    if (!live) {
549
        return 0;
550
    }
551

    
552
    avail = alsa_get_avail (alsa->handle);
553
    if (avail < 0) {
554
        dolog ("Could not get number of available playback frames\n");
555
        return 0;
556
    }
557

    
558
    decr = audio_MIN (live, avail);
559
    samples = decr;
560
    rpos = hw->rpos;
561
    while (samples) {
562
        int left_till_end_samples = hw->samples - rpos;
563
        int len = audio_MIN (samples, left_till_end_samples);
564
        snd_pcm_sframes_t written;
565

    
566
        src = hw->mix_buf + rpos;
567
        dst = advance (alsa->pcm_buf, rpos << hw->info.shift);
568

    
569
        hw->clip (dst, src, len);
570

    
571
        while (len) {
572
            written = snd_pcm_writei (alsa->handle, dst, len);
573

    
574
            if (written <= 0) {
575
                switch (written) {
576
                case 0:
577
                    if (conf.verbose) {
578
                        dolog ("Failed to write %d frames (wrote zero)\n", len);
579
                    }
580
                    goto exit;
581

    
582
                case -EPIPE:
583
                    if (alsa_recover (alsa->handle)) {
584
                        alsa_logerr (written, "Failed to write %d frames\n",
585
                                     len);
586
                        goto exit;
587
                    }
588
                    if (conf.verbose) {
589
                        dolog ("Recovering from playback xrun\n");
590
                    }
591
                    continue;
592

    
593
                case -ESTRPIPE:
594
                    /* stream is suspended and waiting for an
595
                       application recovery */
596
                    if (alsa_resume (alsa->handle)) {
597
                        alsa_logerr (written, "Failed to write %d frames\n",
598
                                     len);
599
                        goto exit;
600
                    }
601
                    if (conf.verbose) {
602
                        dolog ("Resuming suspended output stream\n");
603
                    }
604
                    continue;
605

    
606
                case -EAGAIN:
607
                    goto exit;
608

    
609
                default:
610
                    alsa_logerr (written, "Failed to write %d frames to %p\n",
611
                                 len, dst);
612
                    goto exit;
613
                }
614
            }
615

    
616
            rpos = (rpos + written) % hw->samples;
617
            samples -= written;
618
            len -= written;
619
            dst = advance (dst, written << hw->info.shift);
620
            src += written;
621
        }
622
    }
623

    
624
 exit:
625
    hw->rpos = rpos;
626
    return decr;
627
}
628

    
629
static void alsa_fini_out (HWVoiceOut *hw)
630
{
631
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
632

    
633
    ldebug ("alsa_fini\n");
634
    alsa_anal_close (&alsa->handle);
635

    
636
    if (alsa->pcm_buf) {
637
        qemu_free (alsa->pcm_buf);
638
        alsa->pcm_buf = NULL;
639
    }
640
}
641

    
642
static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
643
{
644
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
645
    struct alsa_params_req req;
646
    struct alsa_params_obt obt;
647
    snd_pcm_t *handle;
648
    struct audsettings obt_as;
649

    
650
    req.fmt = aud_to_alsafmt (as->fmt);
651
    req.freq = as->freq;
652
    req.nchannels = as->nchannels;
653
    req.period_size = conf.period_size_out;
654
    req.buffer_size = conf.buffer_size_out;
655
    req.size_in_usec = conf.size_in_usec_out;
656
    req.override_mask =
657
        (conf.period_size_out_overridden ? 1 : 0) |
658
        (conf.buffer_size_out_overridden ? 2 : 0);
659

    
660
    if (alsa_open (0, &req, &obt, &handle)) {
661
        return -1;
662
    }
663

    
664
    obt_as.freq = obt.freq;
665
    obt_as.nchannels = obt.nchannels;
666
    obt_as.fmt = obt.fmt;
667
    obt_as.endianness = obt.endianness;
668

    
669
    audio_pcm_init_info (&hw->info, &obt_as);
670
    hw->samples = obt.samples;
671

    
672
    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
673
    if (!alsa->pcm_buf) {
674
        dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
675
               hw->samples, 1 << hw->info.shift);
676
        alsa_anal_close (&handle);
677
        return -1;
678
    }
679

    
680
    alsa->handle = handle;
681
    return 0;
682
}
683

    
684
static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
685
{
686
    int err;
687

    
688
    if (pause) {
689
        err = snd_pcm_drop (handle);
690
        if (err < 0) {
691
            alsa_logerr (err, "Could not stop %s\n", typ);
692
            return -1;
693
        }
694
    }
695
    else {
696
        err = snd_pcm_prepare (handle);
697
        if (err < 0) {
698
            alsa_logerr (err, "Could not prepare handle for %s\n", typ);
699
            return -1;
700
        }
701
    }
702

    
703
    return 0;
704
}
705

    
706
static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
707
{
708
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
709

    
710
    switch (cmd) {
711
    case VOICE_ENABLE:
712
        ldebug ("enabling voice\n");
713
        return alsa_voice_ctl (alsa->handle, "playback", 0);
714

    
715
    case VOICE_DISABLE:
716
        ldebug ("disabling voice\n");
717
        return alsa_voice_ctl (alsa->handle, "playback", 1);
718
    }
719

    
720
    return -1;
721
}
722

    
723
static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
724
{
725
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
726
    struct alsa_params_req req;
727
    struct alsa_params_obt obt;
728
    snd_pcm_t *handle;
729
    struct audsettings obt_as;
730

    
731
    req.fmt = aud_to_alsafmt (as->fmt);
732
    req.freq = as->freq;
733
    req.nchannels = as->nchannels;
734
    req.period_size = conf.period_size_in;
735
    req.buffer_size = conf.buffer_size_in;
736
    req.size_in_usec = conf.size_in_usec_in;
737
    req.override_mask =
738
        (conf.period_size_in_overridden ? 1 : 0) |
739
        (conf.buffer_size_in_overridden ? 2 : 0);
740

    
741
    if (alsa_open (1, &req, &obt, &handle)) {
742
        return -1;
743
    }
744

    
745
    obt_as.freq = obt.freq;
746
    obt_as.nchannels = obt.nchannels;
747
    obt_as.fmt = obt.fmt;
748
    obt_as.endianness = obt.endianness;
749

    
750
    audio_pcm_init_info (&hw->info, &obt_as);
751
    hw->samples = obt.samples;
752

    
753
    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
754
    if (!alsa->pcm_buf) {
755
        dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
756
               hw->samples, 1 << hw->info.shift);
757
        alsa_anal_close (&handle);
758
        return -1;
759
    }
760

    
761
    alsa->handle = handle;
762
    return 0;
763
}
764

    
765
static void alsa_fini_in (HWVoiceIn *hw)
766
{
767
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
768

    
769
    alsa_anal_close (&alsa->handle);
770

    
771
    if (alsa->pcm_buf) {
772
        qemu_free (alsa->pcm_buf);
773
        alsa->pcm_buf = NULL;
774
    }
775
}
776

    
777
static int alsa_run_in (HWVoiceIn *hw)
778
{
779
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
780
    int hwshift = hw->info.shift;
781
    int i;
782
    int live = audio_pcm_hw_get_live_in (hw);
783
    int dead = hw->samples - live;
784
    int decr;
785
    struct {
786
        int add;
787
        int len;
788
    } bufs[2] = {
789
        { .add = hw->wpos, .len = 0 },
790
        { .add = 0,        .len = 0 }
791
    };
792
    snd_pcm_sframes_t avail;
793
    snd_pcm_uframes_t read_samples = 0;
794

    
795
    if (!dead) {
796
        return 0;
797
    }
798

    
799
    avail = alsa_get_avail (alsa->handle);
800
    if (avail < 0) {
801
        dolog ("Could not get number of captured frames\n");
802
        return 0;
803
    }
804

    
805
    if (!avail) {
806
        snd_pcm_state_t state;
807

    
808
        state = snd_pcm_state (alsa->handle);
809
        switch (state) {
810
        case SND_PCM_STATE_PREPARED:
811
            avail = hw->samples;
812
            break;
813
        case SND_PCM_STATE_SUSPENDED:
814
            /* stream is suspended and waiting for an application recovery */
815
            if (alsa_resume (alsa->handle)) {
816
                dolog ("Failed to resume suspended input stream\n");
817
                return 0;
818
            }
819
            if (conf.verbose) {
820
                dolog ("Resuming suspended input stream\n");
821
            }
822
            break;
823
        default:
824
            if (conf.verbose) {
825
                dolog ("No frames available and ALSA state is %d\n", state);
826
            }
827
            return 0;
828
        }
829
    }
830

    
831
    decr = audio_MIN (dead, avail);
832
    if (!decr) {
833
        return 0;
834
    }
835

    
836
    if (hw->wpos + decr > hw->samples) {
837
        bufs[0].len = (hw->samples - hw->wpos);
838
        bufs[1].len = (decr - (hw->samples - hw->wpos));
839
    }
840
    else {
841
        bufs[0].len = decr;
842
    }
843

    
844
    for (i = 0; i < 2; ++i) {
845
        void *src;
846
        struct st_sample *dst;
847
        snd_pcm_sframes_t nread;
848
        snd_pcm_uframes_t len;
849

    
850
        len = bufs[i].len;
851

    
852
        src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
853
        dst = hw->conv_buf + bufs[i].add;
854

    
855
        while (len) {
856
            nread = snd_pcm_readi (alsa->handle, src, len);
857

    
858
            if (nread <= 0) {
859
                switch (nread) {
860
                case 0:
861
                    if (conf.verbose) {
862
                        dolog ("Failed to read %ld frames (read zero)\n", len);
863
                    }
864
                    goto exit;
865

    
866
                case -EPIPE:
867
                    if (alsa_recover (alsa->handle)) {
868
                        alsa_logerr (nread, "Failed to read %ld frames\n", len);
869
                        goto exit;
870
                    }
871
                    if (conf.verbose) {
872
                        dolog ("Recovering from capture xrun\n");
873
                    }
874
                    continue;
875

    
876
                case -EAGAIN:
877
                    goto exit;
878

    
879
                default:
880
                    alsa_logerr (
881
                        nread,
882
                        "Failed to read %ld frames from %p\n",
883
                        len,
884
                        src
885
                        );
886
                    goto exit;
887
                }
888
            }
889

    
890
            hw->conv (dst, src, nread, &nominal_volume);
891

    
892
            src = advance (src, nread << hwshift);
893
            dst += nread;
894

    
895
            read_samples += nread;
896
            len -= nread;
897
        }
898
    }
899

    
900
 exit:
901
    hw->wpos = (hw->wpos + read_samples) % hw->samples;
902
    return read_samples;
903
}
904

    
905
static int alsa_read (SWVoiceIn *sw, void *buf, int size)
906
{
907
    return audio_pcm_sw_read (sw, buf, size);
908
}
909

    
910
static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
911
{
912
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
913

    
914
    switch (cmd) {
915
    case VOICE_ENABLE:
916
        ldebug ("enabling voice\n");
917
        return alsa_voice_ctl (alsa->handle, "capture", 0);
918

    
919
    case VOICE_DISABLE:
920
        ldebug ("disabling voice\n");
921
        return alsa_voice_ctl (alsa->handle, "capture", 1);
922
    }
923

    
924
    return -1;
925
}
926

    
927
static void *alsa_audio_init (void)
928
{
929
    return &conf;
930
}
931

    
932
static void alsa_audio_fini (void *opaque)
933
{
934
    (void) opaque;
935
}
936

    
937
static struct audio_option alsa_options[] = {
938
    {
939
        .name        = "DAC_SIZE_IN_USEC",
940
        .tag         = AUD_OPT_BOOL,
941
        .valp        = &conf.size_in_usec_out,
942
        .descr       = "DAC period/buffer size in microseconds (otherwise in frames)"
943
    },
944
    {
945
        .name        = "DAC_PERIOD_SIZE",
946
        .tag         = AUD_OPT_INT,
947
        .valp        = &conf.period_size_out,
948
        .descr       = "DAC period size (0 to go with system default)",
949
        .overriddenp = &conf.period_size_out_overridden
950
    },
951
    {
952
        .name        = "DAC_BUFFER_SIZE",
953
        .tag         = AUD_OPT_INT,
954
        .valp        = &conf.buffer_size_out,
955
        .descr       = "DAC buffer size (0 to go with system default)",
956
        .overriddenp = &conf.buffer_size_out_overridden
957
    },
958
    {
959
        .name        = "ADC_SIZE_IN_USEC",
960
        .tag         = AUD_OPT_BOOL,
961
        .valp        = &conf.size_in_usec_in,
962
        .descr       =
963
        "ADC period/buffer size in microseconds (otherwise in frames)"
964
    },
965
    {
966
        .name        = "ADC_PERIOD_SIZE",
967
        .tag         = AUD_OPT_INT,
968
        .valp        = &conf.period_size_in,
969
        .descr       = "ADC period size (0 to go with system default)",
970
        .overriddenp = &conf.period_size_in_overridden
971
    },
972
    {
973
        .name        = "ADC_BUFFER_SIZE",
974
        .tag         = AUD_OPT_INT,
975
        .valp        = &conf.buffer_size_in,
976
        .descr       = "ADC buffer size (0 to go with system default)",
977
        .overriddenp = &conf.buffer_size_in_overridden
978
    },
979
    {
980
        .name        = "THRESHOLD",
981
        .tag         = AUD_OPT_INT,
982
        .valp        = &conf.threshold,
983
        .descr       = "(undocumented)"
984
    },
985
    {
986
        .name        = "DAC_DEV",
987
        .tag         = AUD_OPT_STR,
988
        .valp        = &conf.pcm_name_out,
989
        .descr       = "DAC device name (for instance dmix)"
990
    },
991
    {
992
        .name        = "ADC_DEV",
993
        .tag         = AUD_OPT_STR,
994
        .valp        = &conf.pcm_name_in,
995
        .descr       = "ADC device name"
996
    },
997
    {
998
        .name        = "VERBOSE",
999
        .tag         = AUD_OPT_BOOL,
1000
        .valp        = &conf.verbose,
1001
        .descr       = "Behave in a more verbose way"
1002
    },
1003
    { /* End of list */ }
1004
};
1005

    
1006
static struct audio_pcm_ops alsa_pcm_ops = {
1007
    .init_out = alsa_init_out,
1008
    .fini_out = alsa_fini_out,
1009
    .run_out  = alsa_run_out,
1010
    .write    = alsa_write,
1011
    .ctl_out  = alsa_ctl_out,
1012

    
1013
    .init_in  = alsa_init_in,
1014
    .fini_in  = alsa_fini_in,
1015
    .run_in   = alsa_run_in,
1016
    .read     = alsa_read,
1017
    .ctl_in   = alsa_ctl_in
1018
};
1019

    
1020
struct audio_driver alsa_audio_driver = {
1021
    .name           = "alsa",
1022
    .descr          = "ALSA http://www.alsa-project.org",
1023
    .options        = alsa_options,
1024
    .init           = alsa_audio_init,
1025
    .fini           = alsa_audio_fini,
1026
    .pcm_ops        = &alsa_pcm_ops,
1027
    .can_be_default = 1,
1028
    .max_voices_out = INT_MAX,
1029
    .max_voices_in  = INT_MAX,
1030
    .voice_size_out = sizeof (ALSAVoiceOut),
1031
    .voice_size_in  = sizeof (ALSAVoiceIn)
1032
};