~alextee/zrythm

df91a70abad3c62808209d1a5867f924baf8695c — Alexandros Theodotou 2 years ago 84f9e11 audio_region_bpm_change_fix
<temporary commit>
M inc/actions/arranger_selections.h => inc/actions/arranger_selections.h +6 -18
@@ 1,21 1,5 @@
/*
 * Copyright (C) 2019-2022 Alexandros Theodotou <alex at zrythm dot org>
 *
 * This file is part of Zrythm
 *
 * Zrythm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Zrythm is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
 */
// SPDX-FileCopyrightText: © 2019-2022 Alexandros Theodotou <alex@zrythm.org>
// SPDX-License-Identifier: LicenseRef-ZrythmLicense

/**
 * \file


@@ 424,6 408,10 @@ void
arranger_selections_action_init_loaded (
  ArrangerSelectionsAction * self);

void
arranger_selections_action_update_positions (
  ArrangerSelectionsAction * self);

/**
 * Creates a new action for creating/deleting
 * objects.

M inc/actions/range_action.h => inc/actions/range_action.h +4 -0
@@ 117,6 117,10 @@ static const cyaml_schema_value_t
void
range_action_init_loaded (RangeAction * self);

void
range_action_update_positions (
  RangeAction * self);

/**
 * Creates a new action.
 *

M inc/actions/undoable_action.h => inc/actions/undoable_action.h +20 -18
@@ 1,21 1,5 @@
/*
 * Copyright (C) 2018-2022 Alexandros Theodotou <alex at zrythm dot org>
 *
 * This file is part of Zrythm
 *
 * Zrythm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Zrythm is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
 */
// SPDX-FileCopyrightText: © 2018-2022 Alexandros Theodotou <alex@zrythm.org>
// SPDX-License-Identifier: LicenseRef-ZrythmLicense

/**
 * \file


@@ 29,6 13,7 @@
#include <stdbool.h>

#include "utils/yaml.h"
#include "utils/types.h"

typedef struct AudioClip AudioClip;
typedef struct PortConnectionsManager


@@ 104,6 89,23 @@ typedef struct UndoableAction
  UndoableActionType type;

  /**
   * Whether undoable_action_init_loaded() must
   * be called before this action is used.
   *
   * This was added because sometimes the action
   * depends on the current state of the project
   * (such as BPM) to run the initialization logic
   * successfully.
   */
  //bool pending_init_loaded;

  /** BPM on action creation. */
  bpm_t bpm_on_creation;

  /** BPM on action creation. */
  sample_rate_t sample_rate_on_creation;

  /**
   * Index in the stack.
   *
   * Used during deserialization.

M inc/audio/port.h => inc/audio/port.h +2 -18
@@ 1,21 1,5 @@
/*
 * Copyright (C) 2018-2022 Alexandros Theodotou <alex at zrythm dot org>
 *
 * This file is part of Zrythm
 *
 * Zrythm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Zrythm is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
 */
// SPDX-FileCopyrightText: © 2018-2022 Alexandros Theodotou <alex@zrythm.org>
// SPDX-License-Identifier: LicenseRef-ZrythmLicense

/**
 * \file

M inc/audio/tempo_track.h => inc/audio/tempo_track.h +3 -5
@@ 107,13 107,11 @@ tempo_track_get_current_bpm_as_str (void * self);
/**
 * Sets the BPM.
 *
 * @param update_snap_points Whether to update the
 *   snap points.
 * @param stretch_audio_region Whether to stretch
 *   audio regions. This should only be true when
 *   the BPM change is final.
 * @param start_bpm The BPM at the start of the
 *   action, if not temporary.
 * @param temporary Whether the change is temporary
 *   (eg, while dragging the BPM meter). If false,
 *   an undoable action will be performed.
 */
