diff --git a/audio/jackaudio.c b/audio/jackaudio.c index 722ddb1dfe43335eb9897e57c9166412257fde19..72ed7c492998315e329a9e30f98125c7e81f3868 100644 --- a/audio/jackaudio.c +++ b/audio/jackaudio.c @@ -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,9 +271,17 @@ static int qjack_process(jack_nframes_t nframes, void *arg) } if (c->out) { - qjack_buffer_read_l(&c->fifo, buffers, nframes); + 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 { - qjack_buffer_write_l(&c->fifo, buffers, nframes); + 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; } diff --git a/hw/audio/gusemu_hal.c b/hw/audio/gusemu_hal.c index ae40ca341cc4ef43b2c430d84dfac465378398f7..5b9a14ee21b668a3627aa2bfd2c6eca14ba0ea11 100644 --- a/hw/audio/gusemu_hal.c +++ b/hw/audio/gusemu_hal.c @@ -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) diff --git a/hw/audio/gusemu_mixer.c b/hw/audio/gusemu_mixer.c index 00b9861b92b222b48a9d7a484a8f4a70a4217a24..56300de77e4429b5c02d4d2b00dfc6f87d4b348c 100644 --- a/hw/audio/gusemu_mixer.c +++ b/hw/audio/gusemu_mixer.c @@ -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)))