MIDIFileReader.cxx

Go to the documentation of this file.
00001 #include "MIDITrack.hxx"
00002 #include "MIDISong.hxx"
00003 #include "MIDIReader.hxx"
00004 #include "MIDITempo.hxx"
00005 #include "MIDIFileReader.hxx"
00006 
00007 namespace CLAM
00008 {
00009         MIDIFileReader::MIDIFileReader()
00010                 : mOutput("MIDISong Output",this)
00011         {
00012                 MIDIFileIOConfig cfg;
00013                 Configure(cfg);
00014         }
00015 
00016         MIDIFileReader::MIDIFileReader(const MIDIFileIOConfig& cfg)
00017                 : mOutput("MIDISong Output",this)
00018         {
00019                 Configure(cfg);
00020         }
00021 
00022         MIDIFileReader::~MIDIFileReader()
00023         {
00024         }
00025 
00026         bool MIDIFileReader::Do()
00027         {
00028                 bool result = Do(mOutput.GetData());
00029                 mOutput.Produce();
00030                 return result;
00031         }
00032 
00033         bool MIDIFileReader::Do(MIDISong& out)
00034         {
00035                 MIDI::Reader r(mConfig.GetFileName().c_str());
00036                 MIDI::Song s;
00037                 r.Read(s);
00038                 MIDI::Tempo t(&s);
00039                 static int nbytesPerChnMsg[7] = { 3,3,3,3,2,3,3 };
00040                 bool onset=true;
00041                 int nTracks = s.Tracks();
00042                 for(int i=0; i < nTracks; i++)
00043                 {
00044                         MIDI::Track* track = s.GetTrack(i);
00045                         MIDI::Track::EventIterator it = track->Begin();
00046                         MIDITrack  midiTrack;
00047                         for(;it != track->End(); it++)
00048                         {
00049                                 const MIDI::Event &ev = **it;
00050                                 int type = ((ev[0]&0xF0)>>4)-8;
00051                                 if(type==7) continue;
00052                                 if(((ev[0]&0xF0)==0x90) || ((ev[0]&0xF0)==0x80))
00053                                 {
00054                                         onset = ((ev[0]&0xF0)==0x90) ? (ev[2] > 0) : false; // velocity > 0 -> onset
00055                                         if(onset)
00056                                         {
00057                                                 midiTrack.GetChannels().AddElem((int)(ev[0]&0x0F));
00058                                                 MIDINote note;
00059                                                 note.GetTime().SetBegin(TData(t.TicksToTime(ev.GetTicks())/1000.0));
00060                                                 note.GetTime().SetEnd(TData(-1.0));
00061                                                 note.SetKey((int)ev[1]);
00062                                                 note.SetVelocity((int)ev[2]);
00063                                                 midiTrack.GetTrackMelody().GetNoteArray().AddElem(note);
00064                                                 midiTrack.GetTrackMelody().GetNumberOfNotes()++;
00065                                         }
00066                                         else
00067                                         {
00068                                                 for(int n=0; n < midiTrack.GetTrackMelody().GetNumberOfNotes(); n++)
00069                                                 {
00070                                                         if((midiTrack.GetTrackMelody().GetNoteArray()[n].GetKey() == (int)(ev[1])) && 
00071                                                            (midiTrack.GetTrackMelody().GetNoteArray()[n].GetTime().GetEnd()==TData(-1.0)))
00072                                                         {
00073                                                                 midiTrack.GetTrackMelody().GetNoteArray()[n].GetTime().SetEnd(TData(t.TicksToTime(ev.GetTicks())/1000.0));
00074                                                                 break;
00075                                                         }
00076                                                 }
00077                                         }
00078                                 }
00079                                 else
00080                                 {
00081                                         MIDIEvent e;
00082                                         e.SetName(GetEventName((ev[0]&0xF0)));
00083                                         e.SetTime((TTime)(t.TicksToTime(ev.GetTicks())/1000.0));
00084                                         int len = nbytesPerChnMsg[type];
00085                                         for(int k=0; k < len; k++)
00086                                         {
00087                                                 e.GetMessage().AddElem(ev[k]);
00088                                         }
00089                                         midiTrack.GetEventInfo().AddElem(e);
00090                                 }                       
00091                         }                       
00092                         if(midiTrack.GetTrackMelody().GetNumberOfNotes() > 0)
00093                         {
00094                                 out.GetTracks().AddElem(midiTrack);
00095                                 out.GetNumberOfTracks()++;
00096                         }
00097                 }
00098                 return true;
00099         }
00100 
00101         bool MIDIFileReader::ConcreteConfigure(const ProcessingConfig& c)
00102         {
00103                 CopyAsConcreteConfig(mConfig, c);
00104                 return true;
00105         }
00106 
00107         std::string MIDIFileReader::GetEventName(TMIDIByte b)
00108         {
00109                 switch(b)
00110                 {
00111                         case 0xA0:
00112                                 return "PolyAftertouch";
00113                                 break;
00114                         case 0xB0:
00115                                 return "ControlChange";
00116                                 break;
00117                         case 0xC0:
00118                                 return "ProgramChange";
00119                                 break;
00120                         case 0xD0:
00121                                 return "ChnAftertouch";
00122                         case 0xE0:
00123                                 return "PitchBend";
00124                                 break;
00125                         default:
00126                                 return "Unknow";
00127                 }
00128         }
00129            
00130 }
00131 
00132 // END
00133 
Generated by  doxygen 1.6.3