Пример #1
0
void MidiJackDevice::recordEvent(MidiRecordEvent& event)/*{{{*/
{
    if (audio->isPlaying())
        event.setLoopNum(audio->loopCount());

    if (midiInputTrace)
    {
        printf("Jack MidiInput: ");
        event.dump();
    }

    int typ = event.type();

    if (_port != -1)
    {
        //call our midimonitor with the data, it can then decide what to do
        monitorEvent(event);
    }

    //
    //  process midi event input filtering and
    //    transformation
    //

    processMidiInputTransformPlugins(event);

    if (filterEvent(event, midiRecordType, false))
        return;

    if (!applyMidiInputTransformation(event))
    {
        if (midiInputTrace)
            printf("   midi input transformation: event filtered\n");
        return;
    }

    //
    // transfer noteOn events to gui for step recording and keyboard
    // remote control
    //
    if (typ == ME_NOTEON)
    {
        int pv = ((event.dataA() & 0xff) << 8) + (event.dataB() & 0xff);
        song->putEvent(pv);
    }
    //This was not sending noteoff events at all sometimes causing strange endless note in step rec
    else if(typ == ME_NOTEOFF)
    {
        int pv = ((event.dataA() & 0xff) << 8) + (0x00);
        song->putEvent(pv);
    }

    // Do not bother recording if it is NOT actually being used by a port.
    // Because from this point on, process handles things, by selected port.
    if (_port == -1)
        return;

    // Split the events up into channel fifos. Special 'channel' number 17 for sysex events.
    unsigned int ch = (typ == ME_SYSEX) ? kMaxMidiChannels : event.channel();
    if (_recordFifo[ch].put(MidiPlayEvent(event)))
        printf("MidiJackDevice::recordEvent: fifo channel %d overflow\n", ch);
}/*}}}*/
Пример #2
0
void MidiJackDevice::eventReceived(jack_midi_event_t* ev)/*{{{*/
{
    MidiRecordEvent event;
    event.setB(0);

    // NOTE: From LOS-2. Not done here in LOS-1 (yet).
    // move all events 2*segmentSize into the future to get
    // jitterfree playback
    //
    //  cycle   n-1         n          n+1
    //          -+----------+----------+----------+-
    //               ^          ^          ^
    //               catch      process    play
    //
    //      const SeqTime* st = audio->seqTime();

    unsigned pos = audio->pos().frame();

    event.setTime(pos + ev->time);

    event.setChannel(*(ev->buffer) & 0xf);
    int type = *(ev->buffer) & 0xf0;
    int a = *(ev->buffer + 1) & 0x7f;
    int b = *(ev->buffer + 2) & 0x7f;
    event.setType(type);
    switch (type)
    {
        case ME_NOTEON:
        case ME_NOTEOFF:
        case ME_CONTROLLER:
            event.setA(*(ev->buffer + 1));
            event.setB(*(ev->buffer + 2));
            break;
        case ME_PROGRAM:
        case ME_AFTERTOUCH:
            event.setA(*(ev->buffer + 1));
            break;

        case ME_PITCHBEND:
            event.setA(((b << 7) + a) - 8192);
            break;

        case ME_SYSEX:
        {
            int type = *(ev->buffer) & 0xff;
            switch (type)
            {
                case ME_SYSEX:

                    // TODO: Deal with large sysex, which are broken up into chunks!
                    // For now, do not accept if the last byte is not EOX, meaning it's a chunk with more chunks to follow.
                    if (*(((unsigned char*) ev->buffer) + ev->size - 1) != ME_SYSEX_END)
                    {
                        printf("MidiJackDevice::eventReceived sysex chunks not supported!\n");
                        return;
                    }

                    //event.setTime(0);      // mark as used
                    event.setType(ME_SYSEX);
                    event.setData((unsigned char*) (ev->buffer + 1), ev->size - 2);
                    break;
                case ME_MTC_QUARTER:
                case ME_SONGPOS:
                case ME_CLOCK:
                case ME_TICK:
                case ME_START:
                case ME_CONTINUE:
                case ME_STOP:
                    return;
                default:
                    printf("MidiJackDevice::eventReceived unsupported system event 0x%02x\n", type);
                    return;
            }
        }
            break;
        default:
            printf("MidiJackDevice::eventReceived unknown event 0x%02x\n", type);
            //printf("MidiJackDevice::eventReceived unknown event 0x%02x size:%d buf:0x%02x 0x%02x 0x%02x ...0x%02x\n", type, ev->size, *(ev->buffer), *(ev->buffer + 1), *(ev->buffer + 2), *(ev->buffer + (ev->size - 1)));
            return;
    }

    if (midiInputTrace)
    {
        printf("MidiInput<%s>: ", name().toLatin1().constData());
        event.dump();
    }

#ifdef JACK_MIDI_DEBUG
    printf("MidiJackDevice::eventReceived time:%d type:%d ch:%d A:%d B:%d\n", event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
#endif

    // Let recordEvent handle it from here, with timestamps, filtering, gui triggering etc.
    recordEvent(event);
}/*}}}*/
Пример #3
0
void MidiDevice::recordEvent(MidiRecordEvent& event)
      {
      if(MusEGlobal::audio->isPlaying())
        event.setLoopNum(MusEGlobal::audio->loopCount());
      
      if (MusEGlobal::midiInputTrace) {
            fprintf(stderr, "MidiInput: ");
            dumpMPEvent(&event);
            }

      int typ = event.type();
      
      if(_port != -1)
      {
        int idin = MusEGlobal::midiPorts[_port].syncInfo().idIn();
          
        //---------------------------------------------------
        // filter some SYSEX events
        //---------------------------------------------------
  
        if (typ == ME_SYSEX) {
              const unsigned char* p = event.data();
              int n = event.len();
              if (n >= 4) {
                    if ((p[0] == 0x7f)
                      && ((p[1] == 0x7f) || (idin == 0x7f) || (p[1] == idin))) {
                          if (p[2] == 0x06) {
                                MusEGlobal::midiSyncContainer.mmcInput(_port, p, n);
                                return;
                                }
                          if (p[2] == 0x01) {
                                MusEGlobal::midiSyncContainer.mtcInputFull(_port, p, n);
                                return;
                                }
                          }
                    else if (p[0] == 0x7e) {
                          MusEGlobal::midiSyncContainer.nonRealtimeSystemSysex(_port, p, n);
                          return;
                          }
                    }
          }
          else    
            // Trigger general activity indicator detector. Sysex has no channel, don't trigger.
            MusEGlobal::midiPorts[_port].syncInfo().trigActDetect(event.channel());
      }
      
      //
      //  process midi event input filtering and
      //    transformation
      //

      processMidiInputTransformPlugins(event);

      if (filterEvent(event, MusEGlobal::midiRecordType, false))
            return;

      if (!applyMidiInputTransformation(event)) {
            if (MusEGlobal::midiInputTrace)
                  fprintf(stderr, "   midi input transformation: event filtered\n");
            return;
            }

      //
      // transfer noteOn and Off events to gui for step recording and keyboard
      // remote control (changed by flo93: added noteOff-events)
      //
      if (typ == ME_NOTEON) {
            int pv = ((event.dataA() & 0xff)<<8) + (event.dataB() & 0xff);
            MusEGlobal::song->putEvent(pv);
            }
      else if (typ == ME_NOTEOFF) {
            int pv = ((event.dataA() & 0xff)<<8) + (0x00); //send an event with velo=0
            MusEGlobal::song->putEvent(pv);
            }
      
      // Do not bother recording if it is NOT actually being used by a port.
      // Because from this point on, process handles things, by selected port.
      if(_port == -1)
        return;
      
      // Split the events up into channel fifos. Special 'channel' number 17 for sysex events.
      unsigned int ch = (typ == ME_SYSEX)? MusECore::MUSE_MIDI_CHANNELS : event.channel();
      if(_recordFifo[ch].put(event))
        fprintf(stderr, "MidiDevice::recordEvent: fifo channel %d overflow\n", ch);
      }