提交 bae31bfa 编写于 作者: P Peter Maydell

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: NPeter Maydell <peter.maydell@linaro.org>
......@@ -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;
}
......
......@@ -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)
......
......@@ -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)))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册