Browse Source

Merge branch 'ventosus-fix_alsa_midi_hotplug'

tags/0.125.0rc1
Paul Davis 10 years ago
parent
commit
6685cc737e
4 changed files with 51 additions and 48 deletions
  1. +0
    -1
      drivers/alsa_midi/a2j.h
  2. +14
    -24
      drivers/alsa_midi/alsa_midi.c
  3. +34
    -21
      drivers/alsa_midi/port_thread.c
  4. +3
    -2
      drivers/alsa_midi/port_thread.h

+ 0
- 1
drivers/alsa_midi/a2j.h View File

@@ -88,7 +88,6 @@ typedef struct alsa_midi_driver
bool running;
bool finishing;

jack_ringbuffer_t* port_add; // snd_seq_addr_t
jack_ringbuffer_t* port_del; // struct a2j_port*
jack_ringbuffer_t* outbound_events; // struct a2j_delivery_event
jack_nframes_t cycle_start;


+ 14
- 24
drivers/alsa_midi/alsa_midi.c View File

@@ -44,7 +44,7 @@ _a2j_debug (const char* fmt, ...)
va_list ap;
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
fputc ('\n', stdout);
fputc ('\n', stderr);
}
#endif

@@ -150,13 +150,12 @@ a2j_port_event (alsa_midi_driver_t* driver, snd_seq_event_t * ev)
if (addr.client == driver->client_id)
return;

