Verovio
Source code documentation
midifunctor.h
1 // Name: midifunctor.h
3 // Author: David Bauer
4 // Created: 2023
5 // Copyright (c) Authors and others. All rights reserved.
7 
8 #ifndef __VRV_MIDIFUNCTOR_H__
9 #define __VRV_MIDIFUNCTOR_H__
10 
11 #include "functor.h"
12 
13 //----------------------------------------------------------------------------
14 
15 #include "alignfunctor.h"
16 
17 namespace smf {
18 class MidiFile;
19 }
20 
21 namespace vrv {
22 
23 class CustomTuning;
24 class FeatureExtractor;
25 class InstrDef;
26 class Timemap;
27 
28 //----------------------------------------------------------------------------
29 // InitOnsetOffsetFunctor
30 //----------------------------------------------------------------------------
31 
36 public:
42  virtual ~InitOnsetOffsetFunctor() = default;
44 
45  /*
46  * Abstract base implementation
47  */
48  bool ImplementsEndInterface() const override { return true; }
49 
50  /*
51  * Functor interface
52  */
54  FunctorCode VisitChordEnd(Chord *chord) override;
55  FunctorCode VisitLayer(Layer *layer) override;
56  FunctorCode VisitLayerElement(LayerElement *layerElement) override;
57  FunctorCode VisitMeasure(Measure *measure) override;
58  FunctorCode VisitStaff(Staff *staff) override;
59  FunctorCode VisitTabGrpEnd(TabGrp *tabGrp) override;
61 
62 protected:
63  //
64 private:
65  //
66 public:
67  //
68 private:
69  // The current score time in the measure (incremented by each element)
70  Fraction m_currentScoreTime;
71  // The current real time in seconds in the measure (incremented by each element)
72  double m_currentRealTimeSeconds;
73  // The current time alignment parameters
74  AlignMeterParams m_meterParams;
75  // The current notation type
76  data_NOTATIONTYPE m_notationType;
77  // The current tempo
78  double m_currentTempo;
79 };
80 
81 //----------------------------------------------------------------------------
82 // InitMaxMeasureDurationFunctor
83 //----------------------------------------------------------------------------
84 
89 public:
95  virtual ~InitMaxMeasureDurationFunctor() = default;
97 
98  /*
99  * Abstract base implementation
100  */
101  bool ImplementsEndInterface() const override { return true; }
102 
103  /*
104  * Set the tempo
105  */
107  void SetCurrentTempo(double tempo) { m_currentTempo = tempo; }
108  void SetTempoAdjustment(double adjustment) { m_tempoAdjustment = adjustment; }
110 
111  /*
112  * Functor interface
113  */
115  FunctorCode VisitLayerElement(LayerElement *layerElement) override;
116  FunctorCode VisitMeasure(Measure *measure) override;
117  FunctorCode VisitMeasureEnd(Measure *measure) override;
118  FunctorCode VisitScoreDef(ScoreDef *scoreDef) override;
119  FunctorCode VisitTempo(Tempo *tempo) override;
121 
122 protected:
123  //
124 private:
125  // Returns the current tempo with adjustment
126  double GetAdjustedTempo() const { return m_currentTempo * m_tempoAdjustment; }
127 
128 public:
129  //
130 private:
131  // The current score time
132  Fraction m_currentScoreTime;
133  // The current time in seconds
134  double m_currentRealTimeSeconds;
135  // The current tempo
136  double m_currentTempo;
137  // The tempo adjustment
138  double m_tempoAdjustment;
139  // The factor for multibar rests
140  int m_multiRestFactor;
141 };
142 
143 //----------------------------------------------------------------------------
144 // InitTimemapTiesFunctor
145 //----------------------------------------------------------------------------
146 
151 public:
157  virtual ~InitTimemapTiesFunctor() = default;
159 
160  /*
161  * Abstract base implementation
162  */
163  bool ImplementsEndInterface() const override { return false; }
164 
165  /*
166  * Functor interface
167  */
169  FunctorCode VisitTie(Tie *tie) override;
171 
172 protected:
173  //
174 private:
175  //
176 public:
177  //
178 private:
179  //
180 };
181 //----------------------------------------------------------------------------
182 // InitTimemapAdjustNotesFunctor
183 //----------------------------------------------------------------------------
184 
189 public:
195  virtual ~InitTimemapAdjustNotesFunctor() = default;
197 
198  /*
199  * Abstract base implementation
200  */
201  bool ImplementsEndInterface() const override { return true; }
202 
203  /*
204  * Setter for various properties
205  */
207  void SetNoCue(bool noCue) { m_noCue = noCue; }
209 
210  /*
211  * Functor interface
212  */
214  FunctorCode VisitArpeg(Arpeg *arpeg) override;
215  FunctorCode VisitChord(Chord *chord) override;
216  FunctorCode VisitGraceGrpEnd(GraceGrp *graceGrp) override;
217  FunctorCode VisitLayerEnd(Layer *layer) override;
218  FunctorCode VisitMeasure(Measure *measure) override;
219  FunctorCode VisitNote(Note *note) override;
221 
222 protected:
223  //
224 private:
228  struct Grace {
229  std::list<Note *> notes;
230  data_DURATION duration;
231  data_PERCENT time;
232  };
233 
237  void SetGraceNotesFor(Note *refNote);
238 
242  void SetNoteOrChordStartStop(Note *note, const Fraction &startTime, const Fraction &stopTime = VRV_UNSET);
243  void SetNoteStartStop(Note *note, const Fraction &startTime, const Fraction &stopTime = VRV_UNSET);
244 
245 public:
246  //
247 private:
248  // Indicates whether cue notes should be included
249  bool m_noCue;
250  // Grace note/chord sequence
251  std::list<Grace> m_graces;
252  // Indicates whether the last grace note/chord was accented
253  bool m_accentedGraceNote;
254  // The current tempo
255  double m_currentTempo;
256  // The last (non grace) note
257  Note *m_lastNote;
258 };
259 
260 //----------------------------------------------------------------------------
261 // InitMIDIFunctor
262 //----------------------------------------------------------------------------
263 
267 struct OctaveInfo {
268  const Octave *octave;
269  int staffN;
270  int layerN;
271  int octaveShift;
272  bool isActive;
273 };
274 
281 public:
286  InitMIDIFunctor();
287  virtual ~InitMIDIFunctor() = default;
289 
290  /*
291  * Abstract base implementation
292  */
293  bool ImplementsEndInterface() const override { return false; }
294 
295  /*
296  * Setter and getter for properties
297  */
299  void SetCurrentTempo(double tempo) { m_currentTempo = tempo; }
300  const std::list<OctaveInfo> &GetOctaves() const { return m_octaves; }
302 
303  /*
304  * Functor interface
305  */
307  FunctorCode VisitMeasure(const Measure *measure) override;
308  FunctorCode VisitOctave(const Octave *octave) override;
310 
311 protected:
312  //
313 private:
314  //
315 public:
316  //
317 private:
318  // The current tempo
319  double m_currentTempo;
320  // Octave info which is collected
321  std::list<OctaveInfo> m_octaves;
322 };
323 
324 //----------------------------------------------------------------------------
325 // GenerateMIDIFunctor
326 //----------------------------------------------------------------------------
327 
331 struct MIDINote {
332  int pitch;
333  double duration;
334 };
335 
336 using MIDINoteSequence = std::list<MIDINote>;
337 
341 struct MIDIHeldNote {
342  int m_pitch = 0;
343  double m_stopTime = 0;
344 };
345 
350 public:
355  GenerateMIDIFunctor(smf::MidiFile *midiFile);
356  virtual ~GenerateMIDIFunctor() = default;
358 
359  /*
360  * Abstract base implementation
361  */
362  bool ImplementsEndInterface() const override { return true; }
363 
364  /*
365  * Getter for properties
366  */
368  std::set<int> GetTempoEventTicks() const { return m_tempoEventTicks; }
370 
371  /*
372  * Setter for various properties
373  */
375  void SetChannel(int channel) { m_midiChannel = channel; }
376  void SetControlEvents(bool controlEvents) { m_controlEvents = controlEvents; }
377  void SetNoCue(bool noCue) { m_noCue = noCue; }
378  void SetCurrentTempo(double tempo) { m_currentTempo = tempo; }
379  void SetDeferredNotes(const std::map<const Note *, double> &deferredNotes) { m_deferredNotes = deferredNotes; }
380  void SetLayerN(int layerN) { m_layerN = layerN; }
381  void SetOctaves(const std::list<OctaveInfo> &octaves) { m_octaves = octaves; }
382  void SetStaffN(int staffN) { m_staffN = staffN; }
383  void SetTempoEventTicks(const std::set<int> &ticks) { m_tempoEventTicks = ticks; }
384  void SetTrack(int track) { m_midiTrack = track; }
385  void SetTransSemi(int transSemi) { m_transSemi = transSemi; }
386  void SetInstrDef(const InstrDef *instrDef) { m_instrDef = instrDef; }
387  void SetCustomTuning(const CustomTuning *customTuning) { m_customTuning = customTuning; }
389 
390  /*
391  * Functor interface
392  */
394  FunctorCode VisitBeatRpt(const BeatRpt *beatRpt) override;
395  FunctorCode VisitBTrem(const BTrem *bTrem) override;
396  FunctorCode VisitChord(const Chord *chord) override;
397  FunctorCode VisitFTrem(const FTrem *fTrem) override;
398  FunctorCode VisitHalfmRpt(const HalfmRpt *halfmRpt) override;
399  FunctorCode VisitLayer(const Layer *layer) override;
400  FunctorCode VisitLayerEnd(const Layer *layer) override;
401  FunctorCode VisitLayerElement(const LayerElement *layerElement) override;
402  FunctorCode VisitMeasure(const Measure *measure) override;
403  FunctorCode VisitMRpt(const MRpt *mRpt) override;
404  FunctorCode VisitNote(const Note *note) override;
405  FunctorCode VisitPedal(const Pedal *pedal) override;
406  FunctorCode VisitScoreDef(const ScoreDef *scoreDef) override;
407  FunctorCode VisitStaff(const Staff *staff) override;
408  FunctorCode VisitStaffDef(const StaffDef *staffDef) override;
409  FunctorCode VisitSyl(const Syl *syl) override;
410  FunctorCode VisitVolta(const Volta *volta) override;
411  FunctorCode VisitRefrain(const Refrain *refrain) override;
412  FunctorCode VisitVerse(const Verse *verse) override;
414 
415 protected:
416  //
417 private:
421  void DeferMIDINote(const Note *refNote, double shift, bool includeChordSiblings);
422 
426  void HandleOctave(const LayerElement *layerElement);
427 
431  int GetMIDIPitch(const Note *note);
432 
433 public:
434  //
435 private:
436  // The MidiFile we are writing to
437  smf::MidiFile *m_midiFile;
438  // The MIDI track number
439  int m_midiTrack;
440  // The MIDI channel number
441  int m_midiChannel;
442  // The score time from the start of the music to the start of the current measure
443  double m_totalTime;
444  // The current staff number
445  int m_staffN;
446  // The current layer number
447  int m_layerN;
448  // The semi tone transposition for the current track
449  int m_transSemi;
450  // The octave shift for the current track
451  int m_octaveShift;
452  // The current tempo
453  double m_currentTempo;
454  // Tempo events are always added on track 0
455  // This set contains the ticks of all added tempo events to avoid multiple events at the same time
456  std::set<int> m_tempoEventTicks;
457  // The last (non grace) note that was performed
458  const Note *m_lastNote;
459  // Expanded notes due to ornaments and tremolandi
460  std::map<const Note *, MIDINoteSequence> m_expandedNotes;
461  // Deferred notes which start slightly later
462  std::map<const Note *, double> m_deferredNotes;
463  // Octave info which is used to determine the octave shift
464  std::list<OctaveInfo> m_octaves;
465  // Indicates whether cue notes should be included
466  bool m_noCue;
467  // Tablature held notes indexed by (course - 1)
468  std::vector<MIDIHeldNote> m_heldNotes;
469  // A flag indicating we want to process control events
470  bool m_controlEvents;
471  // Current instrument definition
472  const InstrDef *m_instrDef;
473  // Current custom tuning
474  const CustomTuning *m_customTuning;
475 };
476 
477 //----------------------------------------------------------------------------
478 // GenerateTimemapFunctor
479 //----------------------------------------------------------------------------
480 
485 public:
491  virtual ~GenerateTimemapFunctor() = default;
493 
494  /*
495  * Abstract base implementation
496  */
497  bool ImplementsEndInterface() const override { return false; }
498 
499  /*
500  * Set the cue exclusion flag
501  */
502  void SetNoCue(bool noCue) { m_noCue = noCue; }
503 
504  /*
505  * Functor interface
506  */
508  FunctorCode VisitLayerElement(const LayerElement *layerElement) override;
509  FunctorCode VisitMeasure(const Measure *measure) override;
510  FunctorCode VisitMRest(const MRest *mRest) override;
511  FunctorCode VisitMultiRest(const MultiRest *multiRest) override;
512  FunctorCode VisitNote(const Note *note) override;
513  FunctorCode VisitRest(const Rest *rest) override;
514  FunctorCode VisitStaff(const Staff *staff) override;
516 
517 protected:
518  //
519 private:
523  void AddTimemapEntry(const Object *object);
524 
525 public:
526  //
527 private:
528  // The score time from the start of the piece to the previous barline in quarter notes
529  Fraction m_currentScoreTime;
530  // Real time from the start of the piece to the previous barline in ms
531  double m_currentRealTimeMilliseconds;
532  // The current tempo
533  double m_currentTempo;
534  // Indicates whether cue notes should be included
535  bool m_noCue;
536  // The timemap
537  Timemap *m_timemap;
538 };
539 
540 //----------------------------------------------------------------------------
541 // GenerateFeaturesFunctor
542 //----------------------------------------------------------------------------
543 
548 public:
554  virtual ~GenerateFeaturesFunctor() = default;
556 
557  /*
558  * Abstract base implementation
559  */
560  bool ImplementsEndInterface() const override { return false; }
561 
562  /*
563  * Functor interface
564  */
566  FunctorCode VisitObject(const Object *object) override;
568 
569 protected:
570  //
571 private:
572  //
573 public:
574  //
575 private:
576  // The FeatureExtractor to which extraction is delegated
577  FeatureExtractor *m_extractor;
578 };
579 
580 } // namespace vrv
581 
582 #endif // __VRV_MIDIFUNCTOR_H__
This class represents a collection of notes in the same layer with the same onset time.
Definition: chord.h:44
This abstract class is the base class for all const functors.
Definition: functor.h:126
This abstract class is the base class for all mutable functors that need access to the document.
Definition: functor.h:151
This class is a hold the data and corresponds to the model of a MVC design pattern.
Definition: doc.h:41
Definition: featureextractor.h:21
Definition: fraction.h:19
This abstract class is the base class for all mutable functors.
Definition: functor.h:101
This class exports the object to a JSON feature file.
Definition: midifunctor.h:547
bool ImplementsEndInterface() const override
Return true if the functor implements the end interface.
Definition: midifunctor.h:560
This class performs the export to a MidiFile.
Definition: midifunctor.h:349
bool ImplementsEndInterface() const override
Return true if the functor implements the end interface.
Definition: midifunctor.h:362
This class exports the object to a JSON timemap file.
Definition: midifunctor.h:484
bool ImplementsEndInterface() const override
Return true if the functor implements the end interface.
Definition: midifunctor.h:497
This class initializes the MIDI export.
Definition: midifunctor.h:280
bool ImplementsEndInterface() const override
Return true if the functor implements the end interface.
Definition: midifunctor.h:293
This class calculates the maximum duration of each measure.
Definition: midifunctor.h:88
bool ImplementsEndInterface() const override
Return true if the functor implements the end interface.
Definition: midifunctor.h:101
This class prepares Note onsets.
Definition: midifunctor.h:35
bool ImplementsEndInterface() const override
Return true if the functor implements the end interface.
Definition: midifunctor.h:48
This class adjusts note duration for grace notes and arpeggios.
Definition: midifunctor.h:188
bool ImplementsEndInterface() const override
Return true if the functor implements the end interface.
Definition: midifunctor.h:201
This class adjusts note timings based on ties.
Definition: midifunctor.h:150
bool ImplementsEndInterface() const override
Return true if the functor implements the end interface.
Definition: midifunctor.h:163
This class is a base class for the Layer (<layer>) content.
Definition: layerelement.h:51
This class represents a layer in a laid-out score (Doc).
Definition: layer.h:40
This class represents a measure in a page-based score (Doc).
Definition: measure.h:46
This class represents a basic object.
Definition: object.h:66
This class models the MEI <octave> element.
Definition: octave.h:31
This class represents a staff in a laid-out score (Doc).
Definition: staff.h:110
This class models the MEI <tabGrp> element.
Definition: tabgrp.h:24
This class models the MEI <tie> element.
Definition: tie.h:32
This class holds a timemap for exporting onset / offset values.
Definition: timemap.h:52
Regroup pointers to meterSig, mensur and proport objects.
Definition: alignfunctor.h:21
Helper struct for held notes in tablature.
Definition: midifunctor.h:341
Helper struct to store note sequences which replace notes in MIDI output due to expanded ornaments an...
Definition: midifunctor.h:331
Helper struct to store octave data.
Definition: midifunctor.h:267