⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 track_r36.c

📁 一个很好的c++ midi解码算法,不依赖于任何平台.
💻 C
字号:
/* *  track_r36.cc *  Copyright (C) 1998-2000 SAKAI Katsuya * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdio.h> // #include <iostream.h>#include "config.h"#include "defines.h"#include "recomposer.h"#include "queue.h"#include "extern.h"#include "midievdefs.h"R36_Track::R36_Track(){  Mute=FALSE;  Port = 0;  Data=NULL;  RolandEx[0]=0xF0;  YamahaEx[0]=0xF0;  RolandEx[1]=0x41;  YamahaEx[1]=0x43;  RolandEx[2]=0;     YamahaEx[2]=0;  RolandEx[3]=0;     YamahaEx[3]=0;  RolandEx[4]=0x12;  YamahaEx[4]=0;  RolandEx[5]=0;     YamahaEx[5]=0;  RolandEx[6]=0;     YamahaEx[6]=0;  RolandEx[7]=0;     YamahaEx[7]=0;  RolandEx[8]=0;     YamahaEx[8]=0xF7;  RolandEx[9]=0;  RolandEx[10]=0xF7;}R36_Track::~R36_Track(){  if(Data!=NULL)    {      delete [] Data;      Data = NULL;    }}void R36_Track::init(ComeOn_Header *head, ComeOn_UserExclusiveDef *ex, EventQueue *q){  Header = head;  Exclusive = ex;  Noff_Queue = q;    for(int i=0;i<128;i++)    {      N_ON[i] = 0;    }    SameMeasureFlag=OFF;  TotalStep = 100 + (int)ST_Bias;    Index = 0;}int R36_Track::playaEvent(){  if(Version!=V_RCP)    {      if (Index+6 >= DataLength)	{	  printf("file broken.\n"); // cout << "file broken." << endl;	  return -1;	}    }  else    {      if (Index+4 >= DataLength)	{	  printf("file broken.\n"); // cout << "file broken." << endl;	  return -1;	}    }#ifdef SHOW_EVENT# ifdef LOOP  static int cnt=0;  cnt++;  if(cnt>LOOP) exit(1);# endif    cout << dec << "Tick:" << (u_long)TotalStep       << " Track:" << (int)Number       << "  Index:"  << Index << "\t"       << hex << (int)Data[Index] << ' '       << (int)Data[Index+1] << ' '        << (int)Data[Index+2] << ' '        << (int)Data[Index+3] << ' ';  if(Version!=V_RCP)    {      cout << (int)Data[Index+4] << ' '	   << (int)Data[Index+5] << ' ';    }  cout << '\t';#endif    int Continue=FALSE, rtn=0;  if(EVENT<0x80)    {      TotalStep += Step();      if(Step()==0) Continue=TRUE;      NoteOn();    }  else    {      switch(EVENT)	{	case 0xFD:	  MeasureEnd();	  Continue=TRUE;	  break;	  	case 0xEB: case 0xED: case 0xEE:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  MidiEvent2((EVENT&0x0f)<<4);	  break;	case 0xEA: case 0xEC:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  MidiEvent1((EVENT&0x0f)<<4);	  break;	  	case 0xF6:	  CommentProc();	  Continue=TRUE;	  break;	case 0xF8:	  LoopEnd();	  Continue=TRUE;	  break;	case 0xF9:	  LoopStart();	  Continue=TRUE;	  break;	case 0xFC:	  SameMeasure();	  Continue=TRUE;	  break;	  	case 0x98:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  TrackExclusive();	  break;	case 0x90: case 0x91: case 0x92: case 0x93:	case 0x94: case 0x95: case 0x96: case 0x97:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  UserExclusive(EVENT&0xf);	  break;	  	case 0xE6:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  MidiChChange();	  break;	case 0xE7:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  TempoChange();	  break;	  	case 0xE2: case 0xE1:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  BankPGChange(EVENT);	  break;	  	case 0xD0:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  YamahaBase();	  break;	case 0xD2:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  YamahaDevice();	  break;	case 0xD1: case 0xD3:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  YamahaPara();	  break;		  	case 0xDD:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  RolandBase();	  break;	case 0xDE:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  RolandPara();	  break;	case 0xDF:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  RolandDevice();	  break;	  	case 0xF5:	  Continue=TRUE;	  KeyChange();	  break;	  	case 0xFE:#         ifdef SHOW_EVENT	  cout << "EndOfTrack" << endl;#         endif	  return -1;	  break;	  	case 0xE5:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  KeyScan();	  break;	  	default:	  TotalStep += Step();	  if(Step()==0) Continue=TRUE;	  UnknownEvent();	  break;	}    }    if(Continue==TRUE) rtn=playaEvent();  return rtn;}void R36_Track::MeasureEnd(){    if(SameMeasureFlag==ON)    {#ifdef SHOW_EVENT      cout << "_";#endif      Index = SameMeasurePtr;      SameMeasureFlag=OFF;    }    NextRecord();#ifdef SHOW_EVENT  cout << "MeasureEnd" << endl;#endif  if(EVENT==0xFC) SameMeasure();}void R36_Track::MidiEvent1(u_char Command){  Command |= Channel;  aSequencer->midiEvent1(Port, Command, Gate());#ifdef SHOW_EVENT  cout << hex << (int)Command << " " << dec << (int)Gate() <<  endl;#endif  NextRecord();}void R36_Track::MidiEvent2(u_char Command){  Command |= Channel;  aSequencer->midiEvent2(Port, Command, Gate(), Vel());#ifdef SHOW_EVENT  cout << hex << (int)Command << " " << dec << (int)Gate() << ' ' << (int)Vel() << endl;#endif  NextRecord();}void R36_Track::BankPGChange(u_char ev){  if((ev&0xf)==0x2)    {      aSequencer->midiEvent2(Port, MIDI_CTL_CHANGE|Channel, 0x0, Vel());    }  else    {      aSequencer->midiEvent2(Port, MIDI_CTL_CHANGE|Channel, 0x20, Vel());    }  aSequencer->midiEvent1(Port, MIDI_PGM_CHANGE|Channel, Gate());  #ifdef SHOW_EVENT  cout << dec << "Bank:" << (int)Vel() << " PGCHNG:" << (int)Gate() << endl;#endif  NextRecord();}void R36_Track::MidiChChange(){  if(Gate()==0)    Mute=TRUE;  else    Mute=FALSE;  Port = (((Gate()-1)&0xf0)>>4);  Channel = (Gate()-1)&0x0f;  NextRecord();  #ifdef SHOW_EVENT  cout << dec << "MidiChChange" << (int)Channel+1  << endl;#endif}void R36_Track::TempoChange(){  aSequencer->set_tempo (60*1000000/(Header->Tempo*Gate()/64));  #ifndef SHOW_EVENT#ifdef SHOW_TEMPO  cout << dec       << "Track:" << (int)Number        << " Index:" << Index       << " MasterTempo:" << Header->Tempo <<  " Gate:" << Gate()       << " Tempo:" << (int)(Header->Tempo*Gate()/64)       << endl;#endif#else  cout << dec << " MasterTempo:" << Header->Tempo <<  " Gate:" << Gate() <<" Tempo:" << (int)(Header->Tempo*Gate()/64) << endl;#endif      NextRecord();}void R36_Track::LoopEnd(){  LoopData *Loop;  Loop = LoopStack.pop();  if(Loop!=NULL)     {      if(Loop->count==-1)	Loop->count=Step()-1;      else	Loop->count--;            if(Loop->count==0){	NextRecord();	delete Loop;      }      else	{	  Index = Loop->Index;	  SameMeasureFlag = Loop->SameMeasureFlag;	  SameMeasurePtr  = Loop->SameMeasurePtr;	  NextRecord();	  LoopStack.push(Loop);	}    }  else    NextRecord();  #ifdef SHOW_EVENT  cout << "LoopEnd"  << endl;#endif}void R36_Track::LoopStart(){  LoopData *Loop;  Loop = new LoopData;  Loop->Index = Index;  Loop->count = -1;  Loop->SameMeasureFlag = SameMeasureFlag;  Loop->SameMeasurePtr  = SameMeasurePtr;    LoopStack.push(Loop);  NextRecord();  #ifdef SHOW_EVENT  cout << "LoopStart"  << endl;#endif}void R36_Track::UserExclusive(u_char num){  int ExEndFlag=FALSE;  int sum=0, exlen=0;  u_char ex[26];#ifdef RUNNING_ST  aSequencer->clearStatus(Port);#endif  ex[exlen++]=0xF0;  for(int i=0; i< 24; i++)    {      switch(Exclusive->Data[num][i])	{	case 0x80:	  ex[exlen++]=Gate();	  sum+=Gate();	  break;	case 0x81:	  ex[exlen++]=Vel();	  sum+=Vel();	  break;	case 0x82:	  ex[exlen++]=Channel;	  sum+=Channel;	  break;	case 0x83:	  sum = 0;	  break;	case 0x84:	  ex[exlen++]= (0x0 - sum)&0x7F;	  sum += ((0x0 - sum)&0x7F);	  break;	case 0xF7:	  ExEndFlag=TRUE;	  break;	default:	  ex[exlen++]= Exclusive->Data[num][i];	  sum += (int)Exclusive->Data[num][i];	  break;	}      if(ExEndFlag==TRUE)	break;    }  ex[exlen++]=0xF7;  aSequencer->send_exclusive(Port, ex, exlen);  NextRecord();  #ifdef SHOW_EVENT  cout << "UserExclusive"  << (int)num <<  endl;#endif}void R36_Track::YamahaBase(){  YamahaEx[4]=Gate();  YamahaEx[5]=Vel();  NextRecord();#ifdef SHOW_EVENT  cout << "YamahaBase" << endl;#endif}void R36_Track::YamahaPara(){#ifdef RUNNING_ST  aSequencer->clearStatus(Port);#endif  YamahaEx[6]=Gate();  YamahaEx[7]=Vel();    aSequencer->send_exclusive(Port, YamahaEx, 9);#ifdef SHOW_EVENT  for(int i=0;i<9;i++)    {      cout << hex << (int)YamahaEx[i] << ' ';    }#endif  #ifdef SHOW_EVENT  if(EVENT==0xD1) cout << "Yamaha";  else cout << "XG";  cout << "Para" << endl;#endif  NextRecord();}void R36_Track::YamahaDevice(){  YamahaEx[2]=Gate();  YamahaEx[3]=Vel();  NextRecord();#ifdef SHOW_EVENT  cout << "YamahaDevice" << endl;#endif}void R36_Track::RolandBase(){  RolandEx[5]=Gate();  RolandEx[6]=Vel();  NextRecord();#ifdef SHOW_EVENT  cout << "RolBase" << endl;#endif}void R36_Track::RolandPara(){  int sum=0, i;#ifdef RUNNING_ST  aSequencer->clearStatus(Port);#endif  RolandEx[7]=Gate();  RolandEx[8]=Vel();  for(i=5;i<9;i++)    sum+=RolandEx[i];    sum = ((0x0 - sum)&0x7F);  RolandEx[9]=(u_char)sum;    aSequencer->send_exclusive (Port, RolandEx, 11);#ifdef SHOW_EVENT  for(i=0;i<11;i++)    {      cout << hex << (int)RolandEx[i] << ' ';    }#endif  NextRecord();  #ifdef SHOW_EVENT  cout << "RolPara" << endl;#endif}void R36_Track::RolandDevice(){  RolandEx[2]=Gate();  RolandEx[3]=Vel();  NextRecord();#ifdef SHOW_EVENT  cout << "RolDev" << endl;#endif}void R36_Track::KeyScan(){  NextRecord();#ifdef SHOW_EVENT  cout << "KeyScan" << endl;#endif}void R36_Track::KeyChange(){  NextRecord();#ifdef SHOW_EVENT  cout << "KeyChange" << endl;#endif}	  void R36_Track::UnknownEvent(){  NextRecord();#ifdef SHOW_EVENT  cout << "UnknownEvent!" << endl;#endif}void R36_Track::AllNoteOff(){  if(Mute==TRUE || Mode==MUTE) return;  aSequencer->midiEvent2(Port, MIDI_CTL_CHANGE|Channel, 64, 0);  aSequencer->midiEvent2(Port, MIDI_CTL_CHANGE|Channel, 66, 0);  aSequencer->midiEvent2(Port, MIDI_CTL_CHANGE|Channel, 123, 0);}inline void R36_Track::NextRecord(){  Index += 4;}inline int R36_Track::Step(){  return (int)Data[Index+1];}inline int R36_Track::Gate(){  return (int)Data[Index+2];} inline int R36_Track::Vel(){  return (int)Data[Index+3];} void R36_Track::NoteOn(){  u_char cmd, note;  Event *Noff_Event;  if(Mode!=MUTE && Gate()!=0 && Vel()!=0 && Mute!=TRUE)    {      cmd = Channel | 0x90;            if(Key_Bias & KEY_OFF)	{	  note = EVENT;	}      else	{	  note=(EVENT+Header->PlayBIAS+Key_Bias)&0x7f;	}      if(N_ON[note]==0)	{	  aSequencer->midiEvent2(Port, cmd, (u_char)note, Vel());	}                  N_ON[note]++;      Noff_Event = new Event;      Noff_Event->Track = Number-1;      Noff_Event->Time = TotalStep+(u_long)Gate()-Step();      Noff_Event->Type = EV_NOTE_OFF;            Noff_Event->Channel = Channel;      Noff_Event->Note = note;      Noff_Event->Port = Port;            Noff_Queue->store(Noff_Event);      #     ifdef SHOW_EVENT      cout << hex << (int)cmd << " " << dec << (int)note << ' ' << (int)Vel()	   <<" "  << (int)N_ON[note]	   << " NoteOff:"<< Noff_Event->Time << endl;#     endif		    }# ifdef SHOW_EVENT  else    cout << "rest" << endl;# endif    NextRecord();}void R36_Track::TrackExclusive(){  int ExEndFlag=FALSE;  int sum=0, exlen=0;  u_char ex[512], ExData[2];  #ifdef RUNNING_ST  aSequencer->clearStatus(Port);#endif  ex[exlen++] = 0xF0;# ifdef SHOW_EVENT  cout << hex  << " F0 ";# endif    int i, len;  len=4;  while(1)    {      ExData[0]=Data[Index+len+2];      ExData[1]=Data[Index+len+3];      for(i=0;i<2;i++)	{	  if(ExEndFlag==FALSE)	    switch(ExData[i])	      {	      case 0x80:		ex[exlen++] = Gate();		sum+=(int)Gate();#ifdef SHOW_EVENT		cout << (int)Gate() << ' ';#endif		break;	      case 0x81:		ex[exlen++] = Vel();		sum+=(int)Vel();#ifdef SHOW_EVENT		cout << (int)Vel() << ' ';#endif		break;	      case 0x82:		ex[exlen++] = Channel;		sum+=(int)Channel;#ifdef SHOW_EVENT		cout << (int)Channel << ' ';#endif		break;	      case 0x83:		sum = 0;		break;	      case 0x84:		ex[exlen++] = (0x0 - sum)&0x7F;#ifdef SHOW_EVENT		cout << (int)((0x0 - sum)&0x7F) << ' ';#endif		sum += ((0x0 - sum)&0x7F);		break;	      case 0xF7:		ExEndFlag=TRUE;		break;	      default:		ex[exlen++] = ExData[i];#ifdef SHOW_EVENT		cout << (int)ExData[i] << ' ';#endif		sum += ExData[i];		break;	      }	}      if(Data[Index+len+4]!=0xF7)	{	  break;	}      len+=4;    }  ex[exlen++] = 0xF7;  aSequencer->send_exclusive (Port, ex, exlen);  Index += (len+4);  # ifdef SHOW_EVENT  cout << "F7 ChExclusive"  << endl;# endif}void R36_Track::CommentProc(){  int len=4, i=0, j;  char str[256];  while(1)    {      if(Data[Index+len]!=0xF7) break;      for (j=2;j<=3;j++)	str[i++]=Data[Index+len+j];      len+=4;    }  aSequencer->metaEvent (1, i, str);  Index += len;  # ifdef SHOW_EVENT  cout << "Comment:" << str << endl;# endif}void R36_Track::SameMeasure(){  static u_long idx;  if(SameMeasureFlag==ON)    {      Index = SameMeasurePtr;      SameMeasureFlag=OFF;      NextRecord();    }  else    {      SameMeasurePtr=Index;      SameMeasureFlag=ON;      do	{#         ifdef SHOW_EVENT	  cout << "index:" << dec << (long)((Gate()&0xfc)|(Vel()<<8))-44L	       << " meas:" << (long)(Step()+((Gate()&3)<<8)) << hex << " ";#         endif	  idx = (u_long)((Gate()&0xfc)|(Vel()<<8)) - 44L;	  if (idx<Index) Index=idx;	  else	    {	      SameMeasureFlag=OFF;	      Index=SameMeasurePtr;	      NextRecord();	      TotalStep += aSequencer->show_timebase ()		* aSequencer->show_timebase ()		* Header->TimeSignature[0]		* 4 / Header->TimeSignature[1];	    }	} while(EVENT==0xFC && SameMeasureFlag==ON);    }  #ifdef SHOW_EVENT  cout << "SameMeasure"  << endl;#endif  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -