1 typedef long int signed_frame_t;
2
3 typedef struct Track Track;
4 typedef struct ZRegion ZRegion;
5 typedef struct AutomationTrack AutomationTrack;
6 typedef struct MidiNote MidiNote;
7 typedef struct ArrangerObject ArrangerObject;
8 typedef struct Project Project;
9 typedef struct ZRegion ZRegion;
10 typedef struct Position Position;
11 typedef struct Track Track;
12 typedef struct ClipEditor ClipEditor;
13
14 typedef enum ArrangerObjectType
15 {
16 /* .... */
17 ARRANGER_OBJECT_TYPE_REGION,
18 ARRANGER_OBJECT_TYPE_MIDI_NOTE,
19 /* .... */
20 } ArrangerObjectType;
21
22 typedef enum ArrangerObjectPositionType
23 {
24 ARRANGER_OBJECT_POSITION_TYPE_START,
25 ARRANGER_OBJECT_POSITION_TYPE_END,
26 ARRANGER_OBJECT_POSITION_TYPE_CLIP_START,
27 ARRANGER_OBJECT_POSITION_TYPE_LOOP_START,
28 ARRANGER_OBJECT_POSITION_TYPE_LOOP_END,
29 ARRANGER_OBJECT_POSITION_TYPE_FADE_IN,
30 ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT,
31 } ArrangerObjectPositionType;
32
33 typedef struct Position
34 {
35 /* .... */
36 double ticks;
37 /* .... */
38 } Position;
39
40 typedef enum RegionType
41 {
42 /* .... */
43 REGION_TYPE_AUTOMATION = 1 << 2,
44 /* .... */
45 } RegionType;
46
47 typedef struct RegionIdentifier
48 {
49 /* .... */
50 RegionType type;
51 /* .... */
52 int lane_pos;
53 /* .... */
54 } RegionIdentifier;
55
56 typedef struct ArrangerObject
57 {
58 /* .... */
59
60 ArrangerObjectType type;
61 /* .... */
62 Position pos;
63 Position end_pos;
64 Position clip_start_pos;
65
66 Position loop_start_pos;
67 Position loop_end_pos;
68
69 Position fade_in_pos;
70 Position fade_out_pos;
71
72 /* .... */
73 } ArrangerObject;
74
75 typedef struct ZRegion
76 {
77 /* .... */
78 RegionIdentifier id;
79 /* .... */
80 int num_midi_notes;
81 /* .... */
82 } ZRegion;
83
84 typedef struct Zrythm
85 {
86 /* ... */
87 Project *project;
88 /* ... */
89 } Zrythm;
90
91 typedef struct Project
92 {
93 /* ... */
94
95 ClipEditor *clip_editor;
96
97 /* ... */
98 } Project;
99
100 extern Zrythm *zrythm;
101
102 extern void g_return_if_fail_warning (const char *log_domain,
103 const char *pretty_function,
104 const char *expression);
105 extern void position_add_ticks (Position *self, double ticks);
106 extern _Bool
107 arranger_object_is_position_valid (const ArrangerObject *const self,
108 const Position *pos,
109 ArrangerObjectPositionType pos_type);
110 extern Track *arranger_object_get_track (const ArrangerObject *const self);
111 extern void midi_region_insert_midi_note (ZRegion *region, MidiNote *midi_note,
112 int idx, int pub_events);
113 extern ZRegion *midi_note_get_region (MidiNote *self);
114 extern AutomationTrack *
115 region_get_automation_track (const ZRegion *const region);
116 extern void track_add_region (Track *track, ZRegion *region,
117 AutomationTrack *at, int lane_pos, int gen_name,
118 int fire_events);
119 extern void clip_editor_set_region (ClipEditor *self, ZRegion *region,
120 _Bool fire_events);
121 extern ZRegion *clip_editor_get_region (ClipEditor *self);
122
123 static Position *
124 get_position_ptr (ArrangerObject *self, ArrangerObjectPositionType pos_type)
125 {
126 switch (pos_type)
127 {
128 case ARRANGER_OBJECT_POSITION_TYPE_START:
129 return &self->pos;
130 case ARRANGER_OBJECT_POSITION_TYPE_END:
131 return &self->end_pos;
132 case ARRANGER_OBJECT_POSITION_TYPE_CLIP_START:
133 return &self->clip_start_pos;
134 case ARRANGER_OBJECT_POSITION_TYPE_LOOP_START:
135 return &self->loop_start_pos;
136 case ARRANGER_OBJECT_POSITION_TYPE_LOOP_END:
137 return &self->loop_end_pos;
138 case ARRANGER_OBJECT_POSITION_TYPE_FADE_IN:
139 return &self->fade_in_pos;
140 case ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT:
141 return &self->fade_out_pos;
142 }
143 return (((void *)0));
144 }
145
146 void
147 arranger_object_set_position (ArrangerObject *self, const Position *pos,
148 ArrangerObjectPositionType pos_type,
149 const int validate)
150 {
151 if (!(self && pos))
152 {
153 g_return_if_fail_warning ("zrythm", ((const char *)(__func__)),
154 "self && pos");
155 return;
156 }
157
158 if (validate && !arranger_object_is_position_valid (self, pos, pos_type))
159 return;
160
161 Position *pos_ptr;
162 pos_ptr = get_position_ptr (self, pos_type);
163 if (!pos_ptr)
164 {
165 g_return_if_fail_warning ("zrythm", ((const char *)(__func__)),
166 "pos_ptr");
167 return;
168 }
169 *(pos_ptr) = *(pos);
170 }
171
172 void
173 arranger_object_end_pos_setter (ArrangerObject *self, const Position *pos)
174 {
175 arranger_object_set_position (self, pos, ARRANGER_OBJECT_POSITION_TYPE_END,
176 1);
177 }
178
179 ArrangerObject *
180 arranger_object_clone (const ArrangerObject *self)
181 {
182 if (!self)
183 {
184 g_return_if_fail_warning ("zrythm", ((const char *)(__func__)), "self");
185 return (((void *)0));
186 }
187 /* .... */
188 return (((void *)0));
189 }
190
191 __attribute__((nonnull(1, 2)))
192 void
193 arranger_object_unsplit (ArrangerObject *r1, ArrangerObject *r2,
194 ArrangerObject **obj, _Bool fire_events)
195 {
196 ZRegion *clip_editor_region
197 = clip_editor_get_region (((zrythm)->project->clip_editor));
198
199 _Bool set_clip_editor_region = 0;
200 if (clip_editor_region == (ZRegion *)r1
201 || clip_editor_region == (ZRegion *)r2)
202 {
203 set_clip_editor_region = 1;
204 clip_editor_set_region (((zrythm)->project->clip_editor), ((void *)0),
205 1);
206 }
207
208 *obj = arranger_object_clone (r1);
209
210 arranger_object_end_pos_setter (*obj, &r2->end_pos);
211 Position fade_out_pos;
212 *(&fade_out_pos) = *(&r2->end_pos);
213 position_add_ticks (&fade_out_pos, -r2->pos.ticks);
214 arranger_object_set_position (*obj, &fade_out_pos,
215 ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT, 0);
216
217 switch (r1->type) /* { dg-bogus "dereference of NULL 'r1'" } */
218 {
219 case ARRANGER_OBJECT_TYPE_REGION:
220 {
221 ZRegion *r1_region = (ZRegion *)r1;
222 AutomationTrack *at = ((void *)0);
223 if (r1_region->id.type == REGION_TYPE_AUTOMATION)
224 {
225 at = region_get_automation_track (r1_region);
226 }
227 track_add_region (arranger_object_get_track (r1), (ZRegion *)*obj, at,
228 ((ZRegion *)r1)->id.lane_pos, 1, fire_events);
229 }
230 break;
231 case ARRANGER_OBJECT_TYPE_MIDI_NOTE:
232 {
233 ZRegion *parent_region = midi_note_get_region (((MidiNote *)r1));
234 midi_region_insert_midi_note (
235 parent_region, (MidiNote *)*obj,
236 ((ZRegion *)(parent_region))->num_midi_notes, 1);
237 }
238 break;
239 default:
240 break;
241 }
242
243 switch (r1->type) /* { dg-bogus "dereference of NULL 'r1'" } */
244 {
245 /* .... */
246 default:
247 break;
248 }
249 /* .... */
250 }