简体   繁体   中英

Scheduled events to ALSA sequencer are not being outputted

In this example code I set up an ALSA client, create a sequencer queue and output port. Then I output a scheduled note on and note off event to this port and wait for a keystroke. At this point I set up midisnoop to read from the port.

When keystroke arrives I start the queue and read the realtime ticks. I am expecting the note to show on the output port which I am monitoring. Nothing appears.

#include <stdio.h>
#include <alsa/asoundlib.h>

int queue, out_port;
snd_seq_t *seq_handle;
snd_seq_tick_time_t current_tick;
snd_seq_queue_status_t *status;

int main (int argc, char **argv) {

    // open sequencer and create queue
    snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT | SND_SEQ_OPEN_OUTPUT, 0);
    queue = snd_seq_alloc_queue( seq_handle );
    fprintf(stderr,"queue id=%d\n", queue);

    // create an output port
    out_port = snd_seq_create_simple_port(seq_handle, "test:out",
        SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ,
        SND_SEQ_PORT_TYPE_APPLICATION); 
    if( out_port < 0 ) return 1;

    // set up a midi event for scheduling noteon and noteoff
    snd_seq_event_t event;
    snd_seq_ev_clear( &event );

    // set up source address
    snd_seq_addr_t addr;
    addr.client = snd_seq_client_id( seq_handle);
    addr.port = out_port;
    event.source = addr;

    // set destination addressing to all subscribers
    snd_seq_ev_set_subs( &event );

    // note specifics
    int chan = 0;
    int note = 64;
    int veloc = 127;
    int tick = 0;

    // note on at zero
    snd_seq_ev_set_noteon( &event, chan, note, veloc);
    snd_seq_ev_schedule_tick( &event, queue, 0, tick );
    snd_seq_event_output( seq_handle, &event );

    // note off at 96
    tick = 96;
    snd_seq_ev_set_noteoff( &event, chan, note, veloc);
    snd_seq_ev_schedule_tick( &event, queue, 0, tick );
    snd_seq_event_output( seq_handle, &event );

    // drain output
    snd_seq_drain_output( seq_handle );

    // wait here for keystroke, so we can set up midisnoop 
    fgetc( stdin );

    // start queue and read ticks
    snd_seq_start_queue( seq_handle, queue, NULL );
    snd_seq_drain_output( seq_handle );

    for(int i=0;i<4;i++) {
        snd_seq_queue_status_malloc(&status);
        snd_seq_get_queue_status(seq_handle, queue, status);
        current_tick = snd_seq_queue_status_get_tick_time(status);
        snd_seq_queue_status_free(status);

        fprintf(stderr,"tick=%d\n", current_tick );
        sleep(1);
    }

    snd_seq_stop_queue( seq_handle, queue, NULL );
    snd_seq_free_queue( seq_handle, queue );
    return 0;
}

Starting a queue clears it.

You must send the queue start event before the actual events. (You do not need to drain it separately.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM