Mark Knecht wrote:
> Does anyone have a simple page I could read with an explanation about how
> one would go about transmitting a given number of MIDI events at a known
> tempo using the Alsa MIDI services?
You'd use the sequencer. There isn't an easy HOWTO that I'd know of.
To send some events at a specific time:
- open the sequencer
- create your own (source) port
- create a queue
- set the queue's tempo
- send some events through the queue, and start it
To open the sequencer, call snd_seq_open.
(You can get your client number with snd_seq_client_id.)
snd_seq_t seq;
snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
To create a port, allocate a port info object with
snd_seq_port_info_alloca, set port parameters with
snd_seq_port_info_set_xxx, and call snd_seq_create_port.
Or simply call snd_seq_create_simple_port.
int port;
port = snd_seq_create_simple_port(seq, "my port",
SND_SEQ_PORT_CAP_READ | SND_SEQ_POR_CAP_WRITE,
SND_SEQ_PORT_TYPE_APPLICATION);
To create a queue, allocate a queue info object with
snd_seq_queue_info_alloca, set queue parameters with
snd_seq_queue_info_set_xxx, and call snd_seq_create_queue.
Or simply call snd_seq_alloc_queue.
int queue;
queue = snd_seq_alloc_queue(seq);
To set the queue's tempo, allocate a queue tempo object with
snd_seq_queue_tempo_alloca, set tempo parameters with
snd_seq_queue_tempo_set_xxx, and call snd_seq_set_queue_tempo.
snd_seq_queue_tempo_t *tempo;
snd_seq_queue_tempo_alloca(&tempo);
snd_seq_queue_tempo_set_ppq(tempo, 4); /* ??? */
snd_seq_queue_tempo_set_tempo(tempo, 92);
snd_seq_set_queue_tempo(seq, queue, tempo);
To send an event though the queue, allocate an event structure (just
for a change, you can use a local snd_seq_event_t variable), call
snd_seq_ev_clear, call snd_seq_ev_set_dest, call
snd_seq_ev_schedule_tick, and specify the actual event you want to
send (probably with snd_seq_ev_set_note). Then call
snd_seq_event_output, and snd_seq_drain_output after you've sent all
events.
snd_seq_event_t ev;
snd_seq_ev_clear(&ev);
snd_seq_ev_set_dest(&ev, 64, 0); /* 64:0 */
snd_seq_ev_schedule_tick(&ev, queue, 0, 4); /* starts at 4 ticks */
snd_seq_ev_set_note(&ev, 0, 60, 127, 8); /* length 8 ticks */
snd_seq_event_output(seq, &ev);
snd_seq_ev_schedule_tick(&ev, queue, 0, 12);
snd_seq_ev_set_note(&ev, 0, 67, 127, 8);
snd_seq_event_output(seq, &ev);
snd_seq_drain_output(seq);
To start a queue, call snd_seq_start_queue and snd_seq_drain_output.
snd_seq_start_queue(seq, queue, NULL);
snd_seq_drain_output(seq);
/* wait until the notes are played before exiting */
This is off the top of my head, so I'll have to check if this works
myself ... ;-)
HTH
Clemens
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel