static int alsa_seqmidi_start(alsa_midi_t *m) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; int err; debug_log("midi: start"); if (!self->seq) return -EBADF; if (self->keep_walking) return -EALREADY; snd_seq_connect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); snd_seq_drop_input(self->seq); add_existing_ports(self); update_ports(self); add_ports(&self->stream[PORT_INPUT]); add_ports(&self->stream[PORT_OUTPUT]); self->keep_walking = 1; if ((err = pthread_create(&self->port_thread, NULL, port_thread, self))) { self->keep_walking = 0; return -errno; } return 0; }
static int snd_rawmidi_virtual_drop(snd_rawmidi_t *rmidi) { snd_rawmidi_virtual_t *virt = rmidi->private_data; if (rmidi->stream == SND_RAWMIDI_STREAM_OUTPUT) { snd_seq_drop_output(virt->handle); snd_midi_event_reset_encode(virt->midi_event); virt->pending = 0; } else { snd_seq_drop_input(virt->handle); snd_midi_event_reset_decode(virt->midi_event); virt->in_buf_ofs = 0; } return 0; }
int connect_to_alsa (struct a2j* self) { int error; void * thread_status; self->port_add = jack_ringbuffer_create(2 * MAX_PORTS * sizeof(snd_seq_addr_t)); if (self->port_add == NULL) { goto free_self; } self->port_del = jack_ringbuffer_create(2 * MAX_PORTS * sizeof(struct a2j_port *)); if (self->port_del == NULL) { goto free_ringbuffer_add; } if (!a2j_stream_init(self)) { goto free_ringbuffer_outbound; } if ((error = snd_seq_open(&self->seq, "hw", SND_SEQ_OPEN_DUPLEX, 0)) < 0) { a2j_error("failed to open alsa seq"); goto close_stream; } if ((error = snd_seq_set_client_name(self->seq, "midi_in")) < 0) { a2j_error("snd_seq_set_client_name() failed"); goto close_seq_client; } if ((self->port_id = snd_seq_create_simple_port( self->seq, "port", SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_WRITE #ifndef DEBUG |SND_SEQ_PORT_CAP_NO_EXPORT #endif ,SND_SEQ_PORT_TYPE_APPLICATION)) < 0) { a2j_error("snd_seq_create_simple_port() failed"); goto close_seq_client; } if ((self->client_id = snd_seq_client_id(self->seq)) < 0) { a2j_error("snd_seq_client_id() failed"); goto close_seq_client; } if ((self->queue = snd_seq_alloc_queue(self->seq)) < 0) { a2j_error("snd_seq_alloc_queue() failed"); goto close_seq_client; } snd_seq_start_queue (self->seq, self->queue, 0); a2j_stream_attach (&self->stream); if ((error = snd_seq_nonblock(self->seq, 1)) < 0) { a2j_error("snd_seq_nonblock() failed"); goto close_seq_client; } snd_seq_drop_input (self->seq); a2j_add_ports(&self->stream); if (sem_init(&self->io_semaphore, 0, 0) < 0) { a2j_error("can't create IO semaphore"); goto close_jack_client; } g_keep_alsa_walking = true; if (pthread_create(&self->alsa_io_thread, NULL, alsa_input_thread, self) < 0) { a2j_error("cannot start ALSA input thread"); goto sem_destroy; } /* wake the poll loop in the alsa input thread so initial ports are fetched */ if ((error = snd_seq_connect_from (self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE)) < 0) { a2j_error("snd_seq_connect_from() failed"); goto join_io_thread; } return 0; g_keep_alsa_walking = false; /* tell alsa threads to stop */ snd_seq_disconnect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); join_io_thread: pthread_join(self->alsa_io_thread, &thread_status); sem_destroy: sem_destroy(&self->io_semaphore); close_jack_client: if ((error = jack_client_close(self->jack_client)) < 0) { a2j_error("Cannot close jack client"); } close_seq_client: snd_seq_close(self->seq); close_stream: a2j_stream_close(self); free_ringbuffer_outbound: jack_ringbuffer_free(self->outbound_events); jack_ringbuffer_free(self->port_del); free_ringbuffer_add: jack_ringbuffer_free(self->port_add); free_self: free(self); return -1; }
/** * \brief reset client input pool * \param seq sequencer handle * \return 0 on success or negative error code * * So far, this works identically like #snd_seq_drop_input(). */ int snd_seq_reset_pool_input(snd_seq_t *seq) { return snd_seq_drop_input(seq); }