if (ev->type == SND_SEQ_EVENT_PORT_START || ev->type == SND_SEQ_EVENT_PORT_CHANGE) {
if (jack_ringbuffer_write_space(driver->port_add) >= sizeof(addr)) {
a2j_debug("port_event: add/change %d:%d", addr.client, addr.port);
jack_ringbuffer_write(driver->port_add, (char*)&addr, sizeof(addr));
} else {
a2j_error("dropping port_event: add/change %d:%d", addr.client, addr.port);
}
if (ev->type == SND_SEQ_EVENT_PORT_START) {
a2j_debug("port_event: add %d:%d", addr.client, addr.port);
a2j_new_ports (driver, addr);
} else if (ev->type == SND_SEQ_EVENT_PORT_CHANGE) {
a2j_debug("port_event: change %d:%d", addr.client, addr.port);
a2j_update_ports (driver, addr);
} else if (ev->type == SND_SEQ_EVENT_PORT_EXIT) {
a2j_debug("port_event: del %d:%d", addr.client, addr.port);
a2j_port_setdead(driver->stream[A2J_PORT_CAPTURE].port_hash, addr);
@@ -321,7 +320,6 @@ alsa_input_thread (void* arg)
struct pollfd * pfd;
snd_seq_addr_t addr;
snd_seq_client_info_t * client_info;
snd_seq_port_info_t * port_info;
bool initial;
snd_seq_event_t * event;
int ret;
@@ -338,19 +336,14 @@ alsa_input_thread (void* arg)
while (snd_seq_event_input (driver->seq, &event) > 0) {
if (initial) {
snd_seq_client_info_alloca(&client_info);
snd_seq_port_info_alloca(&port_info);
snd_seq_client_info_set_client(client_info, -1);
while (snd_seq_query_next_client(driver->seq, client_info) >= 0) {
addr.client = snd_seq_client_info_get_client(client_info);
if (addr.client == SND_SEQ_CLIENT_SYSTEM || addr.client == driver->client_id) {
continue;
}
snd_seq_port_info_set_client(port_info, addr.client);
snd_seq_port_info_set_port(port_info, -1);
while (snd_seq_query_next_port(driver->seq, port_info) >= 0) {
addr.port = snd_seq_port_info_get_port(port_info);
a2j_update_port(driver, addr, port_info);
}
a2j_new_ports (driver, addr);
}

initial = false;
@@ -470,6 +463,10 @@ alsa_output_thread(void * arg)
int limit;

while (driver->running) {
/* pre-first, handle port deletion requests */

a2j_free_ports(driver);

/* first, make a list of all events in the outbound_events FIFO */
INIT_LIST_HEAD(&evlist);
@@ -610,6 +607,7 @@ a2j_jack_process_internal (alsa_midi_driver_t* driver, int dir, jack_nframes_t n
a2j_debug("jack: removed port %s", port_ptr->name);
*port_ptr_ptr = port_ptr->next;
jack_ringbuffer_write(driver->port_del, (char*)&port_ptr, sizeof(port_ptr));
nevents += 1; /* wake up output thread, see: a2j_free_ports */
continue;
}
@@ -695,13 +693,6 @@ alsa_midi_attach (alsa_midi_driver_t* driver, jack_engine_t* engine)
{
int error;
driver->port_add = jack_ringbuffer_create (2 * MAX_PORTS * sizeof(snd_seq_addr_t));
if (driver->port_add == NULL) {
return -1;
}
driver->port_del = jack_ringbuffer_create(2 * MAX_PORTS * sizeof(struct a2j_port *));
if (driver->port_del == NULL) {
return -1;
@@ -813,7 +804,6 @@ alsa_midi_driver_delete (alsa_midi_driver_t* driver)
sem_destroy (&driver->output_semaphore);

jack_ringbuffer_free (driver->outbound_events);
jack_ringbuffer_free (driver->port_add);
jack_ringbuffer_free (driver->port_del);
}



+ 34
- 21
drivers/alsa_midi/port_thread.c View File

@@ -196,12 +196,12 @@ a2j_update_port (alsa_midi_driver_t * driver, snd_seq_addr_t addr, const snd_seq
}

void
a2j_free_ports (jack_ringbuffer_t * ports)
a2j_free_ports (alsa_midi_driver_t * driver)
{
struct a2j_port *port;
int sz;

while ((sz = jack_ringbuffer_read (ports, (char*)&port, sizeof(port)))) {
while ((sz = jack_ringbuffer_read (driver->port_del, (char*)&port, sizeof(port)))) {
assert (sz == sizeof(port));
a2j_debug("port deleted: %s", port->name);
list_del (&port->siblings);
@@ -210,26 +210,39 @@ a2j_free_ports (jack_ringbuffer_t * ports)
}

void
a2j_update_ports (alsa_midi_driver_t * driver)
a2j_update_ports (alsa_midi_driver_t * driver, snd_seq_addr_t addr)
{
snd_seq_addr_t addr;
int size;
snd_seq_port_info_t * info;
int err;
while ((size = jack_ringbuffer_read(driver->port_add, (char *)&addr, sizeof(addr))) != 0) {
snd_seq_port_info_t * info;
int err;
snd_seq_port_info_alloca(&info);
assert (size == sizeof(addr));
assert (addr.client != driver->client_id);
if ((err = snd_seq_get_any_port_info(driver->seq, addr.client, addr.port, info)) >= 0) {
a2j_update_port(driver, addr, info);
} else {
a2j_port_setdead(driver->stream[A2J_PORT_CAPTURE].port_hash, addr);
a2j_port_setdead(driver->stream[A2J_PORT_PLAYBACK].port_hash, addr);
}
assert (addr.client != driver->client_id);
snd_seq_port_info_alloca(&info);
if ((err = snd_seq_get_any_port_info(driver->seq, addr.client, addr.port, info)) >= 0) {
a2j_debug("updating: %d:%d", addr.client, addr.port);
a2j_update_port(driver, addr, info);
} else {
a2j_debug("setting dead: %d:%d", addr.client, addr.port);
a2j_port_setdead(driver->stream[A2J_PORT_CAPTURE].port_hash, addr);
a2j_port_setdead(driver->stream[A2J_PORT_PLAYBACK].port_hash, addr);
}
}

void
a2j_new_ports (alsa_midi_driver_t * driver, snd_seq_addr_t addr)
{
snd_seq_port_info_t * port_info;

assert (addr.client != driver->client_id);

snd_seq_port_info_alloca(&port_info);

a2j_debug("adding new port: %d:%d", addr.client, addr.port);
snd_seq_port_info_set_client(port_info, addr.client);
snd_seq_port_info_set_port(port_info, -1);
while (snd_seq_query_next_port(driver->seq, port_info) >= 0) {
addr.port = snd_seq_port_info_get_port(port_info);
a2j_update_port(driver, addr, port_info);
}
}

+ 3
- 2
drivers/alsa_midi/port_thread.h View File

@@ -23,8 +23,9 @@
#define PORT_THREAD_H__1C6B5065_5556_4AC6_AA9F_44C32A9648C6__INCLUDED

void a2j_update_port (alsa_midi_driver_t* driver, snd_seq_addr_t addr, const snd_seq_port_info_t* info);
void a2j_update_ports (alsa_midi_driver_t* driver);
void a2j_free_ports (jack_ringbuffer_t * ports);
void a2j_update_ports (alsa_midi_driver_t* driver, snd_seq_addr_t addr);
void a2j_new_ports (alsa_midi_driver_t* driver, snd_seq_addr_t addr);
void a2j_free_ports (alsa_midi_driver_t* driver);
struct a2j_port * a2j_find_port_by_addr (struct a2j_stream * stream_ptr, snd_seq_addr_t addr);
struct a2j_port * a2j_find_port_by_jack_port_name (struct a2j_stream * stream_ptr, const char * jack_port);



Loading…
Cancel
Save