All of lore.kernel.org
 help / color / mirror / Atom feed
From: malc <av1474@comtv.ru>
To: Gerd Hoffmann <kraxel@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [RfC PATCH 11/11] spice: add audio
Date: Thu, 15 Apr 2010 00:51:52 +0400 (MSD)	[thread overview]
Message-ID: <alpine.LNX.2.00.1004150046460.1599@linmac> (raw)
In-Reply-To: <1271238922-10008-12-git-send-email-kraxel@redhat.com>

On Wed, 14 Apr 2010, Gerd Hoffmann wrote:

The code does not follow neither audio(which is passable should it be 
internally consistent) nor general QEMU code style (braces missing)

> ---
>  Makefile.objs      |    1 +
>  audio/audio.c      |    3 +
>  audio/audio_int.h  |    1 +
>  audio/spiceaudio.c |  315 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 320 insertions(+), 0 deletions(-)
>  create mode 100644 audio/spiceaudio.c
> 
> diff --git a/Makefile.objs b/Makefile.objs
> index ab1af88..b11db4c 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -84,6 +84,7 @@ common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
>  audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
>  audio-obj-$(CONFIG_SDL) += sdlaudio.o
>  audio-obj-$(CONFIG_OSS) += ossaudio.o
> +audio-obj-$(CONFIG_SPICE) += spiceaudio.o
>  audio-obj-$(CONFIG_COREAUDIO) += coreaudio.o
>  audio-obj-$(CONFIG_ALSA) += alsaaudio.o
>  audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
> diff --git a/audio/audio.c b/audio/audio.c
> index dbf0b96..67fc1d3 100644
> --- a/audio/audio.c
> +++ b/audio/audio.c
> @@ -45,6 +45,9 @@
>  */
>  static struct audio_driver *drvtab[] = {
>      CONFIG_AUDIO_DRIVERS
> +#ifdef CONFIG_SPICE
> +    &spice_audio_driver,
> +#endif
>      &no_audio_driver,
>      &wav_audio_driver
>  };
> diff --git a/audio/audio_int.h b/audio/audio_int.h
> index 06e313f..d1f6c2d 100644
> --- a/audio/audio_int.h
> +++ b/audio/audio_int.h
> @@ -209,6 +209,7 @@ extern struct audio_driver coreaudio_audio_driver;
>  extern struct audio_driver dsound_audio_driver;
>  extern struct audio_driver esd_audio_driver;
>  extern struct audio_driver pa_audio_driver;
> +extern struct audio_driver spice_audio_driver;
>  extern struct audio_driver winwave_audio_driver;
>  extern struct mixeng_volume nominal_volume;
>  
> diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
> new file mode 100644
> index 0000000..0e18f2f
> --- /dev/null
> +++ b/audio/spiceaudio.c
> @@ -0,0 +1,315 @@
> +#include "hw/hw.h"
> +#include "qemu-timer.h"
> +#include "qemu-spice.h"
> +
> +#define AUDIO_CAP "spice"
> +#include "audio.h"
> +#include "audio_int.h"
> +
> +#define LINE_IN_SAMPLES 1024
> +#define LINE_OUT_SAMPLES 1024
> +
> +typedef struct SpiceVoiceOut {
> +    HWVoiceOut            hw;
> +    SpicePlaybackInstance sin;
> +    uint32_t              *frame;
> +    uint32_t              *fpos;
> +    uint32_t              fsize;
> +    uint64_t              prev_ticks;
> +    int                   active;
> +} SpiceVoiceOut;
> +
> +typedef struct SpiceVoiceIn {
> +    HWVoiceIn             hw;
> +    SpiceRecordInstance   sin;
> +    uint64_t              prev_ticks;
> +    int                   active;
> +    uint32_t              samples[LINE_IN_SAMPLES];
> +} SpiceVoiceIn;
> +
> +static SpicePlaybackInterface playback_sif = {
> +    .base.type          = SPICE_INTERFACE_PLAYBACK,
> +    .base.description   = "playback",
> +    .base.major_version = SPICE_INTERFACE_PLAYBACK_MAJOR,
> +    .base.minor_version = SPICE_INTERFACE_PLAYBACK_MINOR,
> +};
> +
> +static SpiceRecordInterface record_sif = {
> +    .base.type          = SPICE_INTERFACE_RECORD,
> +    .base.description   = "record",
> +    .base.major_version = SPICE_INTERFACE_RECORD_MAJOR,
> +    .base.minor_version = SPICE_INTERFACE_RECORD_MINOR,
> +};
> +
> +static void *spice_audio_init(void)
> +{
> +    if (!using_spice)
> +        return NULL;
> +    return qemu_malloc(42);

Eh? The HGttG references should at least be given an explanation in
the comments.

> +}
> +
> +static void spice_audio_fini(void *opaque)
> +{
> +    qemu_free(opaque);
> +}
> +
> +static uint64_t get_monotonic_time(void)
> +{
> +    struct timespec time_space;
> +    clock_gettime(CLOCK_MONOTONIC, &time_space);

a. The presence of monotonic clock is not guranteed
b. The call can fail yet the result value is not checked
c. I have a really hard time following what rt clock (regardless
   of monotonicity is doing here at all)

> +    return (uint64_t)time_space.tv_sec * 1000 * 1000 * 1000 + time_space.tv_nsec;
> +}
> +
> +/* playback */
> +
> +static int line_out_init(HWVoiceOut *hw, struct audsettings *as)
> +{
> +    SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
> +    struct audsettings settings;
> +
> +    settings.freq       = SPICE_INTERFACE_PLAYBACK_FREQ;
> +    settings.nchannels  = SPICE_INTERFACE_PLAYBACK_CHAN;
> +    settings.fmt        = AUD_FMT_S16;
> +    settings.endianness = AUDIO_HOST_ENDIANNESS;
> +
> +    audio_pcm_init_info(&hw->info, &settings);
> +    hw->samples = LINE_OUT_SAMPLES;
> +    out->active = 0;
> +
> +    out->sin.base.sif = &playback_sif.base;
> +    spice_server_add_interface(spice_server, &out->sin.base);
> +    return 0;
> +}
> +
> +static void line_out_fini(HWVoiceOut *hw)
> +{
> +    SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
> +
> +    spice_server_remove_interface(&out->sin.base);
> +}
> +
> +static int line_out_run(HWVoiceOut *hw, int live)
> +{
> +    SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
> +    int rpos, decr;
> +    int samples;
> +    uint64_t now;
> +    uint64_t ticks;
> +    uint64_t bytes;
> +
> +    if (!live) {
> +        return 0;
> +    }
> +
> +    now = get_monotonic_time();
> +    ticks = now - out->prev_ticks;
> +    bytes = (ticks * hw->info.bytes_per_second) / (1000 * 1000 * 1000);
> +    out->prev_ticks = now;
> +
> +    decr = (bytes > INT_MAX)
> +        ? INT_MAX >> hw->info.shift
> +        : (bytes + (1 << (hw->info.shift - 1))) >> hw->info.shift;
> +    decr = audio_MIN(live, decr);
> +
> +    samples = decr;
> +    rpos = hw->rpos;
> +    while (samples) {
> +        int left_till_end_samples = hw->samples - rpos;
> +        int len = audio_MIN(samples, left_till_end_samples);
> +
> +        if (!out->frame) {
> +            spice_server_playback_get_buffer(&out->sin, &out->frame, &out->fsize);
> +            out->fpos = out->frame;
> +        }
> +        if (out->frame) {
> +            len = audio_MIN(len, out->fsize);
> +            hw->clip(out->fpos, hw->mix_buf + rpos, len);
> +            out->fsize -= len;
> +            out->fpos  += len;
> +            if (out->fsize == 0) {
> +                spice_server_playback_put_samples(&out->sin, out->frame);
> +                out->frame = out->fpos = NULL;
> +            }
> +        }
> +        rpos = (rpos + len) % hw->samples;
> +        samples -= len;
> +    }
> +    hw->rpos = rpos;
> +    return decr;
> +}
> +
> +static int line_out_write(SWVoiceOut *sw, void *buf, int len)
> +{
> +    return audio_pcm_sw_write(sw, buf, len);
> +}
> +
> +static int line_out_ctl(HWVoiceOut *hw, int cmd, ...)
> +{
> +    SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
> +
> +    switch (cmd) {
> +    case VOICE_ENABLE:
> +        if (out->active) {
> +            break;
> +        }
> +        out->active = 1;
> +        out->prev_ticks = get_monotonic_time();
> +        spice_server_playback_start(&out->sin);
> +        break;
> +    case VOICE_DISABLE:
> +        if (!out->active) {
> +            break;
> +        }
> +        out->active = 0;
> +        if (out->frame) {
> +            memset(out->fpos, 0, out->fsize << 2);
> +            spice_server_playback_put_samples(&out->sin, out->frame);
> +            out->frame = out->fpos = NULL;
> +            spice_server_playback_stop(&out->sin);
> +        }
> +        break;
> +    }
> +    return 0;
> +}
> +
> +/* record */
> +
> +static int line_in_init(HWVoiceIn *hw, struct audsettings *as)
> +{
> +    SpiceVoiceIn *in = container_of(hw, SpiceVoiceIn, hw);
> +    struct audsettings settings;
> +
> +    settings.freq       = SPICE_INTERFACE_RECORD_FREQ;
> +    settings.nchannels  = SPICE_INTERFACE_RECORD_CHAN;
> +    settings.fmt        = AUD_FMT_S16;
> +    settings.endianness = AUDIO_HOST_ENDIANNESS;
> +
> +    audio_pcm_init_info(&hw->info, &settings);
> +    hw->samples = LINE_IN_SAMPLES;
> +    in->active = 0;
> +
> +    in->sin.base.sif = &record_sif.base;
> +    spice_server_add_interface(spice_server, &in->sin.base);
> +    return 0;
> +}
> +
> +static void line_in_fini(HWVoiceIn *hw)
> +{
> +    SpiceVoiceIn *in = container_of(hw, SpiceVoiceIn, hw);
> +
> +    spice_server_remove_interface(&in->sin.base);
> +}
> +
> +static int line_in_run(HWVoiceIn *hw)
> +{
> +    SpiceVoiceIn *in = container_of(hw, SpiceVoiceIn, hw);
> +    int num_samples;
> +    int ready;
> +    int len[2];
> +    uint64_t now;
> +    uint64_t ticks;
> +    uint64_t delta_samp;
> +    uint32_t *samples;
> +
> +    if (!(num_samples = hw->samples - audio_pcm_hw_get_live_in(hw))) {
> +        return 0;
> +    }
> +
> +    now = get_monotonic_time();
> +    ticks = now - in->prev_ticks;
> +    in->prev_ticks = now;
> +    delta_samp = (ticks * hw->info.bytes_per_second) / (1000 * 1000 * 1000);
> +    delta_samp = (delta_samp + (1 << (hw->info.shift - 1))) >> hw->info.shift;
> +
> +    num_samples = audio_MIN(num_samples, delta_samp);
> +
> +    ready = spice_server_record_get_samples(&in->sin, in->samples, num_samples);
> +    samples = in->samples;
> +    if (ready == 0) {
> +        static uint32_t silence[LINE_IN_SAMPLES];
> +        samples = silence;
> +        ready = LINE_IN_SAMPLES;
> +    }
> +
> +    num_samples = audio_MIN(ready, num_samples);
> +
> +    if (hw->wpos + num_samples > hw->samples) {
> +        len[0] = hw->samples - hw->wpos;
> +        len[1] = num_samples - len[0];
> +    } else {
> +        len[0] = num_samples;
> +        len[1] = 0;
> +    }
> +
> +    hw->conv(hw->conv_buf + hw->wpos, samples, len[0], &nominal_volume);
> +
> +    if (len[1]) {
> +        hw->conv(hw->conv_buf, samples + len[0], len[1],
> +                 &nominal_volume);
> +    }
> +
> +    hw->wpos = (hw->wpos + num_samples) % hw->samples;
> +
> +    return num_samples;
> +}
> +
> +static int line_in_read(SWVoiceIn *sw, void *buf, int size)
> +{
> +    return audio_pcm_sw_read(sw, buf, size);
> +}
> +
> +static int line_in_ctl(HWVoiceIn *hw, int cmd, ...)
> +{
> +    SpiceVoiceIn *in = container_of(hw, SpiceVoiceIn, hw);
> +
> +    switch (cmd) {
> +    case VOICE_ENABLE:
> +        if (in->active) {
> +            break;
> +        }
> +        in->active = 1;
> +        in->prev_ticks = get_monotonic_time();
> +        spice_server_record_start(&in->sin);
> +        break;
> +    case VOICE_DISABLE:
> +        if (!in->active) {
> +            break;
> +        }
> +        in->active = 0;
> +        spice_server_record_stop(&in->sin);
> +        break;
> +    }
> +    return 0;
> +}
> +
> +static struct audio_option audio_options[] = {
> +    { /* end of list */ },
> +};
> +
> +static struct audio_pcm_ops audio_callbacks = {
> +    .init_out = line_out_init,
> +    .fini_out = line_out_fini,
> +    .run_out  = line_out_run,
> +    .write    = line_out_write,
> +    .ctl_out  = line_out_ctl,
> +
> +    .init_in  = line_in_init,
> +    .fini_in  = line_in_fini,
> +    .run_in   = line_in_run,
> +    .read     = line_in_read,
> +    .ctl_in   = line_in_ctl,
> +};
> +
> +struct audio_driver spice_audio_driver = {
> +    .name           = "spice",
> +    .descr          = "spice audio driver",
> +    .options        = audio_options,
> +    .init           = spice_audio_init,
> +    .fini           = spice_audio_fini,
> +    .pcm_ops        = &audio_callbacks,
> +    .can_be_default = 1,
> +    .max_voices_out = 1,
> +    .max_voices_in  = 1,
> +    .voice_size_out = sizeof(SpiceVoiceOut),
> +    .voice_size_in  = sizeof(SpiceVoiceIn),
> +};
> 

-- 
mailto:av1474@comtv.ru

  reply	other threads:[~2010-04-14 20:52 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-14  9:55 [Qemu-devel] [RfC PATCH 00/11] Add spice support to qemu Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 01/11] vgabios update to 0.6c, add bios for qxl/unstable Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 02/11] add spice into the configure file Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 03/11] spice: core bits Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 04/11] spice: add keyboard Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 05/11] spice: add mouse Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 06/11] spice: simple display Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 07/11] spice: tls support Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 08/11] spice: add qxl device Gerd Hoffmann
2010-04-14 16:52   ` Blue Swirl
2010-04-14 23:08     ` [Qemu-devel] " Paolo Bonzini
2010-04-15 16:47       ` Blue Swirl
2010-04-15 19:27         ` Richard Henderson
2010-04-16  8:02       ` Gerd Hoffmann
2010-04-16 10:18         ` Paolo Bonzini
2010-04-16 10:34           ` Gerd Hoffmann
2010-04-16 12:53           ` Richard Henderson
2010-04-14 22:21   ` [Qemu-devel] " Alexander Graf
2010-04-16  8:08     ` Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 09/11] qxl: local rendering for sdl/vnc Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 10/11] spice: add tablet support Gerd Hoffmann
2010-04-14  9:55 ` [Qemu-devel] [RfC PATCH 11/11] spice: add audio Gerd Hoffmann
2010-04-14 20:51   ` malc [this message]
2010-04-14 23:14     ` [Qemu-devel] " Paolo Bonzini
2010-04-15  0:13       ` malc
2010-04-15  0:26         ` Paolo Bonzini
2010-04-15  0:29           ` malc
2010-04-16  8:40     ` [Qemu-devel] " Gerd Hoffmann
2010-04-16 11:13       ` Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.LNX.2.00.1004150046460.1599@linmac \
    --to=av1474@comtv.ru \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.