NiCMidi 1.1.0
A MIDI library derived from J.D.Koftinoff jdksmidi
sequencer.h
Go to the documentation of this file.
1/*
2 * NiCMidi - A C++ Class Library for MIDI
3 *
4 * Copyright (C) 2004 J.D. Koftinoff Software, Ltd.
5 * www.jdkoftinoff.com jeffk@jdkoftinoff.com
6 * Copyright (C) 2021, 2022 Nicola Cassetta
7 * https://github.com/ncassetta/NiCMidi
8 *
9 * This file is part of NiCMidi.
10 *
11 * NiCMidi is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as
13 * published by the Free Software Foundation, either version 3 of
14 * the License, or (at your option) any later version.
15 *
16 * NiCMidi is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with NiCMidi. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25
28
29#ifndef _NICMIDI_SEQUENCER_H
30#define _NICMIDI_SEQUENCER_H
31
32#include "multitrack.h"
33#include "matrix.h"
34#include "processor.h"
35#include "notifier.h"
36#include "tick.h"
37
38#include <string>
39#include <mutex>
40#include <atomic>
41
42
43class MIDISequencer; // forward declaration
44
45
46
56 public:
63
64 // Copy constructor and assignment operator generated by the compiler
65 // MIDISequencerTrackState(const MIDISequencerTrackState &s);
66
68 virtual void Reset();
69
70 int16_t program;
71 int16_t bender_value;
72 std::string track_name;
78};
79
80
95// Doesn't inherit from MIDISequencerGUINotifier because notifier and sequencer must be independent objects
96// (notifier is used also by the MIDIManager)
97// All is public: used by various classes
98 public:
112
116 void Reset();
125 void Notify(int group, int item = 0) const;
128 void NotifyTrack(int item) const;
134
135
136
140
143 unsigned int cur_beat;
144 unsigned int cur_measure;
146 unsigned int number_of_beats;
148
149 float tempobpm;
150 unsigned int tempo_scale;
151 unsigned char timesig_numerator;
152 unsigned char timesig_denominator;
153 signed char keysig_sharpflat;
154 unsigned char keysig_mode;
155 std::string marker_text;
156 std::vector<MIDISequencerTrackState*>
164
165 // TODO: change the name of this variable for example count_in_stop
166 unsigned char playing_status;
167 static int metronome_mode;
168};
169
170
194 public:
203 virtual ~MIDISequencer();
211 virtual void Reset();
212
213 //virtual bool IsPlaying() const { return (MIDITickComponent::IsPlaying() || autostop.load()); }
217 float GetCurrentTimeMs() const;
219 unsigned int GetCurrentMeasure() const
220 { return state.cur_measure; }
222 unsigned int GetCurrentBeat() const { return state.cur_beat; }
225 { return state.cur_clock - state.last_beat_time; }
229 unsigned int GetClksPerBeat() const { return state.multitrack->GetClksPerBeat(); }
230
232 MIDIMultiTrack* GetMultiTrack() { return state.multitrack; }
234 const MIDIMultiTrack* GetMultiTrack() const { return state.multitrack; }
236 MIDITrack* GetTrack(unsigned int trk_num)
237 { return state.multitrack->IsValidTrackNumber(trk_num) ?
238 state.multitrack->GetTrack(trk_num) : 0; }
240 unsigned int GetNumTracks() const { return state.multitrack->GetNumTracks(); }
242 unsigned int GetTempoScale() const { return state.tempo_scale; }
245 { return state.tempobpm; }
247 float GetTempoWithScale() const
248 { return state.tempobpm * state.tempo_scale * 0.01; }
250 bool GetRepeatPlay() const { return repeat_play_mode; }
252 unsigned int GetRepeatPlayStart() const
253 { return repeat_start_meas; }
255 unsigned int GetRepeatPlayEnd() const
256 { return repeat_end_meas; }
258 bool GetCountInEnable() const { return state.playing_status & COUNT_IN_ENABLED; }
260 bool GetCountInPending() const { return state.playing_status & COUNT_IN_PENDING; }
261
265 bool GetTimeShiftMode() const { return time_shift_mode; }
268 MIDISequencerState* GetState() { return &state; }
271 const MIDISequencerState* GetState() const { return &state; }
273 bool GetPlayMode() { return play_mode; }
277 { return state.track_states[trk_num]; }
280 const MIDISequencerTrackState* GetTrackState(unsigned int trk_num) const
281 { return state.track_states[trk_num]; }
284 unsigned int GetTrackOutPort(unsigned int trk_num) const
285 { return state.multitrack->GetTrack(trk_num)->GetOutPort(); }
290 MIDIProcessor* GetTrackProcessor(unsigned int trk_num)
291 { return track_processors[trk_num]; }
296 const MIDIProcessor* GetTrackProcessor(unsigned int trk_num) const
297 { return track_processors[trk_num]; }
301 int GetTrackTimeShift(unsigned int trk_num) const
302 { return state.multitrack->GetTrack(trk_num)->GetTimeShift(); }
316 virtual bool SetRepeatPlay(int on_off, int start_meas = -1, int end_meas = -1);
318 virtual void SetCountIn(bool on_off);
322 virtual bool SetTempoScale(unsigned int scale);
328 virtual void SetTimeShiftMode(bool f);
335 virtual void SetState(MIDISequencerState* s);
343 virtual void SetPlayMode(int mode);
349 virtual bool SetTrackOutPort(unsigned int trk_num, unsigned int port);
356 virtual bool SetTrackProcessor(unsigned int trk_num, MIDIProcessor* p);
365 virtual bool SetTrackTimeShift(unsigned int trk_num, int offset);
366
378 virtual bool InsertTrack(int trk_num = -1);
387 virtual bool DeleteTrack(int trk_num = -1);
395 virtual bool MoveTrack(int from, int to);
399 virtual void GoToZero();
406 virtual bool GoToTime (MIDIClockTime time_clk);
409 virtual bool GoToTimeMs (float time_ms);
414 virtual bool GoToMeasure (unsigned int measure, unsigned int beat = 0);
426 virtual bool GetNextEvent (int *trk_num, MIDITimedMessage *msg);
434 virtual bool GetNextEventTime (MIDIClockTime *time_clk);
436 virtual bool GetNextEventTimeMs (float *time_ms);
440 float MIDItoMs(MIDIClockTime time_clk); // new : added by me
442 MIDIClockTime MeasToMIDI(unsigned int meas, unsigned int beat = 0, unsigned int offset = 0);
447 virtual void UpdateStatus() { GoToTime(state.cur_clock); }
448
449 // Inherited from MIDITICK
451 virtual void Start();
453 virtual void Stop();
455 virtual void Play() { Start(); }
456
458 enum {
462 };
463
473 static void SetMetronomeMode(int mode)
475
477 enum {
480 };
481
483 enum {
487 };
488
489 protected:
492 static void StaticTickProc(tMsecs sys_time, void* pt);
494 virtual void TickProc(tMsecs sys_time);
496 static void StaticStopProc(MIDISequencer* p) { p->Stop(); }
497
499 // Internal use: scans events at 'now' time upgrading the sequencer state
500 void ScanEventsAtThisTime();
501
502 // Internal use: prepares the count in
503 void CountInPrepare();
504
505 MIDITimedMessage beat_marker_msg; // Used by the sequencer to send beat marker messages
506
507 bool repeat_play_mode; // Enables the repeat play mode
508 unsigned int repeat_start_meas; // The loop start measure
509 unsigned int repeat_end_meas; // The loop end measure
510 bool time_shift_mode; // The time shift on/off (during playback time shift is always on)
511 int play_mode; // PLAY_BOUNDED or PLAY_UNBOUNDED
512
513 std::vector<MIDIProcessor*> track_processors; // A MIDIProcessor for every track
514 MIDISequencerState state; // The sequencer state
516};
517
518
519#endif
520
This MIDIProcessor subclass implements a matrix which keeps track of notes on and hold pedal for ever...
Definition: matrix.h:43
Holds an array of pointers to MIDITrack objects to be played simultaneously.
Definition: multitrack.h:50
A forward iterator for moving along a MIDIMultiTrack.
Definition: multitrack.h:230
A pure virtual class implementing an object that can manipulate a MIDI message, inspecting or changin...
Definition: processor.h:47
A pure virtual class implementing a device that can send MIDISequencerGUIEvent messages to a GUI.
Definition: notifier.h:162
A MIDITickComponent which implements a basic sequencer, able to play the MIDI events contained in a M...
Definition: sequencer.h:193
virtual bool SetRepeatPlay(int on_off, int start_meas=-1, int end_meas=-1)
Sets the repeat play (loop) parameters: you can set the repeat play status on/off,...
virtual void Play()
This is an alias of Start().
Definition: sequencer.h:455
virtual bool SetTrackTimeShift(unsigned int trk_num, int offset)
Sets the time shift offset (in MIDI ticks) for a track.
const MIDISequencerState * GetState() const
Returns a pointer to the current MIDISequencerState (i.e.
Definition: sequencer.h:271
int GetTrackTimeShift(unsigned int trk_num) const
Returns the time offset (in MIDI ticks) assigned to a track.
Definition: sequencer.h:301
MIDIClockTime MeasToMIDI(unsigned int meas, unsigned int beat=0, unsigned int offset=0)
TODO.
MIDIClockTime GetCurrentMIDIClockTime() const
Returns current MIDIClockTime in MIDI ticks; it is effective even during playback.
virtual bool GoToTime(MIDIClockTime time_clk)
Sets the current time to a given the MIDI time, updating the internal status.
bool GetRepeatPlay() const
Returns the repeat play (loop) status on/off.
Definition: sequencer.h:250
bool GetCountInEnable() const
Returns true if the count in is enabled.
Definition: sequencer.h:258
virtual bool GoToTimeMs(float time_ms)
Same as GoToTime(), but the time is given in milliseconds.
unsigned int GetCurrentBeat() const
Returns current beat in the measure (1st beat is 0).
Definition: sequencer.h:222
virtual bool MoveTrack(int from, int to)
Moves a track from one position to another in the internal MIDIMultiTrack.
unsigned int GetClksPerBeat() const
Returns the base MIDI ticks per beat ratio of the internal MIDIMultiTrack.
Definition: sequencer.h:229
@ FOLLOW_THEORETIC_VALUE
follow the music theory value
Definition: sequencer.h:461
@ FOLLOW_TIMESIG_DENOMINATOR
follow the denominator of the time signature
Definition: sequencer.h:460
@ FOLLOW_MIDI_TIMESIG_MESSAGE
follow the value stored in the last seen MIDI TimeSig message
Definition: sequencer.h:459
const MIDISequencerTrackState * GetTrackState(unsigned int trk_num) const
Returns a pointer to the MIDISequencerTrackState for a track.
Definition: sequencer.h:280
virtual bool SetTrackProcessor(unsigned int trk_num, MIDIProcessor *p)
Sets a MIDIProcessor for the given track.
unsigned int GetTrackOutPort(unsigned int trk_num) const
Returns the number of the out port assigned to a track.
Definition: sequencer.h:284
@ PLAY_BOUNDED
See SetPlayMode()
Definition: sequencer.h:478
@ PLAY_UNBOUNDED
See SetPlayMode()
Definition: sequencer.h:479
unsigned int GetTempoScale() const
Returns current tempo scale in percentage (100 = no scaling, 200 = twice faster, etc....
Definition: sequencer.h:242
virtual void SetState(MIDISequencerState *s)
Copies a given MIDISequencerState into the internal sequencer state.
MIDIProcessor * GetTrackProcessor(unsigned int trk_num)
Returns a pointer to the MIDISequencerTrackProcessor for a track.
Definition: sequencer.h:290
unsigned int GetRepeatPlayEnd() const
Returns the repeat play (loop) end measure.
Definition: sequencer.h:255
virtual void SetPlayMode(int mode)
Sets the play mode.
bool GetTimeShiftMode() const
Returns the time shift mode (on or off).
Definition: sequencer.h:265
virtual void SetTimeShiftMode(bool f)
Sets the time shifting of events on and off.
const MIDIProcessor * GetTrackProcessor(unsigned int trk_num) const
Returns a pointer to the MIDISequencerTrackProcessor for a track.
Definition: sequencer.h:296
float GetCurrentTimeMs() const
Returns current time in milliseconds; it is effective even during playback.
virtual bool DeleteTrack(int trk_num=-1)
Deletes a track and all its events from the internal MIDIMultiTrack.
virtual bool InsertTrack(int trk_num=-1)
Inserts into the internal MIDIMultiTrack a new empty track with default track parameters (transpose,...
virtual bool SetTrackOutPort(unsigned int trk_num, unsigned int port)
Sets the MIDI out port for a track.
const MIDIMultiTrack * GetMultiTrack() const
Returns a pointer to the internal MIDIMultiTrack.
Definition: sequencer.h:234
virtual bool GoToMeasure(unsigned int measure, unsigned int beat=0)
Sets the current time to the given measure and beat, updating the internal status.
float MIDItoMs(MIDIClockTime time_clk)
Converts a time from MIDI ticks into milliseconds, taking into account all tempo changes from the beg...
virtual void Start()
Starts the sequencer playing from the current time.
MIDISequencerTrackState * GetTrackState(unsigned int trk_num)
Returns a pointer to the MIDISequencerTrackState for a track.
Definition: sequencer.h:276
MIDISequencerState * GetState()
Returns a pointer to the current MIDISequencerState (i.e.
Definition: sequencer.h:268
MIDIMultiTrack * GetMultiTrack()
Returns a pointer to the internal MIDIMultiTrack.
Definition: sequencer.h:232
static void StaticStopProc(MIDISequencer *p)
Internal use for auto stop.
Definition: sequencer.h:496
MIDIClockTime GetCurrentBeatOffset() const
Returns the current MIDI time offset respect to current beat.
Definition: sequencer.h:224
unsigned int GetNumTracks() const
Returns the number of tracks of the multitrack.
Definition: sequencer.h:240
virtual void SetCountIn(bool on_off)
Sets the count in enable or disable.
bool GetCountInPending() const
Returns true if the count in is pending (the sequencer is counting in).
Definition: sequencer.h:260
float GetTempoWithScale() const
Returns current tempo (BPM) taking into account scaling (this is the true actual tempo).
Definition: sequencer.h:247
virtual void TickProc(tMsecs sys_time)
Implements the pure virtual method inherited from MIDITickComponent (you must not call it directly).
virtual bool SetTempoScale(unsigned int scale)
Sets the global tempo scale.
virtual bool GetNextEventTimeMs(float *time_ms)
Same of GetNextEventTime(), but time is returned in milliseconds from the beginning.
static void StaticTickProc(tMsecs sys_time, void *pt)
Implements the static method inherited by MIDITickComponent and called at every timer tick.
@ AUTO_STOP_PENDING
0 if no autostop, 4 if yes
Definition: sequencer.h:486
@ COUNT_IN_ENABLED
0 if no count in before starting, 1 if yes
Definition: sequencer.h:484
@ COUNT_IN_PENDING
0 if count in is done, 2 if it is pending
Definition: sequencer.h:485
unsigned int GetRepeatPlayStart() const
Returns the repeat play (loop) start measure.
Definition: sequencer.h:252
virtual void Stop()
Stops the sequencer playing.
virtual ~MIDISequencer()
The destructor.
virtual void Reset()
Resets the MIDISequencer to its initial state.
virtual bool GetNextEvent(int *trk_num, MIDITimedMessage *msg)
Gets the next event (respect current position).
float GetTempoWithoutScale() const
Returns current tempo (BPM) without scaling.
Definition: sequencer.h:244
unsigned int GetCurrentMeasure() const
Returns current measure (1st measure is 0).
Definition: sequencer.h:219
bool GetPlayMode()
Returns the play mode state (see SetPlayMode()).
Definition: sequencer.h:273
MIDITrack * GetTrack(unsigned int trk_num)
Returns a pointer to the given track, or 0 if _num_trk is not a valid number.
Definition: sequencer.h:236
static void SetMetronomeMode(int mode)
Selects the way the sequencer calculates metronome beat.
Definition: sequencer.h:473
virtual bool GetNextEventTime(MIDIClockTime *time_clk)
Gets the time of the next event (it can be different from current time if at current time there are n...
virtual void UpdateStatus()
This is equivalent of GoToTime(state.cur_clock) and should be used to update the sequencer state afte...
Definition: sequencer.h:447
MIDISequencer(MIDIMultiTrack *m, MIDISequencerGUINotifier *n=0)
The constructor.
virtual void GoToZero()
Sets the current time to the beginning of the song, updating the internal status.
Stores current MIDI general parameters for a MIDISequencer object, embedding a MIDISequencerTrackStat...
Definition: sequencer.h:94
MIDIClockTime count_in_time
Internal use.
Definition: sequencer.h:163
unsigned char playing_status
Flag affecting the TickProc (count in, auto stop, etc.)
Definition: sequencer.h:166
MIDISequencerState(MIDIMultiTrack *multitrack_, MIDISequencerGUINotifier *n=0)
The constructor is called by the MIDISequencer class constructor, which sets appropriate values for p...
MIDIMultiTrack * multitrack
The MIDIMultiTrack holding MIDI messages.
Definition: sequencer.h:138
const MIDISequencerState & operator=(const MIDISequencerState &s)
The assignment operator. See the note to the copy constructor.
MIDIClockTime last_beat_time
Internal use.
Definition: sequencer.h:159
void NotifyTrack(int item) const
These are used for notifying the GUI when something happens (a parameter was changed,...
unsigned char timesig_numerator
The numerator of current time signature.
Definition: sequencer.h:151
signed char keysig_sharpflat
The current key signature accidents (.
Definition: sequencer.h:153
MIDISequencerState(const MIDISequencerState &s)
The copy constructor.
MIDIClockTime last_tempo_change
Internal use.
Definition: sequencer.h:162
float tempobpm
The current tempo in beats per minute.
Definition: sequencer.h:149
int last_event_track
Internal use.
Definition: sequencer.h:158
MIDIClockTime cur_clock
The current MIDI clock in MIDI ticks.
Definition: sequencer.h:141
unsigned char keysig_mode
Major mode (0) or minor (1)
Definition: sequencer.h:154
static int metronome_mode
Flag affecting how metronome beat is calculated.
Definition: sequencer.h:167
MIDIClockTime next_beat_time
The MIDI time of the next beat (for internal use)
Definition: sequencer.h:147
unsigned int cur_beat
The current beat in the measure (1st beat is 0)
Definition: sequencer.h:143
std::string marker_text
The current marker.
Definition: sequencer.h:155
unsigned int cur_measure
The current measure (1st measure is 0)
Definition: sequencer.h:144
unsigned int number_of_beats
Number of beats in the measure.
Definition: sequencer.h:146
void Reset()
Resets the state to default values.
MIDIMultiTrackIterator iterator
The iterator for moving along the multitrack.
Definition: sequencer.h:139
void GoForwardNoEvent(MIDIClockTime t)
Sets the cur time to the given time.
unsigned char timesig_denominator
The denominator of current time signature.
Definition: sequencer.h:152
unsigned int tempo_scale
The tempo scale in percentage (100 = true time)
Definition: sequencer.h:150
std::vector< MIDISequencerTrackState * > track_states
A track state for every track.
Definition: sequencer.h:157
virtual ~MIDISequencerState()
The destructor.
MIDISequencerGUINotifier * notifier
The notifier.
Definition: sequencer.h:137
float cur_time_ms
The current clock in milliseconds.
Definition: sequencer.h:142
float last_time_ms
Internal use.
Definition: sequencer.h:161
void Notify(int group, int item=0) const
Notifies the GUI when something happens (a parameter was changed, current time is moved,...
MIDIClockTime beat_length
The duration of a beat.
Definition: sequencer.h:145
bool Process(MIDITimedMessage *msg)
This is the process function inherited from MIDIProcessor.
float ms_per_clock
Internal use.
Definition: sequencer.h:160
Stores current MIDI parameters for a sequencer track.
Definition: sequencer.h:55
int16_t program
the current program change, or -1 if undefined
Definition: sequencer.h:70
bool notes_are_on
true if there are notes currently on
Definition: sequencer.h:73
virtual ~MIDISequencerTrackState()
The destructor does nothing.
Definition: sequencer.h:62
bool got_good_track_name
internal use
Definition: sequencer.h:77
std::string track_name
the track name
Definition: sequencer.h:72
int16_t bender_value
the last seen bender value
Definition: sequencer.h:71
MIDISequencerTrackState()
The constructor.
MIDIMatrix note_matrix
to keep track of all notes on
Definition: sequencer.h:74
int16_t control_values[C_ALL_NOTES_OFF]
an array of current control change values, or -1 if not defined
Definition: sequencer.h:75
virtual void Reset()
Resets default values.
A pure virtual class implementing an object which has a callback procedure to be called at every tick...
Definition: tick.h:65
The MIDITimedMessage class inherits from the MIDIMessage and represents a message associated with a s...
Definition: msg.h:382
Manages a std::vector of MIDITimedMessage objects storing MIDI events, with methods for editing them.
Definition: track.h:86
unsigned long MIDIClockTime
The type of a variable which can hold a time in MIDI ticks.
Definition: midi.h:40
unsigned long long tMsecs
The type of a variable which can hold the elapsed time in milliseconds.
Definition: timer.h:44
@ C_ALL_NOTES_OFF
all notes off
Definition: midi.h:180
Contains the definition of the class MIDIMatrix.
Contains the definition of the classes MIDIMultiTrack, MIDIMultiTrackIteratorState,...
Contains the definition of the classes MIDISequencerGUIEvent, MIDISequencerGUINotifier (abstract),...
Contains the definition of the pure virtual MIDIProcessor class and its specializations MIDIMultiProc...
Contains the definition of the pure virtual class MIDITickComponent.