/* entry points for broadcasting system events */ void snd_seq_system_broadcast(int client, int port, int type) { struct snd_seq_event ev; if (setheader(&ev, client, port) < 0) return; ev.type = type; snd_seq_kernel_client_dispatch(sysclient, &ev, 0, 0); }
/* entry points for broadcasting system events */ int snd_seq_system_notify(int client, int port, struct snd_seq_event *ev) { ev->flags = SNDRV_SEQ_EVENT_LENGTH_FIXED; ev->source.client = sysclient; ev->source.port = announce_port; ev->dest.client = client; ev->dest.port = port; return snd_seq_kernel_client_dispatch(sysclient, ev, 0, 0); }
static void send_note(unsigned char notevalue, unsigned char velocity) { struct snd_seq_event note; int err; if (client > 0) { config_note(¬e, notevalue, velocity); err = snd_seq_kernel_client_dispatch(client, ¬e, in_atomic(), 0); if (err < 0) { printk(KERN_ERR LOGPREFIX "Error dispatch client(%d) code:%d\n", client, err); } } }
/* * unuse callback - send ALL_SOUNDS_OFF and RESET_CONTROLLERS events * to subscribers. * Note: this callback is called only after all subscribers are removed. */ static int dummy_unuse(void *private_data, struct snd_seq_port_subscribe *info) { struct snd_seq_dummy_port *p; int i; struct snd_seq_event ev; p = private_data; memset(&ev, 0, sizeof(ev)); if (p->duplex) ev.source.port = p->connect; else ev.source.port = p->port; ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS; ev.type = SNDRV_SEQ_EVENT_CONTROLLER; for (i = 0; i < 16; i++) { ev.data.control.channel = i; ev.data.control.param = MIDI_CTL_ALL_SOUNDS_OFF; snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0); ev.data.control.param = MIDI_CTL_RESET_CONTROLLERS; snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0); } return 0; }
/* * send events to all subscribed ports */ static void queue_broadcast_event(queue_t *q, snd_seq_event_t *ev, int atomic, int hop) { snd_seq_event_t sev; sev = *ev; sev.flags = SNDRV_SEQ_TIME_STAMP_TICK|SNDRV_SEQ_TIME_MODE_ABS; sev.time.tick = q->timer->tick.cur_tick; sev.queue = q->queue; sev.data.queue.queue = q->queue; /* broadcast events from Timer port */ sev.source.client = SNDRV_SEQ_CLIENT_SYSTEM; sev.source.port = SNDRV_SEQ_PORT_SYSTEM_TIMER; sev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS; snd_seq_kernel_client_dispatch(SNDRV_SEQ_CLIENT_SYSTEM, &sev, atomic, hop); }
/* * event input callback - just redirect events to subscribers */ static int dummy_input(snd_seq_event_t *ev, int direct, void *private_data, int atomic, int hop) { snd_seq_dummy_port_t *p; snd_seq_event_t tmpev; p = private_data; if (ev->source.client == SNDRV_SEQ_CLIENT_SYSTEM || ev->type == SNDRV_SEQ_EVENT_KERNEL_ERROR) return 0; /* ignore system messages */ tmpev = *ev; if (p->duplex) tmpev.source.port = p->connect; else tmpev.source.port = p->port; tmpev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS; return snd_seq_kernel_client_dispatch(p->client, &tmpev, atomic, hop); }
/* handle rawmidi input event (MIDI v1.0 stream) */ static void snd_midi_input_event(snd_rawmidi_substream_t * substream) { snd_rawmidi_runtime_t *runtime; seq_midisynth_t *msynth; snd_seq_event_t ev; char buf[16], *pbuf; long res, count; if (substream == NULL) return; runtime = substream->runtime; msynth = (seq_midisynth_t *) runtime->private_data; if (msynth == NULL) return; memset(&ev, 0, sizeof(ev)); while (runtime->avail > 0) { res = snd_rawmidi_kernel_read(substream, buf, sizeof(buf)); if (res <= 0) continue; if (msynth->parser == NULL) continue; pbuf = buf; while (res > 0) { count = snd_midi_event_encode(msynth->parser, pbuf, res, &ev); if (count < 0) break; pbuf += count; res -= count; if (ev.type != SNDRV_SEQ_EVENT_NONE) { ev.source.port = msynth->seq_port; ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS; snd_seq_kernel_client_dispatch(msynth->seq_client, &ev, 1, 0); /* clear event and reset header */ memset(&ev, 0, sizeof(ev)); } } } }