CFugue
MidiEventManager.h
1 /*
2  This is part of CFugue, a C++ Runtime for MIDI Score Programming
3  Copyright (C) 2009 Gopalakrishna Palem
4 
5  For links to further information, or to contact the author,
6  see <http://cfugue.sourceforge.net/>.
7 
8  $LastChangedDate: 2013-12-31 19:21:29 +0530 (Tue, 31 Dec 2013) $
9  $Rev: 201 $
10  $LastChangedBy: krishnapg $
11 */
12 
13 #ifndef __MIDIEVENTMANAGER_H__74C2A3BA_DFCF_4048_BC1D_20E9E04E809A__
14 #define __MIDIEVENTMANAGER_H__74C2A3BA_DFCF_4048_BC1D_20E9E04E809A__
15 
16 #include "jdkmidi/sequencer.h"
17 
18 namespace CFugue
19 {
20  /// <Summary> Takes care of MIDI Events, Tracks and Sequencing </Summary>
22  {
23  protected:
24  unsigned short m_nCurrentTrack;
25  unsigned short m_nCurrentLayer;
26 
27  enum { MAX_CHANNELS = 16, MAX_LAYERS = 16 };
28 
29  unsigned short m_CurrentLayer[MAX_CHANNELS];
30  unsigned long m_Time[MAX_CHANNELS][MAX_LAYERS];
31 
32  jdkmidi::MIDIMultiTrack m_Tracks;
33 
34  jdkmidi::MIDISequencer m_Sequencer;
35 
36  public:
37 
38  inline MIDIEventManager(void) : m_Sequencer(&m_Tracks)
39  {
40  Clear();
41  m_Tracks.SetClksPerBeat(24); //TODO: Correct this
42  }
43 
44  inline ~MIDIEventManager(void)
45  {
46  }
47 
48  /// <Summary> Returns the Sequencer holding the collection of tracks </Summary>
49  inline jdkmidi::MIDISequencer* GetSequencer() { return &m_Sequencer; }
50 
51  /// <Summary> Returns the Multitrack object </Summary>
52  inline jdkmidi::MIDIMultiTrack* GetTracks() { return &m_Tracks; }
53 
54  /// <Summary>
55  /// Clears all the Events stored in the tracks and Resets the Track Timers
56  /// </Summary>
57  inline void Clear()
58  {
59  memset(m_CurrentLayer, 0, sizeof(m_CurrentLayer));
60  memset(m_Time, 0, sizeof(m_Time));
61  m_nCurrentTrack = 0;
62  m_nCurrentLayer = 0;
63  m_Tracks.Clear();
64  m_Sequencer.ResetAllTracks();
65  }
66 
67  /// <Summary>Sets the current Track/Channel to which new Events will be added
68  /// </Summary>
69  inline void SetCurrentTrack(unsigned short nTrack)
70  {
71  m_nCurrentTrack = nTrack;
72  }
73 
74  inline void SetCurrentLayer(unsigned short nLayer)
75  {
76  m_CurrentLayer[m_nCurrentTrack] = nLayer;
77  }
78 
79  /// <Summary>
80  /// Returns the Timer value for the current track (in Pulses Per Quarter)
81  /// </Summary>
82  inline unsigned long GetTrackTime() const
83  {
84  return m_Time[m_nCurrentTrack][m_CurrentLayer[m_nCurrentTrack]];
85  }
86 
87  /// <Summary>
88  /// Sets the current Track's time to the supplied new time (specified in Pulses Per Quarter)
89  /// </Summary>
90  inline void SetTrackTime(unsigned long lNewTime)
91  {
92  m_Time[m_nCurrentTrack][m_CurrentLayer[m_nCurrentTrack]] = lNewTime;
93  }
94 
95  /// <Summary>
96  /// Advances the timer for the current Track by the duration (specified in Pulses Per Quarter)
97  /// </Summary>
98  inline void AdvanceTrackTime(unsigned long lDuration)
99  {
100  m_Time[m_nCurrentTrack][m_CurrentLayer[m_nCurrentTrack]] += lDuration;
101  }
102 
103  /// <Summary>
104  /// Adds a Channel Pressure event to the current track
105  /// @param uPressure the pressure value that should be applied to the notes on the current channel
106  /// </Summary>
107  inline void AddChannelPressureEvent(unsigned char uPressure)
108  {
109  jdkmidi::MIDITimedBigMessage msg;
110  msg.SetTime(GetTrackTime());
111  msg.SetChannelPressure((unsigned char)m_nCurrentTrack, uPressure);
112  m_Tracks.GetTrack(m_nCurrentTrack)->PutEvent(msg);
113  }
114 
115  /// <Summary>
116  /// Adds a MIDI controller event to the current track.
117  /// @param uControlIndex the controller
118  /// @param uControlValue value for the controller
119  /// </Summary>
120  inline void AddControllerEvent(unsigned char uControlIndex, unsigned char uControlValue)
121  {
122  jdkmidi::MIDITimedBigMessage msg;
123  msg.SetTime(GetTrackTime());
124  msg.SetControlChange((unsigned char)m_nCurrentTrack, uControlIndex, uControlValue);
125  m_Tracks.GetTrack(m_nCurrentTrack)->PutEvent(msg);
126  }
127 
128  /// <Summary>
129  /// Adds a short Key Singature event to the current track.
130  /// @param nKeySig a value in the range [-7, 7]
131  /// @param MajMin indicates if this is Major (0) scale or Min (1) scale
132  /// </Summary>
133  inline void AddKeySignatureEvent(signed char nKeySig, unsigned char MajMin)
134  {
135  jdkmidi::MIDITimedBigMessage msg;
136  msg.SetTime(GetTrackTime());
137  msg.SetKeySig(nKeySig, MajMin);
138  m_Tracks.GetTrack(m_nCurrentTrack)->PutEvent(msg);
139  }
140 
141  /// <Summary>
142  /// Adds a PitchBend event to the current track.
143  /// @param uLowByte the low byte value of the pitch bend
144  /// @param uHighByte the high byte value of the pitch bend
145  /// </Summary>
146  inline void AddPitchBendEvent(unsigned char uLowByte, unsigned char uHighByte)
147  {
148  jdkmidi::MIDITimedBigMessage msg;
149  msg.SetTime(GetTrackTime());
150  msg.SetPitchBend((unsigned char)m_nCurrentTrack, uLowByte, uHighByte);
151  m_Tracks.GetTrack(m_nCurrentTrack)->PutEvent(msg);
152  }
153 
154  /// <Summary>
155  /// Adds a key pressure event to the current track.
156  /// @param uKey the note the pressure should be applied to
157  /// @param uPressure the Pressure value that should be applied to the key
158  /// </Summary>
159  inline void AddPolyphonicPressureEvent(unsigned char uKey, unsigned char uPressure)
160  {
161  jdkmidi::MIDITimedBigMessage msg;
162  msg.SetTime(GetTrackTime());
163  msg.SetPolyPressure((unsigned char)m_nCurrentTrack, uKey, uPressure);
164  m_Tracks.GetTrack(m_nCurrentTrack)->PutEvent(msg);
165  }
166 
167  /// <Summary>
168  /// Adds a short ProgramChange message event to the current track.
169  /// @param nInstrumentID indicates the selected instrument that should be used for playing further notes;
170  /// </Summary>
171  inline void AddProgramChangeEvent(unsigned char nInstrumentID)
172  {
173  jdkmidi::MIDITimedBigMessage msg;
174  msg.SetTime(GetTrackTime());
175  msg.SetProgramChange((unsigned char)m_nCurrentTrack, nInstrumentID);
176  m_Tracks.GetTrack(m_nCurrentTrack)->PutEvent(msg);
177  }
178 
179  /// <Summary>
180  /// Adds a short Tempo message event to the current track.
181  /// @param nTempo indicates the selected Tempo value in BPM that should be used for playing further notes;
182  /// </Summary>
183  inline void AddTempoEvent(unsigned short nTempo)
184  {
185  jdkmidi::MIDITimedBigMessage msg;
186  msg.SetTime(GetTrackTime());
187  msg.SetTempo32(nTempo * 32); // Line 415 of jdkmidi_sequencer.cpp indicates 1/32 th part. So we compensate it here with *32
188  m_Tracks.GetTrack(m_nCurrentTrack)->PutEvent(msg);
189  }
190 
191  /// <Summary>
192  /// Adds a short NoteOn message event to the current track using attack/decay velocities. Automatically
193  /// adds a NoteOff message using the specified duration. These NoteOn and NoteOff can be suppressed (useful
194  /// when notes are tied).
195  /// @param noteValue the MIDI note value. For example, Mid-C = 60
196  /// @param attackVel the attack Velocity of the note
197  /// @param decayVel the decay Velocity of the note
198  /// @param lNoteDuration duration of the MIDI note
199  /// @param addNoteOn indicates if NoteOn event should be created automatically. For the end of a tied note, this should be false; otherwise true;
200  /// @param addNoteOff indicates if NoteOff event should be created automatically. For the start of a tied note, this should be false; otherwise true;
201  /// </Summary>
202  inline void AddNoteEvent(int noteValue, int attackVel, int decayVel, long lNoteDuration, bool addNoteOn, bool addNoteOff)
203  {
204  if(addNoteOn)
205  {
206  jdkmidi::MIDITimedBigMessage msg;
207 
208  msg.SetTime(GetTrackTime());
209 
210  msg.SetNoteOn((unsigned char)m_nCurrentTrack, (unsigned char) noteValue, (unsigned char) attackVel);
211 
212  m_Tracks.GetTrack(m_nCurrentTrack)->PutEvent(msg);
213  }
214 
215  AdvanceTrackTime(lNoteDuration);
216 
217  if(addNoteOff)
218  {
219  jdkmidi::MIDITimedBigMessage msg;
220 
221  msg.SetTime(GetTrackTime());
222 
223  msg.SetNoteOff((unsigned char)m_nCurrentTrack, (unsigned char)noteValue, (unsigned char)decayVel);
224 
225  m_Tracks.GetTrack(m_nCurrentTrack)->PutEvent(msg);
226  }
227  }
228  };
229 
230 } // namespace CFugue
231 
232 #endif // __MIDIEVENTMANAGER_H__74C2A3BA_DFCF_4048_BC1D_20E9E04E809A__
void AddChannelPressureEvent(unsigned char uPressure)
unsigned long GetTrackTime() const
jdkmidi::MIDISequencer * GetSequencer()
Returns the Sequencer holding the collection of tracks
void AddTempoEvent(unsigned short nTempo)
void AdvanceTrackTime(unsigned long lDuration)
void AddProgramChangeEvent(unsigned char nInstrumentID)
void SetCurrentTrack(unsigned short nTrack)
void SetTrackTime(unsigned long lNewTime)
Takes care of MIDI Events, Tracks and Sequencing
void AddPolyphonicPressureEvent(unsigned char uKey, unsigned char uPressure)
void AddControllerEvent(unsigned char uControlIndex, unsigned char uControlValue)
jdkmidi::MIDIMultiTrack * GetTracks()
Returns the Multitrack object
void AddPitchBendEvent(unsigned char uLowByte, unsigned char uHighByte)
void AddNoteEvent(int noteValue, int attackVel, int decayVel, long lNoteDuration, bool addNoteOn, bool addNoteOff)
void AddKeySignatureEvent(signed char nKeySig, unsigned char MajMin)

CFugue, the C++ Music Programming Library © Copyright 2009 Cenacle Research India Private Limited Gopalakrishna Palem