NiCMidi 1.1.0
A MIDI library derived from J.D.Koftinoff jdksmidi
recorder.h
Go to the documentation of this file.
1/*
2 * NiCMidi - A C++ Class Library for MIDI
3 *
4 * Copyright (C) 2021, 2022 Nicola Cassetta
5 * https://github.com/ncassetta/NiCMidi
6 *
7 * This file is part of NiCMidi.
8 *
9 * NiCMidi is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation, either version 3 of
12 * the License, or (at your option) any later version.
13 *
14 * NiCMidi is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with NiCMidi. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23
26
27
28#ifndef _NICMIDI_RECORDER_H
29#define _NICMIDI_RECORDER_H
30
31#include "sequencer.h"
32#include "processor.h"
33
34#include <atomic>
35#include <vector>
36#include <set>
37#include <stack>
38
39/*
40class MIDIMultiTrackCopier {
41 public:
42 MIDIMultiTrackCopier();
43 virtual ~MIDIMultiTrackCopier();
44
45 void Reset();
46 MIDITrack* GetTrackDest(unsigned int n) const;
47
48 void SetTrackDest(unsigned int n, MIDITrack* trk);
49 void ResetTrackDest(unsigned int n);
50
51 void Copy();
52
53 private:
54 MIDIMultiTrack* source;
55 std::vector<MIDITrack*> dest;
56};
57*/
58
59/*
73class MIDIRecorderState : public MIDIProcessor {
74// Doesn't inherit from MIDISequencerGUINotifier because notifier and sequencer must be independent objects
75// (notifier is used also by the MIDIManager)
76// All is public: used by various classes
77 public:
80 MIDIRecorderState(MIDIMultiTrack *multitrack_,
81 MIDISequencerGUINotifier *n = 0);
85 MIDIRecorderState(const MIDIRecorderState &s);
88 virtual ~MIDIRecorderState();
90 const MIDIRecorderState& operator= (const MIDIRecorderState &s);
91
95 void Reset();
99 bool Process( MIDITimedMessage* msg );
102 void Notify(int group, int item = 0) const;
105 void NotifyTrack(int item) const;
106
107 MIDISequencerGUINotifier* notifier; ///< The notifier
108 MIDIMultiTrack* multitrack; ///< The MIDIMultiTrack holding MIDI messages
109 MIDIMultiTrackIterator iterator; ///< The iterator for moving along the multitrack
110
111 MIDIClockTime cur_clock; ///< The current MIDI clock in MIDI ticks
112 float cur_time_ms; ///< The current clock in milliseconds
113 unsigned int cur_beat; ///< The current beat in the measure (1st beat is 0)
114 unsigned int cur_measure; ///< The current measure (1st measure is 0)
115 MIDIClockTime beat_length; ///< The duration of a beat
116 MIDIClockTime next_beat_time; ///< The MIDI time of the next beat (for internal use)
117
118 float tempobpm; ///< The current tempo in beats per minute
119 char timesig_numerator; ///< The numerator of current time signature
120 char timesig_denominator;///< The denominator of current time signature
121 //char keysig_sharpflat; ///< The current key signature accidents (
122 //char keysig_mode; ///< Major mode (0) or minor (1)
123 //std::string marker_text; ///< The current marker
124 //std::vector<MIDISequencerTrackState*>
125 // track_states; ///< A track state for every track
126 int last_event_track; ///< Internal use
127 MIDIClockTime last_beat_time; ///< Internal use
128 static int metronome_mode; ///< Flag affecting how metronome beat is calculated
129};
130*/
131
132
133class RecNotifier: public MIDISequencerGUINotifier {
134 public:
135 RecNotifier(MIDISequencer* seq = 0);
137 unsigned char GetMeasNote() const { return meas_note; }
139 unsigned char GetBeatNote() const { return beat_note; }
141 MIDISequencerGUINotifier* GetOtherNotifier() const { return other_notifier; }
143 void SetMeasNote(unsigned char note) { meas_note = note; }
145 void SetBeatNote(unsigned char note) { beat_note = note; }
149 void SetOutPort(unsigned int p) { port = p; }
152 void SetOutChannel(int ch) { chan = ch & 0x0f; }
154 void SetOtherNotifier(MIDISequencerGUINotifier* n)
155 { other_notifier = n; }
156 virtual void Notify(const MIDISequencerGUIEvent &ev);
157 private:
158 const unsigned char DEFAULT_MEAS_NOTE = 68;
159 const unsigned char DEFAULT_BEAT_NOTE = 60;
160
161 unsigned char meas_note; // The MIDI note number for the measure click (1st note of a measure)
162 unsigned char beat_note; // The MIDI note number for the ordinary beat click
163 unsigned int port; // The out port id
164 unsigned char chan; // The MIDI channel for sound output
165 MIDIMessage on_msg;
166 MIDIMessage off_msg;
167 unsigned char num_beats;
168 MIDISequencerGUINotifier* other_notifier;
169};
170
171
187 public:
191 virtual ~MIDIRecorder();
194 virtual void Reset();
196 MIDIMultiTrack* GetMultiTrack() const { return tracks; }
199 int GetRecMode() const { return rec_mode; }
201 MIDIClockTime GetStartRecTime() const { return rec_start_time; }
203 MIDIClockTime GetEndRecTime() const { return rec_end_time; }
206 MIDITrack* GetTrack(unsigned int trk_num) { return tracks->GetTrack(trk_num); }
209 const MIDITrack* GetTrack(unsigned int trk_num) const
210 { return tracks->GetTrack(trk_num); }
213 unsigned int GetTrackInPort(unsigned int trk_num) const
214 { return seq->GetTrack(trk_num)->GetInPort(); }
217 int GetTrackRecChannel(unsigned int trk_num)
218 { return seq->GetTrack(trk_num)->GetRecChannel(); }
223 bool SetTrackInPort(unsigned int trk_num, unsigned int port);
228 bool SetTrackRecChannel(unsigned int trk_num, int chan);
232 bool SetRecMode(int mode);
239 bool SetStartRecTime(unsigned int meas, unsigned int beat = 0)
240 { return SetStartRecTime(seq->MeasToMIDI(meas, beat)); }
247 bool SetEndRecTime(unsigned int meas, unsigned int beat = 0)
248 { return SetEndRecTime(seq->MeasToMIDI(meas, beat)); }
249
260 bool InsertTrack(int trk_num = -1);
267 bool DeleteTrack(int trk_num = -1);
273 bool MoveTrack(int from, int to);
277 bool EnableTrack(unsigned int trk_num);
281 bool DisableTrack(unsigned int trk_num);
284 bool UndoRec();
285
288 virtual void Start();
290 virtual void Stop();
291
293 enum {
295 REC_OVER
296 };
297
298 protected:
301 void ResizeTracks(unsigned int max_num);
309 void PrepareTrack(unsigned int trk_num);
312 static void StaticTickProc(tMsecs sys_time, void* pt);
314 virtual void TickProc(tMsecs sys_time);
315
317 MIDISequencer* const seq; // The attached sequencer
318 MIDIMultiTrack* tracks; // The internal MIDIMultiTrack
319 MIDIMultiTrack* seq_tracks; // The sequencer multitrack
320 std::vector<bool> en_tracks; // True if the corresponding track isenabled
321 std::set<unsigned int> en_ports; // Enabled input ports
322
323 tMsecs rec_time_offset; // The time between time 0 and sequencer start
324 //tMsecs sys_time_offset; ///< The time between the timer start and the sequencer start
325 MIDIClockTime rec_start_time; // The MIDIClockTime of the beginning of recording
326 MIDIClockTime rec_end_time; // The MIDIClockTime of the end of recording
327 int rec_mode; // The recording mode (REC_MERGE or REC_OVER)
328 RecNotifier notifier; // A notifier used as a metronome
329 int old_seq_mode; // Internal use
330 std::atomic<bool> rec_on; // Internal use
331 std::stack<MIDIMultiTrack*> undo_stack; // Stack of multitracks for undo
332
334};
335
336
337
338#endif // RECORDER_H_INCLUDED
Stores data representing a MIDI event message.
Definition: msg.h:49
Holds an array of pointers to MIDITrack objects to be played simultaneously.
Definition: multitrack.h:50
A MIDITickComponent which can record MIDI messages incoming from a MIDI in port, putting them into an...
Definition: recorder.h:186
bool SetTrackInPort(unsigned int trk_num, unsigned int port)
Sets the MIDI in port for a track.
MIDIClockTime GetStartRecTime() const
Returns the recording start time in MIDI ticks.
Definition: recorder.h:201
virtual void Stop()
Stops the recording from the enabled ports and channels.
MIDIClockTime GetEndRecTime() const
Returns the recording end time in MIDI ticks.
Definition: recorder.h:203
bool DisableTrack(unsigned int trk_num)
Disables a sequencer track for recording.
bool SetStartRecTime(unsigned int meas, unsigned int beat=0)
Sets the recording start time, giving the measure and beat. See SetStartRecTime(MIDIClockTime).
Definition: recorder.h:239
void SetSeqNotifier()
Internal function.
bool SetStartRecTime(MIDIClockTime t)
Sets the recording start time.
MIDIMultiTrack * GetMultiTrack() const
Returns a pointer to the internal MIDIMultiTrack.
Definition: recorder.h:196
bool InsertTrack(int trk_num=-1)
Inserts into the internal MIDIMultiTrack a new track.
void ResizeTracks(unsigned int max_num)
Internal function.
virtual void Reset()
It sets all tracks to recording disabled, empties the internal multitrack and sets the start and end ...
unsigned int GetTrackInPort(unsigned int trk_num) const
Returns the number of the MIDI in port assigned to the given track.
Definition: recorder.h:213
bool SetEndRecTime(unsigned int meas, unsigned int beat=0)
Sets the recording end time, giving the measure and beat. See SetEndRecTime(MIDIClockTime).
Definition: recorder.h:247
bool EnableTrack(unsigned int trk_num)
Enables a sequencer track for recording.
void PrepareTrack(unsigned int trk_num)
Internal function.
static void StaticTickProc(tMsecs sys_time, void *pt)
Implements the static method inherited by MIDITickComponent and called at every timer tick.
int GetRecMode() const
Returns the recording mode.
Definition: recorder.h:199
bool MoveTrack(int from, int to)
Moves a track from one position to another in the internal MIDIMultiTrack.
@ REC_MERGE
Merge old and new content.
Definition: recorder.h:294
@ REC_OVER
Overwrite the old content.
Definition: recorder.h:295
bool SetTrackRecChannel(unsigned int trk_num, int chan)
Sets the recording channel for the given track.
MIDIRecorder(MIDISequencer *const s)
The constructor. It binds the recorder to the given MIDISequencer.
virtual void Start()
Starts the recording from the enabled ports and channels.
bool DeleteTrack(int trk_num=-1)
Deletes a track and all its events from the internal MIDIMultiTrack.
bool UndoRec()
Deletes the changes made in the last recording.
MIDITrack * GetTrack(unsigned int trk_num)
Returns the pointer to a track of the internal multitrack.
Definition: recorder.h:206
virtual ~MIDIRecorder()
The destructor.
bool SetEndRecTime(MIDIClockTime t)
Sets the recording end time.
virtual void TickProc(tMsecs sys_time)
Implements the pure virtual method inherited from MIDITickComponent (you must not call it directly).
void ResetSeqNotifier()
Internal function. It is used in Stop() to reset the hook in the sequencer notifier.
bool SetRecMode(int mode)
Sets the recording mode.
int GetTrackRecChannel(unsigned int trk_num)
Returns the recording channel for the given track, or -1 for any channel.
Definition: recorder.h:217
const MIDITrack * GetTrack(unsigned int trk_num) const
Returns the pointer to a track of the internal multitrack.
Definition: recorder.h:209
Holds data for a message that the sequencer can send to the GUI to warn it when something happens.
Definition: notifier.h:53
A pure virtual class implementing a device that can send MIDISequencerGUIEvent messages to a GUI.
Definition: notifier.h:162
virtual void Notify(const MIDISequencerGUIEvent &ev)=0
Notifies the MIDISequencerGUIEvent ev.
A MIDITickComponent which implements a basic sequencer, able to play the MIDI events contained in a M...
Definition: sequencer.h:193
A pure virtual class implementing an object which has a callback procedure to be called at every tick...
Definition: tick.h:65
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
Contains the definition of the pure virtual MIDIProcessor class and its specializations MIDIMultiProc...
Contains the definitions of the classes MIDISequencerTrackState, MIDISequencerState and MIDISequencer...