main.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "MIDIEvent.hxx"
00023 #include "MIDITrack.hxx"
00024 #include "MIDISong.hxx"
00025 #include "MIDIReader.hxx"
00026 #include "MIDISongPlayer.hxx"
00027
00028
00029 using namespace MIDI;
00030
00031 #include "MIDITempo.hxx"
00032
00033 #include <math.h>
00034 #include <stdio.h>
00035
00036 class SimpleSynth
00037 {
00038
00039 private:
00040 struct note
00041 {
00042 int chn;
00043 int key;
00044 int vel;
00045 float phase;
00046 float amp;
00047 float env;
00048 };
00049
00050 note notes[256];
00051 int nnotes;
00052
00053 float dphase[128];
00054
00055 FILE* file;
00056
00057 int findnote(int chn,int key)
00058
00059 {
00060 int i = 0;
00061 while (i<nnotes)
00062 {
00063 if (notes[i].chn==chn && notes[i].key==key && notes[i].vel!=0) return i;
00064 i++;
00065 }
00066 return i;
00067 }
00068
00069 public:
00070 SimpleSynth()
00071 {
00072 nnotes = 0;
00073 for (int i=0;i<128;i++)
00074 {
00075 float f = pow( 2. , ( float(i) - 69. ) / 12. ) * 440.;
00076 dphase[i] = (M_PI*2.)*f / 44100.;
00077 }
00078 file = fopen("output.raw","wb");
00079 }
00080
00081 ~SimpleSynth()
00082 {
00083 fclose(file);
00084 }
00085
00086 void setnote(int chn,int key,int vel)
00087 {
00088 if (vel==0)
00089 {
00090
00091 int i = findnote(chn,key);
00092 if (i!=nnotes) {
00093 notes[i].vel = 0;
00094 }
00095 return;
00096 }
00097
00098 notes[nnotes].chn = chn;
00099 notes[nnotes].key = key;
00100 notes[nnotes].vel = vel;
00101 notes[nnotes].phase = 0;
00102 notes[nnotes].env = 0;
00103 notes[nnotes].amp = float(vel)/128.;
00104 nnotes++;
00105 }
00106
00107 void synthesize(void)
00108 {
00109 short buf[44];
00110 for (int j=0;j<44;j++)
00111 {
00112 buf[j] = 0;
00113 float out = 0;
00114 int i;
00115 for (i=0;i<nnotes;i++)
00116 {
00117 if (notes[i].vel)
00118 {
00119 if (notes[i].env<1.) notes[i].env+=0.002;
00120 }else{
00121 if (notes[i].env>0.) notes[i].env-=0.001;
00122 }
00123
00124
00125 out += sin(notes[i].phase+sin(notes[i].phase)*2.)
00126 *notes[i].env*notes[i].amp;
00127
00128 notes[i].phase += dphase[notes[i].key];
00129 if (notes[i].phase>2.*M_PI) notes[i].phase -= 2.*M_PI;
00130 }
00131
00132
00133 for (i=0;i<nnotes;)
00134 {
00135 if (notes[i].vel==0 && notes[i].env<0.001)
00136 {
00137 nnotes--;
00138 notes[i] = notes[nnotes];
00139 }else{
00140 i++;
00141 }
00142 }
00143
00144 buf[j] = (short)(out*2000.);
00145 }
00146 fwrite(buf,2,44,file);
00147 }
00148 };
00149
00150 int main(int argc,char** argv)
00151 {
00152
00153 Reader r(argc>1 ? argv[1] : "test.mid");
00154 Song s;
00155 r.Read(s);
00156
00157 Tempo t(&s);
00158
00159 #ifdef DOPRINT
00160 fprintf(stderr,"song has %d tracks\n",s.Tracks());
00161 #endif
00162
00163 int trackId;
00164 Event ev;
00165
00166 SongPlayer sp(&s);
00167
00168 int last = 0;
00169
00170 SimpleSynth synth;
00171
00172 while (sp.GetEvent(ev,trackId))
00173 {
00174 #ifdef DOPRINT
00175 fprintf(stderr,"%d %d %d %02x %02x %02x\n",
00176 ev.mTicks,
00177 t.TicksToTime(ev.mTicks),
00178 trackId,
00179 ev.mMessage[0],
00180 ev.mMessage[1],
00181 ev.mMessage[2]);
00182 #endif
00183 if ((ev[0] & 0xF0)==0x90 || (ev[0] & 0xF0)==0x80)
00184 {
00185 int now = t.TicksToTime(ev.GetTicks());
00186 while (last<now)
00187 {
00188 synth.synthesize();
00189 last++;
00190 }
00191 {
00192 synth.setnote(ev[0]&0x0F, ev[1], (ev[0] & 0xF0)==0x90 ? ev[2] : 0);
00193 }
00194 }
00195 }
00196
00197 for (int k=0;k<1000;k++) synth.synthesize();
00198
00199 return 0;
00200 }
00201