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;
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
00133