Statistics
| Branch: | Revision:

root / audio / audio.c @ 45724d6d

History | View | Annotate | Download (51.3 kB)

1 85571bc7 bellard
/*
2 85571bc7 bellard
 * QEMU Audio subsystem
3 1d14ffa9 bellard
 *
4 1d14ffa9 bellard
 * Copyright (c) 2003-2005 Vassili Karpov (malc)
5 1d14ffa9 bellard
 *
6 85571bc7 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 85571bc7 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 85571bc7 bellard
 * in the Software without restriction, including without limitation the rights
9 85571bc7 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 85571bc7 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 85571bc7 bellard
 * furnished to do so, subject to the following conditions:
12 85571bc7 bellard
 *
13 85571bc7 bellard
 * The above copyright notice and this permission notice shall be included in
14 85571bc7 bellard
 * all copies or substantial portions of the Software.
15 85571bc7 bellard
 *
16 85571bc7 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 85571bc7 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 85571bc7 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 85571bc7 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 85571bc7 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 85571bc7 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 85571bc7 bellard
 * THE SOFTWARE.
23 85571bc7 bellard
 */
24 87ecb68b pbrook
#include "hw/hw.h"
25 87ecb68b pbrook
#include "audio.h"
26 376253ec aliguori
#include "monitor.h"
27 87ecb68b pbrook
#include "qemu-timer.h"
28 87ecb68b pbrook
#include "sysemu.h"
29 85571bc7 bellard
30 1d14ffa9 bellard
#define AUDIO_CAP "audio"
31 1d14ffa9 bellard
#include "audio_int.h"
32 85571bc7 bellard
33 1d14ffa9 bellard
/* #define DEBUG_PLIVE */
34 1d14ffa9 bellard
/* #define DEBUG_LIVE */
35 1d14ffa9 bellard
/* #define DEBUG_OUT */
36 8ead62cf bellard
/* #define DEBUG_CAPTURE */
37 713a98f8 malc
/* #define DEBUG_POLL */
38 85571bc7 bellard
39 c0fe3827 bellard
#define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
40 c0fe3827 bellard
41 2358a494 Juan Quintela
42 2358a494 Juan Quintela
/* Order of CONFIG_AUDIO_DRIVERS is import.
43 2358a494 Juan Quintela
   The 1st one is the one used by default, that is the reason
44 2358a494 Juan Quintela
    that we generate the list.
45 2358a494 Juan Quintela
*/
46 1d14ffa9 bellard
static struct audio_driver *drvtab[] = {
47 3e313753 Gerd Hoffmann
#ifdef CONFIG_SPICE
48 3e313753 Gerd Hoffmann
    &spice_audio_driver,
49 3e313753 Gerd Hoffmann
#endif
50 2358a494 Juan Quintela
    CONFIG_AUDIO_DRIVERS
51 1d14ffa9 bellard
    &no_audio_driver,
52 1d14ffa9 bellard
    &wav_audio_driver
53 1d14ffa9 bellard
};
54 85571bc7 bellard
55 c0fe3827 bellard
struct fixed_settings {
56 c0fe3827 bellard
    int enabled;
57 c0fe3827 bellard
    int nb_voices;
58 c0fe3827 bellard
    int greedy;
59 1ea879e5 malc
    struct audsettings settings;
60 c0fe3827 bellard
};
61 c0fe3827 bellard
62 c0fe3827 bellard
static struct {
63 c0fe3827 bellard
    struct fixed_settings fixed_out;
64 c0fe3827 bellard
    struct fixed_settings fixed_in;
65 c0fe3827 bellard
    union {
66 c310de86 malc
        int hertz;
67 c0fe3827 bellard
        int64_t ticks;
68 c0fe3827 bellard
    } period;
69 c0fe3827 bellard
    int plive;
70 541e0844 bellard
    int log_to_monitor;
71 713a98f8 malc
    int try_poll_in;
72 713a98f8 malc
    int try_poll_out;
73 c0fe3827 bellard
} conf = {
74 14658cd1 Juan Quintela
    .fixed_out = { /* DAC fixed settings */
75 14658cd1 Juan Quintela
        .enabled = 1,
76 14658cd1 Juan Quintela
        .nb_voices = 1,
77 14658cd1 Juan Quintela
        .greedy = 1,
78 14658cd1 Juan Quintela
        .settings = {
79 14658cd1 Juan Quintela
            .freq = 44100,
80 14658cd1 Juan Quintela
            .nchannels = 2,
81 14658cd1 Juan Quintela
            .fmt = AUD_FMT_S16,
82 14658cd1 Juan Quintela
            .endianness =  AUDIO_HOST_ENDIANNESS,
83 c0fe3827 bellard
        }
84 c0fe3827 bellard
    },
85 c0fe3827 bellard
86 14658cd1 Juan Quintela
    .fixed_in = { /* ADC fixed settings */
87 14658cd1 Juan Quintela
        .enabled = 1,
88 14658cd1 Juan Quintela
        .nb_voices = 1,
89 14658cd1 Juan Quintela
        .greedy = 1,
90 14658cd1 Juan Quintela
        .settings = {
91 14658cd1 Juan Quintela
            .freq = 44100,
92 14658cd1 Juan Quintela
            .nchannels = 2,
93 14658cd1 Juan Quintela
            .fmt = AUD_FMT_S16,
94 14658cd1 Juan Quintela
            .endianness = AUDIO_HOST_ENDIANNESS,
95 c0fe3827 bellard
        }
96 c0fe3827 bellard
    },
97 c0fe3827 bellard
98 aea86747 malc
    .period = { .hertz = 250 },
99 14658cd1 Juan Quintela
    .plive = 0,
100 14658cd1 Juan Quintela
    .log_to_monitor = 0,
101 713a98f8 malc
    .try_poll_in = 1,
102 713a98f8 malc
    .try_poll_out = 1,
103 1d14ffa9 bellard
};
104 1d14ffa9 bellard
105 c0fe3827 bellard
static AudioState glob_audio_state;
106 c0fe3827 bellard
107 00e07679 Michael Walle
const struct mixeng_volume nominal_volume = {
108 14658cd1 Juan Quintela
    .mute = 0,
109 1d14ffa9 bellard
#ifdef FLOAT_MIXENG
110 14658cd1 Juan Quintela
    .r = 1.0,
111 14658cd1 Juan Quintela
    .l = 1.0,
112 1d14ffa9 bellard
#else
113 14658cd1 Juan Quintela
    .r = 1ULL << 32,
114 14658cd1 Juan Quintela
    .l = 1ULL << 32,
115 1d14ffa9 bellard
#endif
116 85571bc7 bellard
};
117 85571bc7 bellard
118 1d14ffa9 bellard
#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
119 1d14ffa9 bellard
#error No its not
120 1d14ffa9 bellard
#else
121 82584e21 malc
static void audio_print_options (const char *prefix,
122 82584e21 malc
                                 struct audio_option *opt);
123 82584e21 malc
124 1d14ffa9 bellard
int audio_bug (const char *funcname, int cond)
125 85571bc7 bellard
{
126 1d14ffa9 bellard
    if (cond) {
127 1d14ffa9 bellard
        static int shown;
128 1d14ffa9 bellard
129 8ead62cf bellard
        AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
130 1d14ffa9 bellard
        if (!shown) {
131 82584e21 malc
            struct audio_driver *d;
132 82584e21 malc
133 1d14ffa9 bellard
            shown = 1;
134 1d14ffa9 bellard
            AUD_log (NULL, "Save all your work and restart without audio\n");
135 155a8ad3 malc
            AUD_log (NULL, "Please send bug report to av1474@comtv.ru\n");
136 1d14ffa9 bellard
            AUD_log (NULL, "I am sorry\n");
137 82584e21 malc
            d = glob_audio_state.drv;
138 82584e21 malc
            if (d) {
139 82584e21 malc
                audio_print_options (d->name, d->options);
140 82584e21 malc
            }
141 1d14ffa9 bellard
        }
142 1d14ffa9 bellard
        AUD_log (NULL, "Context:\n");
143 1d14ffa9 bellard
144 1d14ffa9 bellard
#if defined AUDIO_BREAKPOINT_ON_BUG
145 1d14ffa9 bellard
#  if defined HOST_I386
146 1d14ffa9 bellard
#    if defined __GNUC__
147 1d14ffa9 bellard
        __asm__ ("int3");
148 1d14ffa9 bellard
#    elif defined _MSC_VER
149 1d14ffa9 bellard
        _asm _emit 0xcc;
150 1d14ffa9 bellard
#    else
151 1d14ffa9 bellard
        abort ();
152 1d14ffa9 bellard
#    endif
153 1d14ffa9 bellard
#  else
154 1d14ffa9 bellard
        abort ();
155 1d14ffa9 bellard
#  endif
156 1d14ffa9 bellard
#endif
157 85571bc7 bellard
    }
158 85571bc7 bellard
159 1d14ffa9 bellard
    return cond;
160 85571bc7 bellard
}
161 1d14ffa9 bellard
#endif
162 85571bc7 bellard
163 f941aa25 ths
static inline int audio_bits_to_index (int bits)
164 f941aa25 ths
{
165 f941aa25 ths
    switch (bits) {
166 f941aa25 ths
    case 8:
167 f941aa25 ths
        return 0;
168 f941aa25 ths
169 f941aa25 ths
    case 16:
170 f941aa25 ths
        return 1;
171 f941aa25 ths
172 f941aa25 ths
    case 32:
173 f941aa25 ths
        return 2;
174 f941aa25 ths
175 f941aa25 ths
    default:
176 f941aa25 ths
        audio_bug ("bits_to_index", 1);
177 f941aa25 ths
        AUD_log (NULL, "invalid bits %d\n", bits);
178 f941aa25 ths
        return 0;
179 f941aa25 ths
    }
180 f941aa25 ths
}
181 f941aa25 ths
182 c0fe3827 bellard
void *audio_calloc (const char *funcname, int nmemb, size_t size)
183 c0fe3827 bellard
{
184 c0fe3827 bellard
    int cond;
185 c0fe3827 bellard
    size_t len;
186 c0fe3827 bellard
187 c0fe3827 bellard
    len = nmemb * size;
188 c0fe3827 bellard
    cond = !nmemb || !size;
189 c0fe3827 bellard
    cond |= nmemb < 0;
190 c0fe3827 bellard
    cond |= len < size;
191 c0fe3827 bellard
192 c0fe3827 bellard
    if (audio_bug ("audio_calloc", cond)) {
193 c0fe3827 bellard
        AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
194 c0fe3827 bellard
                 funcname);
195 541e0844 bellard
        AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
196 c0fe3827 bellard
        return NULL;
197 c0fe3827 bellard
    }
198 c0fe3827 bellard
199 7267c094 Anthony Liguori
    return g_malloc0 (len);
200 c0fe3827 bellard
}
201 c0fe3827 bellard
202 1d14ffa9 bellard
static char *audio_alloc_prefix (const char *s)
203 85571bc7 bellard
{
204 1d14ffa9 bellard
    const char qemu_prefix[] = "QEMU_";
205 090f1fa3 aliguori
    size_t len, i;
206 090f1fa3 aliguori
    char *r, *u;
207 85571bc7 bellard
208 1d14ffa9 bellard
    if (!s) {
209 1d14ffa9 bellard
        return NULL;
210 1d14ffa9 bellard
    }
211 85571bc7 bellard
212 1d14ffa9 bellard
    len = strlen (s);
213 7267c094 Anthony Liguori
    r = g_malloc (len + sizeof (qemu_prefix));
214 85571bc7 bellard
215 090f1fa3 aliguori
    u = r + sizeof (qemu_prefix) - 1;
216 85571bc7 bellard
217 090f1fa3 aliguori
    pstrcpy (r, len + sizeof (qemu_prefix), qemu_prefix);
218 090f1fa3 aliguori
    pstrcat (r, len + sizeof (qemu_prefix), s);
219 1d14ffa9 bellard
220 090f1fa3 aliguori
    for (i = 0; i < len; ++i) {
221 090f1fa3 aliguori
        u[i] = qemu_toupper(u[i]);
222 85571bc7 bellard
    }
223 090f1fa3 aliguori
224 1d14ffa9 bellard
    return r;
225 85571bc7 bellard
}
226 85571bc7 bellard
227 9596ebb7 pbrook
static const char *audio_audfmt_to_string (audfmt_e fmt)
228 85571bc7 bellard
{
229 1d14ffa9 bellard
    switch (fmt) {
230 1d14ffa9 bellard
    case AUD_FMT_U8:
231 1d14ffa9 bellard
        return "U8";
232 85571bc7 bellard
233 1d14ffa9 bellard
    case AUD_FMT_U16:
234 1d14ffa9 bellard
        return "U16";
235 85571bc7 bellard
236 85571bc7 bellard
    case AUD_FMT_S8:
237 1d14ffa9 bellard
        return "S8";
238 85571bc7 bellard
239 85571bc7 bellard
    case AUD_FMT_S16:
240 1d14ffa9 bellard
        return "S16";
241 f941aa25 ths
242 f941aa25 ths
    case AUD_FMT_U32:
243 f941aa25 ths
        return "U32";
244 f941aa25 ths
245 f941aa25 ths
    case AUD_FMT_S32:
246 f941aa25 ths
        return "S32";
247 85571bc7 bellard
    }
248 85571bc7 bellard
249 1d14ffa9 bellard
    dolog ("Bogus audfmt %d returning S16\n", fmt);
250 1d14ffa9 bellard
    return "S16";
251 85571bc7 bellard
}
252 85571bc7 bellard
253 9596ebb7 pbrook
static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval,
254 9596ebb7 pbrook
                                        int *defaultp)
