繁体   English   中英

未输出到ALSA音序器的预定事件

[英]Scheduled events to ALSA sequencer are not being outputted

在此示例代码中,我设置了一个ALSA客户端,创建了一个音序器队列和输出端口。 然后,我将预定的音符打开和音符关闭事件输出到此端口,然后等待按键。 此时,我设置了midisnoop以从端口读取。

当击键到达时,我开始排队并读取实时滴答声。 我希望该注释显示在我正在监视的输出端口上。 什么也没出现。

#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;
}

启动队列将清除它。

您必须在实际事件之前发送队列开始事件。 (您不需要单独消耗掉它。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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