void
tempo_track_set_bpm (

M inc/gui/backend/arranger_selections.h => inc/gui/backend/arranger_selections.h +4 -0
@@ 138,6 138,10 @@ arranger_selections_init_loaded (
  ArrangerSelections * self,
  bool                 project);

void
arranger_selections_update_positions (
  ArrangerSelections *   self);

/**
 * Initializes the selections.
 */

M inc/gui/widgets/mixer.h => inc/gui/widgets/mixer.h +2 -18
@@ 1,21 1,5 @@
/*
 * Copyright (C) 2018-2021 Alexandros Theodotou <alex at zrythm dot org>
 *
 * This file is part of Zrythm
 *
 * Zrythm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Zrythm is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
 */
// SPDX-FileCopyrightText: © 2018-2021 Alexandros Theodotou <alex@zrythm.org>
// SPDX-License-Identifier: LicenseRef-ZrythmLicense

/**
 * @file

M inc/utils/flags.h => inc/utils/flags.h +5 -18
@@ 1,21 1,5 @@
/*
 * Copyright (C) 2019-2022 Alexandros Theodotou <alex at zrythm dot org>
 *
 * This file is part of Zrythm
 *
 * Zrythm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Zrythm is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
 */
// SPDX-FileCopyrightText: © 2019-2022 Alexandros Theodotou <alex@zrythm.org>
// SPDX-License-Identifier: LicenseRef-ZrythmLicense

/**
 * \file


@@ 367,4 351,7 @@
#define Z_F_DURING_UI_ACTION 1
#define Z_F_NOT_DURING_UI_ACTION 0

#define Z_F_TEMPORARY 1
#define Z_F_NOT_TEMPORARY 0

#endif

M src/actions/arranger_selections.c => src/actions/arranger_selections.c +59 -0
@@ 110,6 110,65 @@ arranger_selections_action_init_loaded (
      arranger_object_init_loaded (
        (ArrangerObject *) self->region_after);
    }
#undef DO_SELECTIONS
}

void
arranger_selections_action_update_positions (
  ArrangerSelectionsAction * self)
{
#define DO_SELECTIONS(sc) \
  if (self->sc##_sel) \
    { \
      arranger_selections_update_positions ( \
        self->sel); \
      if (self->sel_after) \
        { \
          arranger_selections_update_positions ( \
            self->sel_after); \
        } \
    }
  DO_SELECTIONS (chord);
  DO_SELECTIONS (tl);
  DO_SELECTIONS (ma);
  DO_SELECTIONS (automation);
  DO_SELECTIONS (audio);

  for (int j = 0; j < self->num_split_objs; j++)
    {
      if (self->region_r1[j])
        {
          arranger_object_update_positions (
            (ArrangerObject *) self->region_r1[j],
            true, false);
          arranger_object_update_positions (
            (ArrangerObject *) self->region_r2[j],
            true, false);
        }
      else if (self->mn_r1[j])
        {
          arranger_object_update_positions (
            (ArrangerObject *) self->mn_r1[j],
            true, false);
          arranger_object_update_positions (
            (ArrangerObject *) self->mn_r2[j],
            true, false);
        }
    }

  if (self->region_before)
    {
      arranger_object_update_positions (
        (ArrangerObject *) self->region_before,
        true, false);
    }
  if (self->region_after)
    {
      arranger_object_update_positions (
        (ArrangerObject *) self->region_after,
        true, false);
    }
#undef DO_SELECTIONS
}

/**

M src/actions/range_action.c => src/actions/range_action.c +16 -0
@@ 35,6 35,22 @@ range_action_init_loaded (RangeAction * self)
    self->transport, NULL, NULL);
}

void
range_action_update_positions (
  RangeAction * self)
{
  if (self->sel_before)
    {
      arranger_selections_update_positions (
        (ArrangerSelections *) self->sel_before);
    }
  if (self->sel_after)
    {
      arranger_selections_update_positions (
        (ArrangerSelections *) self->sel_after);
    }
}

/**
 * Creates a new action.
 *

M src/actions/undoable_action.c => src/actions/undoable_action.c +33 -0
@@ 65,6 65,11 @@ undoable_action_init (
    UNDOABLE_ACTION_SCHEMA_VERSION;
  self->type = type;
  self->num_actions = 1;

  /*self->bpm_on_creation =*/
    /*AUDIO_ENGINE->bpm;*/
  /*self->sample_rate_on_creation =*/
    /*AUDIO_ENGINE->sample_rate;*/
}

/**


@@ 245,6 250,20 @@ undoable_action_do (

  int ret = 0;

  switch (self->type)
    {
    case UA_ARRANGER_SELECTIONS:
      arranger_selections_action_update_positions (
        (ArrangerSelectionsAction *) self);
      break;
    case UA_RANGE:
      range_action_update_positions (
        (RangeAction *) self);
      break;
    default:
      break;
    }

  /* uppercase, camel case, snake case */
#define DO_ACTION(uc, sc, cc) \
  case UA_##uc: \