255 85571bc7 bellard
{
256 1d14ffa9 bellard
    if (!strcasecmp (s, "u8")) {
257 1d14ffa9 bellard
        *defaultp = 0;
258 1d14ffa9 bellard
        return AUD_FMT_U8;
259 1d14ffa9 bellard
    }
260 1d14ffa9 bellard
    else if (!strcasecmp (s, "u16")) {
261 1d14ffa9 bellard
        *defaultp = 0;
262 1d14ffa9 bellard
        return AUD_FMT_U16;
263 1d14ffa9 bellard
    }
264 f941aa25 ths
    else if (!strcasecmp (s, "u32")) {
265 f941aa25 ths
        *defaultp = 0;
266 f941aa25 ths
        return AUD_FMT_U32;
267 f941aa25 ths
    }
268 1d14ffa9 bellard
    else if (!strcasecmp (s, "s8")) {
269 1d14ffa9 bellard
        *defaultp = 0;
270 1d14ffa9 bellard
        return AUD_FMT_S8;
271 1d14ffa9 bellard
    }
272 1d14ffa9 bellard
    else if (!strcasecmp (s, "s16")) {
273 1d14ffa9 bellard
        *defaultp = 0;
274 1d14ffa9 bellard
        return AUD_FMT_S16;
275 1d14ffa9 bellard
    }
276 f941aa25 ths
    else if (!strcasecmp (s, "s32")) {
277 f941aa25 ths
        *defaultp = 0;
278 f941aa25 ths
        return AUD_FMT_S32;
279 f941aa25 ths
    }
280 1d14ffa9 bellard
    else {
281 1d14ffa9 bellard
        dolog ("Bogus audio format `%s' using %s\n",
282 1d14ffa9 bellard
               s, audio_audfmt_to_string (defval));
283 1d14ffa9 bellard
        *defaultp = 1;
284 1d14ffa9 bellard
        return defval;
285 1d14ffa9 bellard
    }
286 85571bc7 bellard
}
287 85571bc7 bellard
288 1d14ffa9 bellard
static audfmt_e audio_get_conf_fmt (const char *envname,
289 1d14ffa9 bellard
                                    audfmt_e defval,
290 1d14ffa9 bellard
                                    int *defaultp)
291 85571bc7 bellard
{
292 1d14ffa9 bellard
    const char *var = getenv (envname);
293 1d14ffa9 bellard
    if (!var) {
294 1d14ffa9 bellard
        *defaultp = 1;
295 1d14ffa9 bellard
        return defval;
296 85571bc7 bellard
    }
297 1d14ffa9 bellard
    return audio_string_to_audfmt (var, defval, defaultp);
298 85571bc7 bellard
}
299 85571bc7 bellard
300 1d14ffa9 bellard
static int audio_get_conf_int (const char *key, int defval, int *defaultp)
301 85571bc7 bellard
{
302 1d14ffa9 bellard
    int val;
303 1d14ffa9 bellard
    char *strval;
304 85571bc7 bellard
305 1d14ffa9 bellard
    strval = getenv (key);
306 1d14ffa9 bellard
    if (strval) {
307 1d14ffa9 bellard
        *defaultp = 0;
308 1d14ffa9 bellard
        val = atoi (strval);
309 1d14ffa9 bellard
        return val;
310 1d14ffa9 bellard
    }
311 1d14ffa9 bellard
    else {
312 1d14ffa9 bellard
        *defaultp = 1;
313 1d14ffa9 bellard
        return defval;
314 1d14ffa9 bellard
    }
315 85571bc7 bellard
}
316 85571bc7 bellard
317 1d14ffa9 bellard
static const char *audio_get_conf_str (const char *key,
318 1d14ffa9 bellard
                                       const char *defval,
319 1d14ffa9 bellard
                                       int *defaultp)
320 85571bc7 bellard
{
321 1d14ffa9 bellard
    const char *val = getenv (key);
322 1d14ffa9 bellard
    if (!val) {
323 1d14ffa9 bellard
        *defaultp = 1;
324 1d14ffa9 bellard
        return defval;
325 1d14ffa9 bellard
    }
326 1d14ffa9 bellard
    else {
327 1d14ffa9 bellard
        *defaultp = 0;
328 1d14ffa9 bellard
        return val;
329 85571bc7 bellard
    }
330 85571bc7 bellard
}
331 85571bc7 bellard
332 541e0844 bellard
void AUD_vlog (const char *cap, const char *fmt, va_list ap)
333 85571bc7 bellard
{
334 541e0844 bellard
    if (conf.log_to_monitor) {
335 541e0844 bellard
        if (cap) {
336 8631b608 Markus Armbruster
            monitor_printf(default_mon, "%s: ", cap);
337 541e0844 bellard
        }
338 541e0844 bellard
339 8631b608 Markus Armbruster
        monitor_vprintf(default_mon, fmt, ap);
340 541e0844 bellard
    }
341 541e0844 bellard
    else {
342 541e0844 bellard
        if (cap) {
343 541e0844 bellard
            fprintf (stderr, "%s: ", cap);
344 541e0844 bellard
        }
345 541e0844 bellard
346 541e0844 bellard
        vfprintf (stderr, fmt, ap);
347 85571bc7 bellard
    }
348 85571bc7 bellard
}
349 85571bc7 bellard
350 541e0844 bellard
void AUD_log (const char *cap, const char *fmt, ...)
351 85571bc7 bellard
{
352 541e0844 bellard
    va_list ap;
353 541e0844 bellard
354 541e0844 bellard
    va_start (ap, fmt);
355 541e0844 bellard
    AUD_vlog (cap, fmt, ap);
356 541e0844 bellard
    va_end (ap);
357 85571bc7 bellard
}
358 85571bc7 bellard
359 1d14ffa9 bellard
static void audio_print_options (const char *prefix,
360 1d14ffa9 bellard
                                 struct audio_option *opt)
361 85571bc7 bellard
{
362 1d14ffa9 bellard
    char *uprefix;
363 1d14ffa9 bellard
364 1d14ffa9 bellard
    if (!prefix) {
365 1d14ffa9 bellard
        dolog ("No prefix specified\n");
366 1d14ffa9 bellard
        return;
367 1d14ffa9 bellard
    }
368 1d14ffa9 bellard
369 1d14ffa9 bellard
    if (!opt) {
370 1d14ffa9 bellard
        dolog ("No options\n");
371 85571bc7 bellard
        return;
372 1d14ffa9 bellard
    }
373 85571bc7 bellard
374 1d14ffa9 bellard
    uprefix = audio_alloc_prefix (prefix);
375 85571bc7 bellard
376 1d14ffa9 bellard
    for (; opt->name; opt++) {
377 1d14ffa9 bellard
        const char *state = "default";
378 1d14ffa9 bellard
        printf ("  %s_%s: ", uprefix, opt->name);
379 85571bc7 bellard
380 fe8f096b ths
        if (opt->overriddenp && *opt->overriddenp) {
381 1d14ffa9 bellard
            state = "current";
382 1d14ffa9 bellard
        }
383 85571bc7 bellard
384 1d14ffa9 bellard
        switch (opt->tag) {
385 1d14ffa9 bellard
        case AUD_OPT_BOOL:
386 1d14ffa9 bellard
            {
387 1d14ffa9 bellard
                int *intp = opt->valp;
388 1d14ffa9 bellard
                printf ("boolean, %s = %d\n", state, *intp ? 1 : 0);
389 1d14ffa9 bellard
            }
390 1d14ffa9 bellard
            break;
391 1d14ffa9 bellard
392 1d14ffa9 bellard
        case AUD_OPT_INT:
393 1d14ffa9 bellard
            {
394 1d14ffa9 bellard
                int *intp = opt->valp;
395 1d14ffa9 bellard
                printf ("integer, %s = %d\n", state, *intp);
396 1d14ffa9 bellard
            }
397 1d14ffa9 bellard
            break;
398 1d14ffa9 bellard
399 1d14ffa9 bellard
        case AUD_OPT_FMT:
400 1d14ffa9 bellard
            {
401 1d14ffa9 bellard
                audfmt_e *fmtp = opt->valp;
402 1d14ffa9 bellard
                printf (
403 ca9cc28c balrog
                    "format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n",
404 1d14ffa9 bellard
                    state,
405 1d14ffa9 bellard
                    audio_audfmt_to_string (*fmtp)
406 1d14ffa9 bellard
                    );
407 1d14ffa9 bellard
            }
408 1d14ffa9 bellard
            break;
409 1d14ffa9 bellard
410 1d14ffa9 bellard
        case AUD_OPT_STR:
411 1d14ffa9 bellard
            {
412 1d14ffa9 bellard
                const char **strp = opt->valp;
413 1d14ffa9 bellard
                printf ("string, %s = %s\n",
414 1d14ffa9 bellard
                        state,
415 1d14ffa9 bellard
                        *strp ? *strp : "(not set)");
416 85571bc7 bellard
            }
417 1d14ffa9 bellard
            break;
418 1d14ffa9 bellard
419 1d14ffa9 bellard
        default:
420 1d14ffa9 bellard
            printf ("???\n");
421 1d14ffa9 bellard
            dolog ("Bad value tag for option %s_%s %d\n",
422 1d14ffa9 bellard
                   uprefix, opt->name, opt->tag);
423 1d14ffa9 bellard
            break;
424 85571bc7 bellard
        }
425 1d14ffa9 bellard
        printf ("    %s\n", opt->descr);
426 85571bc7 bellard
    }
427 1d14ffa9 bellard
428 7267c094 Anthony Liguori
    g_free (uprefix);
429 85571bc7 bellard
}
430 85571bc7 bellard
431 1d14ffa9 bellard
static void audio_process_options (const char *prefix,
432 1d14ffa9 bellard
                                   struct audio_option *opt)
433 85571bc7 bellard
{
434 1d14ffa9 bellard
    char *optname;
435 1d14ffa9 bellard
    const char qemu_prefix[] = "QEMU_";
436 363a37d5 blueswir1
    size_t preflen, optlen;
437 85571bc7 bellard
438 1d14ffa9 bellard
    if (audio_bug (AUDIO_FUNC, !prefix)) {
439 1d14ffa9 bellard
        dolog ("prefix = NULL\n");
440 1d14ffa9 bellard
        return;
441 1d14ffa9 bellard
    }
442 85571bc7 bellard
443 1d14ffa9 bellard
    if (audio_bug (AUDIO_FUNC, !opt)) {
444 1d14ffa9 bellard
        dolog ("opt = NULL\n");
445 1d14ffa9 bellard
        return;
446 85571bc7 bellard
    }
447 85571bc7 bellard
448 1d14ffa9 bellard
    preflen = strlen (prefix);
449 85571bc7 bellard
450 1d14ffa9 bellard
    for (; opt->name; opt++) {
451 1d14ffa9 bellard
        size_t len, i;
452 1d14ffa9 bellard
        int def;
453 1d14ffa9 bellard
454 1d14ffa9 bellard
        if (!opt->valp) {
455 1d14ffa9 bellard
            dolog ("Option value pointer for `%s' is not set\n",
456 1d14ffa9 bellard
                   opt->name);
457 1d14ffa9 bellard
            continue;
458 1d14ffa9 bellard
        }
459 1d14ffa9 bellard
460 1d14ffa9 bellard
        len = strlen (opt->name);
461 c0fe3827 bellard
        /* len of opt->name + len of prefix + size of qemu_prefix
462 c0fe3827 bellard
         * (includes trailing zero) + zero + underscore (on behalf of
463 c0fe3827 bellard
         * sizeof) */
464 363a37d5 blueswir1
        optlen = len + preflen + sizeof (qemu_prefix) + 1;
465 7267c094 Anthony Liguori
        optname = g_malloc (optlen);
466 1d14ffa9 bellard
467 363a37d5 blueswir1
        pstrcpy (optname, optlen, qemu_prefix);
468 c0fe3827 bellard
469 c0fe3827 bellard
        /* copy while upper-casing, including trailing zero */
470 1d14ffa9 bellard
        for (i = 0; i <= preflen; ++i) {
471 cd390083 blueswir1
            optname[i + sizeof (qemu_prefix) - 1] = qemu_toupper(prefix[i]);
472 1d14ffa9 bellard
        }
473 363a37d5 blueswir1
        pstrcat (optname, optlen, "_");
474 363a37d5 blueswir1
        pstrcat (optname, optlen, opt->name);
475 1d14ffa9 bellard
476 1d14ffa9 bellard
        def = 1;
477 1d14ffa9 bellard
        switch (opt->tag) {
478 1d14ffa9 bellard
        case AUD_OPT_BOOL:
479 1d14ffa9 bellard
        case AUD_OPT_INT:
480 1d14ffa9 bellard
            {
481 1d14ffa9 bellard
                int *intp = opt->valp;
482 1d14ffa9 bellard
                *intp = audio_get_conf_int (optname, *intp, &def);
483 1d14ffa9 bellard
            }
484 1d14ffa9 bellard
            break;
485 1d14ffa9 bellard
486 1d14ffa9 bellard
        case AUD_OPT_FMT:
487 1d14ffa9 bellard
            {
488 1d14ffa9 bellard
                audfmt_e *fmtp = opt->valp;
489 1d14ffa9 bellard
                *fmtp = audio_get_conf_fmt (optname, *fmtp, &def);
490 1d14ffa9 bellard
            }
491 1d14ffa9 bellard
            break;
492 1d14ffa9 bellard
493 1d14ffa9 bellard
        case AUD_OPT_STR:
494 1d14ffa9 bellard
            {
495 1d14ffa9 bellard
                const char **strp = opt->valp;
496 1d14ffa9 bellard
                *strp = audio_get_conf_str (optname, *strp, &def);
497 1d14ffa9 bellard
            }
498 1d14ffa9 bellard
            break;
499 1d14ffa9 bellard
500 1d14ffa9 bellard
        default:
501 1d14ffa9 bellard
            dolog ("Bad value tag for option `%s' - %d\n",
502 1d14ffa9 bellard
                   optname, opt->tag);
503 85571bc7 bellard
            break;
504 85571bc7 bellard
        }
505 85571bc7 bellard
506 fe8f096b ths
        if (!opt->overriddenp) {
507 fe8f096b ths
            opt->overriddenp = &opt->overridden;
508 1d14ffa9 bellard
        }
509 fe8f096b ths
        *opt->overriddenp = !def;
510 7267c094 Anthony Liguori
        g_free (optname);
511 1d14ffa9 bellard
    }
512 85571bc7 bellard
}
513 85571bc7 bellard
514 1ea879e5 malc
static void audio_print_settings (struct audsettings *as)
515 c0fe3827 bellard
{
516 c0fe3827 bellard
    dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels);
517 c0fe3827 bellard
518 c0fe3827 bellard
    switch (as->fmt) {
519 c0fe3827 bellard
    case AUD_FMT_S8:
520 c0fe3827 bellard
        AUD_log (NULL, "S8");
521 c0fe3827 bellard
        break;
522 c0fe3827 bellard
    case AUD_FMT_U8:
523 c0fe3827 bellard
        AUD_log (NULL, "U8");
524 c0fe3827 bellard
        break;
525 c0fe3827 bellard
    case AUD_FMT_S16:
526 c0fe3827 bellard
        AUD_log (NULL, "S16");
527 c0fe3827 bellard
        break;
528 c0fe3827 bellard
    case AUD_FMT_U16:
529 c0fe3827 bellard
        AUD_log (NULL, "U16");
530 c0fe3827 bellard
        break;
531 d50997f9 malc
    case AUD_FMT_S32:
532 d50997f9 malc
        AUD_log (NULL, "S32");
533 d50997f9 malc
        break;
534 d50997f9 malc
    case AUD_FMT_U32:
535 d50997f9 malc
        AUD_log (NULL, "U32");
536 d50997f9 malc
        break;
537 c0fe3827 bellard
    default:
538 c0fe3827 bellard
        AUD_log (NULL, "invalid(%d)", as->fmt);
539 c0fe3827 bellard
        break;
540 c0fe3827 bellard
    }
