Statistics
| Branch: | Revision:

root / audio / audio_template.h @ 26a76461

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
    int endian
145
    )
146
{
147
    int err;
148

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
267
    hw->pcm_ops = drv->pcm_ops;
268
    LIST_INIT (&hw->sw_head);
269

    
270
    if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
271
        goto err0;
272
    }
273

    
274
    if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
275
        dolog ("hw->samples=%d\n", hw->samples);
276
        goto err1;
277
    }
278

    
279
#ifdef DAC
280
    hw->clip = mixeng_clip
281
#else
282
    hw->conv = mixeng_conv
283
#endif
284
        [hw->info.nchannels == 2]
285
        [hw->info.sign]
286
        [hw->info.swap_endian]
287
        [hw->info.bits == 16];
288

    
289
    if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
290
        goto err1;
291
    }
292

    
293
    LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
294
    glue (s->nb_hw_voices_, TYPE) -= 1;
295
    return hw;
296

    
297
 err1:
298
    glue (hw->pcm_ops->fini_, TYPE) (hw);
299
 err0:
300
    qemu_free (hw);
301
    return NULL;
302
}
303

    
304
static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
305
{
306
    HW *hw;
307

    
308
    if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
309
        hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
310
        if (hw) {
311
            return hw;
312
        }
313
    }
314

    
315
    hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
316
    if (hw) {
317
        return hw;
318
    }
319

    
320
    hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
321
    if (hw) {
322
        return hw;
323
    }
324

    
325
    return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
326
}
327

    
328
static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
329
    AudioState *s,
330
    const char *sw_name,
331
    audsettings_t *as,
332
    int sw_endian
333
    )
334
{
335
    SW *sw;
336
    HW *hw;
337
    audsettings_t hw_as;
338

    
339
    if (glue (conf.fixed_, TYPE).enabled) {
340
        hw_as = glue (conf.fixed_, TYPE).settings;
341
    }
342
    else {
343
        hw_as = *as;
344
    }
345

    
346
    sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
347
    if (!sw) {
348
        dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
349
               sw_name ? sw_name : "unknown", sizeof (*sw));
350
        goto err1;
351
    }
352

    
353
    hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
354
    if (!hw) {
355
        goto err2;
356
    }
357

    
358
    glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
359

    
360
    if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as, sw_endian)) {
361
        goto err3;
362
    }
363

    
364
    return sw;
365

    
366
err3:
367
    glue (audio_pcm_hw_del_sw_, TYPE) (sw);
368
    glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
369
err2:
370
    qemu_free (sw);
371
err1:
372
    return NULL;
373
}
374

    
375
static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
376
{
377
    glue (audio_pcm_sw_fini_, TYPE) (sw);
378
    glue (audio_pcm_hw_del_sw_, TYPE) (sw);
379
    glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
380
    qemu_free (sw);
381
}
382

    
383
void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
384
{
385
    if (sw) {
386
        if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
387
            dolog ("card=%p card->audio=%p\n",
388
                   card, card ? card->audio : NULL);
389
            return;
390
        }
391

    
392
        glue (audio_close_, TYPE) (card->audio, sw);
393
    }
394
}
395

    
396
SW *glue (AUD_open_, TYPE) (
397
    QEMUSoundCard *card,
398
    SW *sw,
399
    const char *name,
400
    void *callback_opaque ,
401
    audio_callback_fn_t callback_fn,
402
    audsettings_t *as,
403
    int sw_endian
404
    )
405
{
406
    AudioState *s;
407
#ifdef DAC
408
    int live = 0;
409
    SW *old_sw = NULL;
410
#endif
411

    
412
    ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
413
            name, as->freq, as->nchannels, as->fmt);
414

    
415
    if (audio_bug (AUDIO_FUNC,
416
                   !card || !card->audio || !name || !callback_fn || !as)) {
417
        dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
418
               card, card ? card->audio : NULL, name, callback_fn, as);
419
        goto fail;