@@ 342,6 361,20 @@ undoable_action_undo (

  int ret = 0;

  switch (self->type)
    {
    case UA_ARRANGER_SELECTIONS:
      arranger_selections_action_update_positions (
        (ArrangerSelectionsAction *) self);
      break;
    case UA_RANGE:
      range_action_update_positions (
        (RangeAction *) self);
      break;
    default:
      break;
    }

/* uppercase, camel case, snake case */
#define UNDO_ACTION(uc, sc, cc) \
  case UA_##uc: \

M src/audio/channel.c => src/audio/channel.c +1 -3
@@ 1,7 1,5 @@
// SPDX-FileCopyrightText: © 2018-2022 Alexandros Theodotou <alex@zrythm.org>
// SPDX-License-Identifier: LicenseRef-ZrythmLicense
/*
 * Copyright (C) 2018-2022 Alexandros Theodotou <alex and zrythm dot org>
 */

#include "zrythm-config.h"


M src/audio/tempo_track.c => src/audio/tempo_track.c +3 -5
@@ 172,13 172,11 @@ tempo_track_get_current_bpm_as_str (void * self)
/**
 * Sets the BPM.
 *
 * @param update_snap_points Whether to update the
 *   snap points.
 * @param stretch_audio_region Whether to stretch
 *   audio regions. This should only be true when
 *   the BPM change is final.
 * @param start_bpm The BPM at the start of the
 *   action, if not temporary.
 * @param temporary Whether the change is temporary
 *   (eg, while dragging the BPM meter). If false,
 *   an undoable action will be performed.
 */
void
tempo_track_set_bpm (

M src/gui/backend/arranger_selections.c => src/gui/backend/arranger_selections.c +60 -4
@@ 77,8 77,6 @@ arranger_selections_init_loaded (
                    g_get_monotonic_time (); \
                } \
            } \
          arranger_object_update_positions ( \
            obj, true, false); \
          sel->sc##s[i] = \
            (cc *) arranger_object_find (obj); \
        } \


@@ 86,8 84,6 @@ arranger_selections_init_loaded (
        { \
          arranger_object_init_loaded ( \
            (ArrangerObject *) sel->sc##s[i]); \
          arranger_object_update_positions ( \
            obj, true, false); \
        } \
    }



@@ 140,6 136,66 @@ arranger_selections_init_loaded (
#undef SET_OBJ
}

void
arranger_selections_update_positions (
  ArrangerSelections *   self)
{
  int                      i;
  TimelineSelections *     ts;
  ChordSelections *        cs;
  MidiArrangerSelections * mas;
  AutomationSelections *   as;

#define UPDATE_POSITIONS(sel, cc, sc) \
  for (i = 0; i < sel->num_##sc##s; i++) \
    { \
      ArrangerObject * obj = \
        (ArrangerObject *) sel->sc##s[i]; \
      arranger_object_update_positions ( \
        obj, true, false); \
    }

  switch (self->type)
    {
    case TYPE (TIMELINE):
      ts = (TimelineSelections *) self;
      UPDATE_POSITIONS (ts, ZRegion, region);
      UPDATE_POSITIONS (ts, ScaleObject, scale_object);
      UPDATE_POSITIONS (ts, Marker, marker);
      break;
    case TYPE (MIDI):
      mas = (MidiArrangerSelections *) self;
      for (i = 0; i < mas->num_midi_notes; i++)
        {
          MidiNote *       mn = mas->midi_notes[i];
          ArrangerObject * mn_obj =
            (ArrangerObject *) mn;
          arranger_object_update_positions (
            mn_obj, true, false);
          arranger_object_init_loaded (
            (ArrangerObject *)
              mas->midi_notes[i]);
          g_warn_if_fail (mas->midi_notes[i]);
        }
      break;
    case TYPE (AUTOMATION):
      as = (AutomationSelections *) self;
      UPDATE_POSITIONS (
        as, AutomationPoint, automation_point);
      break;
    case TYPE (CHORD):
      cs = (ChordSelections *) self;
      UPDATE_POSITIONS (cs, ChordObject, chord_object);
      break;
    case TYPE (AUDIO):
      break;
    default:
      g_return_if_reached ();
    }

#undef UPDATE_POSITIONS
}

/**
 * Initializes the selections.
 */

M src/gui/widgets/mixer.c => src/gui/widgets/mixer.c +2 -18
@@ 1,21 1,5 @@
/*
 * Copyright (C) 2018-2021 Alexandros Theodotou <alex at zrythm dot org>
 *
 * This file is part of Zrythm
 *
 * Zrythm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Zrythm is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
 */
// SPDX-FileCopyrightText: © 2018-2021 Alexandros Theodotou <alex@zrythm.org>
// SPDX-License-Identifier: LicenseRef-ZrythmLicense

#include "audio/channel.h"
#include "audio/track.h"

M src/project.c => src/project.c +12 -0
@@ 1128,6 1128,18 @@ load (const char * filename, const int is_template)
  arranger_selections_init_loaded (
    (ArrangerSelections *) self->audio_selections,
    true);
  arranger_selections_update_positions (
    (ArrangerSelections *) self->timeline_selections);
  arranger_selections_update_positions (
    (ArrangerSelections *)
      self->midi_arranger_selections);
  arranger_selections_update_positions (
    (ArrangerSelections *) self->chord_selections);
  arranger_selections_update_positions (
    (ArrangerSelections *)
      self->automation_selections);
  arranger_selections_update_positions (
    (ArrangerSelections *) self->audio_selections);

  tracklist_selections_init_loaded (
    self->tracklist_selections);