1 //========================================================= 2 // MusE 3 // Linux Music Editor 4 // operations.h 5 // (C) Copyright 2014, 2016 Tim E. Real (terminator356 on users dot sourceforge dot net) 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU General Public License 9 // as published by the Free Software Foundation; version 2 of 10 // the License, or (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License 18 // along with this program; if not, write to the Free Software 19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 // 21 //========================================================= 22 23 #ifndef __OPERATIONS_H__ 24 #define __OPERATIONS_H__ 25 26 #include <list> 27 #include <map> 28 #include <set> 29 #include <stdint.h> 30 31 #include "type_defs.h" 32 #include "muse_time.h" 33 #include "event.h" 34 #include "midictrl.h" 35 #include "ctrl.h" 36 #include "time_stretch.h" 37 #include "part.h" 38 #include "track.h" 39 #include "route.h" 40 #include "mididev.h" 41 #include "marker/marker.h" 42 #include "instruments/minstrument.h" 43 #include "wave.h" 44 #include "pos.h" 45 46 namespace MusECore { 47 48 // Forward declarations: 49 class TempoList; 50 class SigList; 51 class KeyList; 52 class MidiPort; 53 class MetroAccentsMap; 54 class AudioConverterSettingsGroup; 55 class AudioConverterPluginI; 56 57 typedef std::list < iMidiCtrlValList > MidiCtrlValListIterators_t; 58 typedef MidiCtrlValListIterators_t::iterator iMidiCtrlValListIterators_t; 59 typedef MidiCtrlValListIterators_t::const_iterator ciMidiCtrlValListIterators_t; 60 class MidiCtrlValListIterators : public MidiCtrlValListIterators_t 61 { 62 public: 63 iterator findList(const MidiCtrlValList* valList); 64 const_iterator findList(const MidiCtrlValList* valList) const; 65 }; 66 67 typedef std::map < int /*port*/, MidiCtrlValListIterators, std::less<int> > MidiCtrlValLists2bErased_t; 68 typedef MidiCtrlValLists2bErased_t::iterator iMidiCtrlValLists2bErased_t; 69 typedef MidiCtrlValLists2bErased_t::const_iterator ciMidiCtrlValLists2bErased_t; 70 typedef std::pair<iMidiCtrlValLists2bErased_t, bool> MidiCtrlValLists2bErasedInsertResult_t; 71 typedef std::pair<int, MidiCtrlValListIterators> MidiCtrlValLists2bErasedInsertPair_t; 72 typedef std::pair<iMidiCtrlValLists2bErased_t, iMidiCtrlValLists2bErased_t> MidiCtrlValLists2bErasedRangePair_t; 73 74 class MidiCtrlValLists2bErased : public MidiCtrlValLists2bErased_t 75 { 76 public: 77 void add(int port, const iMidiCtrlValList& item); 78 iterator findList(int port, const MidiCtrlValList* valList); 79 const_iterator findList(int port, const MidiCtrlValList* valList) const; 80 }; 81 82 83 typedef std::set < MidiCtrlValList* > MidiCtrlValLists2bDeleted_t; 84 typedef MidiCtrlValLists2bDeleted_t::iterator iMidiCtrlValLists2bDeleted_t; 85 typedef MidiCtrlValLists2bDeleted_t::const_iterator ciMidiCtrlValLists2bDeleted_t; 86 class MidiCtrlValLists2bDeleted : public MidiCtrlValLists2bDeleted_t 87 { 88 89 }; 90 91 92 typedef std::map < int /*port*/, MidiCtrlValListList*, std::less<int> > MidiCtrlValLists2bAdded_t; 93 typedef MidiCtrlValLists2bAdded_t::iterator iMidiCtrlValLists2bAdded_t; 94 typedef MidiCtrlValLists2bAdded_t::const_iterator ciMidiCtrlValLists2bAdded_t; 95 typedef std::pair<iMidiCtrlValLists2bAdded_t, bool> MidiCtrlValLists2bAddedInsertResult_t; 96 typedef std::pair<int, MidiCtrlValListList*> MidiCtrlValLists2bAddedInsertPair_t; 97 typedef std::pair<iMidiCtrlValLists2bAdded_t, iMidiCtrlValLists2bAdded_t> MidiCtrlValLists2bAddedRangePair_t; 98 99 class MidiCtrlValLists2bAdded : public MidiCtrlValLists2bAdded_t 100 { 101 // public: 102 // void add(int port, const MidiCtrlValListList* item); 103 // void remove(int port, const MidiCtrlValListList* item); 104 }; 105 106 107 struct MidiCtrlValRemapOperation 108 { 109 // Iterators to be erased in realtime stage. 110 MidiCtrlValLists2bErased _midiCtrlValLists2bErased; 111 // New items to be added in realtime stage. 112 MidiCtrlValLists2bAdded _midiCtrlValLists2bAdded; 113 // Orphaned pointers after the iterators have been erased, deleted in post non-realtime stage. 114 // Automatically filled by constructor. 115 MidiCtrlValLists2bDeleted_t _midiCtrlValLists2bDeleted; 116 }; 117 118 struct DrumMapTrackOperation 119 { 120 // Whether this is a setting operation or a reset to defaults. 121 bool _isReset; 122 bool _isInstrumentMod; 123 bool _doWholeMap; 124 bool _includeDefault; 125 WorkingDrumMapList _workingItemList; 126 // List of tracks to apply to. 127 MidiTrackList _tracks; 128 }; 129 130 struct DrumMapTrackPatchOperation 131 { 132 // Whether to clear the list of overrides. 133 bool _clear; 134 // Whether this is a setting operation or a reset to defaults. 135 bool _isReset; 136 bool _isInstrumentMod; 137 WorkingDrumMapPatchList _workingItemPatchList; 138 // List of tracks to apply to. 139 MidiTrackList _tracks; 140 }; 141 142 struct DrumMapTrackPatchReplaceOperation 143 { 144 bool _isInstrumentMod; 145 WorkingDrumMapPatchList* _workingItemPatchList; 146 // Track to apply to. 147 MidiTrack* _track; 148 }; 149 150 // New items created in GUI thread awaiting addition in audio thread. 151 struct PendingOperationItem 152 { 153 enum PendingOperationType { 154 Uninitialized = 0, 155 ModifySongLength, 156 AddMidiInstrument, DeleteMidiInstrument, ReplaceMidiInstrument, 157 AddMidiDevice, DeleteMidiDevice, 158 ModifyMidiDeviceAddress, ModifyMidiDeviceFlags, ModifyMidiDeviceName, 159 SetInstrument, 160 AddTrack, DeleteTrack, MoveTrack, ModifyTrackName, 161 SetTrackRecord, SetTrackMute, SetTrackSolo, SetTrackRecMonitor, SetTrackOff, 162 ModifyTrackDrumMapItem, ReplaceTrackDrumMapPatchList, UpdateDrumMaps, 163 AddPart, DeletePart, MovePart, SelectPart, ModifyPartStart, ModifyPartLength, ModifyPartName, 164 AddEvent, DeleteEvent, SelectEvent, ModifyEventList, 165 166 AddMidiCtrlVal, DeleteMidiCtrlVal, ModifyMidiCtrlVal, AddMidiCtrlValList, 167 ModifyMidiCtrlValList, 168 169 RemapDrumControllers, 170 AddAudioCtrlVal, DeleteAudioCtrlVal, ModifyAudioCtrlVal, ModifyAudioCtrlValList, 171 ModifyTempoList, SetStaticTempo, SetGlobalTempo, 172 ModifySigList, 173 ModifyKeyList, 174 175 ModifyDefaultAudioConverterSettings, ModifyLocalAudioConverterSettings, ModifyLocalAudioConverter, 176 SetAudioConverterOfflineMode, 177 AddStretchListRatioAt, DeleteStretchListRatioAt, ModifyStretchListRatioAt, 178 ModifyStretchListRatio, 179 180 AddAuxSendValue, 181 AddRoute, DeleteRoute, 182 AddRouteNode, DeleteRouteNode, ModifyRouteNode, 183 UpdateSoloStates, 184 EnableAllAudioControllers, 185 GlobalSelectAllEvents, 186 ModifyAudioSamples, 187 SwitchMetronomeSettings, ModifyMetronomeAccentMap, 188 SetExternalSyncFlag, SetUseJackTransport, SetUseMasterTrack, 189 ModifyMarkerList 190 }; 191 192 PendingOperationType _type; 193 194 union { 195 Part* _part; 196 MidiPort* _midi_port; 197 void* _void_track_list; 198 int* _audioSamplesLen; 199 }; 200 201 union { 202 EventList* _orig_event_list; 203 MidiCtrlValList* _orig_mcvl; 204 MidiCtrlValListList* _mcvll; 205 CtrlListList* _aud_ctrl_list_list; 206 TempoList* _orig_tempo_list; 207 MusECore::SigList* _orig_sig_list; 208 KeyList* _orig_key_list; 209 StretchList* _stretch_list; 210 PartList* _part_list; 211 TrackList* _track_list; 212 MidiDeviceList* _midi_device_list; 213 MidiInstrumentList* _midi_instrument_list; 214 AuxSendValueList* _aux_send_value_list; 215 RouteList* _route_list; 216 MarkerList** _orig_marker_list; 217 float** _audioSamplesPointer; 218 MetroAccentsMap** _metroAccentsMap; 219 }; 220 221 union { 222 EventList* _event_list; 223 MidiInstrument* _midi_instrument; 224 MidiDevice* _midi_device; 225 Track* _track; 226 MidiCtrlValList* _mcvl; 227 CtrlList* _aud_ctrl_list; 228 MarkerList* _marker_list; 229 TempoList* _tempo_list; 230 MusECore::SigList* _sig_list; 231 KeyList* _key_list; 232 Route* _dst_route_pointer; 233 float* _newAudioSamples; 234 bool* _bool_pointer; 235 MetroAccentsMap* _newMetroAccentsMap; 236 AudioConverterSettingsGroup* _audio_converter_settings; 237 }; 238 239 iPart _iPart; 240 Event _ev; 241 iEvent _iev; 242 iMidiCtrlVal _imcv; 243 iCtrl _iCtrl; 244 iCtrlList _iCtrlList; 245 iStretchListItem _iStretchEvent; 246 iMidiInstrument _iMidiInstrument; 247 iMidiDevice _iMidiDevice; 248 iRoute _iRoute; 249 iMarker _iMarker; 250 Route _src_route; 251 Route _dst_route; 252 // SndFileR is only 8 bytes but can't be in a union becuase of non-trivial destructor (?). 253 SndFileR _sndFileR; 254 255 union { 256 int _intA; 257 unsigned int _uintA; 258 unsigned int _posLenVal; 259 bool _boolA; 260 const QString *_name; 261 double _aux_send_value; 262 int _insert_at; 263 int _from_idx; 264 int _address_client; 265 int _rw_flags; 266 int _newAudioSamplesLen; 267 //DrumMapOperation* _drum_map_operation; 268 DrumMapTrackOperation* _drum_map_track_operation; 269 DrumMapTrackPatchOperation* _drum_map_track_patch_operation; 270 DrumMapTrackPatchReplaceOperation* _drum_map_track_patch_replace_operation; 271 MidiCtrlValRemapOperation* _midi_ctrl_val_remap_operation; 272 MuseFrame_t _museFrame; 273 AudioConverterPluginI* _audio_converter; 274 }; 275 276 union { 277 int _intB; 278 unsigned int _uintB; 279 unsigned int _lenVal; 280 unsigned int _marker_tick; 281 int _to_idx; 282 int _address_port; 283 int _open_flags; 284 int _ctl_num; 285 int _stretch_type; 286 AudioConverterPluginI* _audio_converter_ui; 287 }; 288 289 union { 290 int _intC; 291 unsigned int _uintC; 292 int _ctl_val; 293 double _ctl_dbl_val; 294 double _audio_converter_value; 295 bool _marker_lock; 296 }; 297 298 PendingOperationItem(AudioConverterSettingsGroup* new_settings, 299 PendingOperationType type = ModifyDefaultAudioConverterSettings) 300 { _type = type; _audio_converter_settings = new_settings; } 301 302 PendingOperationItem(SndFileR sf, AudioConverterSettingsGroup* new_settings, 303 PendingOperationType type = ModifyLocalAudioConverterSettings) 304 { _type = type; _sndFileR = sf; 305 _audio_converter_settings = new_settings; } 306 307 PendingOperationItem(SndFileR sf, 308 AudioConverterPluginI* newAudioConverter, 309 AudioConverterPluginI* newAudioConverterUI, 310 PendingOperationType type = ModifyLocalAudioConverter) 311 { _type = type; _sndFileR = sf; 312 _audio_converter = newAudioConverter; 313 _audio_converter_ui = newAudioConverterUI; } 314 315 PendingOperationItem(SndFileR sf, AudioConverterPluginI* newAudioConverter, 316 PendingOperationType type = SetAudioConverterOfflineMode) 317 { _type = type; _sndFileR = sf; _audio_converter = newAudioConverter; } 318 319 320 PendingOperationItem(float** samples, float* new_samples, int* samples_len, int new_samples_len, 321 PendingOperationType type = ModifyAudioSamples) 322 { _type = type; _audioSamplesPointer = samples; _newAudioSamples = new_samples; 323 _audioSamplesLen = samples_len, _newAudioSamplesLen = new_samples_len; } 324 325 326 // The operation is constructed and allocated in non-realtime before the call, then the controllers modified in realtime stage, 327 // then operation is deleted in non-realtime stage. 328 PendingOperationItem(MidiCtrlValRemapOperation* operation, PendingOperationType type = RemapDrumControllers) 329 { _type = type; _midi_ctrl_val_remap_operation = operation; } 330 331 // The operation is constructed and allocated in non-realtime before the call, then the track's map is modified in realtime stage, 332 // then operation is deleted in non-realtime stage. 333 PendingOperationItem(DrumMapTrackOperation* operation, PendingOperationType type = ModifyTrackDrumMapItem) 334 { _type = type; _drum_map_track_operation = operation; } 335 336 // The operation is constructed and allocated in non-realtime before the call, then the track's map is modified in realtime stage, 337 // then operation is deleted in non-realtime stage. 338 PendingOperationItem(DrumMapTrackPatchReplaceOperation* operation, PendingOperationType type = ReplaceTrackDrumMapPatchList) 339 { _type = type; _drum_map_track_patch_replace_operation = operation; } 340 341 PendingOperationItem(MidiPort* mp, PendingOperationType type = UpdateDrumMaps) 342 { _type = type; _midi_port = mp; } 343 344 PendingOperationItem(TrackList* tl, PendingOperationType type = UpdateSoloStates) 345 { _type = type; _track_list = tl; } 346 347 // TODO: Try to break this operation down so that only the actual operation is executed stage-2. PendingOperationItemPendingOperationItem348 PendingOperationItem(const Route& src_route, const Route& dst_route, PendingOperationType type) // Type is AddRoute or DeleteRoute. 349 { _type = type; _src_route = src_route; _dst_route = dst_route; } 350 351 PendingOperationItem(RouteList* route_list, const Route& route, PendingOperationType type = AddRouteNode) 352 { _type = type; _route_list = route_list; _src_route = route; } 353 354 PendingOperationItem(RouteList* route_list, const iRoute& ir, PendingOperationType type = DeleteRouteNode) 355 { _type = type; _route_list = route_list; _iRoute = ir; } 356 357 PendingOperationItem(const Route& src_route, Route* dst_route, PendingOperationType type = ModifyRouteNode) 358 { _type = type; _src_route = src_route; _dst_route_pointer = dst_route; } 359 360 PendingOperationItem(AuxSendValueList* asvl, double val, PendingOperationType type = AddAuxSendValue) 361 { _type = type; _aux_send_value_list = asvl; _aux_send_value = val; } 362 363 PendingOperationItem(MidiInstrumentList* mil, MidiInstrument* midi_instrument, PendingOperationType type = AddMidiInstrument) 364 { _type = type; _midi_instrument_list = mil; _midi_instrument = midi_instrument; } 365 366 PendingOperationItem(MidiInstrumentList* mil, const iMidiInstrument& imi, PendingOperationType type = DeleteMidiInstrument) 367 { _type = type; _midi_instrument_list = mil; _iMidiInstrument = imi; } 368 369 PendingOperationItem(MidiInstrumentList* mil, const iMidiInstrument& imi, MidiInstrument* new_instrument, 370 PendingOperationType type = ReplaceMidiInstrument) 371 { _type = type; _midi_instrument_list = mil; _iMidiInstrument = imi; _midi_instrument = new_instrument; } 372 373 PendingOperationItem(MidiDeviceList* mdl, MidiDevice* midi_device, PendingOperationType type = AddMidiDevice) 374 { _type = type; _midi_device_list = mdl; _midi_device = midi_device; } 375 376 PendingOperationItem(MidiDeviceList* mdl, const iMidiDevice& imd, PendingOperationType type = DeleteMidiDevice) 377 { _type = type; _midi_device_list = mdl; _iMidiDevice = imd; } 378 379 // Type is ModifyMidiDeviceAddress or ModifyMidiDeviceFlags PendingOperationItemPendingOperationItem380 PendingOperationItem(MidiDevice* midi_device, int address_client_or_rw_flags, int address_port_or_open_flags, PendingOperationType type) 381 { _type = type; _midi_device = midi_device; _intA = address_client_or_rw_flags; _intB = address_port_or_open_flags; } 382 383 PendingOperationItem(MidiDevice* midi_device, const QString* new_name, PendingOperationType type = ModifyMidiDeviceName) 384 { _type = type; _midi_device = midi_device; _name = new_name; } 385 386 387 PendingOperationItem(MidiPort* midi_port, MidiInstrument* midi_instrument, PendingOperationType type = SetInstrument) 388 { _type = type; _midi_port = midi_port; _midi_instrument = midi_instrument; } 389 390 391 PendingOperationItem(TrackList* tl, Track* track, int insert_at, PendingOperationType type = AddTrack, void* sec_track_list = 0) 392 { _type = type; _track_list = tl; _track = track; _insert_at = insert_at; _void_track_list = sec_track_list; } 393 394 PendingOperationItem(TrackList* tl, Track* track, PendingOperationType type = DeleteTrack, void* sec_track_list = 0) 395 { _type = type; _track_list = tl; _track = track; _void_track_list = sec_track_list; } 396 397 PendingOperationItem(TrackList* tl, int from_idx, int to_idx, PendingOperationType type = MoveTrack) 398 { _type = type; _track_list = tl; _from_idx = from_idx; _to_idx = to_idx; } 399 400 PendingOperationItem(TrackList* tl, bool select, unsigned long /*t0*/, unsigned long /*t1*/, 401 PendingOperationType type = GlobalSelectAllEvents) 402 { _type = type; _track_list = tl; 403 _boolA = select; } 404 405 PendingOperationItem(Track* track, const QString* new_name, PendingOperationType type = ModifyTrackName) 406 { _type = type; _track = track; _name = new_name; } 407 408 // type is SetTrackRecord, SetTrackMute, SetTrackSolo, SetTrackRecMonitor, SetTrackOff PendingOperationItemPendingOperationItem409 PendingOperationItem(Track* track, bool v, PendingOperationType type) 410 { _type = type; _track = track; _boolA = v; } 411 412 413 PendingOperationItem(Part* part, const QString* new_name, PendingOperationType type = ModifyPartName) 414 { _type = type; _part = part; _name = new_name; } 415 416 PendingOperationItem(Part* part, bool v, PendingOperationType type = SelectPart) 417 { _type = type; _part = part; _boolA = v; } 418 419 // new_pos and new_len must already be in the part's time domain (ticks or frames). 420 // The new_event_list can be set to null, or if the part's events are to be dragged with the border 421 // it can be supplied to do a wholesale fast constant-time swap of the event lists. 422 PendingOperationItem(iPart ip, Part* part, unsigned int new_pos, unsigned int new_len, 423 EventList* new_event_list, PendingOperationType type = ModifyPartStart) 424 { _type = type; _iPart = ip, _part = part; _event_list = new_event_list; _posLenVal = new_pos; _lenVal = new_len; } 425 426 // new_len must already be in the part's time domain (ticks or frames). 427 // The new_event_list can be set to null, or if the part's events are to be dragged with the border 428 // it can be supplied to do a wholesale fast constant-time swap of the event lists. 429 PendingOperationItem(iPart ip, Part* part, unsigned int new_len, EventList* new_event_list, PendingOperationType type = ModifyPartLength) 430 { _type = type; _iPart = ip, _part = part; _event_list = new_event_list; _posLenVal = new_len; } 431 432 // Erases ip from part->track()->parts(), then adds part to new_track. NOTE: ip may be part->track()->parts()->end(). 433 // new_pos must already be in the part's time domain (ticks or frames). 434 PendingOperationItem(iPart ip, Part* part, unsigned int new_pos, PendingOperationType type = MovePart, Track* new_track = 0) 435 { _type = type; _iPart = ip; _part = part; _track = new_track; 436 _posLenVal = new_pos;} 437 438 PendingOperationItem(PartList* pl, Part* part, PendingOperationType type = AddPart) 439 { _type = type; _part_list = pl; _part = part; } 440 441 PendingOperationItem(PartList* pl, const iPart& ip, PendingOperationType type = DeletePart) 442 { _type = type; _part_list = pl; _iPart = ip; } 443 444 445 PendingOperationItem(Part* part, const Event& ev, PendingOperationType type = AddEvent) 446 { _type = type; _part = part; _ev = ev; } 447 448 // NOTE: To avoid possibly deleting the event in RT stage 2 when the event is erased from the list, 449 // _ev is used simply to hold a reference until non-RT stage 3 or after, when the list is cleared. 450 PendingOperationItem(Part* part, const iEvent& iev, PendingOperationType type = DeleteEvent) 451 { _type = type; _part = part; _iev = iev; _ev = iev->second; } 452 453 // Type is SelectEvent, or some (likely) future boolean operation. PendingOperationItemPendingOperationItem454 PendingOperationItem(Part* part, const Event& ev, int v, PendingOperationType type) 455 { _type = type; _part = part; _ev = ev; _intA = v; } 456 457 458 PendingOperationItem(MidiCtrlValListList* mcvll, MidiCtrlValList* mcvl, int channel, int control_num, PendingOperationType type = AddMidiCtrlValList) 459 { _type = type; _mcvll = mcvll; _mcvl = mcvl; _intA = channel; _intB = control_num; } 460 461 PendingOperationItem(const iCtrlList& ictl_l, CtrlList* ctrl_l, PendingOperationType type = ModifyAudioCtrlValList) 462 { _type = type; _iCtrlList = ictl_l; _aud_ctrl_list = ctrl_l; } 463 464 PendingOperationItem(MidiCtrlValList* mcvl, Part* part, unsigned int tick, int val, PendingOperationType type = AddMidiCtrlVal) 465 { _type = type; _mcvl = mcvl; _part = part; 466 _posLenVal = tick; _intB = val; } 467 468 PendingOperationItem(MidiCtrlValList* mcvl, const iMidiCtrlVal& imcv, PendingOperationType type = DeleteMidiCtrlVal) 469 { _type = type; _mcvl = mcvl; _imcv = imcv; } 470 471 // NOTE: mcvl is supplied in case the operation needs to be merged, or transformed into an AddMidiCtrlVal. 472 PendingOperationItem(MidiCtrlValList* mcvl, const iMidiCtrlVal& imcv, int val, PendingOperationType type = ModifyMidiCtrlVal) 473 { _type = type; _mcvl = mcvl; _imcv = imcv; _intA = val; } 474 475 476 PendingOperationItem(MidiCtrlValList* orig_mcvl, MidiCtrlValList* mcvl, PendingOperationType type = ModifyMidiCtrlValList) 477 { _type = type; _orig_mcvl = orig_mcvl; _mcvl = mcvl; } 478 479 PendingOperationItem(CtrlList* ctrl_l, unsigned int frame, double ctrl_val, PendingOperationType type = AddAudioCtrlVal) 480 { _type = type; _aud_ctrl_list = ctrl_l; _posLenVal = frame; _ctl_dbl_val = ctrl_val; } 481 482 PendingOperationItem(CtrlList* ctrl_l, const iCtrl& ictl, PendingOperationType type = DeleteAudioCtrlVal) 483 { _type = type; _aud_ctrl_list = ctrl_l; _iCtrl = ictl; } 484 485 // NOTE: ctrl_l is supplied in case the operation needs to be merged, or transformed into an AddAudioCtrlVal. 486 PendingOperationItem(CtrlList* ctrl_l, const iCtrl& ictl, unsigned int new_frame, 487 double new_ctrl_val, PendingOperationType type = ModifyAudioCtrlVal) 488 { _type = type; _aud_ctrl_list = ctrl_l; _iCtrl = ictl; _posLenVal = new_frame; _ctl_dbl_val = new_ctrl_val; } 489 490 491 // Takes ownership of the original list so it can be deleted in the non-RT stage. 492 PendingOperationItem(TempoList* orig_tempo_l, TempoList* new_tempo_l, PendingOperationType type = ModifyTempoList) 493 { _type = type; _orig_tempo_list = orig_tempo_l; _tempo_list = new_tempo_l; } 494 495 // type is SetGlobalTempo, SetStaticTempo. PendingOperationItemPendingOperationItem496 PendingOperationItem(TempoList* tl, int tempo, PendingOperationType type) 497 { _type = type; _tempo_list = tl; _intA = tempo; } 498 499 PendingOperationItem(TempoList* tl, bool v, PendingOperationType type = SetUseMasterTrack) 500 { _type = type; _tempo_list = tl; _boolA = v; } 501 502 503 // Takes ownership of the original list so it can be deleted in the non-RT stage. 504 PendingOperationItem(SigList* orig_sig_l, SigList* new_sig_l, PendingOperationType type = ModifySigList) 505 { _type = type; _orig_sig_list = orig_sig_l; _sig_list = new_sig_l; } 506 507 508 // Takes ownership of the original list so it can be deleted in the non-RT stage. 509 PendingOperationItem(KeyList* orig_key_l, KeyList* new_key_l, PendingOperationType type = ModifyKeyList) 510 { _type = type; _orig_key_list = orig_key_l; _key_list = new_key_l; } 511 512 513 PendingOperationItem(int stretchType, StretchList* sl, MuseFrame_t frame, double ratio, PendingOperationType type = AddStretchListRatioAt) 514 { _type = type; _stretch_type = stretchType, _stretch_list = sl; _museFrame = frame; _audio_converter_value = ratio; } 515 516 PendingOperationItem(int stretchTypes, StretchList* sl, const iStretchListItem& ise, PendingOperationType type = DeleteStretchListRatioAt) 517 { _type = type; _stretch_type = stretchTypes, _stretch_list = sl; _iStretchEvent = ise; } 518 519 PendingOperationItem(int stretchType, StretchList* sl, const iStretchListItem& ise, MuseFrame_t new_frame, double ratio, 520 PendingOperationType type = ModifyStretchListRatioAt) 521 { _type = type; _stretch_type = stretchType, _stretch_list = sl; _iStretchEvent = ise; 522 _museFrame = new_frame; _audio_converter_value = ratio; } 523 524 PendingOperationItem(int stretchType, StretchList* sl, double ratio, PendingOperationType type = ModifyStretchListRatio) 525 { _type = type; _stretch_type = stretchType, _stretch_list = sl; _audio_converter_value = ratio; } 526 527 528 PendingOperationItem(unsigned int len, PendingOperationType type = ModifySongLength) 529 { _type = type; _posLenVal = len; } 530 531 PendingOperationItem(MetroAccentsMap** old_map, MetroAccentsMap* new_map, PendingOperationType type = ModifyMetronomeAccentMap) 532 { _type = type; _metroAccentsMap = old_map; _newMetroAccentsMap = new_map; } 533 534 // Type is SwitchMetronomeSettings, SetExternalSyncFlag, SetUseJackTransport. PendingOperationItemPendingOperationItem535 PendingOperationItem(bool* bool_pointer, bool v, PendingOperationType type) 536 { _type = type; _bool_pointer = bool_pointer; _boolA = v; } 537 PendingOperationItemPendingOperationItem538 PendingOperationItem(PendingOperationType type) // type is EnableAllAudioControllers. 539 { _type = type; } 540 541 // Takes ownership of the original list so it can be deleted in the non-RT stage. 542 PendingOperationItem(MarkerList** orig_marker_l, MarkerList* new_marker_l, PendingOperationType type = ModifyMarkerList) 543 { _type = type; _orig_marker_list = orig_marker_l; _marker_list = new_marker_l; } 544 PendingOperationItemPendingOperationItem545 PendingOperationItem() 546 { _type = Uninitialized; } 547 548 // Execute the operation. Called only from RT stage 2. 549 SongChangedStruct_t executeRTStage(); 550 // Execute the operation. Called only from post RT stage 3. 551 SongChangedStruct_t executeNonRTStage(); 552 // Get an appropriate indexing value from ops like AddEvent that use it. Other ops like AddMidiCtrlValList return their type (rather than say, zero). 553 unsigned int getIndex() const; 554 // Whether the two special allocating ops (like AddMidiCtrlValList) are the same. 555 // The comparison ignores the actual allocated value, so that such commands can be found before they do their allocating. 556 bool isAllocationOp(const PendingOperationItem&) const; 557 }; 558 559 class PendingOperationList : public std::list<PendingOperationItem> 560 { 561 private: 562 // Holds sorted version of list. Index is time value for items which have it like events or parts, 563 // otherwise it is the operation type for other items. It doesn't matter too much that ticks and frames 564 // are mixed here, sorting by time is just to speed up searches, we look for operation types. 565 std::multimap<unsigned int, iterator, std::less<unsigned int> > _map; 566 // Accumulated song changed flags. 567 SongChangedStruct_t _sc_flags; 568 569 public: PendingOperationList()570 PendingOperationList() : _sc_flags(0) { } 571 // Add an operation. Returns false if the operation already exists or could not be added 572 // (such as with a DeleteEvent being cancelled by an AddEvent on identical base events), 573 // or various other optimizations that essentially render the operation ineffectual. 574 // Some operations optimize by replacing an existing operation with the requested one. 575 // For example requesting operations which simply change a value replace any existing 576 // such operation with the requested new value. Thus only one operation exists - the LATEST. 577 // Returns true in those cases so that the caller can proceed to perform other operations 578 // on the item even though the operation was not officially added to the list (it replaced one). 579 // Otherwise returns true. Optimizes all added items (merge, discard, alter, embellish etc.) 580 bool add(PendingOperationItem); 581 // Execute the RT portion of the operations contained in the list. Called only from RT stage 2. 582 SongChangedStruct_t executeRTStage(); 583 // Execute the Non-RT portion of the operations contained in the list. Called only from post RT stage 3. 584 SongChangedStruct_t executeNonRTStage(); 585 // Clear both the list and the map, and flags. 586 void clear(); 587 // Returns the accumulated song changed flags. flags()588 SongChangedStruct_t flags() const { return _sc_flags; } 589 // Find an existing special allocation command (like AddMidiCtrlValList). 590 // The comparison ignores the actual allocated value, so that such commands can be found before they do their allocating. 591 iterator findAllocationOp(const PendingOperationItem& op); 592 593 594 void addDeviceOperation(MidiDeviceList* devlist, MidiDevice* dev); 595 596 void addTrackPortCtrlEvents(Track* track); 597 void removeTrackPortCtrlEvents(Track* track); 598 599 void addPartPortCtrlEvents( 600 const Event& event, Part* part, unsigned int tick, unsigned int /*len*/, Track* track); 601 void addPartPortCtrlEvents(Part* part, unsigned int tick, unsigned int len, Track* track); 602 bool removePartPortCtrlEvents(const Event& event, Part* part, Track* track); 603 void removePartPortCtrlEvents(Part* part, Track* track); 604 void modifyPartPortCtrlEvents(const Event& old_event, const Event& event, Part* part); 605 606 void addPartOperation(PartList *partlist, Part* part); 607 void delPartOperation(PartList *partlist, Part* part); 608 void movePartOperation(PartList *partlist, Part* part, unsigned int new_pos, Track* track = 0); 609 void modifyPartStartOperation(Part* part, unsigned int new_pos, unsigned int new_len, int64_t events_offset, Pos::TType events_offset_time_type); 610 void modifyPartLengthOperation(Part* part, unsigned int new_len, int64_t events_offset, Pos::TType events_offset_time_type); 611 612 void addTrackAuxSendOperation(AudioTrack *atrack, int n); 613 614 //void TrackMidiCtrlRemapOperation(int index, int newPort, int newChan, int newNote, MidiCtrlValRemapOperation* rmop); 615 }; 616 617 typedef PendingOperationList::iterator iPendingOperation; 618 typedef std::multimap<unsigned int, iPendingOperation, std::less<unsigned int> >::iterator iPendingOperationSorted; 619 typedef std::multimap<unsigned int, iPendingOperation, std::less<unsigned int> >::reverse_iterator riPendingOperationSorted; 620 typedef std::pair <iPendingOperationSorted, iPendingOperationSorted> iPendingOperationSortedRange; 621 622 extern void TrackMidiCtrlRemapOperation( 623 MidiTrack *mtrack, int index, int newPort, int newChan, int newNote, MidiCtrlValRemapOperation* rmop); 624 625 } // namespace MusECore 626 627 #endif 628