Statistics
| Branch: | Revision:

root / audio / audio_template.h @ d929eba5

History | View | Annotate | Download (13.2 kB)

1
/*
2
 * QEMU Audio subsystem header
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

    
25
#ifdef DAC
26
#define NAME "playback"
27
#define HWBUF hw->mix_buf
28
#define TYPE out
29
#define HW HWVoiceOut
30
#define SW SWVoiceOut
31
#else
32
#define NAME "capture"
33
#define TYPE in
34
#define HW HWVoiceIn
35
#define SW SWVoiceIn
36
#define HWBUF hw->conv_buf
37
#endif
38

    
39
static void glue (audio_init_nb_voices_, TYPE) (
40
    AudioState *s,
41
    struct audio_driver *drv
42
    )
43
{
44
    int max_voices = glue (drv->max_voices_, TYPE);
45
    int voice_size = glue (drv->voice_size_, TYPE);
46

    
47
    if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
48
        if (!max_voices) {
49
#ifdef DAC
50
            dolog ("Driver `%s' does not support " NAME "\n", drv->name);
51
#endif
52
        }
53
        else {
54
            dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
55
                   drv->name,
56
                   glue (s->nb_hw_voices_, TYPE),
57
                   max_voices);
58
        }
59
        glue (s->nb_hw_voices_, TYPE) = max_voices;
60
    }
61

    
62
    if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
63
        dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
64
               drv->name, max_voices);
65
        glue (s->nb_hw_voices_, TYPE) = 0;
66
    }
67

    
68
    if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
69
        dolog ("drv=`%s' voice_size=%d max_voices=0\n",
70
               drv->name, voice_size);
71
    }
72
}
73

    
74
static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
75
{
76
    if (HWBUF) {
77
        qemu_free (HWBUF);
78
    }
79

    
80
    HWBUF = NULL;
81
}
82

    
83
static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
84
{
85
    HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (st_sample_t));
86
    if (!HWBUF) {
87
        dolog ("Could not allocate " NAME " buffer (%d samples)\n",
88
               hw->samples);
89
        return -1;
90
    }
91

    
92
    return 0;
93
}
94

    
95
static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
96
{
97
    if (sw->buf) {
98
        qemu_free (sw->buf);
99
    }
100

    
101
    if (sw->rate) {
102
        st_rate_stop (sw->rate);
103
    }
104

    
105
    sw->buf = NULL;
106
    sw->rate = NULL;
107
}
108

    
109
static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
110
{
111
    int samples;
112

    
113
#ifdef DAC
114
    samples = sw->hw->samples;
115
#else
116
    samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
117
#endif
118

    
119
    sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (st_sample_t));
120
    if (!sw->buf) {
121
        dolog ("Could not allocate buffer for `%s' (%d samples)\n",
122
               SW_NAME (sw), samples);
123
        return -1;
124
    }
125

    
126
#ifdef DAC
127
    sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
128
#else
129
    sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
130
#endif
131
    if (!sw->rate) {
132
        qemu_free (sw->buf);
133
        sw->buf = NULL;
134
        return -1;
135
    }
136
    return 0;
137
}
138

    
139
static int glue (audio_pcm_sw_init_, TYPE) (
140
    SW *sw,
141
    HW *hw,
142
    const char *name,
143
    audsettings_t *as
144
    )
145
{
146
    int err;
147

    
148
    audio_pcm_init_info (&sw->info, as);
149
    sw->hw = hw;
150
    sw->active = 0;
151
#ifdef DAC
152
    sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
153
    sw->total_hw_samples_mixed = 0;
154
    sw->empty = 1;
155
#else
156
    sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
157
#endif
158

    
159
#ifdef DAC
160
    sw->conv = mixeng_conv
161
#else
162
    sw->clip = mixeng_clip
163
#endif
164
        [sw->info.nchannels == 2]
165
        [sw->info.sign]
166
        [sw->info.swap_endianness]
167
        [sw->info.bits == 16];
168

    
169
    sw->name = qemu_strdup (name);
170
    err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
171
    if (err) {
172
        qemu_free (sw->name);
173
        sw->name = NULL;
174
    }
175
    return err;
176
}
177

    
178
static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
179
{
180
    glue (audio_pcm_sw_free_resources_, TYPE) (sw);
181
    if (sw->name) {
182
        qemu_free (sw->name);
183
        sw->name = NULL;
184
    }
185
}
186

    
187
static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
188
{
189
    LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
190
}
191

    
192
static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
193
{
194
    LIST_REMOVE (sw, entries);
195
}
196

    
197
static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
198
{
199
    HW *hw = *hwp;
200

    
201
    if (!hw->sw_head.lh_first) {
202
#ifdef DAC
203
        audio_detach_capture (hw);
204
#endif
205
        LIST_REMOVE (hw, entries);
206
        glue (s->nb_hw_voices_, TYPE) += 1;
207
        glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
208
        glue (hw->pcm_ops->fini_, TYPE) (hw);
209
        qemu_free (hw);
210
        *hwp = NULL;
211
    }
212
}
213

    
214
static HW *glue (audio_pcm_hw_find_any_, TYPE) (AudioState *s, HW *hw)
215
{
216
    return hw ? hw->entries.le_next : s->glue (hw_head_, TYPE).lh_first;
217
}
218

    
219
static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
220
{
221
    while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
222
        if (hw->enabled) {
223
            return hw;
224
        }
225
    }
226
    return NULL;
227
}
228

    
229
static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
230
    AudioState *s,
231
    HW *hw,
232
    audsettings_t *as
233
    )
234
{
235
    while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
236
        if (audio_pcm_info_eq (&hw->info, as)) {
237
            return hw;
238
        }
239
    }
240
    return NULL;
241
}
242

    
243
static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
244
{
245
    HW *hw;
246
    struct audio_driver *drv = s->drv;
247

    
248
    if (!glue (s->nb_hw_voices_, TYPE)) {
249
        return NULL;
250
    }
251

    
252
    if (audio_bug (AUDIO_FUNC, !drv)) {
253
        dolog ("No host audio driver\n");
254
        return NULL;
255
    }
256

    
257
    if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
258
        dolog ("Host audio driver without pcm_ops\n");
259
        return NULL;
260
    }
261

    
262
    hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
263
    if (!hw) {
264
        dolog ("Can not allocate voice `%s' size %d\n",
265
               drv->name, glue (drv->voice_size_, TYPE));
266
        return NULL;
267
    }
268

    
269
    hw->pcm_ops = drv->pcm_ops;
270
    LIST_INIT (&hw->sw_head);
271
#ifdef DAC
272
    LIST_INIT (&hw->sw_cap_head);
273
#endif
274
    if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
275
        goto err0;
276
    }
277

    
278
    if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
279
        dolog ("hw->samples=%d\n", hw->samples);
280
        goto err1;
281
    }
282

    
283
#ifdef DAC
284
    hw->clip = mixeng_clip
285
#else
286
    hw->conv = mixeng_conv
287
#endif
288
        [hw->info.nchannels == 2]
289
        [hw->info.sign]
290
        [hw->info.swap_endianness]
291
        [hw->info.bits == 16];
292

    
293
    if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
294
        goto err1;
295
    }
296

    
297
    LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
298
    glue (s->nb_hw_voices_, TYPE) -= 1;
299
#ifdef DAC
300
    audio_attach_capture (s, hw);
301
#endif
302
    return hw;
303

    
304
 err1:
305
    glue (hw->pcm_ops->fini_, TYPE) (hw);
306
 err0:
307
    qemu_free (hw);
308
    return NULL;
309
}
310

    
311
static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
312
{
313
    HW *hw;
314

    
315
    if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
316
        hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
317
        if (hw) {
318
            return hw;
319
        }
320
    }
321

    
322
    hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
323
    if (hw) {
324
        return hw;
325
    }
326

    
327
    hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
328
    if (hw) {
329
        return hw;
330
    }
331

    
332
    return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
333
}
334

    
335
static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
336
    AudioState *s,
337
    const char *sw_name,
338
    audsettings_t *as
339
    )
340
{
341
    SW *sw;
342
    HW *hw;
343
    audsettings_t hw_as;
344

    
345
    if (glue (conf.fixed_, TYPE).enabled) {
346
        hw_as = glue (conf.fixed_, TYPE).settings;
347
    }
348
    else {
349
        hw_as = *as;
350
    }
351

    
352
    sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
353
    if (!sw) {
354
        dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
355
               sw_name ? sw_name : "unknown", sizeof (*sw));
356
        goto err1;
357
    }
358

    
359
    hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
360
    if (!hw) {
361
        goto err2;
362
    }
363

    
364
    glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
365

    
366
    if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
367
        goto err3;
368
    }
369

    
370
    return sw;
371

    
372
err3:
373
    glue (audio_pcm_hw_del_sw_, TYPE) (sw);
374
    glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
375
err2:
376
    qemu_free (sw);
377
err1:
378
    return NULL;
379
}
380

    
381
static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
382
{
383
    glue (audio_pcm_sw_fini_, TYPE) (sw);
384
    glue (audio_pcm_hw_del_sw_, TYPE) (sw);
385
    glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
386
    qemu_free (sw);
387
}
388

    
389
void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
390
{
391
    if (sw) {
392
        if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
393
            dolog ("card=%p card->audio=%p\n",
394
                   card, card ? card->audio : NULL);
395
            return;
396
        }
397

    
398
        glue (audio_close_, TYPE) (card->audio, sw);
399
    }
400
}
401

    
402
SW *glue (AUD_open_, TYPE) (
403
    QEMUSoundCard *card,
404
    SW *sw,
405
    const char *name,
406
    void *callback_opaque ,
407
    audio_callback_fn_t callback_fn,
408
    audsettings_t *as
409
    )
410
{
411
    AudioState *s;
412
#ifdef DAC
413
    int live = 0;
414
    SW *old_sw = NULL;
415
#endif
416

    
417
    ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
418
            name, as->freq, as->nchannels, as->fmt);
419

    
420
    if (audio_bug (AUDIO_FUNC,
421
                   !card || !card->audio || !name || !callback_fn || !as)) {
422
        dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
423
               card, card ? card->audio : NULL, name, callback_fn, as);
424
        goto fail;
425
    }
426

    
427
    s = card->audio;
428

    
429
    if (audio_bug (AUDIO_FUNC, audio_validate_settigs (as))) {
430
        audio_print_settings (as);
431
        goto fail;
432
    }
433

    
434
    if (audio_bug (AUDIO_FUNC, !s->drv)) {
435
        dolog ("Can not open `%s' (no host audio driver)\n", name);
436
        goto fail;
437
    }
438

    
439
    if (sw && audio_pcm_info_eq (&sw->info, as)) {
440
        return sw;
441
    }
442

    
443
#ifdef DAC
444
    if (conf.plive && sw && (!sw->active && !sw->empty)) {
445
        live = sw->total_hw_samples_mixed;
446

    
447
#ifdef DEBUG_PLIVE
448
        dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
449
        dolog ("Old %s freq %d, bits %d, channels %d\n",
450
               SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
451
        dolog ("New %s freq %d, bits %d, channels %d\n",
452
               name,
453
               freq,
454
               (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
455
               nchannels);
456
#endif
457

    
458
        if (live) {
459
            old_sw = sw;
460
            old_sw->callback.fn = NULL;
461
            sw = NULL;
462
        }
463
    }
464
#endif
465

    
466
    if (!glue (conf.fixed_, TYPE).enabled && sw) {
467
        glue (AUD_close_, TYPE) (card, sw);
468
        sw = NULL;
469
    }
470

    
471
    if (sw) {
472
        HW *hw = sw->hw;
473

    
474
        if (!hw) {
475
            dolog ("Internal logic error voice `%s' has no hardware store\n",
476
                   SW_NAME (sw));
477
            goto fail;
478
        }
479

    
480
        glue (audio_pcm_sw_fini_, TYPE) (sw);
481
        if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
482
            goto fail;
483
        }
484
    }
485
    else {
486
        sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);
487
        if (!sw) {
488
            dolog ("Failed to create voice `%s'\n", name);
489
            return NULL;
490
        }
491
    }
492

    
493
    if (sw) {
494
        sw->vol = nominal_volume;
495
        sw->callback.fn = callback_fn;
496
        sw->callback.opaque = callback_opaque;
497

    
498
#ifdef DAC
499
        if (live) {
500
            int mixed =
501
                (live << old_sw->info.shift)
502
                * old_sw->info.bytes_per_second
503
                / sw->info.bytes_per_second;
504

    
505
#ifdef DEBUG_PLIVE
506
            dolog ("Silence will be mixed %d\n", mixed);
507
#endif
508
            sw->total_hw_samples_mixed += mixed;
509
        }
510
#endif
511

    
512
#ifdef DEBUG_AUDIO
513
        dolog ("%s\n", name);
514
        audio_pcm_print_info ("hw", &sw->hw->info);
515
        audio_pcm_print_info ("sw", &sw->info);
516
#endif
517
    }
518

    
519
    return sw;
520

    
521
 fail:
522
    glue (AUD_close_, TYPE) (card, sw);
523
    return NULL;
524
}
525

    
526
int glue (AUD_is_active_, TYPE) (SW *sw)
527
{
528
    return sw ? sw->active : 0;
529
}
530

    
531
void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
532
{
533
    if (!sw) {
534
        return;
535
    }
536

    
537
    ts->old_ts = sw->hw->ts_helper;
538
}
539

    
540
uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
541
{
542
    uint64_t delta, cur_ts, old_ts;
543

    
544
    if (!sw) {
545
        return 0;
546
    }
547

    
548
    cur_ts = sw->hw->ts_helper;
549
    old_ts = ts->old_ts;
550
    /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
551

    
552
    if (cur_ts >= old_ts) {
553
        delta = cur_ts - old_ts;
554
    }
555
    else {
556
        delta = UINT64_MAX - old_ts + cur_ts;
557
    }
558

    
559
    if (!delta) {
560
        return 0;
561
    }
562

    
563
    return (delta * sw->hw->info.freq) / 1000000;
564
}
565

    
566
#undef TYPE
567
#undef HW
568
#undef SW
569
#undef HWBUF
570
#undef NAME