420
    }
421

    
422
    s = card->audio;
423

    
424
    if (audio_bug (AUDIO_FUNC, audio_validate_settigs (as))) {
425
        audio_print_settings (as);
426
        goto fail;
427
    }
428

    
429
    if (audio_bug (AUDIO_FUNC, !s->drv)) {
430
        dolog ("Can not open `%s' (no host audio driver)\n", name);
431
        goto fail;
432
    }
433

    
434
    if (sw && audio_pcm_info_eq (&sw->info, as)) {
435
        return sw;
436
    }
437

    
438
#ifdef DAC
439
    if (conf.plive && sw && (!sw->active && !sw->empty)) {
440
        live = sw->total_hw_samples_mixed;
441

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

    
453
        if (live) {
454
            old_sw = sw;
455
            old_sw->callback.fn = NULL;
456
            sw = NULL;
457
        }
458
    }
459
#endif
460

    
461
    if (!glue (conf.fixed_, TYPE).enabled && sw) {
462
        glue (AUD_close_, TYPE) (card, sw);
463
        sw = NULL;
464
    }
465

    
466
    if (sw) {
467
        HW *hw = sw->hw;
468

    
469
        if (!hw) {
470
            dolog ("Internal logic error voice `%s' has no hardware store\n",
471
                   SW_NAME (sw));
472
            goto fail;
473
        }
474

    
475
        glue (audio_pcm_sw_fini_, TYPE) (sw);
476
        if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as, sw_endian)) {
477
            goto fail;
478
        }
479
    }
480
    else {
481
        sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as, sw_endian);
482
        if (!sw) {
483
            dolog ("Failed to create voice `%s'\n", name);
484
            return NULL;
485
        }
486
    }
487

    
488
    if (sw) {
489
        sw->vol = nominal_volume;
490
        sw->callback.fn = callback_fn;
491
        sw->callback.opaque = callback_opaque;
492

    
493
#ifdef DAC
494
        if (live) {
495
            int mixed =
496
                (live << old_sw->info.shift)
497
                * old_sw->info.bytes_per_second
498
                / sw->info.bytes_per_second;
499

    
500
#ifdef DEBUG_PLIVE
501
            dolog ("Silence will be mixed %d\n", mixed);
502
#endif
503
            sw->total_hw_samples_mixed += mixed;
504
        }
505
#endif
506

    
507
#ifdef DEBUG_AUDIO
508
        dolog ("%s\n", name);
509
        audio_pcm_print_info ("hw", &sw->hw->info);
510
        audio_pcm_print_info ("sw", &sw->info);
511
#endif
512
    }
513

    
514
    return sw;
515

    
516
 fail:
517
    glue (AUD_close_, TYPE) (card, sw);
518
    return NULL;
519
}
520

    
521
int glue (AUD_is_active_, TYPE) (SW *sw)
522
{
523
    return sw ? sw->active : 0;
524
}
525

    
526
void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
527
{
528
    if (!sw) {
529
        return;
530
    }
531

    
532
    ts->old_ts = sw->hw->ts_helper;
533
}
534

    
535
uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
536
{
537
    uint64_t delta, cur_ts, old_ts;
538

    
539
    if (!sw) {
540
        return 0;
541
    }
542

    
543
    cur_ts = sw->hw->ts_helper;
544
    old_ts = ts->old_ts;
545
    /* dolog ("cur %" PRId64 " old %" PRId64 "\n", cur_ts, old_ts); */
546

    
547
    if (cur_ts >= old_ts) {
548
        delta = cur_ts - old_ts;
549
    }
550
    else {
551
        delta = UINT64_MAX - old_ts + cur_ts;
552
    }
553

    
554
    if (!delta) {
555
        return 0;
556
    }
557

    
558
    return (delta * sw->hw->info.freq) / 1000000;
559
}
560

    
561
#undef TYPE
562
#undef HW
563
#undef SW
564
#undef HWBUF
565
#undef NAME