コード例 #1
0
bool
mastermidibus::get_midi_event (event * inev)
{
#ifdef SEQ64_HAVE_LIBASOUND

    automutex locker(m_mutex);
    snd_seq_event_t * ev;
    bool sysex = false;
    bool result = false;
    midibyte buffer[0x1000];                /* temporary buffer for MIDI data */
    snd_seq_event_input(m_alsa_seq, &ev);
    if (! rc().manual_alsa_ports())
    {
        switch (ev->type)
        {
        case SND_SEQ_EVENT_PORT_START:
        {
            port_start(ev->data.addr.client, ev->data.addr.port);
            result = true;
            break;
        }
        case SND_SEQ_EVENT_PORT_EXIT:
        {
            port_exit(ev->data.addr.client, ev->data.addr.port);
            result = true;
            break;
        }
        case SND_SEQ_EVENT_PORT_CHANGE:
        {
            result = true;
            break;
        }
        default:
            break;
        }
    }
    if (result)
        return false;

    snd_midi_event_t * midi_ev;                     /* for ALSA MIDI parser  */
    snd_midi_event_new(sizeof(buffer), &midi_ev);   /* make ALSA MIDI parser */
    long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev);
    if (bytes <= 0)
    {
        /*
         * This happens even at startup, before anything is really happening.
         * Let's not show it.
         *
         * if (bytes < 0)
         * {
         *     errprint("error decoding MIDI event");
         * }
         */

        return false;
    }

    inev->set_timestamp(ev->time.tick);
    inev->set_status_keep_channel(buffer[0]);

    /**
     *  We will only get EVENT_SYSEX on the first packet of MIDI data;
     *  the rest we have to poll for.  SysEx processing is currently
     *  disabled.
     */

#ifdef USE_SYSEX_PROCESSING                    /* currently disabled           */
    inev->set_sysex_size(bytes);
    if (buffer[0] == EVENT_MIDI_SYSEX)
    {
        inev->restart_sysex();              /* set up for sysex if needed   */
        sysex = inev->append_sysex(buffer, bytes);
    }
    else
    {
#endif
        /*
         *  Some keyboards send Note On with velocity 0 for Note Off, so we
         *  take care of that situation here by creating a Note Off event,
         *  with the channel nybble preserved. Note that we call
         *  event :: set_status_keep_channel() instead of using stazed's
         *  set_status function with the "record" parameter.  A little more
         *  confusing, but faster.
         */

        inev->set_data(buffer[1], buffer[2]);
        if (inev->is_note_off_recorded())
            inev->set_status_keep_channel(EVENT_NOTE_OFF);

        sysex = false;

#ifdef USE_SYSEX_PROCESSING
    }
#endif

    while (sysex)       /* sysex messages might be more than one message */
    {
        snd_seq_event_input(m_alsa_seq, &ev);
        long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev);
        if (bytes > 0)
            sysex = inev->append_sysex(buffer, bytes);
        else
            sysex = false;
    }
    snd_midi_event_free(midi_ev);

