PCM Digital Synthesizer

Dependencies:   LCD mbed

/media/uploads/p_igmon/img_1731-w480.jpg

midi_work.cpp

Committer:
p_igmon
Date:
2016-09-02
Revision:
0:ad6637c36dc7

File content as of revision 0:ad6637c36dc7:

#include "synthesizer.h"

#define MIDI_IDLE       0
#define MIDI_NOTEON     1
#define MIDI_NOTEOFF    2
#define MIDI_VELOCITY   3
#define MIDI_VELOCITY0  4
#define MIDI_PGMCHG     5
#define MIDI_CONTCHG    6
#define MIDI_VOLH       7
#define MIDI_VOLL       8
#define MIDI_PORH       9
#define MIDI_PORL       10
#define MIDI_PORD       24
#define MIDI_LFO1H      11
#define MIDI_LFO1L      12
#define MIDI_NOTECHG    13
#define MIDI_OTHER      14
#define MIDI_PORSW      15
#define MIDI_SETMVOL    16
#define MIDI_INCMVOL    17
#define MIDI_DECMVOL    18
#define MIDI_INCMVOL2   19
#define MIDI_DECMVOL2   20
#define MIDI_ATTACKTIME 21
#define MIDI_RELEASETIME    22
#define MIDI_DECAYTIME  23
#define MIDI_BUFSIZE    256

extern DigitalOut myled;

volatile U8 midi_com;
volatile U8 midi_ch;
volatile U8 notenum;
volatile U8 *midi_rdptr;
volatile U8 *midi_wrptr;
volatile U16 md_voltemp;
volatile U16 md_lfo1depth;
volatile S16 md_portemp;
volatile U8 midi_receivebuf[MIDI_BUFSIZE];

extern int portament;
extern GENERATOR *pgen;
extern GENERATOR *gen;// ProgramChangeによるテンポラリに変更する。
extern GENERATOR_TEMP *pgen_temp;//  = &dgen_temp[0]; 

extern volatile U8 midi_base_ch;
extern volatile U8 midi_note_ch;
extern volatile U8 midi_prog_ch;
extern volatile S16 interpovalue;
extern volatile S16 MasterVolume;
extern volatile S16 mvoldiv;

void init_midi(void){
    midi_com = MIDI_IDLE;
    midi_wrptr = midi_rdptr = &midi_receivebuf[0];
}

