Zrythm
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
arranger_selections.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2019-2023 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
10#ifndef __UNDO_ARRANGER_SELECTIONS_ACTION_H__
11#define __UNDO_ARRANGER_SELECTIONS_ACTION_H__
12
13#include <stdbool.h>
14#include <stdint.h>
15
17#include "dsp/audio_function.h"
19#include "dsp/midi_function.h"
20#include "dsp/port_identifier.h"
21#include "dsp/position.h"
28
30typedef struct ArrangerObject ArrangerObject;
31typedef struct Position Position;
32typedef struct QuantizeOptions QuantizeOptions;
33
40typedef enum ArrangerSelectionsActionType
41{
42 AS_ACTION_AUTOMATION_FILL,
43 AS_ACTION_CREATE,
44 AS_ACTION_DELETE,
45 AS_ACTION_DUPLICATE,
46 AS_ACTION_EDIT,
47 AS_ACTION_LINK,
48 AS_ACTION_MERGE,
49 AS_ACTION_MOVE,
50 AS_ACTION_QUANTIZE,
51 AS_ACTION_RECORD,
52 AS_ACTION_RESIZE,
53 AS_ACTION_SPLIT,
54} ArrangerSelectionsActionType;
55
56static const cyaml_strval_t arranger_selections_action_type_strings[] = {
57 {"Automation fill", AS_ACTION_AUTOMATION_FILL},
58 { "Create", AS_ACTION_CREATE },
59 { "Delete", AS_ACTION_DELETE },
60 { "Duplicate", AS_ACTION_DUPLICATE },
61 { "Edit", AS_ACTION_EDIT },
62 { "Link", AS_ACTION_LINK },
63 { "Merge", AS_ACTION_MERGE },
64 { "Move", AS_ACTION_MOVE },
65 { "Quantize", AS_ACTION_QUANTIZE },
66 { "Record", AS_ACTION_RECORD },
67 { "Resize", AS_ACTION_RESIZE },
68 { "Split", AS_ACTION_SPLIT },
69};
70
75{
76 ARRANGER_SELECTIONS_ACTION_RESIZE_L,
77 ARRANGER_SELECTIONS_ACTION_RESIZE_R,
78 ARRANGER_SELECTIONS_ACTION_RESIZE_L_LOOP,
79 ARRANGER_SELECTIONS_ACTION_RESIZE_R_LOOP,
80 ARRANGER_SELECTIONS_ACTION_RESIZE_L_FADE,
81 ARRANGER_SELECTIONS_ACTION_RESIZE_R_FADE,
82 ARRANGER_SELECTIONS_ACTION_STRETCH_L,
83 ARRANGER_SELECTIONS_ACTION_STRETCH_R,
85
86static const cyaml_strval_t arranger_selections_action_resize_type_strings[] = {
87 {"Resize L", ARRANGER_SELECTIONS_ACTION_RESIZE_L },
88 { "Resize R", ARRANGER_SELECTIONS_ACTION_RESIZE_R },
89 { "Resize L (loop)", ARRANGER_SELECTIONS_ACTION_RESIZE_L_LOOP},
90 { "Resize R (loop)", ARRANGER_SELECTIONS_ACTION_RESIZE_R_LOOP},
91 { "Resize L (fade)", ARRANGER_SELECTIONS_ACTION_RESIZE_L_FADE},
92 { "Resize R (fade)", ARRANGER_SELECTIONS_ACTION_RESIZE_R_FADE},
93 { "Stretch L", ARRANGER_SELECTIONS_ACTION_STRETCH_L },
94 { "Stretch R", ARRANGER_SELECTIONS_ACTION_STRETCH_R },
95};
96
142
143static const cyaml_strval_t arranger_selections_action_edit_type_strings[] = {
151};
152
157{
158 UndoableAction parent_instance;
159
161 ArrangerSelectionsActionType type;
162
165
171
174
176
178 double ticks;
194
199
201 char * str;
202
205
209 ArrangerObject * r2[800];
210
214
221
224
225 /* --- below for serialization only --- */
226 ChordSelections * chord_sel;
227 ChordSelections * chord_sel_after;
228 TimelineSelections * tl_sel;
229 TimelineSelections * tl_sel_after;
230 MidiArrangerSelections * ma_sel;
231 MidiArrangerSelections * ma_sel_after;
232 AutomationSelections * automation_sel;
233 AutomationSelections * automation_sel_after;
234 AudioSelections * audio_sel;
235 AudioSelections * audio_sel_after;
236
237 /* arranger objects that can be split */
238 ZRegion * region_r1[800];
239 ZRegion * region_r2[800];
240 MidiNote * mn_r1[800];
241 MidiNote * mn_r2[800];
242
245 ZRegion * region_after;
246
248
249void
250arranger_selections_action_init_loaded (ArrangerSelectionsAction * self);
251
258WARN_UNUSED_RESULT UndoableAction *
260 ArrangerSelections * sel,
261 const bool create,
262 GError ** error);
263
264#define arranger_selections_action_new_create(sel, error) \
265 arranger_selections_action_new_create_or_delete ( \
266 (ArrangerSelections *) sel, true, error)
267
268#define arranger_selections_action_new_delete(sel, error) \
269 arranger_selections_action_new_create_or_delete ( \
270 (ArrangerSelections *) sel, false, error)
271
272WARN_UNUSED_RESULT UndoableAction *
273arranger_selections_action_new_record (
274 ArrangerSelections * sel_before,
275 ArrangerSelections * sel_after,
276 const bool already_recorded,
277 GError ** error);
278
290WARN_UNUSED_RESULT UndoableAction *
292 ArrangerSelections * sel,
293 const bool move,
294 const double ticks,
295 const int delta_chords,
296 const int delta_pitch,
297 const int delta_tracks,
298 const int delta_lanes,
299 const double delta_normalized_amount,
300 const PortIdentifier * tgt_port_id,
301 const bool already_moved,
302 GError ** error);
303
304#define arranger_selections_action_new_move( \
305 sel, ticks, chords, pitch, tracks, lanes, norm_amt, port_id, already_moved, \
306 error) \
307 arranger_selections_action_new_move_or_duplicate ( \
308 (ArrangerSelections *) sel, 1, ticks, chords, pitch, tracks, lanes, \
309 norm_amt, port_id, already_moved, error)
310#define arranger_selections_action_new_duplicate( \
311 sel, ticks, chords, pitch, tracks, lanes, norm_amt, port_id, already_moved, \
312 error) \
313 arranger_selections_action_new_move_or_duplicate ( \
314 (ArrangerSelections *) sel, 0, ticks, chords, pitch, tracks, lanes, \
315 norm_amt, port_id, already_moved, error)
316
317#define arranger_selections_action_new_move_timeline( \
318 sel, ticks, delta_tracks, delta_lanes, port_id, already_moved, error) \
319 arranger_selections_action_new_move ( \
320 sel, ticks, 0, 0, delta_tracks, delta_lanes, 0, port_id, already_moved, \
321 error)
322#define arranger_selections_action_new_duplicate_timeline( \
323 sel, ticks, delta_tracks, delta_lanes, port_id, already_moved, error) \
324 arranger_selections_action_new_duplicate ( \
325 sel, ticks, 0, 0, delta_tracks, delta_lanes, 0, port_id, already_moved, \
326 error)
327
328#define arranger_selections_action_new_move_midi( \
329 sel, ticks, delta_pitch, already_moved, error) \
330 arranger_selections_action_new_move ( \
331 sel, ticks, 0, delta_pitch, 0, 0, 0, NULL, already_moved, error)
332#define arranger_selections_action_new_duplicate_midi( \
333 sel, ticks, delta_pitch, already_moved, error) \
334 arranger_selections_action_new_duplicate ( \
335 sel, ticks, 0, delta_pitch, 0, 0, 0, NULL, already_moved, error)
336#define arranger_selections_action_new_move_chord( \
337 sel, ticks, delta_chords, already_moved, error) \
338 arranger_selections_action_new_move ( \
339 sel, ticks, delta_chords, 0, 0, 0, 0, NULL, already_moved, error)
340#define arranger_selections_action_new_duplicate_chord( \
341 sel, ticks, delta_chords, already_moved, error) \
342 arranger_selections_action_new_duplicate ( \
343 sel, ticks, delta_chords, 0, 0, 0, 0, NULL, already_moved, error)
344
345#define arranger_selections_action_new_move_automation( \
346 sel, ticks, norm_amt, already_moved, error) \
347 arranger_selections_action_new_move ( \
348 sel, ticks, 0, 0, 0, 0, norm_amt, NULL, already_moved, error)
349#define arranger_selections_action_new_duplicate_automation( \
350 sel, ticks, norm_amt, already_moved, error) \
351 arranger_selections_action_new_duplicate ( \
352 sel, ticks, 0, 0, 0, 0, norm_amt, NULL, already_moved, error)
353
362WARN_UNUSED_RESULT UndoableAction *
364 ArrangerSelections * sel_before,
365 ArrangerSelections * sel_after,
366 const double ticks,
367 const int delta_tracks,
368 const int delta_lanes,
369 const bool already_moved,
370 GError ** error);
371
382WARN_UNUSED_RESULT UndoableAction *
384 ArrangerSelections * sel_before,
385 ArrangerSelections * sel_after,
387 bool already_edited,
388 GError ** error);
389
390WARN_UNUSED_RESULT UndoableAction *
391arranger_selections_action_new_edit_single_obj (
392 const ArrangerObject * obj_before,
393 const ArrangerObject * obj_after,
395 bool already_edited,
396 GError ** error);
397
403WARN_UNUSED_RESULT UndoableAction *
405 ArrangerSelections * sel_before,
406 MidiFunctionType midi_func_type,
407 MidiFunctionOpts opts,
408 GError ** error);
409
415WARN_UNUSED_RESULT UndoableAction *
417 ArrangerSelections * sel_before,
418 AutomationFunctionType automation_func_type,
419 GError ** error);
420
426WARN_UNUSED_RESULT UndoableAction *
428 ArrangerSelections * sel_before,
429 AudioFunctionType audio_func_type,
431 const char * uri,
432 GError ** error);
433
444WARN_UNUSED_RESULT UndoableAction *
446 ZRegion * region_before,
447 ZRegion * region_after,
448 bool already_changed,
449 GError ** error);
450
457WARN_UNUSED_RESULT UndoableAction *
459 ArrangerSelections * sel,
460 const Position * pos,
461 GError ** error);
462
467WARN_UNUSED_RESULT UndoableAction *
469
476WARN_UNUSED_RESULT UndoableAction *
478 ArrangerSelections * sel_before,
479 ArrangerSelections * sel_after,
481 const double ticks,
482 GError ** error);
483
490WARN_UNUSED_RESULT UndoableAction *
492 ArrangerSelections * sel,
493 QuantizeOptions * opts,
494 GError ** error);
495
497arranger_selections_action_clone (const ArrangerSelectionsAction * src);
498
499bool
500arranger_selections_action_perform_create_or_delete (
501 ArrangerSelections * sel,
502 const bool create,
503 GError ** error);
504
505#define arranger_selections_action_perform_create(sel, error) \
506 arranger_selections_action_perform_create_or_delete ( \
507 (ArrangerSelections *) sel, true, error)
508
509#define arranger_selections_action_perform_delete(sel, error) \
510 arranger_selections_action_perform_create_or_delete ( \
511 (ArrangerSelections *) sel, false, error)
512
513bool
514arranger_selections_action_perform_record (
515 ArrangerSelections * sel_before,
516 ArrangerSelections * sel_after,
517 const bool already_recorded,
518 GError ** error);
519
520bool
521arranger_selections_action_perform_move_or_duplicate (
522 ArrangerSelections * sel,
523 const bool move,
524 const double ticks,
525 const int delta_chords,
526 const int delta_pitch,
527 const int delta_tracks,
528 const int delta_lanes,
529 const double delta_normalized_amount,
530 const PortIdentifier * port_id,
531 const bool already_moved,
532 GError ** error);
533
534#define arranger_selections_action_perform_move( \
535 sel, ticks, chords, pitch, tracks, lanes, norm_amt, port_id, already_moved, \
536 error) \
537 arranger_selections_action_perform_move_or_duplicate ( \
538 (ArrangerSelections *) sel, 1, ticks, chords, pitch, tracks, lanes, \
539 norm_amt, port_id, already_moved, error)
540#define arranger_selections_action_perform_duplicate( \
541 sel, ticks, chords, pitch, tracks, lanes, norm_amt, port_id, already_moved, \
542 error) \
543 arranger_selections_action_perform_move_or_duplicate ( \
544 (ArrangerSelections *) sel, 0, ticks, chords, pitch, tracks, lanes, \
545 norm_amt, port_id, already_moved, error)
546
547#define arranger_selections_action_perform_move_timeline( \
548 sel, ticks, delta_tracks, delta_lanes, port_id, already_moved, error) \
549 arranger_selections_action_perform_move ( \
550 sel, ticks, 0, 0, delta_tracks, delta_lanes, 0, port_id, already_moved, \
551 error)
552#define arranger_selections_action_perform_duplicate_timeline( \
553 sel, ticks, delta_tracks, delta_lanes, port_id, already_moved, error) \
554 arranger_selections_action_perform_duplicate ( \
555 sel, ticks, 0, 0, delta_tracks, delta_lanes, 0, port_id, already_moved, \
556 error)
557
558#define arranger_selections_action_perform_move_midi( \
559 sel, ticks, delta_pitch, already_moved, error) \
560 arranger_selections_action_perform_move ( \
561 sel, ticks, 0, delta_pitch, 0, 0, 0, NULL, already_moved, error)
562#define arranger_selections_action_perform_duplicate_midi( \
563 sel, ticks, delta_pitch, already_moved, error) \
564 arranger_selections_action_perform_duplicate ( \
565 sel, ticks, 0, delta_pitch, 0, 0, 0, NULL, already_moved, error)
566#define arranger_selections_action_perform_move_chord( \
567 sel, ticks, delta_chords, already_moved, error) \
568 arranger_selections_action_perform_move ( \
569 sel, ticks, delta_chords, 0, 0, 0, 0, NULL, already_moved, error)
570#define arranger_selections_action_perform_duplicate_chord( \
571 sel, ticks, delta_chords, already_moved, error) \
572 arranger_selections_action_perform_duplicate ( \
573 sel, ticks, delta_chords, 0, 0, 0, 0, NULL, already_moved, error)
574
575#define arranger_selections_action_perform_move_automation( \
576 sel, ticks, norm_amt, already_moved, error) \
577 arranger_selections_action_perform_move ( \
578 sel, ticks, 0, 0, 0, 0, norm_amt, NULL, already_moved, error)
579#define arranger_selections_action_perform_duplicate_automation( \
580 sel, ticks, norm_amt, already_moved, error) \
581 arranger_selections_action_perform_duplicate ( \
582 sel, ticks, 0, 0, 0, 0, norm_amt, NULL, already_moved, error)
583
584bool
585arranger_selections_action_perform_link (
586 ArrangerSelections * sel_before,
587 ArrangerSelections * sel_after,
588 const double ticks,
589 const int delta_tracks,
590 const int delta_lanes,
591 const bool already_moved,
592 GError ** error);
593
594bool
595arranger_selections_action_perform_edit (
596 ArrangerSelections * sel_before,
597 ArrangerSelections * sel_after,
599 bool already_edited,
600 GError ** error);
601
602bool
603arranger_selections_action_perform_edit_single_obj (
604 const ArrangerObject * obj_before,
605 const ArrangerObject * obj_after,
607 bool already_edited,
608 GError ** error);
609
610bool
611arranger_selections_action_perform_edit_midi_function (
612 ArrangerSelections * sel_before,
613 MidiFunctionType midi_func_type,
614 MidiFunctionOpts opts,
615 GError ** error);
616
617bool
618arranger_selections_action_perform_edit_automation_function (
619 ArrangerSelections * sel_before,
620 AutomationFunctionType automation_func_type,
621 GError ** error);
622
623bool
624arranger_selections_action_perform_edit_audio_function (
625 ArrangerSelections * sel_before,
626 AudioFunctionType audio_func_type,
628 const char * uri,
629 GError ** error);
630
631bool
632arranger_selections_action_perform_automation_fill (
633 ZRegion * region_before,
634 ZRegion * region_after,
635 bool already_changed,
636 GError ** error);
637
638bool
639arranger_selections_action_perform_split (
640 ArrangerSelections * sel,
641 const Position * pos,
642 GError ** error);
643
644bool
645arranger_selections_action_perform_merge (
646 ArrangerSelections * sel,
647 GError ** error);
648
649bool
650arranger_selections_action_perform_resize (
651 ArrangerSelections * sel_before,
652 ArrangerSelections * sel_after,
654 const double ticks,
655 GError ** error);
656
657bool
658arranger_selections_action_perform_quantize (
659 ArrangerSelections * sel,
660 QuantizeOptions * opts,
661 GError ** error);
662
663int
664arranger_selections_action_do (ArrangerSelectionsAction * self, GError ** error);
665
666int
667arranger_selections_action_undo (
669 GError ** error);
670
671char *
672arranger_selections_action_stringize (ArrangerSelectionsAction * self);
673
674bool
675arranger_selections_action_contains_clip (
677 AudioClip * clip);
678
679void
680arranger_selections_action_free (ArrangerSelectionsAction * self);
681
686#endif
AUDIO functions.
API for selections in the AudioArrangerWidget.
Automation functions.
API for selections in the AutomationArrangerWidget.
API for selections in the piano roll.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_edit(ArrangerSelections *sel_before, ArrangerSelections *sel_after, ArrangerSelectionsActionEditType type, bool already_edited, GError **error)
Creates a new action for editing properties of an object.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_create_or_delete(ArrangerSelections *sel, const bool create, GError **error)
Creates a new action for creating/deleting objects.
ArrangerSelectionsActionResizeType
Type used when the action is a RESIZE action.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_resize(ArrangerSelections *sel_before, ArrangerSelections *sel_after, ArrangerSelectionsActionResizeType type, const double ticks, GError **error)
Creates a new action for resizing ArrangerObject's.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_split(ArrangerSelections *sel, const Position *pos, GError **error)
Creates a new action for splitting ArrangerObject's.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_automation_fill(ZRegion *region_before, ZRegion *region_after, bool already_changed, GError **error)
Creates a new action for automation autofill.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_quantize(ArrangerSelections *sel, QuantizeOptions *opts, GError **error)
Creates a new action for quantizing ArrangerObject's.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_edit_midi_function(ArrangerSelections *sel_before, MidiFunctionType midi_func_type, MidiFunctionOpts opts, GError **error)
Wrapper over arranger_selections_action_new_edit() for MIDI functions.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_edit_automation_function(ArrangerSelections *sel_before, AutomationFunctionType automation_func_type, GError **error)
Wrapper over arranger_selections_action_new_edit() for automation functions.
ArrangerSelectionsActionEditType
Type used when the action is an EDIT action.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_link(ArrangerSelections *sel_before, ArrangerSelections *sel_after, const double ticks, const int delta_tracks, const int delta_lanes, const bool already_moved, GError **error)
Creates a new action for linking regions.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_merge(ArrangerSelections *sel, GError **error)
Creates a new action for merging ArrangerObject's.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_edit_audio_function(ArrangerSelections *sel_before, AudioFunctionType audio_func_type, AudioFunctionOpts opts, const char *uri, GError **error)
Wrapper over arranger_selections_action_new_edit() for automation functions.
WARN_UNUSED_RESULT UndoableAction * arranger_selections_action_new_move_or_duplicate(ArrangerSelections *sel, const bool move, const double ticks, const int delta_chords, const int delta_pitch, const int delta_tracks, const int delta_lanes, const double delta_normalized_amount, const PortIdentifier *tgt_port_id, const bool already_moved, GError **error)
Creates a new action for moving or duplicating objects.
@ ARRANGER_SELECTIONS_ACTION_EDIT_NAME
Edit the name of the ArrangerObject's in the selection.
@ ARRANGER_SELECTIONS_ACTION_EDIT_EDITOR_FUNCTION
For ramping MidiNote velocities or AutomationPoint values.
@ ARRANGER_SELECTIONS_ACTION_EDIT_MUTE
Change mute status.
@ ARRANGER_SELECTIONS_ACTION_EDIT_SCALE
For editing the MusicalScale inside ScaleObject's.
@ ARRANGER_SELECTIONS_ACTION_EDIT_POS
Edit a Position of the ArrangerObject's in the selection.
@ ARRANGER_SELECTIONS_ACTION_EDIT_PRIMITIVE
Edit a primitive (int, etc) member of ArrangerObject's in the selection.
@ ARRANGER_SELECTIONS_ACTION_EDIT_FADES
Editing fade positions or curve options.
AudioFunctionType
API for selections in the piano roll.
MIDI functions.
Port identifier.
Position struct and API.
Quantize options.
Base struct for arranger objects.
double delta_normalized_amount
Difference in a normalized amount, such as automation point normalized value.
char * str
String, when changing a string.
ArrangerSelectionsActionType type
Action type.
PortIdentifier * target_port
Target port (used to find corresponding automation track when moving/copying automation regions to an...
ArrangerSelections * sel
A clone of the ArrangerSelections before the change.
int delta_chords
Chords moved (up/down in the Chord editor).
ArrangerObject * r1[800]
Used when splitting - these are the split ArrangerObject's.
ArrangerSelectionsActionEditType edit_type
Type of edit action, if an Edit action.
QuantizeOptions * opts
QuantizeOptions clone, if quantizing.
int num_split_objs
Number of split objects inside r1 and r2 each.
ZRegion * region_before
Used for automation autofill action.
int delta_vel
Delta of MidiNote velocity.
Position pos
Position, when changing a Position.
bool first_run
If this is true, the first "do" call does nothing in some cases.
int delta_pitch
Delta of MidiNote pitch.
ArrangerSelections * sel_after
A clone of the ArrangerSelections after the change (used in the EDIT action and quantize).
Audio clips for the pool.
Definition clip.h:33
Selections to be used for the AudioArrangerWidget's current selections, copying, undoing,...
Selections to be used for the AutomationArrangerWidget's current selections, copying,...
Selections to be used for the ChordArrangerWidget's current selections, copying, undoing,...
A collection of selected MidiNote's.
A MIDI note inside a ZRegion shown in the piano roll.
Definition midi_note.h:49
Struct used to identify Ports in the project.
A Position is made up of bars.beats.sixteenths.ticks.
Definition position.h:129
Selections to be used for the timeline's current selections, copying, undoing, etc.
Base struct to be inherited by implementing undoable actions.
A region (clip) is an object on the timeline that contains either MidiNote's or AudioClip's.
Definition region.h:77
Current TimelineArranger selections.
Undoable actions.