zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

MidiIn.cpp (4658B)


      1 /*
      2   ZynAddSubFX - a software synthesizer
      3 
      4   MidiIn.C - This class is inherited by all the Midi input classes
      5   Copyright (C) 2002-2005 Nasca Octavian Paul
      6   Author: Nasca Octavian Paul
      7 
      8   This program is free software; you can redistribute it and/or
      9   modify it under the terms of the GNU General Public License
     10   as published by the Free Software Foundation; either version 2
     11   of the License, or (at your option) any later version.
     12 */
     13 
     14 #include "MidiIn.h"
     15 #include "../globals.h"
     16 #include "InMgr.h"
     17 #include <string.h>
     18 
     19 namespace zyn {
     20 
     21 MidiIn::MidiIn()
     22 {
     23     sysex_offset = 0;
     24     memset(sysex_data, 0, sizeof(sysex_data));
     25 }
     26 
     27 uint8_t MidiIn::midiSysEx(unsigned char data)
     28 {
     29     if (data & 0x80) {
     30         if (data == 0xF0) {
     31             sysex_offset = 0; /* begin */
     32         } else if (data == 0xF7) {
     33                 return (2); /* end */
     34         } else {
     35                 return (1); /* error */
     36         }
     37     } else if (sysex_offset >= sizeof(sysex_data)) {
     38         return (1); /* error */
     39     }
     40     sysex_data[sysex_offset++] = data;
     41     return (0);
     42 }
     43 
     44 void MidiIn::midiProcess(unsigned char head,
     45                          unsigned char num,
     46                          unsigned char value)
     47 {
     48     MidiEvent     ev;
     49     unsigned char chan = head & 0x0f;
     50 
     51     /* SYSEX handling */
     52     if (head == 0xF0 || sysex_offset != 0) {
     53         uint8_t status = 0;
     54 
     55         status |= midiSysEx(head);
     56         status |= midiSysEx(num);
     57         status |= midiSysEx(value);
     58 
     59         if (status & 1) {
     60             /* error parsing SYSEX */
     61             sysex_offset = 0;
     62         } else if (status & 2) {
     63             /* message complete */
     64 
     65             if (sysex_offset >= 10 &&
     66                 sysex_data[1] == 0x0A &&
     67                 sysex_data[2] == 0x55) {
     68                 ev.channel = sysex_data[3] & 0x0F;
     69                 ev.log2_freq = sysex_data[6] +
     70                   (sysex_data[7] / (128.0f)) +
     71                   (sysex_data[8] / (128.0f * 128.0f)) +
     72                   (sysex_data[9] / (128.0f * 128.0f * 128.0f));
     73 
     74                 switch (sysex_data[3] >> 4) {
     75                 case 0: /* Note ON */
     76                     ev.type = M_FLOAT_NOTE;
     77                     ev.num = sysex_data[4];
     78                     ev.value = sysex_data[5];
     79                     ev.log2_freq /= 12.0f;
     80                     break;
     81                 case 1: /* Pressure, Aftertouch */
     82                     ev.type = M_FLOAT_CTRL;
     83                     ev.num = C_aftertouch;
     84                     ev.value = sysex_data[4];
     85                     break;
     86                 case 2: /* Controller */
     87                     ev.type = M_FLOAT_CTRL;
     88                     ev.num = sysex_data[5];
     89                     ev.value = sysex_data[4];
     90                     break;
     91                 case 3: /* Absolute pitch */
     92                     ev.type = M_FLOAT_CTRL;
     93                     ev.num = C_pitch;
     94                     ev.value = sysex_data[4];
     95                     ev.log2_freq /= 12.0f;
     96                     break;
     97                 default:
     98                     return;
     99                 }
    100                 InMgr::getInstance().putEvent(ev);
    101             }
    102             return; /* message complete */
    103         } else {
    104             return; /* wait for more data */
    105         }
    106     }
    107     switch(head & 0xf0) {
    108         case 0x80: //Note Off
    109             ev.type    = M_NOTE;
    110             ev.channel = chan;
    111             ev.num     = num;
    112             ev.value   = 0;
    113             InMgr::getInstance().putEvent(ev);
    114             break;
    115         case 0x90: //Note On
    116             ev.type    = M_NOTE;
    117             ev.channel = chan;
    118             ev.num     = num;
    119             ev.value   = value;
    120             InMgr::getInstance().putEvent(ev);
    121             break;
    122         case 0xA0: /* pressure, aftertouch */
    123             ev.type    = M_PRESSURE;
    124             ev.channel = chan;
    125             ev.num     = num;
    126             ev.value   = value;
    127             InMgr::getInstance().putEvent(ev);
    128             break;
    129         case 0xb0: //Controller
    130             ev.type    = M_CONTROLLER;
    131             ev.channel = chan;
    132             ev.num     = num;
    133             ev.value   = value;
    134             InMgr::getInstance().putEvent(ev);
    135             break;
    136         case 0xc0: //Program Change
    137             ev.type    = M_PGMCHANGE;
    138             ev.channel = chan;
    139             ev.num     = num;
    140             ev.value   = 0;
    141             InMgr::getInstance().putEvent(ev);
    142             break;
    143         case 0xe0: //Pitch Wheel
    144             ev.type    = M_CONTROLLER;
    145             ev.channel = chan;
    146             ev.num     = C_pitchwheel;
    147             ev.value   = (num + value * (int) 128) - 8192;
    148             InMgr::getInstance().putEvent(ev);
    149             break;
    150     }
    151 }
    152 
    153 }