Revision 1d14ffa9 audio/audio.c

b/audio/audio.c
1 1
/*
2 2
 * QEMU Audio subsystem
3
 * 
4
 * Copyright (c) 2003-2004 Vassili Karpov (malc)
5
 * 
3
 *
4
 * Copyright (c) 2003-2005 Vassili Karpov (malc)
5
 *
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
8 8
 * in the Software without restriction, including without limitation the rights
......
21 21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 22
 * THE SOFTWARE.
23 23
 */
24
#include <assert.h>
25 24
#include "vl.h"
26 25

  
27
#define USE_WAV_AUDIO
26
#define AUDIO_CAP "audio"
27
#include "audio_int.h"
28 28

  
29
#include "audio/audio_int.h"
29
static void audio_pcm_hw_fini_in (HWVoiceIn *hw);
30
static void audio_pcm_hw_fini_out (HWVoiceOut *hw);
30 31

  
31
#define dolog(...) AUD_log ("audio", __VA_ARGS__)
32
#ifdef DEBUG
33
#define ldebug(...) dolog (__VA_ARGS__)
34
#else
35
#define ldebug(...)
36
#endif
32
static LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
33
static LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
37 34

  
38
#define QC_AUDIO_DRV    "QEMU_AUDIO_DRV"
39
#define QC_VOICES       "QEMU_VOICES"
40
#define QC_FIXED_FORMAT "QEMU_FIXED_FORMAT"
41
#define QC_FIXED_FREQ   "QEMU_FIXED_FREQ"
35
/* #define DEBUG_PLIVE */
36
/* #define DEBUG_LIVE */
37
/* #define DEBUG_OUT */
42 38

  
43
static HWVoice *hw_voices;
39
static struct audio_driver *drvtab[] = {
40
#ifdef CONFIG_OSS
41
    &oss_audio_driver,
42
#endif
43
#ifdef CONFIG_ALSA
44
    &alsa_audio_driver,
45
#endif
46
#ifdef CONFIG_COREAUDIO
47
    &coreaudio_audio_driver,
48
#endif
49
#ifdef CONFIG_DSOUND
50
    &dsound_audio_driver,
51
#endif
52
#ifdef CONFIG_FMOD
53
    &fmod_audio_driver,
54
#endif
55
#ifdef CONFIG_SDL
56
    &sdl_audio_driver,
57
#endif
58
    &no_audio_driver,
59
    &wav_audio_driver
60
};
44 61

  
45 62
AudioState audio_state = {
63
    /* Out */
64
    1,                          /* use fixed settings */
65
    44100,                      /* fixed frequency */
66
    2,                          /* fixed channels */
67
    AUD_FMT_S16,                /* fixed format */
68
    1,                          /* number of hw voices */
69
    1,                          /* greedy */
70

  
71
    /* In */
46 72
    1,                          /* use fixed settings */
47 73
    44100,                      /* fixed frequency */
48 74
    2,                          /* fixed channels */
49 75
    AUD_FMT_S16,                /* fixed format */
50 76
    1,                          /* number of hw voices */
51
    -1                          /* voice size */
77
    1,                          /* greedy */
78

  
79
    NULL,                       /* driver opaque */
80
    NULL,                       /* driver */
81

  
82
    NULL,                       /* timer handle */
83
    { 0 },                      /* period */
84
    0                           /* plive */
85
};
86

  
87
volume_t nominal_volume = {
88
    0,
89
#ifdef FLOAT_MIXENG
90
    1.0,
91
    1.0
92
#else
93
    UINT_MAX,
94
    UINT_MAX
95
#endif
52 96
};
53 97

  
54 98
/* http://www.df.lth.se/~john_e/gems/gem002d.html */
......
68 112
    return popcount ((u&-u)-1);
69 113
}
70 114

  
71
int audio_get_conf_int (const char *key, int defval)
115
#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
116
#error No its not
117
#else
118
int audio_bug (const char *funcname, int cond)
72 119
{
73
    int val = defval;
74
    char *strval;
75

  
76
    strval = getenv (key);
77
    if (strval) {
78
        val = atoi (strval);
120
    if (cond) {
121
        static int shown;
122

  
123
        AUD_log (NULL, "Error a bug that was just triggered in %s\n", funcname);
124
        if (!shown) {
125
            shown = 1;
126
            AUD_log (NULL, "Save all your work and restart without audio\n");
127
            AUD_log (NULL, "Please send bug report to malc@pulsesoft.com\n");
128
            AUD_log (NULL, "I am sorry\n");
129
        }
130
        AUD_log (NULL, "Context:\n");
131

  
132
#if defined AUDIO_BREAKPOINT_ON_BUG
133
#  if defined HOST_I386
134
#    if defined __GNUC__
135
        __asm__ ("int3");
136
#    elif defined _MSC_VER
137
        _asm _emit 0xcc;
138
#    else
139
        abort ();
140
#    endif
141
#  else
142
        abort ();
143
#  endif
144
#endif
79 145
    }
80 146

  
81
    return val;
147
    return cond;
82 148
}
149
#endif
83 150

  
84
const char *audio_get_conf_str (const char *key, const char *defval)
151
static char *audio_alloc_prefix (const char *s)
85 152
{
86
    const char *val = getenv (key);
87
    if (!val)
88
        return defval;
89
    else
90
        return val;
91
}
153
    const char qemu_prefix[] = "QEMU_";
154
    size_t len;
155
    char *r;
92 156

  
93
void AUD_log (const char *cap, const char *fmt, ...)
94
{
95
    va_list ap;
96
    fprintf (stderr, "%s: ", cap);
97
    va_start (ap, fmt);
98
    vfprintf (stderr, fmt, ap);
99
    va_end (ap);
100
}
157
    if (!s) {
158
        return NULL;
159
    }
101 160

  
102
/*
103
 * Soft Voice
104
 */
105
void pcm_sw_free_resources (SWVoice *sw)
106
{
107
    if (sw->buf) qemu_free (sw->buf);
108
    if (sw->rate) st_rate_stop (sw->rate);
109
    sw->buf = NULL;
110
    sw->rate = NULL;
111
}
161
    len = strlen (s);
162
    r = qemu_malloc (len + sizeof (qemu_prefix));
112 163

  
113
int pcm_sw_alloc_resources (SWVoice *sw)
114
{
115
    sw->buf = qemu_mallocz (sw->hw->samples * sizeof (st_sample_t));
116
    if (!sw->buf)
117
        return -1;
164
    if (r) {
165
        size_t i;
166
        char *u = r + sizeof (qemu_prefix) - 1;
118 167

  
119
    sw->rate = st_rate_start (sw->freq, sw->hw->freq);
120
    if (!sw->rate) {
121
        qemu_free (sw->buf);
122
        sw->buf = NULL;
123
        return -1;
168
        strcpy (r, qemu_prefix);
169
        strcat (r, s);
170

  
171
        for (i = 0; i < len; ++i) {
172
            u[i] = toupper (u[i]);
173
        }
124 174
    }
125
    return 0;
175
    return r;
126 176
}
127 177

  
128
void pcm_sw_fini (SWVoice *sw)
178
const char *audio_audfmt_to_string (audfmt_e fmt)
129 179
{
130
    pcm_sw_free_resources (sw);
131
}
180
    switch (fmt) {
181
    case AUD_FMT_U8:
182
        return "U8";
132 183

  
133
int pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
134
                 int nchannels, audfmt_e fmt)
135
{
136
    int bits = 8, sign = 0;
184
    case AUD_FMT_U16:
185
        return "U16";
137 186

  
138
    switch (fmt) {
139 187
    case AUD_FMT_S8:
140
        sign = 1;
141
    case AUD_FMT_U8:
142
        break;
188
        return "S8";
143 189

  
144 190
    case AUD_FMT_S16:
145
        sign = 1;
146
    case AUD_FMT_U16:
147
        bits = 16;
148
        break;
191
        return "S16";
149 192
    }
150 193

  
151
    sw->hw = hw;
152
    sw->freq = freq;
153
    sw->fmt = fmt;
154
    sw->nchannels = nchannels;
155
    sw->shift = (nchannels == 2) + (bits == 16);
156
    sw->align = (1 << sw->shift) - 1;
157
    sw->left = 0;
158
    sw->pos = 0;
159
    sw->wpos = 0;
160
    sw->live = 0;
161
    sw->ratio = (sw->hw->freq * ((int64_t) INT_MAX)) / sw->freq;
162
    sw->bytes_per_second = sw->freq << sw->shift;
163
    sw->conv = mixeng_conv[nchannels == 2][sign][bits == 16];
164

  
165
    pcm_sw_free_resources (sw);
166
    return pcm_sw_alloc_resources (sw);
167
}
168

  
169
/* Hard voice */
170
void pcm_hw_free_resources (HWVoice *hw)
171
{
172
    if (hw->mix_buf)
173
        qemu_free (hw->mix_buf);
174
    hw->mix_buf = NULL;
194
    dolog ("Bogus audfmt %d returning S16\n", fmt);
195
    return "S16";
175 196
}
176 197

  
177
int pcm_hw_alloc_resources (HWVoice *hw)
198
audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp)
178 199
{
179
    hw->mix_buf = qemu_mallocz (hw->samples * sizeof (st_sample_t));
180
    if (!hw->mix_buf)
181
        return -1;
182
    return 0;
200
    if (!strcasecmp (s, "u8")) {
201
        *defaultp = 0;
202
        return AUD_FMT_U8;
203
    }
204
    else if (!strcasecmp (s, "u16")) {
205
        *defaultp = 0;
206
        return AUD_FMT_U16;
207
    }
208
    else if (!strcasecmp (s, "s8")) {
209
        *defaultp = 0;
210
        return AUD_FMT_S8;
211
    }
212
    else if (!strcasecmp (s, "s16")) {
213
        *defaultp = 0;
214
        return AUD_FMT_S16;
215
    }
216
    else {
217
        dolog ("Bogus audio format `%s' using %s\n",
218
               s, audio_audfmt_to_string (defval));
219
        *defaultp = 1;
220
        return defval;
221
    }
183 222
}
184 223

  
185
void pcm_hw_fini (HWVoice *hw)
224
static audfmt_e audio_get_conf_fmt (const char *envname,
225
                                    audfmt_e defval,
226
                                    int *defaultp)
186 227
{
187
    if (hw->active) {
188
        ldebug ("pcm_hw_fini: %d %d %d\n", hw->freq, hw->nchannels, hw->fmt);
189
        pcm_hw_free_resources (hw);
190
        hw->pcm_ops->fini (hw);
191
        memset (hw, 0, audio_state.drv->voice_size);
228
    const char *var = getenv (envname);
229
    if (!var) {
230
        *defaultp = 1;
231
        return defval;
192 232
    }
233
    return audio_string_to_audfmt (var, defval, defaultp);
193 234
}
194 235

  
195
void pcm_hw_gc (HWVoice *hw)
236
static int audio_get_conf_int (const char *key, int defval, int *defaultp)
196 237
{
197
    if (hw->nb_voices)
198
        return;
238
    int val;
239
    char *strval;
199 240

  
200
    pcm_hw_fini (hw);
241
    strval = getenv (key);
242
    if (strval) {
243
        *defaultp = 0;
244
        val = atoi (strval);
245
        return val;
246
    }
247
    else {
248
        *defaultp = 1;
249
        return defval;
250
    }
201 251
}
202 252

  
203
int pcm_hw_get_live (HWVoice *hw)
253
static const char *audio_get_conf_str (const char *key,
254
                                       const char *defval,
255
                                       int *defaultp)
204 256
{
205
    int i, alive = 0, live = hw->samples;
206

  
207
    for (i = 0; i < hw->nb_voices; i++) {
208
        if (hw->pvoice[i]->live) {
209
            live = audio_MIN (hw->pvoice[i]->live, live);
210
            alive += 1;
211
        }
257
    const char *val = getenv (key);
258
    if (!val) {
259
        *defaultp = 1;
260
        return defval;
261
    }
262
    else {
263
        *defaultp = 0;
264
        return val;
212 265
    }
213

  
214
    if (alive)
215
        return live;
216
    else
217
        return -1;
218 266
}
219 267

  
220
int pcm_hw_get_live2 (HWVoice *hw, int *nb_active)
268
void AUD_log (const char *cap, const char *fmt, ...)
221 269
{
222
    int i, alive = 0, live = hw->samples;
223

  
224
    *nb_active = 0;
225
    for (i = 0; i < hw->nb_voices; i++) {
226
        if (hw->pvoice[i]->live) {
227
            if (hw->pvoice[i]->live < live) {
228
                *nb_active = hw->pvoice[i]->active != 0;
229
                live = hw->pvoice[i]->live;
230
            }
231
            alive += 1;
232
        }
270
    va_list ap;
271
    if (cap) {
272
        fprintf (stderr, "%s: ", cap);
233 273
    }
234

  
235
    if (alive)
236
        return live;
237
    else
238
        return -1;
274
    va_start (ap, fmt);
275
    vfprintf (stderr, fmt, ap);
276
    va_end (ap);
239 277
}
240 278

  
241
void pcm_hw_dec_live (HWVoice *hw, int decr)
279
void AUD_vlog (const char *cap, const char *fmt, va_list ap)
242 280
{
243
    int i;
244

  
245
    for (i = 0; i < hw->nb_voices; i++) {
246
        if (hw->pvoice[i]->live) {
247
            hw->pvoice[i]->live -= decr;
248
        }
281
    if (cap) {
282
        fprintf (stderr, "%s: ", cap);
249 283
    }
284
    vfprintf (stderr, fmt, ap);
250 285
}
251 286

  
252
void pcm_hw_clear (HWVoice *hw, void *buf, int len)
287
static void audio_print_options (const char *prefix,
288
                                 struct audio_option *opt)
253 289
{
254
    if (!len)
290
    char *uprefix;
291

  
292
    if (!prefix) {
293
        dolog ("No prefix specified\n");
294
        return;
295
    }
296

  
297
    if (!opt) {
298
        dolog ("No options\n");
255 299
        return;
300
    }
256 301

  
257
    switch (hw->fmt) {
258
    case AUD_FMT_S16:
259
    case AUD_FMT_S8:
260
        memset (buf, len << hw->shift, 0x00);
261
        break;
302
    uprefix = audio_alloc_prefix (prefix);
262 303

  
263
    case AUD_FMT_U8:
264
        memset (buf, len << hw->shift, 0x80);
265
        break;
304
    for (; opt->name; opt++) {
305
        const char *state = "default";
306
        printf ("  %s_%s: ", uprefix, opt->name);
266 307

  
267
    case AUD_FMT_U16:
268
        {
269
            unsigned int i;
270
            uint16_t *p = buf;
271
            int shift = hw->nchannels - 1;
308
        if (opt->overridenp && *opt->overridenp) {
309
            state = "current";
310
        }
272 311

  
273
            for (i = 0; i < len << shift; i++) {
274
                p[i] = INT16_MAX;
312
        switch (opt->tag) {
313
        case AUD_OPT_BOOL:
314
            {
315
                int *intp = opt->valp;
316
                printf ("boolean, %s = %d\n", state, *intp ? 1 : 0);
317
            }
318
            break;
319

  
320
        case AUD_OPT_INT:
321
            {
322
                int *intp = opt->valp;
323
                printf ("integer, %s = %d\n", state, *intp);
324
            }
325
            break;
326

  
327
        case AUD_OPT_FMT:
328
            {
329
                audfmt_e *fmtp = opt->valp;
330
                printf (
331
                    "format, %s = %s, (one of: U8 S8 U16 S16)\n",
332
                    state,
333
                    audio_audfmt_to_string (*fmtp)
334
                    );
335
            }
336
            break;
337

  
338
        case AUD_OPT_STR:
339
            {
340
                const char **strp = opt->valp;
341
                printf ("string, %s = %s\n",
342
                        state,
343
                        *strp ? *strp : "(not set)");
275 344
            }
345
            break;
346

  
347
        default:
348
            printf ("???\n");
349
            dolog ("Bad value tag for option %s_%s %d\n",
350
                   uprefix, opt->name, opt->tag);
351
            break;
276 352
        }
277
        break;
353
        printf ("    %s\n", opt->descr);
278 354
    }
355

  
356
    qemu_free (uprefix);
279 357
}
280 358

  
281
int pcm_hw_write (SWVoice *sw, void *buf, int size)
359
static void audio_process_options (const char *prefix,
360
                                   struct audio_option *opt)
282 361
{
283
    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
284
    int ret = 0, pos = 0;
285
    if (!sw)
286
        return size;
362
    char *optname;
363
    const char qemu_prefix[] = "QEMU_";
364
    size_t preflen;
287 365

  
288
    hwsamples = sw->hw->samples;
289
    samples = size >> sw->shift;
366
    if (audio_bug (AUDIO_FUNC, !prefix)) {
367
        dolog ("prefix = NULL\n");
368
        return;
369
    }
290 370

  
291
    if (!sw->live) {
292
        sw->wpos = sw->hw->rpos;
371
    if (audio_bug (AUDIO_FUNC, !opt)) {
372
        dolog ("opt = NULL\n");
373
        return;
293 374
    }
294
    wpos = sw->wpos;
295
    live = sw->live;
296
    dead = hwsamples - live;
297
    swlim = (dead * ((int64_t) INT_MAX)) / sw->ratio;
298
    swlim = audio_MIN (swlim, samples);
299 375

  
300
    ldebug ("size=%d live=%d dead=%d swlim=%d wpos=%d\n",
301
           size, live, dead, swlim, wpos);
302
    if (swlim)
303
        sw->conv (sw->buf, buf, swlim);
376
    preflen = strlen (prefix);
304 377

  
305
    while (swlim) {
306
        dead = hwsamples - live;
307
        left = hwsamples - wpos;
308
        blck = audio_MIN (dead, left);
309
        if (!blck) {
310
            /* dolog ("swlim=%d\n", swlim); */
378
    for (; opt->name; opt++) {
379
        size_t len, i;
380
        int def;
381

  
382
        if (!opt->valp) {
383
            dolog ("Option value pointer for `%s' is not set\n",
384
                   opt->name);
385
            continue;
386
        }
387

  
388
        len = strlen (opt->name);
389
        optname = qemu_malloc (len + preflen + sizeof (qemu_prefix) + 1);
390
        if (!optname) {
391
            dolog ("Can not allocate memory for option name `%s'\n",
392
                   opt->name);
393
            continue;
394
        }
395

  
396
        strcpy (optname, qemu_prefix);
397
        for (i = 0; i <= preflen; ++i) {
398
            optname[i + sizeof (qemu_prefix) - 1] = toupper (prefix[i]);
399
        }
400
        strcat (optname, "_");
401
        strcat (optname, opt->name);
402

  
403
        def = 1;
404
        switch (opt->tag) {
405
        case AUD_OPT_BOOL:
406
        case AUD_OPT_INT:
407
            {
408
                int *intp = opt->valp;
409
                *intp = audio_get_conf_int (optname, *intp, &def);
410
            }
411
            break;
412

  
413
        case AUD_OPT_FMT:
414
            {
415
                audfmt_e *fmtp = opt->valp;
416
                *fmtp = audio_get_conf_fmt (optname, *fmtp, &def);
417
            }
418
            break;
419

  
420
        case AUD_OPT_STR:
421
            {
422
                const char **strp = opt->valp;
423
                *strp = audio_get_conf_str (optname, *strp, &def);
424
            }
425
            break;
426

  
427
        default:
428
            dolog ("Bad value tag for option `%s' - %d\n",
429
                   optname, opt->tag);
311 430
            break;
312 431
        }
313
        isamp = swlim;
314
        osamp = blck;
315
        st_rate_flow (sw->rate, sw->buf + pos, sw->hw->mix_buf + wpos, &isamp, &osamp);
316
        ret += isamp;
317
        swlim -= isamp;
318
        pos += isamp;
319
        live += osamp;
320
        wpos = (wpos + osamp) % hwsamples;
321
    }
322 432

  
323
    sw->wpos = wpos;
324
    sw->live = live;
325
    return ret << sw->shift;
433
        if (!opt->overridenp) {
434
            opt->overridenp = &opt->overriden;
435
        }
436
        *opt->overridenp = !def;
437
        qemu_free (optname);
438
    }
326 439
}
327 440

  
328
int pcm_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
441
static int audio_pcm_info_eq (struct audio_pcm_info *info, int freq,
442
                              int nchannels, audfmt_e fmt)
329 443
{
330
    int sign = 0, bits = 8;
444
    int bits = 8, sign = 0;
331 445

  
332
    pcm_hw_fini (hw);
333
    ldebug ("pcm_hw_init: %d %d %d\n", freq, nchannels, fmt);
334
    if (hw->pcm_ops->init (hw, freq, nchannels, fmt)) {
335
        memset (hw, 0, audio_state.drv->voice_size);
336
        return -1;
446
    switch (fmt) {
447
    case AUD_FMT_S8:
448
        sign = 1;
449
    case AUD_FMT_U8:
450
        break;
451

  
452
    case AUD_FMT_S16:
453
        sign = 1;
454
    case AUD_FMT_U16:
455
        bits = 16;
456
        break;
337 457
    }
458
    return info->freq == freq
459
        && info->nchannels == nchannels
460
        && info->sign == sign
461
        && info->bits == bits;
462
}
338 463

  
339
    switch (hw->fmt) {
464
void audio_pcm_init_info (struct audio_pcm_info *info, int freq,
465
                          int nchannels, audfmt_e fmt, int swap_endian)
466
{
467
    int bits = 8, sign = 0;
468

  
469
    switch (fmt) {
340 470
    case AUD_FMT_S8:
341 471
        sign = 1;
342 472
    case AUD_FMT_U8:
......
349 479
        break;
350 480
    }
351 481

  
352
    hw->nb_voices = 0;
353
    hw->active = 1;
354
    hw->shift = (hw->nchannels == 2) + (bits == 16);
355
    hw->bytes_per_second = hw->freq << hw->shift;
356
    hw->align = (1 << hw->shift) - 1;
357
    hw->samples = hw->bufsize >> hw->shift;
358
    hw->clip = mixeng_clip[hw->nchannels == 2][sign][bits == 16];
359
    if (pcm_hw_alloc_resources (hw)) {
360
        pcm_hw_fini (hw);
361
        return -1;
362
    }
363
    return 0;
482
    info->freq = freq;
483
    info->bits = bits;
484
    info->sign = sign;
485
    info->nchannels = nchannels;
486
    info->shift = (nchannels == 2) + (bits == 16);
487
    info->align = (1 << info->shift) - 1;
488
    info->bytes_per_second = info->freq << info->shift;
489
    info->swap_endian = swap_endian;
364 490
}
365 491

  
366
static int dist (void *hw)
492
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
367 493
{
368
    if (hw) {
369
        return (((uint8_t *) hw - (uint8_t *) hw_voices)
370
                / audio_state.drv->voice_size) + 1;
494
    if (!len) {
495
        return;
496
    }
497

  
498
    if (info->sign) {
499
        memset (buf, len << info->shift, 0x00);
371 500
    }
372 501
    else {
373
        return 0;
502
        if (info->bits == 8) {
503
            memset (buf, len << info->shift, 0x80);
504
        }
505
        else {
506
            int i;
507
            uint16_t *p = buf;
508
            int shift = info->nchannels - 1;
509
            short s = INT16_MAX;
510

  
511
            if (info->swap_endian) {
512
                s = bswap16 (s);
513
            }
514

  
515
            for (i = 0; i < len << shift; i++) {
516
                p[i] = s;
517
            }
518
        }
374 519
    }
375 520
}
376 521

  
377
#define ADVANCE(hw) \
378
    ((hw) ? advance (hw, audio_state.drv->voice_size) : hw_voices)
379

  
380
HWVoice *pcm_hw_find_any (HWVoice *hw)
522
/*
523
 * Hard voice (capture)
524
 */
525
static void audio_pcm_hw_free_resources_in (HWVoiceIn *hw)
381 526
{
382
    int i = dist (hw);
383
    for (; i < audio_state.nb_hw_voices; i++) {
384
        hw = ADVANCE (hw);
385
        return hw;
527
    if (hw->conv_buf) {
528
        qemu_free (hw->conv_buf);
386 529
    }
387
    return NULL;
530
    hw->conv_buf = NULL;
388 531
}
389 532

  
390
HWVoice *pcm_hw_find_any_active (HWVoice *hw)
533
static int audio_pcm_hw_alloc_resources_in (HWVoiceIn *hw)
391 534
{
392
    int i = dist (hw);
393
    for (; i < audio_state.nb_hw_voices; i++) {
394
        hw = ADVANCE (hw);
395
        if (hw->active)
396
            return hw;
535
    hw->conv_buf = qemu_mallocz (hw->samples * sizeof (st_sample_t));
536
    if (!hw->conv_buf) {
537
        return -1;
397 538
    }
398
    return NULL;
539
    return 0;
399 540
}
400 541

  
401
HWVoice *pcm_hw_find_any_active_enabled (HWVoice *hw)
542
static int audio_pcm_hw_init_in (HWVoiceIn *hw, int freq, int nchannels, audfmt_e fmt)
402 543
{
403
    int i = dist (hw);
404
    for (; i < audio_state.nb_hw_voices; i++) {
405
        hw = ADVANCE (hw);
406
        if (hw->active && hw->enabled)
407
            return hw;
544
    audio_pcm_hw_fini_in (hw);
545

  
546
    if (hw->pcm_ops->init_in (hw, freq, nchannels, fmt)) {
547
        memset (hw, 0, audio_state.drv->voice_size_in);
548
        return -1;
408 549
    }
409
    return NULL;
550
    LIST_INIT (&hw->sw_head);
551
    hw->active = 1;
552
    hw->samples = hw->bufsize >> hw->info.shift;
553
    hw->conv =
554
        mixeng_conv
555
        [nchannels == 2]
556
        [hw->info.sign]
557
        [hw->info.swap_endian]
558
        [hw->info.bits == 16];
559
    if (audio_pcm_hw_alloc_resources_in (hw)) {
560
        audio_pcm_hw_free_resources_in (hw);
561
        return -1;
562
    }
563
    return 0;
410 564
}
411 565

  
412
HWVoice *pcm_hw_find_any_passive (HWVoice *hw)
566
static uint64_t audio_pcm_hw_find_min_in (HWVoiceIn *hw)
413 567
{
414
    int i = dist (hw);
415
    for (; i < audio_state.nb_hw_voices; i++) {
416
        hw = ADVANCE (hw);
417
        if (!hw->active)
418
            return hw;
568
    SWVoiceIn *sw;
569
    int m = hw->total_samples_captured;
570

  
571
    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
572
        if (sw->active) {
573
            m = audio_MIN (m, sw->total_hw_samples_acquired);
574
        }
419 575
    }
420
    return NULL;
576
    return m;
421 577
}
422 578

  
423
HWVoice *pcm_hw_find_specific (HWVoice *hw, int freq,
424
                               int nchannels, audfmt_e fmt)
579
int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
425 580
{
426
    while ((hw = pcm_hw_find_any_active (hw))) {
427
        if (hw->freq == freq &&
428
            hw->nchannels == nchannels &&
429
            hw->fmt == fmt)
430
            return hw;
581
    int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
582
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
583
        dolog ("live=%d hw->samples=%d\n", live, hw->samples);
584
        return 0;
431 585
    }
432
    return NULL;
586
    return live;
433 587
}
434 588

  
435
HWVoice *pcm_hw_add (int freq, int nchannels, audfmt_e fmt)
589
/*
590
 * Soft voice (capture)
591
 */
592
static void audio_pcm_sw_free_resources_in (SWVoiceIn *sw)
436 593
{
437
    HWVoice *hw;
438

  
439
    if (audio_state.fixed_format) {
440
        freq = audio_state.fixed_freq;
441
        nchannels = audio_state.fixed_channels;
442
        fmt = audio_state.fixed_fmt;
594
    if (sw->conv_buf) {
595
        qemu_free (sw->conv_buf);
443 596
    }
444 597

  
445
    hw = pcm_hw_find_specific (NULL, freq, nchannels, fmt);
446

  
447
    if (hw)
448
        return hw;
449

  
450
    hw = pcm_hw_find_any_passive (NULL);
451
    if (hw) {
452
        hw->pcm_ops = audio_state.drv->pcm_ops;
453
        if (!hw->pcm_ops)
454
            return NULL;
455

  
456
        if (pcm_hw_init (hw, freq, nchannels, fmt)) {
457
            pcm_hw_gc (hw);
458
            return NULL;
459
        }
460
        else
461
            return hw;
598
    if (sw->rate) {
599
        st_rate_stop (sw->rate);
462 600
    }
463 601

  
464
    return pcm_hw_find_any (NULL);
602
    sw->conv_buf = NULL;
603
    sw->rate = NULL;
465 604
}
466 605

  
467
int pcm_hw_add_sw (HWVoice *hw, SWVoice *sw)
606
static int audio_pcm_sw_alloc_resources_in (SWVoiceIn *sw)
468 607
{
469
    SWVoice **pvoice = qemu_mallocz ((hw->nb_voices + 1) * sizeof (sw));
470
    if (!pvoice)
608
    int samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
609
    sw->conv_buf = qemu_mallocz (samples * sizeof (st_sample_t));
610
    if (!sw->conv_buf) {
471 611
        return -1;
612
    }
472 613

  
473
    memcpy (pvoice, hw->pvoice, hw->nb_voices * sizeof (sw));
474
    qemu_free (hw->pvoice);
475
    hw->pvoice = pvoice;
476
    hw->pvoice[hw->nb_voices++] = sw;
614
    sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
615
    if (!sw->rate) {
616
        qemu_free (sw->conv_buf);
617
        sw->conv_buf = NULL;
618
        return -1;
619
    }
477 620
    return 0;
478 621
}
479 622

  
480
int pcm_hw_del_sw (HWVoice *hw, SWVoice *sw)
623
static int audio_pcm_sw_init_in (SWVoiceIn *sw, HWVoiceIn *hw, const char *name,
624
                           int freq, int nchannels, audfmt_e fmt)
481 625
{
482
    int i, j;
483
    if (hw->nb_voices > 1) {
484
        SWVoice **pvoice = qemu_mallocz ((hw->nb_voices - 1) * sizeof (sw));
626
    audio_pcm_init_info (&sw->info, freq, nchannels, fmt,
627
                         /* None of the cards emulated by QEMU are big-endian
628
                            hence following shortcut */
629
                         audio_need_to_swap_endian (0));
630
    sw->hw = hw;
631
    sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
485 632

  
486
        if (!pvoice) {
487
            dolog ("Can not maintain consistent state (not enough memory)\n");
488
            return -1;
489
        }
633
    sw->clip =
634
        mixeng_clip
635
        [nchannels == 2]
636
        [sw->info.sign]
637
        [sw->info.swap_endian]
638
        [sw->info.bits == 16];
490 639

  
491
        for (i = 0, j = 0; i < hw->nb_voices; i++) {
492
            if (j >= hw->nb_voices - 1) {
493
                dolog ("Can not maintain consistent state "
494
                       "(invariant violated)\n");
495
                return -1;
496
            }
497
            if (hw->pvoice[i] != sw)
498
                pvoice[j++] = hw->pvoice[i];
499
        }
500
        qemu_free (hw->pvoice);
501
        hw->pvoice = pvoice;
502
        hw->nb_voices -= 1;
640
    sw->name = qemu_strdup (name);
641
    audio_pcm_sw_free_resources_in (sw);
642
    return audio_pcm_sw_alloc_resources_in (sw);
643
}
644

  
645
static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
646
{
647
    HWVoiceIn *hw = sw->hw;
648
    int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
649
    int rpos;
650

  
651
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
652
        dolog ("live=%d hw->samples=%d\n", live, hw->samples);
653
        return 0;
654
    }
655

  
656
    rpos = hw->wpos - live;
657
    if (rpos >= 0) {
658
        return rpos;
503 659
    }
504 660
    else {
505
        qemu_free (hw->pvoice);
506
        hw->pvoice = NULL;
507
        hw->nb_voices = 0;
661
        return hw->samples + rpos;
508 662
    }
509
    return 0;
510 663
}
511 664

  
512
SWVoice *pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt)
665
int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
513 666
{
514
    SWVoice *sw;
515
    HWVoice *hw;
667
    HWVoiceIn *hw = sw->hw;
668
    int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
669
    st_sample_t *src, *dst = sw->conv_buf;
670

  
671
    rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;
672

  
673
    live = hw->total_samples_captured - sw->total_hw_samples_acquired;
674
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
675
        dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);
676
        return 0;
677
    }
678

  
679
    samples = size >> sw->info.shift;
680
    if (!live) {
681
        return 0;
682
    }
516 683

  
517
    sw = qemu_mallocz (sizeof (*sw));
518
    if (!sw)
519
        goto err1;
684
    swlim = (live * sw->ratio) >> 32;
685
    swlim = audio_MIN (swlim, samples);
520 686

  
521
    hw = pcm_hw_add (freq, nchannels, fmt);
522
    if (!hw)
523
        goto err2;
687
    while (swlim) {
688
        src = hw->conv_buf + rpos;
689
        isamp = hw->wpos - rpos;
690
        /* XXX: <= ? */
691
        if (isamp <= 0) {
692
            isamp = hw->samples - rpos;
693
        }
524 694

  
525
    if (pcm_hw_add_sw (hw, sw))
526
        goto err3;
695
        if (!isamp) {
696
            break;
697
        }
698
        osamp = swlim;
527 699

  
528
    if (pcm_sw_init (sw, hw, freq, nchannels, fmt))
529
        goto err4;
700
        if (audio_bug (AUDIO_FUNC, osamp < 0)) {
701
            dolog ("osamp=%d\n", osamp);
702
        }
530 703

  
531
    return sw;
704
        st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
705
        swlim -= osamp;
706
        rpos = (rpos + isamp) % hw->samples;
707
        dst += osamp;
708
        ret += osamp;
709
        total += isamp;
710
    }
532 711

  
533
err4:
534
    pcm_hw_del_sw (hw, sw);
535
err3:
536
    pcm_hw_gc (hw);
537
err2:
538
    qemu_free (sw);
539
err1:
540
    return NULL;
712
    sw->clip (buf, sw->conv_buf, ret);
713
    sw->total_hw_samples_acquired += total;
714
    return ret << sw->info.shift;
541 715
}
542 716

  
543
SWVoice *AUD_open (SWVoice *sw, const char *name,
544
                   int freq, int nchannels, audfmt_e fmt)
717
/*
718
 * Hard voice (playback)
719
 */
720
static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
545 721
{
546
    if (!audio_state.drv) {
547
        return NULL;
722
    SWVoiceOut *sw;
723
    int m = INT_MAX;
724
    int nb_live = 0;
725

  
726
    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
727
        if (sw->active || !sw->empty) {
728
            m = audio_MIN (m, sw->total_hw_samples_mixed);
729
            nb_live += 1;
730
        }
548 731
    }
549 732

  
550
    if (sw && freq == sw->freq && sw->nchannels == nchannels && sw->fmt == fmt) {
551
        return sw;
733
    *nb_livep = nb_live;
734
    return m;
735
}
736

  
737
static void audio_pcm_hw_free_resources_out (HWVoiceOut *hw)
738
{
739
    if (hw->mix_buf) {
740
        qemu_free (hw->mix_buf);
552 741
    }
553 742

  
554
    if (sw) {
555
        ldebug ("Different format %s %d %d %d\n",
556
                name,
557
                sw->freq == freq,
558
                sw->nchannels == nchannels,
559
                sw->fmt == fmt);
743
    hw->mix_buf = NULL;
744
}
745

  
746
static int audio_pcm_hw_alloc_resources_out (HWVoiceOut *hw)
747
{
748
    hw->mix_buf = qemu_mallocz (hw->samples * sizeof (st_sample_t));
749
    if (!hw->mix_buf) {
750
        return -1;
560 751
    }
561 752

  
562
    if (nchannels != 1 && nchannels != 2) {
563
        dolog ("Bogus channel count %d for voice %s\n", nchannels, name);
564
        return NULL;
753
    return 0;
754
}
755

  
756
static int audio_pcm_hw_init_out (HWVoiceOut *hw, int freq,
757
                            int nchannels, audfmt_e fmt)
758
{
759
    audio_pcm_hw_fini_out (hw);
760
    if (hw->pcm_ops->init_out (hw, freq, nchannels, fmt)) {
761
        memset (hw, 0, audio_state.drv->voice_size_out);
762
        return -1;
565 763
    }
566 764

  
567
    if (!audio_state.fixed_format && sw) {
568
        pcm_sw_fini (sw);
569
        pcm_hw_del_sw (sw->hw, sw);
570
        pcm_hw_gc (sw->hw);
571
        if (sw->name) {
572
            qemu_free (sw->name);
573
            sw->name = NULL;
574
        }
575
        qemu_free (sw);
576
        sw = NULL;
765
    LIST_INIT (&hw->sw_head);
766
    hw->active = 1;
767
    hw->samples = hw->bufsize >> hw->info.shift;
768
    hw->clip =
769
        mixeng_clip
770
        [nchannels == 2]
771
        [hw->info.sign]
772
        [hw->info.swap_endian]
773
        [hw->info.bits == 16];
774
    if (audio_pcm_hw_alloc_resources_out (hw)) {
775
        audio_pcm_hw_fini_out (hw);
776
        return -1;
577 777
    }
778
    return 0;
779
}
578 780

  
579
    if (sw) {
580
        HWVoice *hw = sw->hw;
581
        if (!hw) {
582
            dolog ("Internal logic error voice %s has no hardware store\n",
583
                   name);
584
            return sw;
585
        }
781
int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live)
782
{
783
    int smin;
586 784

  
587
        if (pcm_sw_init (sw, hw, freq, nchannels, fmt)) {
588
            pcm_sw_fini (sw);
589
            pcm_hw_del_sw (hw, sw);
590
            pcm_hw_gc (hw);
591
            if (sw->name) {
592
                qemu_free (sw->name);
593
                sw->name = NULL;
594
            }
595
            qemu_free (sw);
596
            return NULL;
597
        }
785
    smin = audio_pcm_hw_find_min_out (hw, nb_live);
786

  
787
    if (!*nb_live) {
788
        return 0;
598 789
    }
599 790
    else {
600
        sw = pcm_create_voice_pair (freq, nchannels, fmt);
601
        if (!sw) {
602
            dolog ("Failed to create voice %s\n", name);
603
            return NULL;
791
        int live = smin;
792

  
793
        if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
794
            dolog ("live=%d hw->samples=%d\n", live, hw->samples);
795
            return 0;
604 796
        }
797
        return live;
605 798
    }
799
}
800

  
801
int audio_pcm_hw_get_live_out (HWVoiceOut *hw)
802
{
803
    int nb_live;
804
    int live;
606 805

  
607
    if (sw->name) {
608
        qemu_free (sw->name);
609
        sw->name = NULL;
806
    live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
807
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
808
        dolog ("live=%d hw->samples=%d\n", live, hw->samples);
809
        return 0;
610 810
    }
611
    sw->name = qemu_strdup (name);
612
    return sw;
811
    return live;
613 812
}
614 813

  
615
void AUD_close (SWVoice *sw)
814
/*
815
 * Soft voice (playback)
816
 */
817
static void audio_pcm_sw_free_resources_out (SWVoiceOut *sw)
616 818
{
617
    if (!sw)
618
        return;
819
    if (sw->buf) {
820
        qemu_free (sw->buf);
821
    }
619 822

  
620
    pcm_sw_fini (sw);
621
    pcm_hw_del_sw (sw->hw, sw);
622
    pcm_hw_gc (sw->hw);
623
    if (sw->name) {
624
        qemu_free (sw->name);
625
        sw->name = NULL;
823
    if (sw->rate) {
824
        st_rate_stop (sw->rate);
626 825
    }
627
    qemu_free (sw);
826

  
827
    sw->buf = NULL;
828
    sw->rate = NULL;
628 829
}
629 830

  
630
int AUD_write (SWVoice *sw, void *buf, int size)
831
static int audio_pcm_sw_alloc_resources_out (SWVoiceOut *sw)
631 832
{
632
    int bytes;
833
    sw->buf = qemu_mallocz (sw->hw->samples * sizeof (st_sample_t));
834
    if (!sw->buf) {
835
        return -1;
836
    }
633 837

  
634
    if (!sw->hw->enabled)
635
        dolog ("Writing to disabled voice %s\n", sw->name);
636
    bytes = sw->hw->pcm_ops->write (sw, buf, size);
637
    return bytes;
838
    sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
839
    if (!sw->rate) {
840
        qemu_free (sw->buf);
841
        sw->buf = NULL;
842
        return -1;
843
    }
844
    return 0;
638 845
}
639 846

  
640
void AUD_run (void)
847
static int audio_pcm_sw_init_out (SWVoiceOut *sw, HWVoiceOut *hw,
848
                            const char *name, int freq,
849
                            int nchannels, audfmt_e fmt)
641 850
{
642
    HWVoice *hw = NULL;
643

  
644
    while ((hw = pcm_hw_find_any_active_enabled (hw))) {
645
        int i;
646
        if (hw->pending_disable && pcm_hw_get_live (hw) <= 0) {
647
            hw->enabled = 0;
648
            hw->pcm_ops->ctl (hw, VOICE_DISABLE);
649
            for (i = 0; i < hw->nb_voices; i++) {
650
                hw->pvoice[i]->live = 0;
651
                /* hw->pvoice[i]->old_ticks = 0; */
652
            }
653
            continue;
654
        }
851
    audio_pcm_init_info (&sw->info, freq, nchannels, fmt,
852
                         /* None of the cards emulated by QEMU are big-endian
853
                            hence following shortcut */
854
                         audio_need_to_swap_endian (0));
855
    sw->hw = hw;
856
    sw->empty = 1;
857
    sw->active = 0;
858
    sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
859
    sw->total_hw_samples_mixed = 0;
860

  
861
    sw->conv =
862
        mixeng_conv
863
        [nchannels == 2]
864
        [sw->info.sign]
865
        [sw->info.swap_endian]
866
        [sw->info.bits == 16];
867
    sw->name = qemu_strdup (name);
655 868

  
656
        hw->pcm_ops->run (hw);
657
        assert (hw->rpos < hw->samples);
658
        for (i = 0; i < hw->nb_voices; i++) {
659
            SWVoice *sw = hw->pvoice[i];
660
            if (!sw->active && !sw->live && sw->old_ticks) {
661
                int64_t delta = qemu_get_clock (vm_clock) - sw->old_ticks;
662
                if (delta > audio_state.ticks_threshold) {
663
                    ldebug ("resetting old_ticks for %s\n", sw->name);
664
                    sw->old_ticks = 0;
665
                }
666
            }
667
        }
668
    }
869
    audio_pcm_sw_free_resources_out (sw);
870
    return audio_pcm_sw_alloc_resources_out (sw);
669 871
}
670 872

  
671
int AUD_get_free (SWVoice *sw)
873
int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
672 874
{
673
    int free;
875
    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
876
    int ret = 0, pos = 0, total = 0;
674 877

  
675
    if (!sw)
676
        return 4096;
878
    if (!sw) {
879
        return size;
880
    }
677 881

  
678
    free = ((sw->hw->samples - sw->live) << sw->hw->shift) * sw->ratio
679
        / INT_MAX;
882
    hwsamples = sw->hw->samples;
680 883

  
681
    free &= ~sw->hw->align;
682
    if (!free) return 0;
884
    live = sw->total_hw_samples_mixed;
885
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){
886
        dolog ("live=%d hw->samples=%d\n", live, hwsamples);
887
        return 0;
888
    }
683 889

  
684
    return free;
685
}
890
    if (live == hwsamples) {
891
        return 0;
892
    }
686 893

  
687
int AUD_get_buffer_size (SWVoice *sw)
688
{
689
    return sw->hw->bufsize;
690
}
894
    wpos = (sw->hw->rpos + live) % hwsamples;
895
    samples = size >> sw->info.shift;
691 896

  
692
void AUD_adjust (SWVoice *sw, int bytes)
693
{
694
    if (!sw)
695
        return;
696
    sw->old_ticks += (ticks_per_sec * (int64_t) bytes) / sw->bytes_per_second;
897
    dead = hwsamples - live;
898
    swlim = ((int64_t) dead << 32) / sw->ratio;
899
    swlim = audio_MIN (swlim, samples);
900
    if (swlim) {
901
        sw->conv (sw->buf, buf, swlim, &sw->vol);
902
    }
903

  
904
    while (swlim) {
905
        dead = hwsamples - live;
906
        left = hwsamples - wpos;
907
        blck = audio_MIN (dead, left);
908
        if (!blck) {
909
            break;
910
        }
911
        isamp = swlim;
912
        osamp = blck;
913
        st_rate_flow_mix (
914
            sw->rate,
915
            sw->buf + pos,
916
            sw->hw->mix_buf + wpos,
917
            &isamp,
918
            &osamp
919
            );
920
        ret += isamp;
921
        swlim -= isamp;
922
        pos += isamp;
923
        live += osamp;
924
        wpos = (wpos + osamp) % hwsamples;
925
        total += osamp;
926
    }
927

  
928
    sw->total_hw_samples_mixed += total;
929
    sw->empty = sw->total_hw_samples_mixed == 0;
930

  
931
#ifdef DEBUG_OUT
932
    dolog (
933
        "%s: write size %d ret %d total sw %d, hw %d\n",
934
        sw->name,
935
        size >> sw->info.shift,
936
        ret,
937
        sw->total_hw_samples_mixed,
938
        sw->hw->total_samples_played
939
        );
940
#endif
941

  
942
    return ret << sw->info.shift;
697 943
}
698 944

  
699
void AUD_reset (SWVoice *sw)
945
#ifdef DEBUG_AUDIO
946
static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
700 947
{
701
    sw->active = 0;
702
    sw->old_ticks = 0;
948
    dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
949
           cap, info->bits, info->sign, info->freq, info->nchannels);
703 950
}
951
#endif
704 952

  
705
int AUD_calc_elapsed (SWVoice *sw)
953
#define DAC
954
#include "audio_template.h"
955
#undef DAC
956
#include "audio_template.h"
957

  
958
int AUD_write (SWVoiceOut *sw, void *buf, int size)
706 959
{
707
    int64_t now, delta, bytes;
708
    int dead, swlim;
960
    int bytes;
709 961

  
710
    if (!sw)
711
        return 0;
962
    if (!sw) {
963
        /* XXX: Consider options */
964
        return size;
965
    }
712 966

  
713
    now = qemu_get_clock (vm_clock);
714
    delta = now - sw->old_ticks;
715
    bytes = (delta * sw->bytes_per_second) / ticks_per_sec;
716
    if (delta < 0) {
717
        dolog ("whoops delta(<0)=%lld\n", delta);
967
    if (!sw->hw->enabled) {
968
        dolog ("Writing to disabled voice %s\n", sw->name);
718 969
        return 0;
719 970
    }
720 971

  
721
    dead = sw->hw->samples - sw->live;
722
    swlim = ((dead * (int64_t) INT_MAX) / sw->ratio);
972
    bytes = sw->hw->pcm_ops->write (sw, buf, size);
973
    return bytes;
974
}
975

  
976
int AUD_read (SWVoiceIn *sw, void *buf, int size)
977
{
978
    int bytes;
723 979

  
724
    if (bytes > swlim) {
725
        return swlim;
980
    if (!sw) {
981
        /* XXX: Consider options */
982
        return size;
726 983
    }
727
    else {
728
        return bytes;
984

  
985
    if (!sw->hw->enabled) {
986
        dolog ("Reading from disabled voice %s\n", sw->name);
987
        return 0;
729 988
    }
989

  
990
    bytes = sw->hw->pcm_ops->read (sw, buf, size);
991
    return bytes;
730 992
}
731 993

  
732
void AUD_enable (SWVoice *sw, int on)
994
int AUD_get_buffer_size_out (SWVoiceOut *sw)
733 995
{
734
    int i;
735
    HWVoice *hw;
996
    return sw->hw->bufsize;
997
}
998

  
999
void AUD_set_active_out (SWVoiceOut *sw, int on)
1000
{
1001
    HWVoiceOut *hw;
736 1002

  
737
    if (!sw)
1003
    if (!sw) {
738 1004
        return;
1005
    }
739 1006

  
740 1007
    hw = sw->hw;
741
    if (on) {
742
        if (!sw->live)
743
            sw->wpos = sw->hw->rpos;
744
        if (!sw->old_ticks) {
745
            sw->old_ticks = qemu_get_clock (vm_clock);
1008
    if (sw->active != on) {
1009
        SWVoiceOut *temp_sw;
1010

  
1011
        if (on) {
1012
            int total;
1013

  
1014
            hw->pending_disable = 0;
1015
            if (!hw->enabled) {
1016
                hw->enabled = 1;
1017
                hw->pcm_ops->ctl_out (hw, VOICE_ENABLE);
1018
            }
1019

  
1020
            if (sw->empty) {
1021
                total = 0;
1022
            }
1023
        }
1024
        else {
1025
            if (hw->enabled) {
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff