Commit bae31bfa authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kraxel/tags/audio-20200619-pull-request' into staging



audio: bugfixes for jack backend and gus emulation.

# gpg: Signature made Fri 19 Jun 2020 14:17:22 BST
# gpg:                using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/audio-20200619-pull-request:
  hw/audio/gus: Fix registers 32-bit access
  audio/jack: simplify the re-init code path
  audio/jack: honour the enable state of the audio device
  audio/jack: do not remove ports when finishing
  audio/jack: remove invalid set of input support bool
  audio/jack: remove unused stopped state
  audio/jack: fix invalid minimum buffer size check

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 06c4cc36 58680345
Loading
Loading
Loading
Loading
+38 −35
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ struct QJack;

typedef enum QJackState {
    QJACK_STATE_DISCONNECTED,
    QJACK_STATE_STOPPED,
    QJACK_STATE_RUNNING,
    QJACK_STATE_SHUTDOWN
}
@@ -57,7 +56,7 @@ typedef struct QJackClient {
    AudiodevJackPerDirectionOptions *opt;

    bool out;
    bool finished;
    bool enabled;
    bool connect_ports;
    int  packets;

@@ -272,10 +271,18 @@ static int qjack_process(jack_nframes_t nframes, void *arg)
    }

    if (c->out) {
        if (likely(c->enabled)) {
            qjack_buffer_read_l(&c->fifo, buffers, nframes);
        } else {
            for(int i = 0; i < c->nchannels; ++i) {
                memset(buffers[i], 0, nframes * sizeof(float));
            }
        }
    } else {
        if (likely(c->enabled)) {
            qjack_buffer_write_l(&c->fifo, buffers, nframes);
        }
    }

    return 0;
}
@@ -315,8 +322,8 @@ static void qjack_client_recover(QJackClient *c)
    if (c->state == QJACK_STATE_DISCONNECTED &&
        c->packets % 100 == 0) {

        /* if not finished then attempt to recover */
        if (!c->finished) {
        /* if enabled then attempt to recover */
        if (c->enabled) {
            dolog("attempting to reconnect to server\n");
            qjack_client_init(c);
        }
@@ -388,7 +395,10 @@ static int qjack_client_init(QJackClient *c)
    char client_name[jack_client_name_size()];
    jack_options_t options = JackNullOption;

    c->finished      = false;
    if (c->state == QJACK_STATE_RUNNING) {
        return 0;
    }

    c->connect_ports = true;

    snprintf(client_name, sizeof(client_name), "%s-%s",
@@ -434,17 +444,6 @@ static int qjack_client_init(QJackClient *c)
    jack_set_xrun_callback(c->client, qjack_xrun, c);
    jack_on_shutdown(c->client, qjack_shutdown, c);

    /*
     * ensure the buffersize is no smaller then 512 samples, some (all?) qemu
     * virtual devices do not work correctly otherwise
     */
    if (c->buffersize < 512) {
        c->buffersize = 512;
    }

    /* create a 2 period buffer */
    qjack_buffer_create(&c->fifo, c->nchannels, c->buffersize * 2);

    /* allocate and register the ports */
    c->port = g_malloc(sizeof(jack_port_t *) * c->nchannels);
    for (int i = 0; i < c->nchannels; ++i) {
@@ -468,6 +467,17 @@ static int qjack_client_init(QJackClient *c)
    jack_activate(c->client);
    c->buffersize = jack_get_buffer_size(c->client);

    /*
     * ensure the buffersize is no smaller then 512 samples, some (all?) qemu
     * virtual devices do not work correctly otherwise
     */
    if (c->buffersize < 512) {
        c->buffersize = 512;
    }

    /* create a 2 period buffer */
    qjack_buffer_create(&c->fifo, c->nchannels, c->buffersize * 2);

    qjack_client_connect_ports(c);
    c->state = QJACK_STATE_RUNNING;
    return 0;
@@ -479,13 +489,13 @@ static int qjack_init_out(HWVoiceOut *hw, struct audsettings *as,
    QJackOut *jo  = (QJackOut *)hw;
    Audiodev *dev = (Audiodev *)drv_opaque;

    if (jo->c.state != QJACK_STATE_DISCONNECTED) {
        return 0;
    }
    qjack_client_fini(&jo->c);

    jo->c.out       = true;
    jo->c.enabled   = false;
    jo->c.nchannels = as->nchannels;
    jo->c.opt       = dev->u.jack.out;

    int ret = qjack_client_init(&jo->c);
    if (ret != 0) {
        return ret;
@@ -515,13 +525,13 @@ static int qjack_init_in(HWVoiceIn *hw, struct audsettings *as,
    QJackIn  *ji  = (QJackIn *)hw;
    Audiodev *dev = (Audiodev *)drv_opaque;

    if (ji->c.state != QJACK_STATE_DISCONNECTED) {
        return 0;
    }
    qjack_client_fini(&ji->c);

    ji->c.out       = false;
    ji->c.enabled   = false;
    ji->c.nchannels = as->nchannels;
    ji->c.opt       = dev->u.jack.in;

    int ret = qjack_client_init(&ji->c);
    if (ret != 0) {
        return ret;
@@ -549,12 +559,6 @@ static void qjack_client_fini(QJackClient *c)
{
    switch (c->state) {
    case QJACK_STATE_RUNNING:
        /* fallthrough */

    case QJACK_STATE_STOPPED:
        for (int i = 0; i < c->nchannels; ++i) {
            jack_port_unregister(c->client, c->port[i]);
        }
        jack_deactivate(c->client);
        /* fallthrough */

@@ -575,23 +579,25 @@ static void qjack_client_fini(QJackClient *c)
static void qjack_fini_out(HWVoiceOut *hw)
{
    QJackOut *jo = (QJackOut *)hw;
    jo->c.finished = true;
    qjack_client_fini(&jo->c);
}

static void qjack_fini_in(HWVoiceIn *hw)
{
    QJackIn *ji = (QJackIn *)hw;
    ji->c.finished = true;
    qjack_client_fini(&ji->c);
}

static void qjack_enable_out(HWVoiceOut *hw, bool enable)
{
    QJackOut *jo = (QJackOut *)hw;
    jo->c.enabled = enable;
}

static void qjack_enable_in(HWVoiceIn *hw, bool enable)
{
    QJackIn *ji = (QJackIn *)hw;
    ji->c.enabled = enable;
}

static int qjack_thread_creator(jack_native_thread_t *thread,
@@ -611,9 +617,6 @@ static int qjack_thread_creator(jack_native_thread_t *thread,
static void *qjack_init(Audiodev *dev)
{
    assert(dev->driver == AUDIODEV_DRIVER_JACK);

    dev->u.jack.has_in = false;

    return dev;
}

+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@

#define GUSregb(position) (*            (gusptr+(position)))
#define GUSregw(position) (*(uint16_t *) (gusptr+(position)))
#define GUSregd(position) (*(uint16_t *)(gusptr+(position)))
#define GUSregd(position) (*(uint32_t *)(gusptr + (position)))

/* size given in bytes */
unsigned int gus_read(GUSEmuState * state, int port, int size)
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@

#define GUSregb(position)  (*            (gusptr+(position)))
#define GUSregw(position)  (*(uint16_t *) (gusptr+(position)))
#define GUSregd(position)  (*(uint16_t *)(gusptr+(position)))
#define GUSregd(position)  (*(uint32_t *)(gusptr + (position)))

#define GUSvoice(position) (*(uint16_t *)(voiceptr+(position)))