Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model Clock time signature change behavior after Ableton's #212

Open
josiah-wolf-oberholtzer opened this issue Aug 27, 2021 · 3 comments
Open

Comments

@josiah-wolf-oberholtzer
Copy link
Contributor

When changing time signature, it applies retroactively against the last time signature change marker - effectively the time origin or wherever a time signature change marker was created.

Time signature change markers always create a new downbeat, even if that means truncating the measure preceding them (e.g. 3/8 of the way into a 4/4 bar).

@josiah-wolf-oberholtzer
Copy link
Contributor Author

Implementation thoughts:

  • Add last_downbeat_offset and last_downbeat_measure_number to clock state
  • Add a set_downbeat bool to ChangeCommand
  • Add a set_downbeat bool to Clock.change(), Clock.cue_change() and Clock.schedule_change()
  • If setting the downbeat, update last_downbeat_offset, and increment last_downbeat_measure_number if necessary
  • Update Moment.measure_offset calculations to make use of last_downbeat_...

@josiah-wolf-oberholtzer
Copy link
Contributor Author

josiah-wolf-oberholtzer commented Jan 14, 2022

Starting the clock would look like:

    async def start(
        self,
        initial_time: Optional[float] = None,
        initial_offset: float = 0.0,
        initial_downbeat_offset: float = 0.0,
        initial_downbeat_measure_number: int = 1,
        time_signature: Optional[Tuple[int, int]] = None,
    ):
        ...

We're going to have to rework the existing ClockState's previous_measure and previous_time_signature_change_offset members, and all of the math referring to them.

All measure math / measure offset math needs to be relative to the last recorded downbeat.

@josiah-wolf-oberholtzer
Copy link
Contributor Author

josiah-wolf-oberholtzer commented Jan 14, 2022

Might be able to drop the initial_ prefix.

Consider:

    async def start(
        self,
        time: Optional[float] = None,
        offset: float = 0.0,
        downbeat_offset: float = 0.0,
        downbeat_measure_number: int = 1,
        time_signature: Optional[Tuple[int, int]] = None,
    ):
        ...

I'm honestly not sure what the utility of the time argument is here... was it to synchronize with other clocks? Possibly for NRT applications actually...

Anyways, this also opens up the possibility of a seek(...) API:

    async def start(
        self,
        offset: float = 0.0,
        downbeat_offset: Optional[float] = None,
        downbeat_measure_number: Optional[int] = None,
        time_signature: Optional[Tuple[int, int]] = None,
    ):
        ...

... where time_signature, downbeat_offset, downbeat_measure_number are optionally recalculated from the current state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants