MuseScore  3.4
Music composition and notation
importmidi_operations.h
Go to the documentation of this file.
1 #ifndef IMPORTMIDI_OPERATIONS_H
2 #define IMPORTMIDI_OPERATIONS_H
3 
4 #include "importmidi_inner.h"
5 #include "importmidi_operation.h"
6 #include "midi/midifile.h"
7 
8 
9 namespace Ms {
10 
11 class ReducedFraction;
12 class InstrumentTemplate;
13 
14 namespace MidiCharset {
15  QString defaultCharset();
16 }
17 namespace Quantize {
19 }
20 
21 namespace MidiOperations {
22 
23 // operation types are in importmidi_operation.h
24 
25 // to add an operation one need to add code also to:
26 // - importmidi_operation.h,
27 // - importmidi_opmodel.cpp (2 places),
28 // - importmidi_trmodel.cpp (2 places),
29 // and - other importmidi files where algorithm requires it
30 
31 template<typename T>
32 class TrackOp
33  {
34  public:
35  explicit TrackOp(T defaultValue)
36  : _operation{{-1, defaultValue}}, _canRedefineDefaultLater(true)
37  {}
38 
39  const T& value(int trackIndex) const
40  {
41  const auto it = _operation.find(trackIndex);
42  if (it == _operation.end())
43  return _operation.find(-1)->second;
44  return it->second;
45  }
46 
47  void setValue(int trackIndex, T value)
48  {
49  Q_ASSERT_X(trackIndex >= 0, "TrackOperation", "Invalid track index");
50 
51  if (value != this->value(trackIndex))
52  _operation[trackIndex] = value;
53  }
54 
55  const T& defaultValue() const
56  {
57  return _operation.find(-1)->second;
58  }
59 
60  bool canRedefineDefaultLater() const { return _canRedefineDefaultLater; }
61 
62  void setDefaultValue(T value, bool canRedefineDefaultLater = true)
63  {
64  Q_ASSERT_X(_canRedefineDefaultLater, "TrackOp::setDefaultValue",
65  "Cannot set default value");
66 
67  if (!_canRedefineDefaultLater)
68  return;
69  _operation[-1] = value;
70  _canRedefineDefaultLater = canRedefineDefaultLater;
71  }
72 
73  void clear()
74  {
75  T defaultVal = defaultValue();
76  _operation.clear();
77  _operation[-1] = defaultVal;
78  }
79  private:
80  // <track index, operation value>
81  // if track index == -1 then it's default value (for all tracks)
82  std::map<int, T> _operation;
84  };
85 
86 template<typename T>
87 class Op
88  {
89  public:
90 
91  explicit Op(T defaultValue)
92  : _value(defaultValue), _valueWasSet(false),
93  _defaultValue{defaultValue}, _canRedefineDefaultLater(true)
94  {}
95 
96  T value() const
97  {
98  if (!_valueWasSet)
99  return _defaultValue;
100  return _value;
101  }
102 
103  void setValue(T value)
104  {
105  if (value != this->value()) {
106  _value = value;
107  _valueWasSet = true;
108  }
109  }
110 
111  T defaultValue() const
112  {
113  return _defaultValue;
114  }
115 
116  bool canRedefineDefaultLater() const { return _canRedefineDefaultLater; }
117 
118  void setDefaultValue(T value, bool canRedefineDefaultLater = true)
119  {
120  Q_ASSERT_X(_canRedefineDefaultLater, "Op::setDefaultValue",
121  "Cannot set default value");
122 
123  if (!_canRedefineDefaultLater)
124  return;
125  _defaultValue = value;
126  _canRedefineDefaultLater = canRedefineDefaultLater;
127  }
128  private:
133  };
134 
135 // values that can be changed
136 
137 struct Opers
138  {
139  // data that cannot be changed by the user
140  TrackOp<int> channel = TrackOp<int>(int());
141  TrackOp<std::string> staffName = TrackOp<std::string>(std::string()); // will be converted to unicode later
142  TrackOp<QString> midiInstrName = TrackOp<QString>(QString());
145  std::vector<const InstrumentTemplate *>());
146  TrackOp<bool> isDrumTrack = TrackOp<bool>(false);
147 
148  // operations for all tracks
150  Op<bool> searchPickupMeasure = Op<bool>(true);
151  Op<bool> measureCount2xLess = Op<bool>(false);
152  Op<bool> showTempoText = Op<bool>(true);
153  Op<bool> showChordNames = Op<bool>(true);
154  Op<TimeSigNumerator> timeSigNumerator = Op<TimeSigNumerator>(TimeSigNumerator::_4);
155  Op<TimeSigDenominator> timeSigDenominator = Op<TimeSigDenominator>(TimeSigDenominator::_4);
156 
157  // operations for individual tracks
158  TrackOp<int> trackIndexAfterReorder = TrackOp<int>(0);
159  TrackOp<bool> doImport = TrackOp<bool>(true);
161  TrackOp<bool> searchTuplets = TrackOp<bool>(true);
162  TrackOp<bool> search2plets = TrackOp<bool>(false);
163  TrackOp<bool> search3plets = TrackOp<bool>(true);
164  TrackOp<bool> search4plets = TrackOp<bool>(true);
165  TrackOp<bool> search5plets = TrackOp<bool>(true);
166  TrackOp<bool> search7plets = TrackOp<bool>(true);
167  TrackOp<bool> search9plets = TrackOp<bool>(true);
168  TrackOp<bool> useDots = TrackOp<bool>(true);
169  TrackOp<bool> simplifyDurations = TrackOp<bool>(true); // for drum tracks - remove rests and ties
170  TrackOp<bool> showStaccato = TrackOp<bool>(true);
171  TrackOp<bool> doStaffSplit = TrackOp<bool>(false); // for drum tracks - split by voices
172  TrackOp<VoiceCount> maxVoiceCount = TrackOp<VoiceCount>(VoiceCount::V_4);
173  TrackOp<bool> changeClef = TrackOp<bool>(true);
174  TrackOp<Swing> swing = TrackOp<Swing>(Swing::NONE);
175  TrackOp<bool> removeDrumRests = TrackOp<bool>(true);
176  TrackOp<int> lyricTrackIndex = TrackOp<int>(-1); // empty lyric
177  TrackOp<int> msInstrIndex = TrackOp<int>(-1); // for empty instrument list
178  };
179 
181  {
182  std::set<ReducedFraction> beatSet;
183  // to adapt human beats to a different time sig, if necessary
184  int addedFirstBeats = 0;
185  int addedLastBeats = 0;
189  bool measureCount2xLess = false;
190  };
191 
192 struct FileData
193  {
195  QList<MTrack> tracks;
196  int processingsOfOpenedFile = 0;
197  bool hasTempoText = false;
198  QByteArray HHeaderData;
199  QByteArray VHeaderData;
200  int trackCount = 0;
202  QString charset = MidiCharset::defaultCharset();
203  // after the user apply MIDI import operations
204  // this value should be set to false
205  // tracks of <tick, lyric fragment> from karaoke files
206  // QList of lyric tracks - there can be multiple lyric tracks,
207  // lyric track count != MIDI track count in general
208  QList<std::multimap<ReducedFraction, std::string>> lyricTracks;
209  std::multimap<ReducedFraction, QString> chordNames;
211  };
212 
213 class Data
214  {
215  public:
216  FileData* data();
217  const FileData* data() const;
218 
219  void addNewMidiFile(const QString &fileName);
220  int currentTrack() const;
221  void setMidiFileData(const QString &fileName, const MidiFile &midiFile);
222  void excludeMidiFile(const QString &fileName);
223  bool hasMidiFile(const QString &fileName);
224  const MidiFile* midiFile(const QString &fileName);
225  QStringList allMidiFiles() const;
226  void setOperationsFile(const QString &fileName);
227 
228  private:
229  friend class CurrentTrackSetter;
230  friend class CurrentMidiFileSetter;
231 
234  int _currentTrack = -1;
235 
236  std::map<QString, FileData> _data; // <file name, tracks data>
237  };
238 
239 // scoped setter of current track
241  {
242  public:
243  CurrentTrackSetter(Data &opers, int track)
244  : _opers(opers)
245  {
246  _oldValue = _opers._currentTrack;
247  _opers._currentTrack = track;
248  }
249 
251  {
252  _opers._currentTrack = _oldValue;
253  }
254  private:
257  // disallow heap allocation - for stack-only usage
258  void* operator new(size_t); // standard new
259  void* operator new(size_t, void*); // placement new
260  void* operator new[](size_t); // array new
261  void* operator new[](size_t, void*); // placement array new
262  };
263 
264 // scoped setter of current MIDI file
266  {
267  public:
268  CurrentMidiFileSetter(Data &opers, const QString &fileName)
269  : _opers(opers)
270  {
271  _oldValue = _opers._currentMidiFile;
272  _opers._currentMidiFile = fileName;
273  }
274 
276  {
277  _opers._currentMidiFile = _oldValue;
278  }
279  private:
281  QString _oldValue;
282  // disallow heap allocation - for stack-only usage
283  void* operator new(size_t); // standard new
284  void* operator new(size_t, void*); // placement new
285  void* operator new[](size_t); // array new
286  void* operator new[](size_t, void*); // placement array new
287  };
288 
289 } // namespace MidiOperations
290 
292 } // namespace Ms
293 
294 
295 #endif // IMPORTMIDI_OPERATIONS_H
Definition: importmidi_operations.h:240
std::map< int, T > _operation
Definition: importmidi_operations.h:82
Definition: importmidi_operations.h:87
Definition: importmidi_operations.h:213
QString _midiOperationsFile
Definition: importmidi_operations.h:233
T _value
Definition: importmidi_operations.h:129
void setValue(int trackIndex, T value)
Definition: importmidi_operations.h:47
bool canRedefineDefaultLater() const
Definition: importmidi_operations.h:116
void setValue(T value)
Definition: importmidi_operations.h:103
CurrentTrackSetter(Data &opers, int track)
Definition: importmidi_operations.h:243
QuantValue
Definition: importmidi_operation.h:16
Definition: importmidi_operations.h:192
std::map< QString, FileData > _data
Definition: importmidi_operations.h:236
~CurrentTrackSetter()
Definition: importmidi_operations.h:250
Opers trackOpers
Definition: importmidi_operations.h:201
bool _valueWasSet
Definition: importmidi_operations.h:130
TrackOp(T defaultValue)
Definition: importmidi_operations.h:35
MidiOperations::Data midiImportOperations
Definition: importmidi_operations.cpp:6
ReducedFraction firstChordTick
Definition: importmidi_operations.h:186
void clear()
Definition: importmidi_operations.h:73
const T & defaultValue() const
Definition: importmidi_operations.h:55
bool _canRedefineDefaultLater
Definition: importmidi_operations.h:132
T value() const
Definition: importmidi_operations.h:96
QString _currentMidiFile
Definition: importmidi_operations.h:232
QList< MTrack > tracks
Definition: importmidi_operations.h:195
void simplifyDurations(std::multimap< int, MTrack > &tracks, const TimeSigMap *sigmap, bool simplifyDrumTracks)
Definition: importmidi_simplify.cpp:276
QByteArray HHeaderData
Definition: importmidi_operations.h:198
Definition: midifile.h:70
ReducedFraction lastChordTick
Definition: importmidi_operations.h:187
void setDefaultValue(T value, bool canRedefineDefaultLater=true)
Definition: importmidi_operations.h:118
ReducedFraction timeSig
Definition: importmidi_operations.h:188
bool isHumanPerformance(const std::multimap< ReducedFraction, MidiChord > &chords, const TimeSigMap *sigmap)
Definition: importmidi_quant.cpp:338
Definition: importmidi_operations.h:180
QByteArray VHeaderData
Definition: importmidi_operations.h:199
Definition: aeolus.cpp:26
HumanBeatData humanBeatData
Definition: importmidi_operations.h:210
bool _canRedefineDefaultLater
Definition: importmidi_operations.h:83
Definition: importmidi_operations.h:32
void setDefaultValue(T value, bool canRedefineDefaultLater=true)
Definition: importmidi_operations.h:62
~CurrentMidiFileSetter()
Definition: importmidi_operations.h:275
QString defaultCharset()
Definition: importmidi_inner.cpp:246
Op(T defaultValue)
Definition: importmidi_operations.h:91
std::multimap< ReducedFraction, QString > chordNames
Definition: importmidi_operations.h:209
std::set< ReducedFraction > beatSet
Definition: importmidi_operations.h:182
QString _oldValue
Definition: importmidi_operations.h:281
MidiOperations::QuantValue defaultQuantValueFromPreferences()
Definition: importmidi_quant.cpp:81
Definition: importmidi_operations.h:265
Data & _opers
Definition: importmidi_operations.h:280
bool canRedefineDefaultLater() const
Definition: importmidi_operations.h:60
Definition: importmidi_fraction.h:9
const T & value(int trackIndex) const
Definition: importmidi_operations.h:39
T _defaultValue
Definition: importmidi_operations.h:131
QList< std::multimap< ReducedFraction, std::string > > lyricTracks
Definition: importmidi_operations.h:208
MidiFile midiFile
Definition: importmidi_operations.h:194
Data & _opers
Definition: importmidi_operations.h:255
CurrentMidiFileSetter(Data &opers, const QString &fileName)
Definition: importmidi_operations.h:268
T defaultValue() const
Definition: importmidi_operations.h:111
Definition: importmidi_operations.h:137
int _oldValue
Definition: importmidi_operations.h:256