CLAM-Development  1.4.0
MIDIFileReader.cxx
Go to the documentation of this file.
1 #include "MIDITrack.hxx"
2 #include "MIDISong.hxx"
3 #include "MIDIReader.hxx"
4 #include "MIDITempo.hxx"
5 #include "MIDIFileReader.hxx"
6 
7 namespace CLAM
8 {
10  : mOutput("MIDISong Output",this)
11  {
12  MIDIFileIOConfig cfg;
13  Configure(cfg);
14  }
15 
17  : mOutput("MIDISong Output",this)
18  {
19  Configure(cfg);
20  }
21 
23  {
24  }
25 
27  {
28  bool result = Do(mOutput.GetData());
29  mOutput.Produce();
30  return result;
31  }
32 
34  {
35  MIDI::Reader r(mConfig.GetFileName().c_str());
36  MIDI::Song s;
37  r.Read(s);
38  MIDI::Tempo t(&s);
39  static int nbytesPerChnMsg[7] = { 3,3,3,3,2,3,3 };
40  bool onset=true;
41  int nTracks = s.Tracks();
42  for(int i=0; i < nTracks; i++)
43  {
44  MIDI::Track* track = s.GetTrack(i);
45  MIDI::Track::EventIterator it = track->Begin();
46  MIDITrack midiTrack;
47  for(;it != track->End(); it++)
48  {
49  const MIDI::Event &ev = **it;
50  int type = ((ev[0]&0xF0)>>4)-8;
51  if(type==7) continue;
52  if(((ev[0]&0xF0)==0x90) || ((ev[0]&0xF0)==0x80))
53  {
54  onset = ((ev[0]&0xF0)==0x90) ? (ev[2] > 0) : false; // velocity > 0 -> onset
55  if(onset)
56  {
57  midiTrack.GetChannels().AddElem((int)(ev[0]&0x0F));
58  MIDINote note;
59  note.GetTime().SetBegin(TData(t.TicksToTime(ev.GetTicks())/1000.0));
60  note.GetTime().SetEnd(TData(-1.0));
61  note.SetKey((int)ev[1]);
62  note.SetVelocity((int)ev[2]);
63  midiTrack.GetTrackMelody().GetNoteArray().AddElem(note);
64  midiTrack.GetTrackMelody().GetNumberOfNotes()++;
65  }
66  else
67  {
68  for(int n=0; n < midiTrack.GetTrackMelody().GetNumberOfNotes(); n++)
69  {
70  if((midiTrack.GetTrackMelody().GetNoteArray()[n].GetKey() == (int)(ev[1])) &&
71  (midiTrack.GetTrackMelody().GetNoteArray()[n].GetTime().GetEnd()==TData(-1.0)))
72  {
73  midiTrack.GetTrackMelody().GetNoteArray()[n].GetTime().SetEnd(TData(t.TicksToTime(ev.GetTicks())/1000.0));
74  break;
75  }
76  }
77  }
78  }
79  else
80  {
81  MIDIEvent e;
82  e.SetName(GetEventName((ev[0]&0xF0)));
83  e.SetTime((TTime)(t.TicksToTime(ev.GetTicks())/1000.0));
84  int len = nbytesPerChnMsg[type];
85  for(int k=0; k < len; k++)
86  {
87  e.GetMessage().AddElem(ev[k]);
88  }
89  midiTrack.GetEventInfo().AddElem(e);
90  }
91  }
92  if(midiTrack.GetTrackMelody().GetNumberOfNotes() > 0)
93  {
94  out.GetTracks().AddElem(midiTrack);
95  out.GetNumberOfTracks()++;
96  }
97  }
98  return true;
99  }
100 
102  {
103  CopyAsConcreteConfig(mConfig, c);
104  return true;
105  }
106 
107  std::string MIDIFileReader::GetEventName(TMIDIByte b)
108  {
109  switch(b)
110  {
111  case 0xA0:
112  return "PolyAftertouch";
113  break;
114  case 0xB0:
115  return "ControlChange";
116  break;
117  case 0xC0:
118  return "ProgramChange";
119  break;
120  case 0xD0:
121  return "ChnAftertouch";
122  case 0xE0:
123  return "PitchBend";
124  break;
125  default:
126  return "Unknow";
127  }
128  }
129 
130 }
131 
132 // END
133