541 ec36b695 bellard
542 ec36b695 bellard
    AUD_log (NULL, " endianness=");
543 d929eba5 bellard
    switch (as->endianness) {
544 d929eba5 bellard
    case 0:
545 d929eba5 bellard
        AUD_log (NULL, "little");
546 d929eba5 bellard
        break;
547 d929eba5 bellard
    case 1:
548 d929eba5 bellard
        AUD_log (NULL, "big");
549 d929eba5 bellard
        break;
550 d929eba5 bellard
    default:
551 d929eba5 bellard
        AUD_log (NULL, "invalid");
552 d929eba5 bellard
        break;
553 d929eba5 bellard
    }
554 c0fe3827 bellard
    AUD_log (NULL, "\n");
555 c0fe3827 bellard
}
556 c0fe3827 bellard
557 1ea879e5 malc
static int audio_validate_settings (struct audsettings *as)
558 c0fe3827 bellard
{
559 c0fe3827 bellard
    int invalid;
560 c0fe3827 bellard
561 c0fe3827 bellard
    invalid = as->nchannels != 1 && as->nchannels != 2;
562 d929eba5 bellard
    invalid |= as->endianness != 0 && as->endianness != 1;
563 c0fe3827 bellard
564 c0fe3827 bellard
    switch (as->fmt) {
565 c0fe3827 bellard
    case AUD_FMT_S8:
566 c0fe3827 bellard
    case AUD_FMT_U8:
567 c0fe3827 bellard
    case AUD_FMT_S16:
568 c0fe3827 bellard
    case AUD_FMT_U16:
569 f941aa25 ths
    case AUD_FMT_S32:
570 f941aa25 ths
    case AUD_FMT_U32:
571 c0fe3827 bellard
        break;
572 c0fe3827 bellard
    default:
573 c0fe3827 bellard
        invalid = 1;
574 c0fe3827 bellard
        break;
575 c0fe3827 bellard
    }
576 c0fe3827 bellard
577 c0fe3827 bellard
    invalid |= as->freq <= 0;
578 d929eba5 bellard
    return invalid ? -1 : 0;
579 c0fe3827 bellard
}
580 c0fe3827 bellard
581 1ea879e5 malc
static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *as)
582 85571bc7 bellard
{
583 1d14ffa9 bellard
    int bits = 8, sign = 0;
584 85571bc7 bellard
585 c0fe3827 bellard
    switch (as->fmt) {
586 1d14ffa9 bellard
    case AUD_FMT_S8:
587 1d14ffa9 bellard
        sign = 1;
588 b4bd0b16 Stefan Weil
        /* fall through */
589 1d14ffa9 bellard
    case AUD_FMT_U8:
590 1d14ffa9 bellard
        break;
591 1d14ffa9 bellard
592 1d14ffa9 bellard
    case AUD_FMT_S16:
593 1d14ffa9 bellard
        sign = 1;
594 b4bd0b16 Stefan Weil
        /* fall through */
595 1d14ffa9 bellard
    case AUD_FMT_U16:
596 1d14ffa9 bellard
        bits = 16;
597 1d14ffa9 bellard
        break;
598 f941aa25 ths
599 f941aa25 ths
    case AUD_FMT_S32:
600 f941aa25 ths
        sign = 1;
601 b4bd0b16 Stefan Weil
        /* fall through */
602 f941aa25 ths
    case AUD_FMT_U32:
603 f941aa25 ths
        bits = 32;
604 f941aa25 ths
        break;
605 85571bc7 bellard
    }
606 c0fe3827 bellard
    return info->freq == as->freq
607 c0fe3827 bellard
        && info->nchannels == as->nchannels
608 1d14ffa9 bellard
        && info->sign == sign
609 d929eba5 bellard
        && info->bits == bits
610 d929eba5 bellard
        && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
611 1d14ffa9 bellard
}
612 85571bc7 bellard
613 1ea879e5 malc
void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as)
614 1d14ffa9 bellard
{
615 f941aa25 ths
    int bits = 8, sign = 0, shift = 0;
616 1d14ffa9 bellard
617 c0fe3827 bellard
    switch (as->fmt) {
618 85571bc7 bellard
    case AUD_FMT_S8:
619 85571bc7 bellard
        sign = 1;
620 85571bc7 bellard
    case AUD_FMT_U8:
621 85571bc7 bellard
        break;
622 85571bc7 bellard
623 85571bc7 bellard
    case AUD_FMT_S16:
624 85571bc7 bellard
        sign = 1;
625 85571bc7 bellard
    case AUD_FMT_U16:
626 85571bc7 bellard
        bits = 16;
627 f941aa25 ths
        shift = 1;
628 f941aa25 ths
        break;
629 f941aa25 ths
630 f941aa25 ths
    case AUD_FMT_S32:
631 f941aa25 ths
        sign = 1;
632 f941aa25 ths
    case AUD_FMT_U32:
633 f941aa25 ths
        bits = 32;
634 f941aa25 ths
        shift = 2;
635 85571bc7 bellard
        break;
636 85571bc7 bellard
    }
637 85571bc7 bellard
638 c0fe3827 bellard
    info->freq = as->freq;
639 1d14ffa9 bellard
    info->bits = bits;
640 1d14ffa9 bellard
    info->sign = sign;
641 c0fe3827 bellard
    info->nchannels = as->nchannels;
642 f941aa25 ths
    info->shift = (as->nchannels == 2) + shift;
643 1d14ffa9 bellard
    info->align = (1 << info->shift) - 1;
644 1d14ffa9 bellard
    info->bytes_per_second = info->freq << info->shift;
645 d929eba5 bellard
    info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
646 85571bc7 bellard
}
647 85571bc7 bellard
648 1d14ffa9 bellard
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
649 85571bc7 bellard
{
650 1d14ffa9 bellard
    if (!len) {
651 1d14ffa9 bellard
        return;
652 1d14ffa9 bellard
    }
653 1d14ffa9 bellard
654 1d14ffa9 bellard
    if (info->sign) {
655 e2f909be bellard
        memset (buf, 0x00, len << info->shift);
656 85571bc7 bellard
    }
657 85571bc7 bellard
    else {
658 f941aa25 ths
        switch (info->bits) {
659 f941aa25 ths
        case 8:
660 e2f909be bellard
            memset (buf, 0x80, len << info->shift);
661 f941aa25 ths
            break;
662 1d14ffa9 bellard
663 f941aa25 ths
        case 16:
664 f941aa25 ths
            {
665 f941aa25 ths
                int i;
666 f941aa25 ths
                uint16_t *p = buf;
667 f941aa25 ths
                int shift = info->nchannels - 1;
668 f941aa25 ths
                short s = INT16_MAX;
669 f941aa25 ths
670 f941aa25 ths
                if (info->swap_endianness) {
671 f941aa25 ths
                    s = bswap16 (s);
672 f941aa25 ths
                }
673 f941aa25 ths
674 f941aa25 ths
                for (i = 0; i < len << shift; i++) {
675 f941aa25 ths
                    p[i] = s;
676 f941aa25 ths
                }
677 1d14ffa9 bellard
            }
678 f941aa25 ths
            break;
679 f941aa25 ths
680 f941aa25 ths
        case 32:
681 f941aa25 ths
            {
682 f941aa25 ths
                int i;
683 f941aa25 ths
                uint32_t *p = buf;
684 f941aa25 ths
                int shift = info->nchannels - 1;
685 f941aa25 ths
                int32_t s = INT32_MAX;
686 f941aa25 ths
687 f941aa25 ths
                if (info->swap_endianness) {
688 f941aa25 ths
                    s = bswap32 (s);
689 f941aa25 ths
                }
690 1d14ffa9 bellard
691 f941aa25 ths
                for (i = 0; i < len << shift; i++) {
692 f941aa25 ths
                    p[i] = s;
693 f941aa25 ths
                }
694 1d14ffa9 bellard
            }
695 f941aa25 ths
            break;
696 f941aa25 ths
697 f941aa25 ths
        default:
698 f941aa25 ths
            AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n",
699 f941aa25 ths
                     info->bits);
700 f941aa25 ths
            break;
701 1d14ffa9 bellard
        }
702 85571bc7 bellard
    }
703 85571bc7 bellard
}
704 85571bc7 bellard
705 1d14ffa9 bellard
/*
706 8ead62cf bellard
 * Capture
707 8ead62cf bellard
 */
708 00e07679 Michael Walle
static void noop_conv (struct st_sample *dst, const void *src, int samples)
709 8ead62cf bellard
{
710 8ead62cf bellard
    (void) src;
711 8ead62cf bellard
    (void) dst;
712 8ead62cf bellard
    (void) samples;
713 8ead62cf bellard
}
714 8ead62cf bellard
715 8ead62cf bellard
static CaptureVoiceOut *audio_pcm_capture_find_specific (
716 1ea879e5 malc
    struct audsettings *as
717 8ead62cf bellard
    )
718 8ead62cf bellard
{
719 8ead62cf bellard
    CaptureVoiceOut *cap;
720 1a7dafce malc
    AudioState *s = &glob_audio_state;
721 8ead62cf bellard
722 8ead62cf bellard
    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
723 d929eba5 bellard
        if (audio_pcm_info_eq (&cap->hw.info, as)) {
724 8ead62cf bellard
            return cap;
725 8ead62cf bellard
        }
726 8ead62cf bellard
    }
727 8ead62cf bellard
    return NULL;
728 8ead62cf bellard
}
729 8ead62cf bellard
730 ec36b695 bellard
static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
731 8ead62cf bellard
{
732 ec36b695 bellard
    struct capture_callback *cb;
733 ec36b695 bellard
734 ec36b695 bellard
#ifdef DEBUG_CAPTURE
735 ec36b695 bellard
    dolog ("notification %d sent\n", cmd);
736 ec36b695 bellard
#endif
737 ec36b695 bellard
    for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
738 ec36b695 bellard
        cb->ops.notify (cb->opaque, cmd);
739 ec36b695 bellard
    }
740 ec36b695 bellard
}
741 8ead62cf bellard
742 ec36b695 bellard
static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
743 ec36b695 bellard
{
744 ec36b695 bellard
    if (cap->hw.enabled != enabled) {
745 ec36b695 bellard
        audcnotification_e cmd;
746 8ead62cf bellard
        cap->hw.enabled = enabled;
747 ec36b695 bellard
        cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
748 ec36b695 bellard
        audio_notify_capture (cap, cmd);
749 8ead62cf bellard
    }
750 8ead62cf bellard
}
751 8ead62cf bellard
752 8ead62cf bellard
static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
753 8ead62cf bellard
{
754 8ead62cf bellard
    HWVoiceOut *hw = &cap->hw;
755 8ead62cf bellard
    SWVoiceOut *sw;
756 8ead62cf bellard
    int enabled = 0;
757 8ead62cf bellard
758 ec36b695 bellard
    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
759 8ead62cf bellard
        if (sw->active) {
760 8ead62cf bellard
            enabled = 1;
761 8ead62cf bellard
            break;
762 8ead62cf bellard
        }
763 8ead62cf bellard
    }
764 ec36b695 bellard
    audio_capture_maybe_changed (cap, enabled);
765 8ead62cf bellard
}
766 8ead62cf bellard
767 8ead62cf bellard
static void audio_detach_capture (HWVoiceOut *hw)
768 8ead62cf bellard
{
769 ec36b695 bellard
    SWVoiceCap *sc = hw->cap_head.lh_first;
770 ec36b695 bellard
771 ec36b695 bellard
    while (sc) {
772 ec36b695 bellard
        SWVoiceCap *sc1 = sc->entries.le_next;
773 ec36b695 bellard
        SWVoiceOut *sw = &sc->sw;
774 ec36b695 bellard
        CaptureVoiceOut *cap = sc->cap;
775 ec36b695 bellard
        int was_active = sw->active;
776 8ead62cf bellard
777 8ead62cf bellard
        if (sw->rate) {
778 8ead62cf bellard
            st_rate_stop (sw->rate);
779 8ead62cf bellard
            sw->rate = NULL;
780 8ead62cf bellard
        }
781 8ead62cf bellard
782 72cf2d4f Blue Swirl
        QLIST_REMOVE (sw, entries);
783 72cf2d4f Blue Swirl
        QLIST_REMOVE (sc, entries);
784 7267c094 Anthony Liguori
        g_free (sc);
785 ec36b695 bellard
        if (was_active) {
786 ec36b695 bellard
            /* We have removed soft voice from the capture:
787 ec36b695 bellard
               this might have changed the overall status of the capture
788 ec36b695 bellard
               since this might have been the only active voice */
789 ec36b695 bellard
            audio_recalc_and_notify_capture (cap);
790 ec36b695 bellard
        }
791 ec36b695 bellard
        sc = sc1;
792 8ead62cf bellard
    }
793 8ead62cf bellard
}
794 8ead62cf bellard
795 1a7dafce malc
static int audio_attach_capture (HWVoiceOut *hw)
796 8ead62cf bellard
{
797 1a7dafce malc
    AudioState *s = &glob_audio_state;
798 8ead62cf bellard
    CaptureVoiceOut *cap;
799 8ead62cf bellard
800 8ead62cf bellard
    audio_detach_capture (hw);
801 8ead62cf bellard
    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
802 ec36b695 bellard
        SWVoiceCap *sc;
803 8ead62cf bellard
        SWVoiceOut *sw;
804 ec36b695 bellard
        HWVoiceOut *hw_cap = &cap->hw;
805 8ead62cf bellard
806 ec36b695 bellard
        sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
807 ec36b695 bellard
        if (!sc) {
808 8ead62cf bellard
            dolog ("Could not allocate soft capture voice (%zu bytes)\n",
809 ec36b695 bellard
                   sizeof (*sc));
810 8ead62cf bellard
            return -1;
811 8ead62cf bellard
        }
812 8ead62cf bellard
813 ec36b695 bellard
        sc->cap = cap;
814 ec36b695 bellard
        sw = &sc->sw;
815 8ead62cf bellard
        sw->hw = hw_cap;
816 ec36b695 bellard
        sw->info = hw->info;
817 8ead62cf bellard
        sw->empty = 1;
818 8ead62cf bellard
        sw->active = hw->enabled;
819 8ead62cf bellard
        sw->conv = noop_conv;
820 8ead62cf bellard
        sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
821 83617103 malc
        sw->vol = nominal_volume;
822 8ead62cf bellard
        sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
823 8ead62cf bellard
        if (!sw->rate) {
824 8ead62cf bellard
            dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
825 7267c094 Anthony Liguori
            g_free (sw);
826 8ead62cf bellard
            return -1;
827 8ead62cf bellard
        }
828 72cf2d4f Blue Swirl
        QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
829 72cf2d4f Blue Swirl
        QLIST_INSERT_HEAD (&hw->cap_head, sc, entries);
830 ec36b695 bellard
#ifdef DEBUG_CAPTURE
831 ec36b695 bellard
        asprintf (&sw->name, "for %p %d,%d,%d",
832 ec36b695 bellard
                  hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
833 ec36b695 bellard
        dolog ("Added %s active = %d\n", sw->name, sw->active);
834 ec36b695 bellard
#endif
835 8ead62cf bellard
        if (sw->active) {
836 ec36b695 bellard
            audio_capture_maybe_changed (cap, 1);
837 8ead62cf bellard
        }
838 8ead62cf bellard
    }
839 8ead62cf bellard
    return 0;
840 8ead62cf bellard
}
841 8ead62cf bellard
842 8ead62cf bellard
/*
843 1d14ffa9 bellard
 * Hard voice (capture)
844 1d14ffa9 bellard
 */
845 c0fe3827 bellard
static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
846 85571bc7 bellard
{
847 1d14ffa9 bellard
    SWVoiceIn *sw;
848 1d14ffa9 bellard
    int m = hw->total_samples_captured;
849 1d14ffa9 bellard
850 1d14ffa9 bellard
    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
851 1d14ffa9 bellard
        if (sw->active) {
852 1d14ffa9 bellard
            m = audio_MIN (m, sw->total_hw_samples_acquired);
853 1d14ffa9 bellard
        }
854 85571bc7 bellard
    }
855 1d14ffa9 bellard
    return m;
856 85571bc7 bellard
}
857 85571bc7 bellard
858 1d14ffa9 bellard
int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
859 85571bc7 bellard
{
860 1d14ffa9 bellard
    int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
861 1d14ffa9 bellard
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
862 1d14ffa9 bellard
        dolog ("live=%d hw->samples=%d\n", live, hw->samples);
863 1d14ffa9 bellard
        return 0;
864 85571bc7 bellard
    }
865 1d14ffa9 bellard
    return live;
866 85571bc7 bellard
}
867 85571bc7 bellard
868 ddabec73 malc
int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
869 ddabec73 malc
                           int live, int pending)
870 ddabec73 malc
{
871 ddabec73 malc
    int left = hw->samples - pending;
872 ddabec73 malc
    int len = audio_MIN (left, live);
873 ddabec73 malc
    int clipped = 0;
874 ddabec73 malc
875 ddabec73 malc
    while (len) {
876 ddabec73 malc
        struct st_sample *src = hw->mix_buf + hw->rpos;
877 ddabec73 malc
        uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift);
878 ddabec73 malc
        int samples_till_end_of_buf = hw->samples - hw->rpos;
879 ddabec73 malc
        int samples_to_clip = audio_MIN (len, samples_till_end_of_buf);
880 ddabec73 malc
881 ddabec73 malc
        hw->clip (dst, src, samples_to_clip);
882 ddabec73 malc
883 ddabec73 malc
        hw->rpos = (hw->rpos + samples_to_clip) % hw->samples;
884 ddabec73 malc
        len -= samples_to_clip;
885 ddabec73 malc
        clipped += samples_to_clip;
886 ddabec73 malc
    }
887 ddabec73 malc
    return clipped;
888 ddabec73 malc
}
889 ddabec73 malc
890 1d14ffa9 bellard
/*
891 1d14ffa9 bellard
 * Soft voice (capture)
892 1d14ffa9 bellard
 */
893 1d14ffa9 bellard
static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
894 1d14ffa9 bellard
{
895 1d14ffa9 bellard
    HWVoiceIn *hw = sw->hw;
896 1d14ffa9 bellard
    int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
897 1d14ffa9 bellard
    int rpos;
898 1d14ffa9 bellard
899 1d14ffa9 bellard
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
900 1d14ffa9 bellard
        dolog ("live=%d hw->samples=%d\n", live, hw->samples);
901 1d14ffa9 bellard
        return 0;
902 1d14ffa9 bellard
    }
903 1d14ffa9 bellard
904 1d14ffa9 bellard
    rpos = hw->wpos - live;
905 1d14ffa9 bellard
    if (rpos >= 0) {
906 1d14ffa9 bellard
        return rpos;
907 85571bc7 bellard
    }
908 85571bc7 bellard
    else {
909 1d14ffa9 bellard
        return hw->samples + rpos;
910 85571bc7 bellard
    }
911 85571bc7 bellard
}
912 85571bc7 bellard
913 1d14ffa9 bellard
int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
914 85571bc7 bellard
{
915 1d14ffa9 bellard
    HWVoiceIn *hw = sw->hw;
916 1d14ffa9 bellard
    int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
917 1ea879e5 malc
    struct st_sample *src, *dst = sw->buf;
918 1d14ffa9 bellard
919 1d14ffa9 bellard
    rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;
920 1d14ffa9 bellard
921 1d14ffa9 bellard
    live = hw->total_samples_captured - sw->total_hw_samples_acquired;
922 1d14ffa9 bellard
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
923 1d14ffa9 bellard
        dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);
924 1d14ffa9 bellard
        return 0;
925 1d14ffa9 bellard
    }
926 1d14ffa9 bellard
927 1d14ffa9 bellard
    samples = size >> sw->info.shift;
928 1d14ffa9 bellard
    if (!live) {
929 1d14ffa9 bellard
        return 0;
930 1d14ffa9 bellard
    }
931 85571bc7 bellard
932 1d14ffa9 bellard
    swlim = (live * sw->ratio) >> 32;
933 1d14ffa9 bellard
    swlim = audio_MIN (swlim, samples);
934 85571bc7 bellard
935 1d14ffa9 bellard
    while (swlim) {
936 1d14ffa9 bellard
        src = hw->conv_buf + rpos;
937 1d14ffa9 bellard
        isamp = hw->wpos - rpos;
938 1d14ffa9 bellard
        /* XXX: <= ? */
939 1d14ffa9 bellard
        if (isamp <= 0) {
940 1d14ffa9 bellard
            isamp = hw->samples - rpos;
941 1d14ffa9 bellard
        }
942 85571bc7 bellard
943 1d14ffa9 bellard
        if (!isamp) {
944 1d14ffa9 bellard
            break;
945 1d14ffa9 bellard
        }
946 1d14ffa9 bellard
        osamp = swlim;
947 85571bc7 bellard
948 1d14ffa9 bellard
        if (audio_bug (AUDIO_FUNC, osamp < 0)) {
949 1d14ffa9 bellard
            dolog ("osamp=%d\n", osamp);
950 c0fe3827 bellard
            return 0;
951 1d14ffa9 bellard
        }
952 85571bc7 bellard
953 1d14ffa9 bellard
        st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
954 1d14ffa9 bellard
        swlim -= osamp;
955 1d14ffa9 bellard
        rpos = (rpos + isamp) % hw->samples;
956 1d14ffa9 bellard
        dst += osamp;
957 1d14ffa9 bellard
        ret += osamp;
958 1d14ffa9 bellard
        total += isamp;
959 1d14ffa9 bellard
    }
960 85571bc7 bellard
961 c01b2456 Marc-André Lureau
    if (!(hw->ctl_caps & VOICE_VOLUME_CAP)) {
962 c01b2456 Marc-André Lureau
        mixeng_volume (sw->buf, ret, &sw->vol);
963 c01b2456 Marc-André Lureau
    }
964 00e07679 Michael Walle
965 571ec3d6 bellard
    sw->clip (buf, sw->buf, ret);
966 1d14ffa9 bellard
    sw->total_hw_samples_acquired += total;
967 1d14ffa9 bellard
    return ret << sw->info.shift;
968 85571bc7 bellard
}
969 85571bc7 bellard
970 1d14ffa9 bellard
/*
971 1d14ffa9 bellard
 * Hard voice (playback)
972 1d14ffa9 bellard
 */
973 c0fe3827 bellard
static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
974 1d14ffa9 bellard
{
975 c0fe3827 bellard
    SWVoiceOut *sw;
976 c0fe3827 bellard
    int m = INT_MAX;
977 c0fe3827 bellard
    int nb_live = 0;
978 85571bc7 bellard
979 c0fe3827 bellard
    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
980 c0fe3827 bellard
        if (sw->active || !sw->empty) {
981 c0fe3827 bellard
            m = audio_MIN (m, sw->total_hw_samples_mixed);
982 c0fe3827 bellard
            nb_live += 1;
983 c0fe3827 bellard
        }
984 85571bc7 bellard
    }
985 c0fe3827 bellard
986 c0fe3827 bellard
    *nb_livep = nb_live;
987 c0fe3827 bellard
    return m;
988 1d14ffa9 bellard
}
989 85571bc7 bellard
990 bdff253c malc
static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
991 1d14ffa9 bellard
{
992 1d14ffa9 bellard
    int smin;
993 bdff253c malc
    int nb_live1;
994 85571bc7 bellard
995 bdff253c malc
    smin = audio_pcm_hw_find_min_out (hw, &nb_live1);
996 bdff253c malc
    if (nb_live) {
997 bdff253c malc
        *nb_live = nb_live1;
998 85571bc7 bellard
    }
999 bdff253c malc
1000 bdff253c malc
    if (nb_live1) {
1001 1d14ffa9 bellard
        int live = smin;
1002 1d14ffa9 bellard
1003 1d14ffa9 bellard
        if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
1004 1d14ffa9 bellard
            dolog ("live=%d hw->samples=%d\n", live, hw->samples);
1005 1d14ffa9 bellard
            return 0;
1006 85571bc7 bellard
        }
1007 1d14ffa9 bellard
        return live;
1008 85571bc7 bellard
    }
1009 bdff253c malc
    return 0;
1010 85571bc7 bellard
}
1011 85571bc7 bellard
1012 1d14ffa9 bellard
/*
1013 1d14ffa9 bellard
 * Soft voice (playback)
1014 1d14ffa9 bellard
 */
1015 1d14ffa9 bellard
int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
1016 85571bc7 bellard
{
1017 1d14ffa9 bellard
    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
1018 1d14ffa9 bellard
    int ret = 0, pos = 0, total = 0;
1019 85571bc7 bellard
1020 1d14ffa9 bellard
    if (!sw) {
1021 1d14ffa9 bellard
        return size;
1022 1d14ffa9 bellard
    }
1023 85571bc7 bellard
1024 1d14ffa9 bellard
    hwsamples = sw->hw->samples;
1025 85571bc7 bellard
1026 1d14ffa9 bellard
    live = sw->total_hw_samples_mixed;
1027 1d14ffa9 bellard
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){
1028 1d14ffa9 bellard
        dolog ("live=%d hw->samples=%d\n", live, hwsamples);
1029 1d14ffa9 bellard
        return 0;
1030 1d14ffa9 bellard
    }
1031 85571bc7 bellard
1032 1d14ffa9 bellard
    if (live == hwsamples) {
1033 ec36b695 bellard
#ifdef DEBUG_OUT
1034 ec36b695 bellard
        dolog ("%s is full %d\n", sw->name, live);
1035 ec36b695 bellard
#endif
1036 1d14ffa9 bellard
        return 0;
1037 1d14ffa9 bellard
    }
1038 85571bc7 bellard
1039 1d14ffa9 bellard
    wpos = (sw->hw->rpos + live) % hwsamples;
1040 1d14ffa9 bellard
    samples = size >> sw->info.shift;
1041 85571bc7 bellard
1042 1d14ffa9 bellard
    dead = hwsamples - live;
1043 1d14ffa9 bellard
    swlim = ((int64_t) dead << 32) / sw->ratio;
1044 1d14ffa9 bellard
    swlim = audio_MIN (swlim, samples);
1045 1d14ffa9 bellard
    if (swlim) {
1046 00e07679 Michael Walle
        sw->conv (sw->buf, buf, swlim);
1047 c01b2456 Marc-André Lureau
1048 c01b2456 Marc-André Lureau
        if (!(sw->hw->ctl_caps & VOICE_VOLUME_CAP)) {
1049 c01b2456 Marc-André Lureau
            mixeng_volume (sw->buf, swlim, &sw->vol);
1050 c01b2456 Marc-André Lureau
        }
1051 1d14ffa9 bellard
    }
1052 1d14ffa9 bellard
1053 1d14ffa9 bellard
    while (swlim) {
1054 1d14ffa9 bellard
        dead = hwsamples - live;
1055 1d14ffa9 bellard
        left = hwsamples - wpos;
1056 1d14ffa9 bellard
        blck = audio_MIN (dead, left);
1057 1d14ffa9 bellard
        if (!blck) {
1058 1d14ffa9 bellard
            break;
1059 1d14ffa9 bellard
        }
1060 1d14ffa9 bellard
        isamp = swlim;
1061 1d14ffa9 bellard
        osamp = blck;
1062 1d14ffa9 bellard
        st_rate_flow_mix (
1063 1d14ffa9 bellard
            sw->rate,
1064 1d14ffa9 bellard
            sw->buf + pos,
1065 1d14ffa9 bellard
            sw->hw->mix_buf + wpos,
1066 1d14ffa9 bellard
            &isamp,
1067 1d14ffa9 bellard
            &osamp
1068 1d14ffa9 bellard
            );
1069 1d14ffa9 bellard
        ret += isamp;
1070 1d14ffa9 bellard
        swlim -= isamp;
1071 1d14ffa9 bellard
        pos += isamp;
1072 1d14ffa9 bellard
        live += osamp;
1073 1d14ffa9 bellard
        wpos = (wpos + osamp) % hwsamples;
1074 1d14ffa9 bellard
        total += osamp;
1075 1d14ffa9 bellard
    }
1076 1d14ffa9 bellard
1077 1d14ffa9 bellard
    sw->total_hw_samples_mixed += total;
1078 1d14ffa9 bellard
    sw->empty = sw->total_hw_samples_mixed == 0;
1079 1d14ffa9 bellard
1080 1d14ffa9 bellard
#ifdef DEBUG_OUT
1081 1d14ffa9 bellard
    dolog (
1082 c0fe3827 bellard
        "%s: write size %d ret %d total sw %d\n",
1083 c0fe3827 bellard
        SW_NAME (sw),
1084 1d14ffa9 bellard
        size >> sw->info.shift,
1085 1d14ffa9 bellard
        ret,
1086 c0fe3827 bellard
        sw->total_hw_samples_mixed
1087 1d14ffa9 bellard
        );
1088 1d14ffa9 bellard
#endif
1089 1d14ffa9 bellard
1090 1d14ffa9 bellard
    return ret << sw->info.shift;
1091 85571bc7 bellard
}
1092 85571bc7 bellard
1093 1d14ffa9 bellard
#ifdef DEBUG_AUDIO
1094 1d14ffa9 bellard
static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
1095 85571bc7 bellard
{
1096 1d14ffa9 bellard
    dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
1097 1d14ffa9 bellard
           cap, info->bits, info->sign, info->freq, info->nchannels);
1098 85571bc7 bellard
}
1099 1d14ffa9 bellard
#endif
1100 85571bc7 bellard
1101 1d14ffa9 bellard
#define DAC
1102 1d14ffa9 bellard
#include "audio_template.h"
1103 1d14ffa9 bellard
#undef DAC
1104 1d14ffa9 bellard
#include "audio_template.h"
1105 1d14ffa9 bellard
1106 713a98f8 malc
/*
1107 713a98f8 malc
 * Timer
1108 713a98f8 malc
 */
1109 713a98f8 malc
static int audio_is_timer_needed (void)
1110 713a98f8 malc
{
1111 713a98f8 malc
    HWVoiceIn *hwi = NULL;
1112 713a98f8 malc
    HWVoiceOut *hwo = NULL;
1113 713a98f8 malc
1114 713a98f8 malc
    while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1115 713a98f8 malc
        if (!hwo->poll_mode) return 1;
1116 713a98f8 malc
    }
1117 713a98f8 malc
    while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1118 713a98f8 malc
        if (!hwi->poll_mode) return 1;
1119 713a98f8 malc
    }
1120 713a98f8 malc
    return 0;
1121 713a98f8 malc
}
1122 713a98f8 malc
1123 39deb1e4 malc
static void audio_reset_timer (AudioState *s)
1124 713a98f8 malc
{
1125 713a98f8 malc
    if (audio_is_timer_needed ()) {
1126 74475455 Paolo Bonzini
        qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + 1);
1127 713a98f8 malc
    }
1128 713a98f8 malc
    else {
1129 713a98f8 malc
        qemu_del_timer (s->ts);
1130 713a98f8 malc
    }
1131 713a98f8 malc
}
1132 713a98f8 malc
1133 39deb1e4 malc
static void audio_timer (void *opaque)
1134 39deb1e4 malc
{
1135 39deb1e4 malc
    audio_run ("timer");
1136 39deb1e4 malc
    audio_reset_timer (opaque);
1137 39deb1e4 malc
}
1138 39deb1e4 malc
1139 713a98f8 malc
/*
1140 713a98f8 malc
 * Public API
1141 713a98f8 malc
 */
1142 1d14ffa9 bellard
int AUD_write (SWVoiceOut *sw, void *buf, int size)
1143 85571bc7 bellard
{
1144 1d14ffa9 bellard
    int bytes;
1145 85571bc7 bellard
1146 1d14ffa9 bellard
    if (!sw) {
1147 1d14ffa9 bellard
        /* XXX: Consider options */
1148 1d14ffa9 bellard
        return size;
1149 1d14ffa9 bellard
    }
1150 85571bc7 bellard
1151 1d14ffa9 bellard
    if (!sw->hw->enabled) {
1152 c0fe3827 bellard
        dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
1153 85571bc7 bellard
        return 0;
1154 85571bc7 bellard
    }
1155 85571bc7 bellard
1156 1d14ffa9 bellard
    bytes = sw->hw->pcm_ops->write (sw, buf, size);
1157 1d14ffa9 bellard
    return bytes;
1158 1d14ffa9 bellard
}
1159 1d14ffa9 bellard
1160 1d14ffa9 bellard
int AUD_read (SWVoiceIn *sw, void *buf, int size)
1161 1d14ffa9 bellard
{
1162 1d14ffa9 bellard
    int bytes;
1163 85571bc7 bellard
1164 1d14ffa9 bellard
    if (!sw) {
1165 1d14ffa9 bellard
        /* XXX: Consider options */
1166 1d14ffa9 bellard
        return size;
1167 85571bc7 bellard
    }
1168 1d14ffa9 bellard
1169 1d14ffa9 bellard
    if (!sw->hw->enabled) {
1170 c0fe3827 bellard
        dolog ("Reading from disabled voice %s\n", SW_NAME (sw));
1171 1d14ffa9 bellard
        return 0;
1172 85571bc7 bellard
    }
1173 1d14ffa9 bellard
1174 1d14ffa9 bellard
    bytes = sw->hw->pcm_ops->read (sw, buf, size);
1175 1d14ffa9 bellard
    return bytes;
1176 85571bc7 bellard
}
1177 85571bc7 bellard
1178 1d14ffa9 bellard
int AUD_get_buffer_size_out (SWVoiceOut *sw)
1179 85571bc7 bellard
{
1180 c0fe3827 bellard
    return sw->hw->samples << sw->hw->info.shift;
1181 1d14ffa9 bellard
}
1182 1d14ffa9 bellard
1183 1d14ffa9 bellard
void AUD_set_active_out (SWVoiceOut *sw, int on)
1184 1d14ffa9 bellard
{
1185 1d14ffa9 bellard
    HWVoiceOut *hw;
1186 85571bc7 bellard
1187 1d14ffa9 bellard
    if (!sw) {
1188 85571bc7 bellard
        return;
1189 1d14ffa9 bellard
    }
1190 85571bc7 bellard
1191 85571bc7 bellard
    hw = sw->hw;
1192 1d14ffa9 bellard
    if (sw->active != on) {
1193 978dd635 malc
        AudioState *s = &glob_audio_state;
1194 1d14ffa9 bellard
        SWVoiceOut *temp_sw;
1195 ec36b695 bellard
        SWVoiceCap *sc;
1196 1d14ffa9 bellard
1197 1d14ffa9 bellard
        if (on) {
1198 1d14ffa9 bellard
            hw->pending_disable = 0;
1199 1d14ffa9 bellard
            if (!hw->enabled) {
1200 1d14ffa9 bellard
                hw->enabled = 1;
1201 978dd635 malc
                if (s->vm_running) {
1202 713a98f8 malc
                    hw->pcm_ops->ctl_out (hw, VOICE_ENABLE, conf.try_poll_out);
1203 39deb1e4 malc
                    audio_reset_timer (s);
1204 978dd635 malc
                }
1205 1d14ffa9 bellard
            }
1206 1d14ffa9 bellard
        }
1207 1d14ffa9 bellard
        else {
1208 1d14ffa9 bellard
            if (hw->enabled) {
1209 1d14ffa9 bellard
                int nb_active = 0;
1210 1d14ffa9 bellard
1211 1d14ffa9 bellard
                for (temp_sw = hw->sw_head.lh_first; temp_sw;
1212 1d14ffa9 bellard
                     temp_sw = temp_sw->entries.le_next) {
1213 1d14ffa9 bellard
                    nb_active += temp_sw->active != 0;
1214 1d14ffa9 bellard
                }
1215 1d14ffa9 bellard
1216 1d14ffa9 bellard
                hw->pending_disable = nb_active == 1;
1217 1d14ffa9 bellard
            }
1218 85571bc7 bellard
        }
1219 ec36b695 bellard
1220 ec36b695 bellard
        for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1221 ec36b695 bellard
            sc->sw.active = hw->enabled;
1222 8ead62cf bellard
            if (hw->enabled) {
1223 ec36b695 bellard
                audio_capture_maybe_changed (sc->cap, 1);
1224 8ead62cf bellard
            }
1225 8ead62cf bellard
        }
1226 1d14ffa9 bellard
        sw->active = on;
1227 1d14ffa9 bellard
    }
1228 1d14ffa9 bellard
}
1229 1d14ffa9 bellard
1230 1d14ffa9 bellard
void AUD_set_active_in (SWVoiceIn *sw, int on)
1231 1d14ffa9 bellard
{
1232 1d14ffa9 bellard
    HWVoiceIn *hw;
1233 1d14ffa9 bellard
1234 1d14ffa9 bellard
    if (!sw) {
1235 1d14ffa9 bellard
        return;
1236 85571bc7 bellard
    }
1237 85571bc7 bellard
1238 1d14ffa9 bellard
    hw = sw->hw;
1239 85571bc7 bellard
    if (sw->active != on) {
1240 978dd635 malc
        AudioState *s = &glob_audio_state;
1241 1d14ffa9 bellard
        SWVoiceIn *temp_sw;
1242 1d14ffa9 bellard
1243 85571bc7 bellard
        if (on) {
1244 85571bc7 bellard
            if (!hw->enabled) {
1245 85571bc7 bellard
                hw->enabled = 1;
1246 978dd635 malc
                if (s->vm_running) {
1247 713a98f8 malc
                    hw->pcm_ops->ctl_in (hw, VOICE_ENABLE, conf.try_poll_in);
1248 39deb1e4 malc
                    audio_reset_timer (s);
1249 978dd635 malc
                }
1250 85571bc7 bellard
            }
1251 1d14ffa9 bellard
            sw->total_hw_samples_acquired = hw->total_samples_captured;
1252 85571bc7 bellard
        }
1253 85571bc7 bellard
        else {
1254 1d14ffa9 bellard
            if (hw->enabled) {
1255 85571bc7 bellard
                int nb_active = 0;
1256 1d14ffa9 bellard
1257 1d14ffa9 bellard
                for (temp_sw = hw->sw_head.lh_first; temp_sw;
1258 1d14ffa9 bellard
                     temp_sw = temp_sw->entries.le_next) {
1259 1d14ffa9 bellard
                    nb_active += temp_sw->active != 0;
1260 85571bc7 bellard
                }
1261 85571bc7 bellard
1262 85571bc7 bellard
                if (nb_active == 1) {
1263 1d14ffa9 bellard
                    hw->enabled = 0;
1264 1d14ffa9 bellard
                    hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
1265 85571bc7 bellard
                }
1266 85571bc7 bellard
            }
1267 85571bc7 bellard
        }
1268 85571bc7 bellard
        sw->active = on;
1269 85571bc7 bellard
    }
1270 85571bc7 bellard
}
1271 85571bc7 bellard
1272 1d14ffa9 bellard
static int audio_get_avail (SWVoiceIn *sw)
1273 1d14ffa9 bellard
{
1274 1d14ffa9 bellard
    int live;
1275 1d14ffa9 bellard
1276 1d14ffa9 bellard
    if (!sw) {
1277 1d14ffa9 bellard
        return 0;
1278 1d14ffa9 bellard
    }
1279 1d14ffa9 bellard
1280 1d14ffa9 bellard
    live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
1281 1d14ffa9 bellard
    if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
1282 1d14ffa9 bellard
        dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
1283 1d14ffa9 bellard
        return 0;
1284 1d14ffa9 bellard
    }
1285 1d14ffa9 bellard
1286 1d14ffa9 bellard
    ldebug (
1287 26a76461 bellard
        "%s: get_avail live %d ret %" PRId64 "\n",
1288 c0fe3827 bellard
        SW_NAME (sw),
1289 1d14ffa9 bellard
        live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift
1290 1d14ffa9 bellard
        );
1291 1d14ffa9 bellard
1292 1d14ffa9 bellard
    return (((int64_t) live << 32) / sw->ratio) << sw->info.shift;
1293 1d14ffa9 bellard
}
1294 1d14ffa9 bellard
1295 1d14ffa9 bellard
static int audio_get_free (SWVoiceOut *sw)
1296 1d14ffa9 bellard
{
1297 1d14ffa9 bellard
    int live, dead;
1298 1d14ffa9 bellard
1299 1d14ffa9 bellard
    if (!sw) {
1300 1d14ffa9 bellard
        return 0;
1301 1d14ffa9 bellard
    }
1302 1d14ffa9 bellard
1303 1d14ffa9 bellard
    live = sw->total_hw_samples_mixed;
1304 1d14ffa9 bellard
1305 1d14ffa9 bellard
    if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
1306 1d14ffa9 bellard
        dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
1307 c0fe3827 bellard
        return 0;
1308 1d14ffa9 bellard
    }
1309 1d14ffa9 bellard
1310 1d14ffa9 bellard
    dead = sw->hw->samples - live;
1311 1d14ffa9 bellard
1312 1d14ffa9 bellard
#ifdef DEBUG_OUT
1313 26a76461 bellard
    dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n",
1314 c0fe3827 bellard
           SW_NAME (sw),
1315 1d14ffa9 bellard
           live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
1316 85571bc7 bellard
#endif
1317 1d14ffa9 bellard
1318 1d14ffa9 bellard
    return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
1319 1d14ffa9 bellard
}
1320 1d14ffa9 bellard
1321 8ead62cf bellard
static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
1322 8ead62cf bellard
{
1323 8ead62cf bellard
    int n;
1324 8ead62cf bellard
1325 8ead62cf bellard
    if (hw->enabled) {
1326 ec36b695 bellard
        SWVoiceCap *sc;
1327 8ead62cf bellard
1328 ec36b695 bellard
        for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1329 ec36b695 bellard
            SWVoiceOut *sw = &sc->sw;
1330 8ead62cf bellard
            int rpos2 = rpos;
1331 8ead62cf bellard
1332 8ead62cf bellard
            n = samples;
1333 8ead62cf bellard
            while (n) {
1334 8ead62cf bellard
                int till_end_of_hw = hw->samples - rpos2;
1335 8ead62cf bellard
                int to_write = audio_MIN (till_end_of_hw, n);
1336 8ead62cf bellard
                int bytes = to_write << hw->info.shift;
1337 8ead62cf bellard
                int written;
1338 8ead62cf bellard
1339 8ead62cf bellard
                sw->buf = hw->mix_buf + rpos2;
1340 8ead62cf bellard
                written = audio_pcm_sw_write (sw, NULL, bytes);
1341 8ead62cf bellard
                if (written - bytes) {
1342 ec36b695 bellard
                    dolog ("Could not mix %d bytes into a capture "
1343 ec36b695 bellard
                           "buffer, mixed %d\n",
1344 ec36b695 bellard
                           bytes, written);
1345 8ead62cf bellard
                    break;
1346 8ead62cf bellard
                }
1347 8ead62cf bellard
                n -= to_write;
1348 8ead62cf bellard
                rpos2 = (rpos2 + to_write) % hw->samples;
1349 8ead62cf bellard
            }
1350 8ead62cf bellard
        }
1351 8ead62cf bellard
    }
1352 8ead62cf bellard
1353 8ead62cf bellard
    n = audio_MIN (samples, hw->samples - rpos);
1354 8ead62cf bellard
    mixeng_clear (hw->mix_buf + rpos, n);
1355 8ead62cf bellard
    mixeng_clear (hw->mix_buf, samples - n);
1356 8ead62cf bellard
}
1357 8ead62cf bellard
1358 c0fe3827 bellard
static void audio_run_out (AudioState *s)
1359 1d14ffa9 bellard
{
1360 1d14ffa9 bellard
    HWVoiceOut *hw = NULL;
1361 1d14ffa9 bellard
    SWVoiceOut *sw;
1362 1d14ffa9 bellard
1363 1a7dafce malc
    while ((hw = audio_pcm_hw_find_any_enabled_out (hw))) {
1364 1d14ffa9 bellard
        int played;
1365 8ead62cf bellard
        int live, free, nb_live, cleanup_required, prev_rpos;
1366 1d14ffa9 bellard
1367 bdff253c malc
        live = audio_pcm_hw_get_live_out (hw, &nb_live);
1368 1d14ffa9 bellard
        if (!nb_live) {
1369 1d14ffa9 bellard
            live = 0;
1370 1d14ffa9 bellard
        }
1371 c0fe3827 bellard
1372 1d14ffa9 bellard
        if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
1373 1d14ffa9 bellard
            dolog ("live=%d hw->samples=%d\n", live, hw->samples);
1374 c0fe3827 bellard
            continue;
1375 1d14ffa9 bellard
        }
1376 1d14ffa9 bellard
1377 1d14ffa9 bellard
        if (hw->pending_disable && !nb_live) {
1378 ec36b695 bellard
            SWVoiceCap *sc;
1379 1d14ffa9 bellard
#ifdef DEBUG_OUT
1380 1d14ffa9 bellard
            dolog ("Disabling voice\n");
1381 85571bc7 bellard
#endif
1382 1d14ffa9 bellard
            hw->enabled = 0;
1383 1d14ffa9 bellard
            hw->pending_disable = 0;
1384 1d14ffa9 bellard
            hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
1385 ec36b695 bellard
            for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1386 ec36b695 bellard
                sc->sw.active = 0;
1387 ec36b695 bellard
                audio_recalc_and_notify_capture (sc->cap);
1388 8ead62cf bellard
            }
1389 1d14ffa9 bellard
            continue;
1390 1d14ffa9 bellard
        }
1391 1d14ffa9 bellard
1392 1d14ffa9 bellard
        if (!live) {
1393 1d14ffa9 bellard
            for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1394 1d14ffa9 bellard
                if (sw->active) {
1395 1d14ffa9 bellard
                    free = audio_get_free (sw);
1396 1d14ffa9 bellard
                    if (free > 0) {
1397 1d14ffa9 bellard
                        sw->callback.fn (sw->callback.opaque, free);
1398 1d14ffa9 bellard
                    }
1399 1d14ffa9 bellard
                }
1400 1d14ffa9 bellard
            }
1401 1d14ffa9 bellard
            continue;
1402 1d14ffa9 bellard
        }
1403 1d14ffa9 bellard
1404 8ead62cf bellard
        prev_rpos = hw->rpos;
1405 bdff253c malc
        played = hw->pcm_ops->run_out (hw, live);
1406 1d14ffa9 bellard
        if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
1407 1d14ffa9 bellard
            dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
1408 1d14ffa9 bellard
                   hw->rpos, hw->samples, played);
1409 1d14ffa9 bellard
            hw->rpos = 0;
1410 1d14ffa9 bellard
        }
1411 1d14ffa9 bellard
1412 1d14ffa9 bellard
#ifdef DEBUG_OUT
1413 c0fe3827 bellard
        dolog ("played=%d\n", played);
1414 85571bc7 bellard
#endif
1415 1d14ffa9 bellard
1416 1d14ffa9 bellard
        if (played) {
1417 1d14ffa9 bellard
            hw->ts_helper += played;
1418 8ead62cf bellard
            audio_capture_mix_and_clear (hw, prev_rpos, played);
1419 1d14ffa9 bellard
        }
1420 1d14ffa9 bellard
1421 c0fe3827 bellard
        cleanup_required = 0;
1422 1d14ffa9 bellard
        for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1423 1d14ffa9 bellard
            if (!sw->active && sw->empty) {
1424 1d14ffa9 bellard
                continue;
1425 1d14ffa9 bellard
            }
1426 1d14ffa9 bellard
1427 1d14ffa9 bellard
            if (audio_bug (AUDIO_FUNC, played > sw->total_hw_samples_mixed)) {
1428 1d14ffa9 bellard
                dolog ("played=%d sw->total_hw_samples_mixed=%d\n",
1429 1d14ffa9 bellard
                       played, sw->total_hw_samples_mixed);
1430 1d14ffa9 bellard
                played = sw->total_hw_samples_mixed;
1431 1d14ffa9 bellard
            }
1432 1d14ffa9 bellard
1433 1d14ffa9 bellard
            sw->total_hw_samples_mixed -= played;
1434 1d14ffa9 bellard
1435 1d14ffa9 bellard
            if (!sw->total_hw_samples_mixed) {
1436 1d14ffa9 bellard
                sw->empty = 1;
1437 c0fe3827 bellard
                cleanup_required |= !sw->active && !sw->callback.fn;
1438 1d14ffa9 bellard
            }
1439 1d14ffa9 bellard
1440 1d14ffa9 bellard
            if (sw->active) {
1441 1d14ffa9 bellard
                free = audio_get_free (sw);
1442 1d14ffa9 bellard
                if (free > 0) {
1443 1d14ffa9 bellard
                    sw->callback.fn (sw->callback.opaque, free);
1444 1d14ffa9 bellard
                }
1445 1d14ffa9 bellard
            }
1446 1d14ffa9 bellard
        }
1447 c0fe3827 bellard
1448 c0fe3827 bellard
        if (cleanup_required) {
1449 ec36b695 bellard
            SWVoiceOut *sw1;
1450 ec36b695 bellard
1451 ec36b695 bellard
            sw = hw->sw_head.lh_first;
1452 ec36b695 bellard
            while (sw) {
1453 ec36b695 bellard
                sw1 = sw->entries.le_next;
1454 c0fe3827 bellard
                if (!sw->active && !sw->callback.fn) {
1455 c0fe3827 bellard
#ifdef DEBUG_PLIVE
1456 c0fe3827 bellard
                    dolog ("Finishing with old voice\n");
1457 c0fe3827 bellard
#endif
1458 1a7dafce malc
                    audio_close_out (sw);
1459 c0fe3827 bellard
                }
1460 ec36b695 bellard
                sw = sw1;
1461 c0fe3827 bellard
            }
1462 c0fe3827 bellard
        }
1463 1d14ffa9 bellard
    }
1464 1d14ffa9 bellard
}
1465 1d14ffa9 bellard
1466 c0fe3827 bellard
static void audio_run_in (AudioState *s)
1467 1d14ffa9 bellard
{
1468 1d14ffa9 bellard
    HWVoiceIn *hw = NULL;
1469 1d14ffa9 bellard
1470 1a7dafce malc
    while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) {
1471 1d14ffa9 bellard
        SWVoiceIn *sw;
1472 1d14ffa9 bellard
        int captured, min;
1473 1d14ffa9 bellard
1474 1d14ffa9 bellard
        captured = hw->pcm_ops->run_in (hw);
1475 1d14ffa9 bellard
1476 1d14ffa9 bellard
        min = audio_pcm_hw_find_min_in (hw);
1477 1d14ffa9 bellard
        hw->total_samples_captured += captured - min;
1478 1d14ffa9 bellard
        hw->ts_helper += captured;
1479 1d14ffa9 bellard
1480 1d14ffa9 bellard
        for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1481 1d14ffa9 bellard
            sw->total_hw_samples_acquired -= min;
1482 1d14ffa9 bellard
1483 1d14ffa9 bellard
            if (sw->active) {
1484 1d14ffa9 bellard
                int avail;
1485 1d14ffa9 bellard
1486 1d14ffa9 bellard
                avail = audio_get_avail (sw);
1487 1d14ffa9 bellard
                if (avail > 0) {
1488 1d14ffa9 bellard
                    sw->callback.fn (sw->callback.opaque, avail);
1489 1d14ffa9 bellard
                }
1490 1d14ffa9 bellard
            }
1491 1d14ffa9 bellard
        }
1492 1d14ffa9 bellard
    }
1493 1d14ffa9 bellard
}
1494 1d14ffa9 bellard
1495 8ead62cf bellard
static void audio_run_capture (AudioState *s)
1496 8ead62cf bellard
{
1497 8ead62cf bellard
    CaptureVoiceOut *cap;
1498 8ead62cf bellard
1499 8ead62cf bellard
    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
1500 8ead62cf bellard
        int live, rpos, captured;
1501 8ead62cf bellard
        HWVoiceOut *hw = &cap->hw;
1502 8ead62cf bellard
        SWVoiceOut *sw;
1503 8ead62cf bellard
1504 bdff253c malc
        captured = live = audio_pcm_hw_get_live_out (hw, NULL);
1505 8ead62cf bellard
        rpos = hw->rpos;
1506 8ead62cf bellard
        while (live) {
1507 8ead62cf bellard
            int left = hw->samples - rpos;
1508 8ead62cf bellard
            int to_capture = audio_MIN (live, left);
1509 1ea879e5 malc
            struct st_sample *src;
1510 8ead62cf bellard
            struct capture_callback *cb;
1511 8ead62cf bellard
1512 8ead62cf bellard
            src = hw->mix_buf + rpos;
1513 8ead62cf bellard
            hw->clip (cap->buf, src, to_capture);
1514 8ead62cf bellard
            mixeng_clear (src, to_capture);
1515 8ead62cf bellard
1516 8ead62cf bellard
            for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
1517 8ead62cf bellard
                cb->ops.capture (cb->opaque, cap->buf,
1518 8ead62cf bellard
                                 to_capture << hw->info.shift);
1519 8ead62cf bellard
            }
1520 8ead62cf bellard
            rpos = (rpos + to_capture) % hw->samples;
1521 8ead62cf bellard
            live -= to_capture;
1522 8ead62cf bellard
        }
1523 8ead62cf bellard
        hw->rpos = rpos;
1524 8ead62cf bellard
1525 8ead62cf bellard
        for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1526 8ead62cf bellard
            if (!sw->active && sw->empty) {
1527 8ead62cf bellard
                continue;
1528 8ead62cf bellard
            }
1529 8ead62cf bellard
1530 8ead62cf bellard
            if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) {
1531 8ead62cf bellard
                dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
1532 8ead62cf bellard
                       captured, sw->total_hw_samples_mixed);
1533 8ead62cf bellard
                captured = sw->total_hw_samples_mixed;
1534 8ead62cf bellard
            }
1535 8ead62cf bellard
1536 8ead62cf bellard
            sw->total_hw_samples_mixed -= captured;
1537 8ead62cf bellard
            sw->empty = sw->total_hw_samples_mixed == 0;
1538 8ead62cf bellard
        }
1539 8ead62cf bellard
    }
1540 8ead62cf bellard
}
1541 8ead62cf bellard
1542 713a98f8 malc
void audio_run (const char *msg)
1543 571ec3d6 bellard
{
1544 713a98f8 malc
    AudioState *s = &glob_audio_state;
1545 571ec3d6 bellard
1546 571ec3d6 bellard
    audio_run_out (s);
1547 571ec3d6 bellard
    audio_run_in (s);
1548 8ead62cf bellard
    audio_run_capture (s);
1549 713a98f8 malc
#ifdef DEBUG_POLL
1550 713a98f8 malc
    {
1551 713a98f8 malc
        static double prevtime;
1552 713a98f8 malc
        double currtime;
1553 713a98f8 malc
        struct timeval tv;
1554 571ec3d6 bellard
1555 713a98f8 malc
        if (gettimeofday (&tv, NULL)) {
1556 713a98f8 malc
            perror ("audio_run: gettimeofday");
1557 713a98f8 malc
            return;
1558 713a98f8 malc
        }
1559 713a98f8 malc
1560 713a98f8 malc
        currtime = tv.tv_sec + tv.tv_usec * 1e-6;
1561 713a98f8 malc
        dolog ("Elapsed since last %s: %f\n", msg, currtime - prevtime);
1562 713a98f8 malc
        prevtime = currtime;
1563 713a98f8 malc
    }
1564 713a98f8 malc
#endif
1565 571ec3d6 bellard
}
1566 571ec3d6 bellard
1567 1d14ffa9 bellard
static struct audio_option audio_options[] = {
1568 1d14ffa9 bellard
    /* DAC */
1569 98f9f48c malc
    {
1570 98f9f48c malc
        .name  = "DAC_FIXED_SETTINGS",
1571 98f9f48c malc
        .tag   = AUD_OPT_BOOL,
1572 98f9f48c malc
        .valp  = &conf.fixed_out.enabled,
1573 98f9f48c malc
        .descr = "Use fixed settings for host DAC"
1574 98f9f48c malc
    },
1575 98f9f48c malc
    {
1576 98f9f48c malc
        .name  = "DAC_FIXED_FREQ",
1577 98f9f48c malc
        .tag   = AUD_OPT_INT,
1578 98f9f48c malc
        .valp  = &conf.fixed_out.settings.freq,
1579 98f9f48c malc
        .descr = "Frequency for fixed host DAC"
1580 98f9f48c malc
    },
1581 98f9f48c malc
    {
1582 98f9f48c malc
        .name  = "DAC_FIXED_FMT",
1583 98f9f48c malc
        .tag   = AUD_OPT_FMT,
1584 98f9f48c malc
        .valp  = &conf.fixed_out.settings.fmt,
1585 98f9f48c malc
        .descr = "Format for fixed host DAC"
1586 98f9f48c malc
    },
1587 98f9f48c malc
    {
1588 98f9f48c malc
        .name  = "DAC_FIXED_CHANNELS",
1589 98f9f48c malc
        .tag   = AUD_OPT_INT,
1590 98f9f48c malc
        .valp  = &conf.fixed_out.settings.nchannels,
1591 98f9f48c malc
        .descr = "Number of channels for fixed DAC (1 - mono, 2 - stereo)"
1592 98f9f48c malc
    },
1593 98f9f48c malc
    {
1594 98f9f48c malc
        .name  = "DAC_VOICES",
1595 98f9f48c malc
        .tag   = AUD_OPT_INT,
1596 98f9f48c malc
        .valp  = &conf.fixed_out.nb_voices,
1597 98f9f48c malc
        .descr = "Number of voices for DAC"
1598 98f9f48c malc
    },
1599 713a98f8 malc
    {
1600 713a98f8 malc
        .name  = "DAC_TRY_POLL",
1601 713a98f8 malc
        .tag   = AUD_OPT_BOOL,
1602 713a98f8 malc
        .valp  = &conf.try_poll_out,
1603 713a98f8 malc
        .descr = "Attempt using poll mode for DAC"
1604 713a98f8 malc
    },
1605 1d14ffa9 bellard
    /* ADC */
1606 98f9f48c malc
    {
1607 98f9f48c malc
        .name  = "ADC_FIXED_SETTINGS",
1608 98f9f48c malc
        .tag   = AUD_OPT_BOOL,
1609 98f9f48c malc
        .valp  = &conf.fixed_in.enabled,
1610 98f9f48c malc
        .descr = "Use fixed settings for host ADC"
1611 98f9f48c malc
    },
1612 98f9f48c malc
    {
1613 98f9f48c malc
        .name  = "ADC_FIXED_FREQ",
1614 98f9f48c malc
        .tag   = AUD_OPT_INT,
1615 98f9f48c malc
        .valp  = &conf.fixed_in.settings.freq,
1616 98f9f48c malc
        .descr = "Frequency for fixed host ADC"
1617 98f9f48c malc
    },
1618 98f9f48c malc
    {
1619 98f9f48c malc
        .name  = "ADC_FIXED_FMT",
1620 98f9f48c malc
        .tag   = AUD_OPT_FMT,
1621 98f9f48c malc
        .valp  = &conf.fixed_in.settings.fmt,
1622 98f9f48c malc
        .descr = "Format for fixed host ADC"
1623 98f9f48c malc
    },
1624 98f9f48c malc
    {
1625 98f9f48c malc
        .name  = "ADC_FIXED_CHANNELS",
1626 98f9f48c malc
        .tag   = AUD_OPT_INT,
1627 98f9f48c malc
        .valp  = &conf.fixed_in.settings.nchannels,
1628 98f9f48c malc
        .descr = "Number of channels for fixed ADC (1 - mono, 2 - stereo)"
1629 98f9f48c malc
    },
1630 98f9f48c malc
    {
1631 98f9f48c malc
        .name  = "ADC_VOICES",
1632 98f9f48c malc
        .tag   = AUD_OPT_INT,
1633 98f9f48c malc
        .valp  = &conf.fixed_in.nb_voices,
1634 98f9f48c malc
        .descr = "Number of voices for ADC"
1635 98f9f48c malc
    },
1636 713a98f8 malc
    {
1637 713a98f8 malc
        .name  = "ADC_TRY_POLL",
1638 713a98f8 malc
        .tag   = AUD_OPT_BOOL,
1639 0a90e344 Jan Kiszka
        .valp  = &conf.try_poll_in,
1640 713a98f8 malc
        .descr = "Attempt using poll mode for ADC"
1641 713a98f8 malc
    },
1642 1d14ffa9 bellard
    /* Misc */
1643 98f9f48c malc
    {
1644 98f9f48c malc
        .name  = "TIMER_PERIOD",
1645 98f9f48c malc
        .tag   = AUD_OPT_INT,
1646 98f9f48c malc
        .valp  = &conf.period.hertz,
1647 98f9f48c malc
        .descr = "Timer period in HZ (0 - use lowest possible)"
1648 98f9f48c malc
    },
1649 98f9f48c malc
    {
1650 98f9f48c malc
        .name  = "PLIVE",
1651 98f9f48c malc
        .tag   = AUD_OPT_BOOL,
1652 98f9f48c malc
        .valp  = &conf.plive,
1653 98f9f48c malc
        .descr = "(undocumented)"
1654 98f9f48c malc
    },
1655 98f9f48c malc
    {
1656 98f9f48c malc
        .name  = "LOG_TO_MONITOR",
1657 98f9f48c malc
        .tag   = AUD_OPT_BOOL,
1658 98f9f48c malc
        .valp  = &conf.log_to_monitor,
1659 713a98f8 malc
        .descr = "Print logging messages to monitor instead of stderr"
1660 98f9f48c malc
    },
1661 2700efa3 Juan Quintela
    { /* End of list */ }
1662 85571bc7 bellard
};
1663 85571bc7 bellard
1664 571ec3d6 bellard
static void audio_pp_nb_voices (const char *typ, int nb)
1665 571ec3d6 bellard
{
1666 571ec3d6 bellard
    switch (nb) {
1667 571ec3d6 bellard
    case 0:
1668 571ec3d6 bellard
        printf ("Does not support %s\n", typ);
1669 571ec3d6 bellard
        break;
1670 571ec3d6 bellard
    case 1:
1671 571ec3d6 bellard
        printf ("One %s voice\n", typ);
1672 571ec3d6 bellard
        break;
1673 571ec3d6 bellard
    case INT_MAX:
1674 571ec3d6 bellard
        printf ("Theoretically supports many %s voices\n", typ);
1675 571ec3d6 bellard
        break;
1676 571ec3d6 bellard
    default:
1677 e7d81004 Stefan Weil
        printf ("Theoretically supports up to %d %s voices\n", nb, typ);
1678 571ec3d6 bellard
        break;
1679 571ec3d6 bellard
    }
1680 571ec3d6 bellard
1681 571ec3d6 bellard
}
1682 571ec3d6 bellard
1683 1d14ffa9 bellard
void AUD_help (void)
1684 1d14ffa9 bellard
{
1685 1d14ffa9 bellard
    size_t i;
1686 1d14ffa9 bellard
1687 1d14ffa9 bellard
    audio_process_options ("AUDIO", audio_options);
1688 b1503cda malc
    for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
1689 1d14ffa9 bellard
        struct audio_driver *d = drvtab[i];
1690 1d14ffa9 bellard
        if (d->options) {
1691 1d14ffa9 bellard
            audio_process_options (d->name, d->options);
1692 1d14ffa9 bellard
        }
1693 1d14ffa9 bellard
    }
1694 1d14ffa9 bellard
1695 1d14ffa9 bellard
    printf ("Audio options:\n");
1696 1d14ffa9 bellard
    audio_print_options ("AUDIO", audio_options);
1697 1d14ffa9 bellard
    printf ("\n");
1698 1d14ffa9 bellard
1699 1d14ffa9 bellard
    printf ("Available drivers:\n");
1700 1d14ffa9 bellard
1701 b1503cda malc
    for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
1702 1d14ffa9 bellard
        struct audio_driver *d = drvtab[i];
1703 1d14ffa9 bellard
1704 1d14ffa9 bellard
        printf ("Name: %s\n", d->name);
1705 1d14ffa9 bellard
        printf ("Description: %s\n", d->descr);
1706 1d14ffa9 bellard
1707 571ec3d6 bellard
        audio_pp_nb_voices ("playback", d->max_voices_out);
1708 571ec3d6 bellard
        audio_pp_nb_voices ("capture", d->max_voices_in);
1709 1d14ffa9 bellard
1710 1d14ffa9 bellard
        if (d->options) {
1711 1d14ffa9 bellard
            printf ("Options:\n");
1712 1d14ffa9 bellard
            audio_print_options (d->name, d->options);
1713 1d14ffa9 bellard
        }
1714 1d14ffa9 bellard
        else {
1715 1d14ffa9 bellard
            printf ("No options\n");
1716 1d14ffa9 bellard
        }
1717 1d14ffa9 bellard
        printf ("\n");
1718 1d14ffa9 bellard
    }
1719 1d14ffa9 bellard
1720 1d14ffa9 bellard
    printf (
1721 1d14ffa9 bellard
        "Options are settable through environment variables.\n"
1722 1d14ffa9 bellard
        "Example:\n"
1723 1d14ffa9 bellard
#ifdef _WIN32
1724 1d14ffa9 bellard
        "  set QEMU_AUDIO_DRV=wav\n"
1725 571ec3d6 bellard
        "  set QEMU_WAV_PATH=c:\\tune.wav\n"
1726 1d14ffa9 bellard
#else
1727 1d14ffa9 bellard
        "  export QEMU_AUDIO_DRV=wav\n"
1728 1d14ffa9 bellard
        "  export QEMU_WAV_PATH=$HOME/tune.wav\n"
1729 1d14ffa9 bellard
        "(for csh replace export with setenv in the above)\n"
1730 1d14ffa9 bellard
#endif
1731 1d14ffa9 bellard
        "  qemu ...\n\n"
1732 1d14ffa9 bellard
        );
1733 1d14ffa9 bellard
}
1734 1d14ffa9 bellard
1735 c0fe3827 bellard
static int audio_driver_init (AudioState *s, struct audio_driver *drv)
1736 85571bc7 bellard
{
1737 1d14ffa9 bellard
    if (drv->options) {
1738 1d14ffa9 bellard
        audio_process_options (drv->name, drv->options);
1739 1d14ffa9 bellard
    }
1740 c0fe3827 bellard
    s->drv_opaque = drv->init ();
1741 1d14ffa9 bellard
1742 c0fe3827 bellard
    if (s->drv_opaque) {
1743 1a7dafce malc
        audio_init_nb_voices_out (drv);
1744 1a7dafce malc
        audio_init_nb_voices_in (drv);
1745 c0fe3827 bellard
        s->drv = drv;
1746 1d14ffa9 bellard
        return 0;
1747 85571bc7 bellard
    }
1748 85571bc7 bellard
    else {
1749 1d14ffa9 bellard
        dolog ("Could not init `%s' audio driver\n", drv->name);
1750 1d14ffa9 bellard
        return -1;
1751 85571bc7 bellard
    }
1752 85571bc7 bellard
}
1753 85571bc7 bellard
1754 9781e040 aliguori
static void audio_vm_change_state_handler (void *opaque, int running,
1755 1dfb4dd9 Luiz Capitulino
                                           RunState state)
1756 85571bc7 bellard
{
1757 c0fe3827 bellard
    AudioState *s = opaque;
1758 1d14ffa9 bellard
    HWVoiceOut *hwo = NULL;
1759 1d14ffa9 bellard
    HWVoiceIn *hwi = NULL;
1760 541e0844 bellard
    int op = running ? VOICE_ENABLE : VOICE_DISABLE;
1761 1d14ffa9 bellard
1762 978dd635 malc
    s->vm_running = running;
1763 1a7dafce malc
    while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1764 713a98f8 malc
        hwo->pcm_ops->ctl_out (hwo, op, conf.try_poll_out);
1765 1d14ffa9 bellard
    }
1766 85571bc7 bellard
1767 1a7dafce malc
    while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1768 713a98f8 malc
        hwi->pcm_ops->ctl_in (hwi, op, conf.try_poll_in);
1769 85571bc7 bellard
    }
1770 39deb1e4 malc
    audio_reset_timer (s);
1771 85571bc7 bellard
}
1772 85571bc7 bellard
1773 85571bc7 bellard
static void audio_atexit (void)
1774 85571bc7 bellard
{
1775 c0fe3827 bellard
    AudioState *s = &glob_audio_state;
1776 1d14ffa9 bellard
    HWVoiceOut *hwo = NULL;
1777 1d14ffa9 bellard
    HWVoiceIn *hwi = NULL;
1778 1d14ffa9 bellard
1779 aeb29b64 Jan Kiszka
    while ((hwo = audio_pcm_hw_find_any_out (hwo))) {
1780 ec36b695 bellard
        SWVoiceCap *sc;
1781 8ead62cf bellard
1782 aeb29b64 Jan Kiszka
        if (hwo->enabled) {
1783 aeb29b64 Jan Kiszka
            hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
1784 aeb29b64 Jan Kiszka
        }
1785 1d14ffa9 bellard
        hwo->pcm_ops->fini_out (hwo);
1786 8ead62cf bellard
1787 ec36b695 bellard
        for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1788 ec36b695 bellard
            CaptureVoiceOut *cap = sc->cap;
1789 ec36b695 bellard
            struct capture_callback *cb;
1790 ec36b695 bellard
1791 ec36b695 bellard
            for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
1792 ec36b695 bellard
                cb->ops.destroy (cb->opaque);
1793 ec36b695 bellard
            }
1794 8ead62cf bellard
        }
1795 1d14ffa9 bellard
    }
1796 85571bc7 bellard
1797 aeb29b64 Jan Kiszka
    while ((hwi = audio_pcm_hw_find_any_in (hwi))) {
1798 aeb29b64 Jan Kiszka
        if (hwi->enabled) {
1799 aeb29b64 Jan Kiszka
            hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
1800 aeb29b64 Jan Kiszka
        }
1801 1d14ffa9 bellard
        hwi->pcm_ops->fini_in (hwi);
1802 85571bc7 bellard
    }
1803 c0fe3827 bellard
1804 c0fe3827 bellard
    if (s->drv) {
1805 c0fe3827 bellard
        s->drv->fini (s->drv_opaque);
1806 c0fe3827 bellard
    }
1807 85571bc7 bellard
}
1808 85571bc7 bellard
1809 d959fce9 Juan Quintela
static const VMStateDescription vmstate_audio = {
1810 d959fce9 Juan Quintela
    .name = "audio",
1811 d959fce9 Juan Quintela
    .version_id = 1,
1812 d959fce9 Juan Quintela
    .minimum_version_id = 1,
1813 d959fce9 Juan Quintela
    .minimum_version_id_old = 1,
1814 d959fce9 Juan Quintela
    .fields      = (VMStateField []) {
1815 d959fce9 Juan Quintela
        VMSTATE_END_OF_LIST()
1816 1d14ffa9 bellard
    }
1817 d959fce9 Juan Quintela
};
1818 85571bc7 bellard
1819 1a7dafce malc
static void audio_init (void)
1820 85571bc7 bellard
{
1821 1d14ffa9 bellard
    size_t i;
1822 85571bc7 bellard
    int done = 0;
1823 85571bc7 bellard
    const char *drvname;
1824 713a98f8 malc
    VMChangeStateEntry *e;
1825 c0fe3827 bellard
    AudioState *s = &glob_audio_state;
1826 1d14ffa9 bellard
1827 0d9acba8 Paul Brook
    if (s->drv) {
1828 1a7dafce malc
        return;
1829 0d9acba8 Paul Brook
    }
1830 0d9acba8 Paul Brook
1831 72cf2d4f Blue Swirl
    QLIST_INIT (&s->hw_head_out);
1832 72cf2d4f Blue Swirl
    QLIST_INIT (&s->hw_head_in);
1833 72cf2d4f Blue Swirl
    QLIST_INIT (&s->cap_head);
1834 571ec3d6 bellard
    atexit (audio_atexit);
1835 571ec3d6 bellard
1836 74475455 Paolo Bonzini
    s->ts = qemu_new_timer_ns (vm_clock, audio_timer, s);
1837 571ec3d6 bellard
    if (!s->ts) {
1838 0d9acba8 Paul Brook
        hw_error("Could not create audio timer\n");
1839 571ec3d6 bellard
    }
1840 571ec3d6 bellard
1841 1d14ffa9 bellard
    audio_process_options ("AUDIO", audio_options);
1842 1d14ffa9 bellard
1843 c0fe3827 bellard
    s->nb_hw_voices_out = conf.fixed_out.nb_voices;
1844 c0fe3827 bellard
    s->nb_hw_voices_in = conf.fixed_in.nb_voices;
1845 c0fe3827 bellard
1846 1d14ffa9 bellard
    if (s->nb_hw_voices_out <= 0) {
1847 571ec3d6 bellard
        dolog ("Bogus number of playback voices %d, setting to 1\n",
1848 1d14ffa9 bellard
               s->nb_hw_voices_out);
1849 1d14ffa9 bellard
        s->nb_hw_voices_out = 1;
1850 1d14ffa9 bellard
    }
1851 1d14ffa9 bellard
1852 1d14ffa9 bellard
    if (s->nb_hw_voices_in <= 0) {
1853 571ec3d6 bellard
        dolog ("Bogus number of capture voices %d, setting to 0\n",
1854 1d14ffa9 bellard
               s->nb_hw_voices_in);
1855 571ec3d6 bellard
        s->nb_hw_voices_in = 0;
1856 1d14ffa9 bellard
    }
1857 85571bc7 bellard
1858 1d14ffa9 bellard
    {
1859 1d14ffa9 bellard
        int def;
1860 1d14ffa9 bellard
        drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def);
1861 1d14ffa9 bellard
    }
1862 85571bc7 bellard
1863 85571bc7 bellard
    if (drvname) {
1864 85571bc7 bellard
        int found = 0;
1865 1d14ffa9 bellard
1866 b1503cda malc
        for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
1867 85571bc7 bellard
            if (!strcmp (drvname, drvtab[i]->name)) {
1868 c0fe3827 bellard
                done = !audio_driver_init (s, drvtab[i]);
1869 85571bc7 bellard
                found = 1;
1870 85571bc7 bellard
                break;
1871 85571bc7 bellard
            }
1872 85571bc7 bellard
        }
1873 1d14ffa9 bellard
1874 85571bc7 bellard
        if (!found) {
1875 85571bc7 bellard
            dolog ("Unknown audio driver `%s'\n", drvname);
1876 1d14ffa9 bellard
            dolog ("Run with -audio-help to list available drivers\n");
1877 85571bc7 bellard
        }
1878 85571bc7 bellard
    }
1879 85571bc7 bellard
1880 85571bc7 bellard
    if (!done) {
1881 b1503cda malc
        for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) {
1882 1d14ffa9 bellard
            if (drvtab[i]->can_be_default) {
1883 c0fe3827 bellard
                done = !audio_driver_init (s, drvtab[i]);
1884 1d14ffa9 bellard
            }
1885 85571bc7 bellard
        }
1886 85571bc7 bellard
    }
1887 85571bc7 bellard
1888 85571bc7 bellard
    if (!done) {
1889 c0fe3827 bellard
        done = !audio_driver_init (s, &no_audio_driver);
1890 c0fe3827 bellard
        if (!done) {
1891 0d9acba8 Paul Brook
            hw_error("Could not initialize audio subsystem\n");
1892 1d14ffa9 bellard
        }
1893 1d14ffa9 bellard
        else {
1894 c0fe3827 bellard
            dolog ("warning: Using timer based audio emulation\n");
1895 1d14ffa9 bellard
        }
1896 85571bc7 bellard
    }
1897 1d14ffa9 bellard
1898 0d9acba8 Paul Brook
    if (conf.period.hertz <= 0) {
1899 0d9acba8 Paul Brook
        if (conf.period.hertz < 0) {
1900 0d9acba8 Paul Brook
            dolog ("warning: Timer period is negative - %d "
1901 0d9acba8 Paul Brook
                   "treating as zero\n",
1902 0d9acba8 Paul Brook
                   conf.period.hertz);
1903 571ec3d6 bellard
        }
1904 0d9acba8 Paul Brook
        conf.period.ticks = 1;
1905 0d9acba8 Paul Brook
    } else {
1906 4f4cc0ef malc
        conf.period.ticks =
1907 4f4cc0ef malc
            muldiv64 (1, get_ticks_per_sec (), conf.period.hertz);
1908 1d14ffa9 bellard
    }
1909 0d9acba8 Paul Brook
1910 0d9acba8 Paul Brook
    e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
1911 0d9acba8 Paul Brook
    if (!e) {
1912 0d9acba8 Paul Brook
        dolog ("warning: Could not register change state handler\n"
1913 0d9acba8 Paul Brook
               "(Audio can continue looping even after stopping the VM)\n");
1914 1d14ffa9 bellard
    }
1915 1d14ffa9 bellard
1916 72cf2d4f Blue Swirl
    QLIST_INIT (&s->card_head);
1917 0be71e32 Alex Williamson
    vmstate_register (NULL, 0, &vmstate_audio, s);
1918 85571bc7 bellard
}
1919 8ead62cf bellard
1920 1a7dafce malc
void AUD_register_card (const char *name, QEMUSoundCard *card)
1921 1a7dafce malc
{
1922 1a7dafce malc
    audio_init ();
1923 7267c094 Anthony Liguori
    card->name = g_strdup (name);
1924 1a7dafce malc
    memset (&card->entries, 0, sizeof (card->entries));
1925 72cf2d4f Blue Swirl
    QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries);
1926 1a7dafce malc
}
1927 1a7dafce malc
1928 1a7dafce malc
void AUD_remove_card (QEMUSoundCard *card)
1929 1a7dafce malc
{
1930 72cf2d4f Blue Swirl
    QLIST_REMOVE (card, entries);
1931 7267c094 Anthony Liguori
    g_free (card->name);
1932 1a7dafce malc
}
1933 1a7dafce malc
1934 1a7dafce malc
1935 ec36b695 bellard
CaptureVoiceOut *AUD_add_capture (
1936 1ea879e5 malc
    struct audsettings *as,
1937 8ead62cf bellard
    struct audio_capture_ops *ops,
1938 8ead62cf bellard
    void *cb_opaque
1939 8ead62cf bellard
    )
1940 8ead62cf bellard
{
1941 1a7dafce malc
    AudioState *s = &glob_audio_state;
1942 8ead62cf bellard
    CaptureVoiceOut *cap;
1943 8ead62cf bellard
    struct capture_callback *cb;
1944 8ead62cf bellard
1945 ec36b695 bellard
    if (audio_validate_settings (as)) {
1946 8ead62cf bellard
        dolog ("Invalid settings were passed when trying to add capture\n");
1947 8ead62cf bellard
        audio_print_settings (as);
1948 ec36b695 bellard
        goto err0;
1949 8ead62cf bellard
    }
1950 8ead62cf bellard
1951 8ead62cf bellard
    cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
1952 8ead62cf bellard
    if (!cb) {
1953 8ead62cf bellard
        dolog ("Could not allocate capture callback information, size %zu\n",
1954 8ead62cf bellard
               sizeof (*cb));
1955 8ead62cf bellard
        goto err0;
1956 8ead62cf bellard
    }
1957 8ead62cf bellard
    cb->ops = *ops;
1958 8ead62cf bellard
    cb->opaque = cb_opaque;
1959 8ead62cf bellard
1960 1a7dafce malc
    cap = audio_pcm_capture_find_specific (as);
1961 8ead62cf bellard
    if (cap) {
1962 72cf2d4f Blue Swirl
        QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
1963 ec36b695 bellard
        return cap;
1964 8ead62cf bellard
    }
1965 8ead62cf bellard
    else {
1966 8ead62cf bellard
        HWVoiceOut *hw;
1967 8ead62cf bellard
        CaptureVoiceOut *cap;
1968 8ead62cf bellard
1969 8ead62cf bellard
        cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
1970 8ead62cf bellard
        if (!cap) {
1971 8ead62cf bellard
            dolog ("Could not allocate capture voice, size %zu\n",
1972 8ead62cf bellard
                   sizeof (*cap));
1973 8ead62cf bellard
            goto err1;
1974 8ead62cf bellard
        }
1975 8ead62cf bellard
1976 8ead62cf bellard
        hw = &cap->hw;
1977 72cf2d4f Blue Swirl
        QLIST_INIT (&hw->sw_head);
1978 72cf2d4f Blue Swirl
        QLIST_INIT (&cap->cb_head);
1979 8ead62cf bellard
1980 8ead62cf bellard
        /* XXX find a more elegant way */
1981 8ead62cf bellard
        hw->samples = 4096 * 4;
1982 8ead62cf bellard
        hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
1983 1ea879e5 malc
                                    sizeof (struct st_sample));
1984 8ead62cf bellard
        if (!hw->mix_buf) {
1985 8ead62cf bellard
            dolog ("Could not allocate capture mix buffer (%d samples)\n",
1986 8ead62cf bellard
                   hw->samples);
1987 8ead62cf bellard
            goto err2;
1988 8ead62cf bellard
        }
1989 8ead62cf bellard
1990 d929eba5 bellard
        audio_pcm_init_info (&hw->info, as);
1991 8ead62cf bellard
1992 8ead62cf bellard
        cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
1993 8ead62cf bellard
        if (!cap->buf) {
1994 8ead62cf bellard
            dolog ("Could not allocate capture buffer "
1995 8ead62cf bellard
                   "(%d samples, each %d bytes)\n",
1996 8ead62cf bellard
                   hw->samples, 1 << hw->info.shift);
1997 8ead62cf bellard
            goto err3;
1998 8ead62cf bellard
        }
1999 8ead62cf bellard
2000 8ead62cf bellard
        hw->clip = mixeng_clip
2001 8ead62cf bellard
            [hw->info.nchannels == 2]
2002 8ead62cf bellard
            [hw->info.sign]
2003 d929eba5 bellard
            [hw->info.swap_endianness]
2004 f941aa25 ths
            [audio_bits_to_index (hw->info.bits)];
2005 8ead62cf bellard
2006 72cf2d4f Blue Swirl
        QLIST_INSERT_HEAD (&s->cap_head, cap, entries);
2007 72cf2d4f Blue Swirl
        QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
2008 8ead62cf bellard
2009 8ead62cf bellard
        hw = NULL;
2010 1a7dafce malc
        while ((hw = audio_pcm_hw_find_any_out (hw))) {
2011 1a7dafce malc
            audio_attach_capture (hw);
2012 8ead62cf bellard
        }
2013 ec36b695 bellard
        return cap;
2014 8ead62cf bellard
2015 8ead62cf bellard
    err3:
2016 7267c094 Anthony Liguori
        g_free (cap->hw.mix_buf);
2017 8ead62cf bellard
    err2:
2018 7267c094 Anthony Liguori
        g_free (cap);
2019 8ead62cf bellard
    err1:
2020 7267c094 Anthony Liguori
        g_free (cb);
2021 8ead62cf bellard
    err0:
2022 ec36b695 bellard
        return NULL;
2023 ec36b695 bellard
    }
2024 ec36b695 bellard
}
2025 ec36b695 bellard
2026 ec36b695 bellard
void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
2027 ec36b695 bellard
{
2028 ec36b695 bellard
    struct capture_callback *cb;
2029 ec36b695 bellard
2030 ec36b695 bellard
    for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
2031 ec36b695 bellard
        if (cb->opaque == cb_opaque) {
2032 ec36b695 bellard
            cb->ops.destroy (cb_opaque);
2033 72cf2d4f Blue Swirl
            QLIST_REMOVE (cb, entries);
2034 7267c094 Anthony Liguori
            g_free (cb);
2035 ec36b695 bellard
2036 ec36b695 bellard
            if (!cap->cb_head.lh_first) {
2037 ec36b695 bellard
                SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
2038 a3c25997 bellard
2039 ec36b695 bellard
                while (sw) {
2040 a3c25997 bellard
                    SWVoiceCap *sc = (SWVoiceCap *) sw;
2041 ec36b695 bellard
#ifdef DEBUG_CAPTURE
2042 ec36b695 bellard
                    dolog ("freeing %s\n", sw->name);
2043 ec36b695 bellard
#endif
2044 a3c25997 bellard
2045 ec36b695 bellard
                    sw1 = sw->entries.le_next;
2046 ec36b695 bellard
                    if (sw->rate) {
2047 ec36b695 bellard
                        st_rate_stop (sw->rate);
2048 ec36b695 bellard
                        sw->rate = NULL;
2049 ec36b695 bellard
                    }
2050 72cf2d4f Blue Swirl
                    QLIST_REMOVE (sw, entries);
2051 72cf2d4f Blue Swirl
                    QLIST_REMOVE (sc, entries);
2052 7267c094 Anthony Liguori
                    g_free (sc);
2053 ec36b695 bellard
                    sw = sw1;
2054 ec36b695 bellard
                }
2055 72cf2d4f Blue Swirl
                QLIST_REMOVE (cap, entries);
2056 7267c094 Anthony Liguori
                g_free (cap);
2057 ec36b695 bellard
            }
2058 ec36b695 bellard
            return;
2059 ec36b695 bellard
        }
2060 8ead62cf bellard
    }
2061 8ead62cf bellard
}
2062 683efdcb balrog
2063 683efdcb balrog
void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
2064 683efdcb balrog
{
2065 683efdcb balrog
    if (sw) {
2066 6c95ab94 Marc-André Lureau
        HWVoiceOut *hw = sw->hw;
2067 6c95ab94 Marc-André Lureau
2068 683efdcb balrog
        sw->vol.mute = mute;
2069 683efdcb balrog
        sw->vol.l = nominal_volume.l * lvol / 255;
2070 683efdcb balrog
        sw->vol.r = nominal_volume.r * rvol / 255;
2071 6c95ab94 Marc-André Lureau
2072 6c95ab94 Marc-André Lureau
        if (hw->pcm_ops->ctl_out) {
2073 6c95ab94 Marc-André Lureau
            hw->pcm_ops->ctl_out (hw, VOICE_VOLUME, sw);
2074 6c95ab94 Marc-André Lureau
        }
2075 683efdcb balrog
    }
2076 683efdcb balrog
}
2077 683efdcb balrog
2078 683efdcb balrog
void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol)
2079 683efdcb balrog
{
2080 683efdcb balrog
    if (sw) {
2081 6c95ab94 Marc-André Lureau
        HWVoiceIn *hw = sw->hw;
2082 6c95ab94 Marc-André Lureau
2083 683efdcb balrog
        sw->vol.mute = mute;
2084 683efdcb balrog
        sw->vol.l = nominal_volume.l * lvol / 255;
2085 683efdcb balrog
        sw->vol.r = nominal_volume.r * rvol / 255;
2086 6c95ab94 Marc-André Lureau
2087 6c95ab94 Marc-André Lureau
        if (hw->pcm_ops->ctl_in) {
2088 6c95ab94 Marc-André Lureau
            hw->pcm_ops->ctl_in (hw, VOICE_VOLUME, sw);
2089 6c95ab94 Marc-André Lureau
        }
2090 683efdcb balrog
    }
2091 683efdcb balrog
}