All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

noaudio.c 4.56 KB
Newer Older
bellard's avatar
bellard committed
1
/*
2 3 4 5
 * QEMU Timer based audio emulation
 *
 * Copyright (c) 2004-2005 Vassili Karpov (malc)
 *
bellard's avatar
bellard committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
pbrook's avatar
pbrook committed
24 25 26
#include "qemu-common.h"
#include "audio.h"
#include "qemu-timer.h"
bellard's avatar
bellard committed
27

28 29
#define AUDIO_CAP "noaudio"
#include "audio_int.h"
bellard's avatar
bellard committed
30

31 32
typedef struct NoVoiceOut {
    HWVoiceOut hw;
bellard's avatar
bellard committed
33
    int64_t old_ticks;
34
} NoVoiceOut;
bellard's avatar
bellard committed
35

36 37 38 39
typedef struct NoVoiceIn {
    HWVoiceIn hw;
    int64_t old_ticks;
} NoVoiceIn;
bellard's avatar
bellard committed
40

malc's avatar
malc committed
41
static int no_run_out (HWVoiceOut *hw, int live)
bellard's avatar
bellard committed
42
{
43
    NoVoiceOut *no = (NoVoiceOut *) hw;
malc's avatar
malc committed
44
    int decr, samples;
45 46 47
    int64_t now;
    int64_t ticks;
    int64_t bytes;
bellard's avatar
bellard committed
48

49
    now = qemu_get_clock_ns (vm_clock);
50
    ticks = now - no->old_ticks;
51
    bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
52 53 54
    bytes = audio_MIN (bytes, INT_MAX);
    samples = bytes >> hw->info.shift;

bellard's avatar
bellard committed
55 56
    no->old_ticks = now;
    decr = audio_MIN (live, samples);
57 58 59
    hw->rpos = (hw->rpos + decr) % hw->samples;
    return decr;
}
bellard's avatar
bellard committed
60

61 62 63 64
static int no_write (SWVoiceOut *sw, void *buf, int len)
{
    return audio_pcm_sw_write (sw, buf, len);
}
bellard's avatar
bellard committed
65

malc's avatar
malc committed
66
static int no_init_out (HWVoiceOut *hw, struct audsettings *as)
67
{
bellard's avatar
bellard committed
68
    audio_pcm_init_info (&hw->info, as);
bellard's avatar
bellard committed
69
    hw->samples = 1024;
70 71
    return 0;
}
bellard's avatar
bellard committed
72

73 74 75
static void no_fini_out (HWVoiceOut *hw)
{
    (void) hw;
bellard's avatar
bellard committed
76 77
}

78
static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)
bellard's avatar
bellard committed
79
{
80 81 82
    (void) hw;
    (void) cmd;
    return 0;
bellard's avatar
bellard committed
83 84
}

malc's avatar
malc committed
85
static int no_init_in (HWVoiceIn *hw, struct audsettings *as)
bellard's avatar
bellard committed
86
{
bellard's avatar
bellard committed
87
    audio_pcm_init_info (&hw->info, as);
bellard's avatar
bellard committed
88
    hw->samples = 1024;
bellard's avatar
bellard committed
89 90 91
    return 0;
}

92
static void no_fini_in (HWVoiceIn *hw)
bellard's avatar
bellard committed
93 94 95 96
{
    (void) hw;
}

97 98 99 100 101
static int no_run_in (HWVoiceIn *hw)
{
    NoVoiceIn *no = (NoVoiceIn *) hw;
    int live = audio_pcm_hw_get_live_in (hw);
    int dead = hw->samples - live;
bellard's avatar
bellard committed
102
    int samples = 0;
103

104
    if (dead) {
105
        int64_t now = qemu_get_clock_ns (vm_clock);
106
        int64_t ticks = now - no->old_ticks;
107 108
        int64_t bytes =
            muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
109

110 111 112 113 114
        no->old_ticks = now;
        bytes = audio_MIN (bytes, INT_MAX);
        samples = bytes >> hw->info.shift;
        samples = audio_MIN (samples, dead);
    }
115 116 117 118 119
    return samples;
}

static int no_read (SWVoiceIn *sw, void *buf, int size)
{
120 121
    /* use custom code here instead of audio_pcm_sw_read() to avoid
     * useless resampling/mixing */
122 123 124
    int samples = size >> sw->info.shift;
    int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
    int to_clear = audio_MIN (samples, total);
125
    sw->total_hw_samples_acquired += total;
126
    audio_pcm_info_clear_buf (&sw->info, buf, to_clear);
127
    return to_clear << sw->info.shift;
128 129 130
}

static int no_ctl_in (HWVoiceIn *hw, int cmd, ...)
bellard's avatar
bellard committed
131 132 133 134 135 136 137 138 139 140 141 142 143
{
    (void) hw;
    (void) cmd;
    return 0;
}

static void *no_audio_init (void)
{
    return &no_audio_init;
}

static void no_audio_fini (void *opaque)
{
144
    (void) opaque;
bellard's avatar
bellard committed
145 146
}

147
static struct audio_pcm_ops no_pcm_ops = {
148 149 150 151 152 153 154 155 156 157 158
    .init_out = no_init_out,
    .fini_out = no_fini_out,
    .run_out  = no_run_out,
    .write    = no_write,
    .ctl_out  = no_ctl_out,

    .init_in  = no_init_in,
    .fini_in  = no_fini_in,
    .run_in   = no_run_in,
    .read     = no_read,
    .ctl_in   = no_ctl_in
bellard's avatar
bellard committed
159 160
};

161
struct audio_driver no_audio_driver = {
162 163 164 165 166 167 168 169 170 171 172
    .name           = "none",
    .descr          = "Timer based audio emulation",
    .options        = NULL,
    .init           = no_audio_init,
    .fini           = no_audio_fini,
    .pcm_ops        = &no_pcm_ops,
    .can_be_default = 1,
    .max_voices_out = INT_MAX,
    .max_voices_in  = INT_MAX,
    .voice_size_out = sizeof (NoVoiceOut),
    .voice_size_in  = sizeof (NoVoiceIn)
bellard's avatar
bellard committed
173
};