Skip to main content

PlaybackWindow

Struct PlaybackWindow 

Source
pub struct PlaybackWindow { /* private fields */ }
Expand description

The span of song time one callback renders.

This is the sync guarantee. Clip playback and pattern playback in mixer.rs take the same value and ask it the same question, so a clip note and a pattern step on the same beat cannot land on different samples: there is only one expression that turns a tick into a sample offset, and only one that decides where the window starts and ends.

Windows are half-open and contiguous. The next window begins exactly where this one ended, rather than at the transport’s new position, because those are not always the same number: a block is almost never a whole number of ticks, and a transport that carries the remainder can advance 179 ticks where the block measured 178. Starting the next window at the position would leave a one-tick hole in song time, and an onset that fell in it would never play. Starting it where the last one ended cannot.

Implementations§

Source§

impl PlaybackWindow

Source

pub const MAX_TICK_GAP: i64 = 1

The largest gap between one window’s end and the next block’s position that still counts as continuous playback.

One tick, and it is not a fudge factor: the block length in ticks is truncated and the transport’s advance is not, so consecutive positions can run at most one tick ahead of the measured window. Anything larger is the playhead being moved, which is a discontinuity — pending notes get flushed and nothing is replayed.

Source

pub fn for_block( position: i64, frames: u32, ticks_per_sample: f64, loop_region: Option<(i64, i64)>, previous: Option<Self>, ) -> Self

The window for one callback.

loop_region is the loop’s (start, end) when the transport is looping, and None when it is not — one argument rather than a flag and two numbers, because “looping over nowhere” is not a state that should be spellable.

previous is the window the last callback used, if playback has been running. Two things come from the loop region:

  • A wrap — the transport moving backwards — starts the window at the loop point, so the ticks between it and the position the callback arrived at are played rather than skipped. That is what clip playback has always done.
  • The window never extends past the loop end. Without that, the last callback of a loop would reach across the loop point and play the first notes on the other side of it, and then the wrap would play them again: one doubled downbeat per time round.
Source

pub fn narrowed(&self, from: i64, to: i64) -> Self

A window over part of this one, for splitting a callback at a pattern switch. Sample offsets are unchanged: they are measured from the original start of the block, not from the piece.

Source

pub const fn from(&self) -> i64

Source

pub const fn to(&self) -> i64

Source

pub const fn is_continuous(&self) -> bool

Whether this window carries on from the previous one. false after a jump, a loop wrap, or the first block of playback — every case where notes still sounding have to be turned off.

Source

pub const fn is_empty(&self) -> bool

Source

pub const fn contains(&self, tick: i64) -> bool

Source

pub fn sample_offset(&self, tick: i64) -> u32

Where in the callback’s buffer an event at tick belongs.

The one expression that turns song time into a sample. A tick before the window lands on the first sample rather than underflowing, and one past the end lands on the last: a note played at the wrong end of a buffer is 1.5 ms out, and a note not played at all is a hole in the part.

Trait Implementations§

Source§

impl Clone for PlaybackWindow

Source§

fn clone(&self) -> PlaybackWindow

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for PlaybackWindow

Source§

impl Debug for PlaybackWindow

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more