#endif  // SEQ64_HAVE_LIBASOUND

    return true;
}
コード例 #2
0
ファイル: midibus.cpp プロジェクト: vext01/seq24
bool
mastermidibus::get_midi_event( event *a_in )
{
    lock();
    
    snd_seq_event_t *ev; 
    
    bool sysex = false;
    
    /* temp for midi data */
    unsigned char buffer[0x1000];
    
    snd_seq_event_input(m_alsa_seq, &ev);
    
    
    
    bool ret = false;

    if (! global_manual_alsa_ports )
    {
        switch( ev->type ){ 

            case SND_SEQ_EVENT_PORT_START:
                {   
                    //printf("SND_SEQ_EVENT_PORT_START:    addr[%d:%d]\n", 
                    //	   ev->data.addr.client, ev->data.addr.port );
                    port_start( ev->data.addr.client, ev->data.addr.port );
                    ret = true; 
                    break;
                }

            case SND_SEQ_EVENT_PORT_EXIT:     
                {
                    //printf("SND_SEQ_EVENT_PORT_EXIT:     addr[%d:%d]\n", 
                    //	   ev->data.addr.client, ev->data.addr.port ); 
                    port_exit( ev->data.addr.client, ev->data.addr.port );
                    ret = true; 
                    break;
                }

            case SND_SEQ_EVENT_PORT_CHANGE:
                {   
                    //printf("SND_SEQ_EVENT_PORT_CHANGE:   addr[%d:%d]\n", 
                    //	   ev->data.addr.client, 
                    //	   ev->data.addr.port ); 
                    ret = true; 
                    break;
                }

            default: break;

        }
    }

    if( ret ){
        unlock();
        return false;
    }
    
    /* alsa midi parser */
    snd_midi_event_t *midi_ev;
    snd_midi_event_new( 0x1000, &midi_ev );
    
    long bytes =
        snd_midi_event_decode( midi_ev,
                               buffer,
                               0x1000,
                               ev ); 
    
    a_in->set_timestamp( ev->time.tick );
    a_in->set_status( buffer[0] );
    a_in->set_size( bytes );
    
    /* we will only get EVENT_SYSEX on the first 
       packet of midi data, the rest we have
       to poll for */
    //if ( buffer[0] == EVENT_SYSEX ){
    if ( 0 ){
    
        /* set up for sysex if needed */
        a_in->start_sysex( );
        sysex = a_in->append_sysex( buffer, bytes );
    }
    else {
        
        a_in->set_data( buffer[1], buffer[2] );
        
        // some keyboards send on's with vel 0 for off
        if ( a_in->get_status() == EVENT_NOTE_ON &&
             a_in->get_note_velocity() == 0x00 ){
            a_in->set_status( EVENT_NOTE_OFF );
        }
        
        sysex = false;
    }
    
    /* sysex messages might be more than one message */
    while ( sysex ){
        
        snd_seq_event_input(m_alsa_seq, &ev);
        
        bytes =
            snd_midi_event_decode( midi_ev,
                                   buffer,
                                   0x1000,
                                   ev ); 
        
        sysex = a_in->append_sysex( buffer, bytes );
        
    }
    
    snd_seq_free_event( ev );
    snd_midi_event_free( midi_ev );
    
    unlock();
    
    return true;
}
コード例 #3
0
ファイル: mastermidibus.cpp プロジェクト: EQ4/sequencer24
bool
mastermidibus::get_midi_event (event * a_in)
{
#ifdef HAVE_LIBASOUND
    automutex locker(m_mutex);
    snd_seq_event_t * ev;
    bool sysex = false;
    bool result = false;
    unsigned char buffer[0x1000];       /* temporary buffer for midi data */
    snd_seq_event_input(m_alsa_seq, &ev);
    if (! global_manual_alsa_ports)
    {
        switch (ev->type)
        {
        case SND_SEQ_EVENT_PORT_START:
        {
            port_start(ev->data.addr.client, ev->data.addr.port);
            result = true;
            break;
        }
        case SND_SEQ_EVENT_PORT_EXIT:
        {
            port_exit(ev->data.addr.client, ev->data.addr.port);
            result = true;
            break;
        }
        case SND_SEQ_EVENT_PORT_CHANGE:
        {
            result = true;
            break;
        }
        default:
            break;
        }
    }
    if (result)
        return false;

    snd_midi_event_t * midi_ev;                         /* alsa midi parser */
    snd_midi_event_new(sizeof(buffer), &midi_ev);
    long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev);
    if (bytes <= 0)
        return false;

    a_in->set_timestamp(ev->time.tick);
    a_in->set_status(buffer[0]);
    a_in->set_size(bytes);

    /*
     *  We will only get EVENT_SYSEX on the first packet of MIDI data;
     *  the rest we have to poll for.
     */

#if 0
    if ( buffer[0] == EVENT_SYSEX )
    {
        a_in->start_sysex();            /* set up for sysex if needed */
        sysex = a_in->append_sysex(buffer, bytes);
    }
    else
    {
#endif
        /* some keyboards send Note On with velocity 0 for Note Off */

        a_in->set_data(buffer[1], buffer[2]);
        if (a_in->get_status() == EVENT_NOTE_ON && a_in->get_note_velocity() == 0)
            a_in->set_status(EVENT_NOTE_OFF);

        sysex = false;
#if 0
    }
#endif

    while (sysex)       /* sysex messages might be more than one message */
    {
        snd_seq_event_input(m_alsa_seq, &ev);
        long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev);
        if (bytes > 0)
            sysex = a_in->append_sysex(buffer, bytes);
        else
            sysex = false;
    }
    snd_midi_event_free(midi_ev);
#endif  // HAVE_LIBASOUND
    return true;
}