void midi_work(void){
    GENERATOR *gena;// 110824
    GENERATOR_TEMP *gena_temp;// 110824
    U8 i ,data;
    U16 temp16;
    
    while(midi_rdptr != midi_wrptr){
    /* レシーブバッファが空なら、リターン */
       data = *midi_rdptr;
       if (++midi_rdptr >&midi_receivebuf[255]) midi_rdptr = &midi_receivebuf[0];//
        if (data > 0xf7){
            /* リアルタイムメッセージ */
            if (data == 0xff){// 110824 システムリセット
                //prog_enable = 0;
                MasterVolume = 127 <<8 ;// s7e8f
                mvoldiv = 0;
                portament = 0;
 //               gena = pgen;
                gena_temp = pgen_temp;
                for(i=0;i<GENMAX;i++){
                    gena_temp->status = GEN_IDLE;
                    // ge_tempna->midich =255;
                    gena_temp->voltemp = 0;
 //                   gena++;
                    gena_temp++;
                }
            }
        }else if (data <0x80){
            /* 何かしらの値 */
            switch (midi_com){ // 有効になっているMIDIコマンドを適用する。
                case MIDI_NOTEON:
                    notenum = data;
                    midi_com = MIDI_VELOCITY;
                    break;
                case MIDI_VELOCITY:
                    midi_com = MIDI_NOTEON;
                    if (midi_ch == midi_base_ch) {
                        if(data >0){
                            /* ノートONの処理 */
                            noteon(notenum ,data);
                        }else{
                            /* ノートOFFの処理 */
                            noteoff(notenum ,0);
                        }
                    }   
                    break;
                case MIDI_NOTEOFF:
                    notenum = data;
                    midi_com = MIDI_VELOCITY0;
                    break;
                case MIDI_VELOCITY0:
                    midi_com = MIDI_NOTEON;
                    if (midi_ch == midi_base_ch){
                        /* ノートOFFの処理 */
                        noteoff(notenum ,0);
                    }
                    break;
                case MIDI_PGMCHG:
                    midi_com = MIDI_PGMCHG;
                    if (midi_ch == midi_base_ch){ //やはり 戻す 131230
//                  if (midi_ch == midi_prog_ch){
                        /* 音色変更の処理 */
                        pgmchg(data);
                    }
                    break;
                case MIDI_CONTCHG:
                    switch(data){
                        case 90:// 121125
//                          if ((midi_ch == midi_base_ch)||(midi_ch == midi_base_ch2)) midi_com = MIDI_NOTECHG;
                            if (midi_ch == midi_base_ch) midi_com = MIDI_NOTECHG;
                            break;
                        case 1:
                            midi_com = MIDI_LFO1H;
                            break;
                        case 1+32:
                            midi_com = MIDI_LFO1L;
                            break;
                        case 5:
                            midi_com = MIDI_PORH;
                            break;
                        case 5+32:
                            midi_com = MIDI_PORL;
                            break;
                        case 38:
                            midi_com = MIDI_PORD;
                            break;
                        case 65:
                            if (midi_ch == midi_base_ch) midi_com = MIDI_PORSW;
                            break;
                        case 70:
                            if (midi_ch == midi_base_ch) midi_com = MIDI_SETMVOL;
                            break;
                        case 71:
                            if (midi_ch == midi_base_ch) midi_com = MIDI_INCMVOL;
                            break;
                        case 72:
                            if (midi_ch == midi_base_ch) midi_com = MIDI_DECMVOL;
                            break;
                        case 73:
                            if (midi_ch == midi_base_ch) midi_com = MIDI_INCMVOL2;
                            break;
                        case 74:
                            if (midi_ch == midi_base_ch) midi_com = MIDI_DECMVOL2;
                            break;
                        case 50:
                            if (midi_ch == midi_base_ch) midi_com = MIDI_ATTACKTIME;
                            break;
                        case 51:
                            if (midi_ch == midi_base_ch) midi_com = MIDI_RELEASETIME;
                            break;
                        case 52:
                            if (midi_ch == midi_base_ch) midi_com = MIDI_DECAYTIME;
                            break;

                        case 7:
                            midi_com = MIDI_VOLH;
                            break;
                        case 7+32:
                            midi_com = MIDI_VOLL;
                            break;
                        default:    
                            midi_com = MIDI_OTHER;
                            break;
                    }
                    break;
                case MIDI_NOTECHG:
                    midi_note_ch = data & 0x0f;
                    break;
                case MIDI_LFO1H:
                    md_lfo1depth = data<<7;
                    break;
                case MIDI_LFO1L:
                    md_lfo1depth |= data;
                    gena = gen;
                    for(i=0;i<PRGGENMAX;i++){
                        gena->lfo1depth = md_lfo1depth;
                        gena++;
                    }
                    break;
                case MIDI_PORSW:
                    if(data < 64){
                        portament = 0;
                    }else{
                        portament = -1;
                    }
                    break;
                case MIDI_SETMVOL:
                    mvoldiv = 0;
                    MasterVolume = data<<8;
                    break;
                case MIDI_INCMVOL:
                    MasterVolume += (data<<16);
                    if(MasterVolume >(127<<8)) MasterVolume = (127<<8);
                    break;
                case MIDI_DECMVOL:
                    MasterVolume -= (data<<16);
                    if(MasterVolume < 0) MasterVolume = 0;
                    break;
                case MIDI_INCMVOL2:
                    mvoldiv = data;
                    break;
                case MIDI_DECMVOL2:
                    mvoldiv = data * (-1);
                    break;

                case MIDI_ATTACKTIME:
//                  gena = pgen;// 実体のほうで
//                  for(i=0;i<GENMAX;i++){
                    gena = gen;
                    for(i=0;i<PRGGENMAX;i++){
                        gena->attacktime = (1<<data);
                        gena++;
                    }
                    break;  

                case MIDI_RELEASETIME:
                    temp16 = (528 + data) * 100; 
//                  gena = pgen;// 実体のほうで
//                  for(i=0;i<GENMAX;i++){
                    gena = gen;
                    for(i=0;i<PRGGENMAX;i++){
                        gena->releasetime = temp16;
                        gena++;
                    }
                    break;  

                case MIDI_DECAYTIME:
//                  gena = pgen;// 実体のほうで
//                  for(i=0;i<GENMAX;i++){
                    gena = gen;
                    for(i=0;i<PRGGENMAX;i++){
                        gena->decaytime = (1<<data);
                        gena++;
                    }
                    break;  

                case MIDI_PORH:
                    md_portemp = data<<9;
                    break;
                case MIDI_PORL:
//                  md_portemp |= data<<1;
                    gena = pgen;
 //                   gena_temp = pgen_temp;
                    for(i=0;i<GENMAX;i++){
                        gena_temp->dpf = (gena_temp->df >>14)* data;
//                        gena++;
                        gena_temp++;
                    }
                    break;
                case MIDI_PORD:// Portament Down
//                    gena = pgen;
                    gena_temp = pgen_temp;
                    for(i=0;i<GENMAX;i++){
                        gena_temp->dpf = (gena_temp->df >>14)* data;
                        gena_temp->dpf *= -1;
//                       gena++;
                        gena_temp++;
                    }
                    break;
                case MIDI_VOLH:
                    md_voltemp = data<<9;
                    break;
                case MIDI_VOLL:
                    md_voltemp |= data<<1;
                    gena = gen;
                    for(i=0;i<PRGGENMAX;i++){
                        gena->lfo1depth = md_lfo1depth;
                        gena++;
                    }
                    break;
                case MIDI_OTHER:
                default:
                    break;
            }
        }else{
            switch (data & 0xf0){
                case 0x80://  NOTEOFF コマンド
                    midi_com = MIDI_NOTEOFF;
                    midi_ch = data & 0x0f;
                    break;
                case 0x90://  NOTEON コマンド
                    midi_com = MIDI_NOTEON;
                    midi_ch = data & 0x0f;
                    break;
                case 0xc0:// プログラムチェンジコマンド
                    midi_com = MIDI_PGMCHG;
                    midi_ch = data & 0x0f;
                    break;
                case 0xb0:// コントロールチェンジコマンド
                    midi_com = MIDI_CONTCHG;
                    midi_ch = data & 0x0f;
                    break;
                case 0xa0:// ポリフォニックキープレッシャーコマンド
                case 0xd0:// チャンネルプレッシャーコマンド
                case 0xe0:// ピッチベンドコマンド
                default:// エクスクルーシブメッセージ
                    midi_com = MIDI_OTHER;
                    break;
            }
        }
    }
}