typedef long int signed_frame_t; typedef struct Track Track; typedef struct ZRegion ZRegion; typedef struct AutomationTrack AutomationTrack; typedef struct MidiNote MidiNote; typedef struct ArrangerObject ArrangerObject; typedef struct Project Project; typedef struct ZRegion ZRegion; typedef struct Position Position; typedef struct Track Track; typedef struct ClipEditor ClipEditor; typedef enum ArrangerObjectType { /* .... */ ARRANGER_OBJECT_TYPE_REGION, ARRANGER_OBJECT_TYPE_MIDI_NOTE, /* .... */ } ArrangerObjectType; typedef enum ArrangerObjectPositionType { ARRANGER_OBJECT_POSITION_TYPE_START, ARRANGER_OBJECT_POSITION_TYPE_END, ARRANGER_OBJECT_POSITION_TYPE_CLIP_START, ARRANGER_OBJECT_POSITION_TYPE_LOOP_START, ARRANGER_OBJECT_POSITION_TYPE_LOOP_END, ARRANGER_OBJECT_POSITION_TYPE_FADE_IN, ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT, } ArrangerObjectPositionType; typedef struct Position { /* .... */ double ticks; /* .... */ } Position; typedef enum RegionType { /* .... */ REGION_TYPE_AUTOMATION = 1 << 2, /* .... */ } RegionType; typedef struct RegionIdentifier { /* .... */ RegionType type; /* .... */ int lane_pos; /* .... */ } RegionIdentifier; typedef struct ArrangerObject { /* .... */ ArrangerObjectType type; /* .... */ Position pos; Position end_pos; Position clip_start_pos; Position loop_start_pos; Position loop_end_pos; Position fade_in_pos; Position fade_out_pos; /* .... */ } ArrangerObject; typedef struct ZRegion { /* .... */ RegionIdentifier id; /* .... */ int num_midi_notes; /* .... */ } ZRegion; typedef struct Zrythm { /* ... */ Project *project; /* ... */ } Zrythm; typedef struct Project { /* ... */ ClipEditor *clip_editor; /* ... */ } Project; extern Zrythm *zrythm; extern void g_return_if_fail_warning (const char *log_domain, const char *pretty_function, const char *expression); extern void position_add_ticks (Position *self, double ticks); extern _Bool arranger_object_is_position_valid (const ArrangerObject *const self, const Position *pos, ArrangerObjectPositionType pos_type); extern Track *arranger_object_get_track (const ArrangerObject *const self); extern void midi_region_insert_midi_note (ZRegion *region, MidiNote *midi_note, int idx, int pub_events); extern ZRegion *midi_note_get_region (MidiNote *self); extern AutomationTrack * region_get_automation_track (const ZRegion *const region); extern void track_add_region (Track *track, ZRegion *region, AutomationTrack *at, int lane_pos, int gen_name, int fire_events); extern void clip_editor_set_region (ClipEditor *self, ZRegion *region, _Bool fire_events); extern ZRegion *clip_editor_get_region (ClipEditor *self); static Position * get_position_ptr (ArrangerObject *self, ArrangerObjectPositionType pos_type) { switch (pos_type) { case ARRANGER_OBJECT_POSITION_TYPE_START: return &self->pos; case ARRANGER_OBJECT_POSITION_TYPE_END: return &self->end_pos; case ARRANGER_OBJECT_POSITION_TYPE_CLIP_START: return &self->clip_start_pos; case ARRANGER_OBJECT_POSITION_TYPE_LOOP_START: return &self->loop_start_pos; case ARRANGER_OBJECT_POSITION_TYPE_LOOP_END: return &self->loop_end_pos; case ARRANGER_OBJECT_POSITION_TYPE_FADE_IN: return &self->fade_in_pos; case ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT: return &self->fade_out_pos; } return (((void *)0)); } void arranger_object_set_position (ArrangerObject *self, const Position *pos, ArrangerObjectPositionType pos_type, const int validate) { if (!(self && pos)) { g_return_if_fail_warning ("zrythm", ((const char *)(__func__)), "self && pos"); return; } if (validate && !arranger_object_is_position_valid (self, pos, pos_type)) return; Position *pos_ptr; pos_ptr = get_position_ptr (self, pos_type); if (!pos_ptr) { g_return_if_fail_warning ("zrythm", ((const char *)(__func__)), "pos_ptr"); return; } *(pos_ptr) = *(pos); } void arranger_object_end_pos_setter (ArrangerObject *self, const Position *pos) { arranger_object_set_position (self, pos, ARRANGER_OBJECT_POSITION_TYPE_END, 1); } ArrangerObject * arranger_object_clone (const ArrangerObject *self) { if (!self) { g_return_if_fail_warning ("zrythm", ((const char *)(__func__)), "self"); return (((void *)0)); } /* .... */ return (((void *)0)); } __attribute__((nonnull(1, 2))) void arranger_object_unsplit (ArrangerObject *r1, ArrangerObject *r2, ArrangerObject **obj, _Bool fire_events) { ZRegion *clip_editor_region = clip_editor_get_region (((zrythm)->project->clip_editor)); _Bool set_clip_editor_region = 0; if (clip_editor_region == (ZRegion *)r1 || clip_editor_region == (ZRegion *)r2) { set_clip_editor_region = 1; clip_editor_set_region (((zrythm)->project->clip_editor), ((void *)0), 1); } *obj = arranger_object_clone (r1); arranger_object_end_pos_setter (*obj, &r2->end_pos); Position fade_out_pos; *(&fade_out_pos) = *(&r2->end_pos); position_add_ticks (&fade_out_pos, -r2->pos.ticks); arranger_object_set_position (*obj, &fade_out_pos, ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT, 0); switch (r1->type) /* { dg-bogus "dereference of NULL 'r1'" } */ { case ARRANGER_OBJECT_TYPE_REGION: { ZRegion *r1_region = (ZRegion *)r1; AutomationTrack *at = ((void *)0); if (r1_region->id.type == REGION_TYPE_AUTOMATION) { at = region_get_automation_track (r1_region); } track_add_region (arranger_object_get_track (r1), (ZRegion *)*obj, at, ((ZRegion *)r1)->id.lane_pos, 1, fire_events); } break; case ARRANGER_OBJECT_TYPE_MIDI_NOTE: { ZRegion *parent_region = midi_note_get_region (((MidiNote *)r1)); midi_region_insert_midi_note ( parent_region, (MidiNote *)*obj, ((ZRegion *)(parent_region))->num_midi_notes, 1); } break; default: break; } switch (r1->type) /* { dg-bogus "dereference of NULL 'r1'" } */ { /* .... */ default: break; } /* .... */ }