pub struct Pump {
pub depth: Decibels,
pub back: Option<Seconds>,
pub tau: Option<Seconds>,
pub lock: PumpLock,
pub beats: usize,
pub curve: Vec<f64>,
/* private fields */
}Expand description
The pump read of a stem.
Fields§
§depth: DecibelsHow far the median beat curve dips below its reference.
back: Option<Seconds>The time from the dip until the curve comes back within
PUMP_BACK; None when it does not within the beat.
tau: Option<Seconds>back / ln(depth / 1.5), the time constant of an exponential
recovery; None without back and for any lock but the beat: a dip
that follows no beat has no recovery to model.
lock: PumpLockWhat the dip follows.
beats: usizeThe beats a sustained note covers.
curve: Vec<f64>The median curve over those beats, in dB from the reference, one value per phase bin.
Implementations§
Source§impl Pump
impl Pump
Sourcepub fn find(
track: &LevelTrack,
grid: BeatGrid,
notes: &NoteList,
held: &[(f64, f64)],
) -> Option<Self>
pub fn find( track: &LevelTrack, grid: BeatGrid, notes: &NoteList, held: &[(f64, f64)], ) -> Option<Self>
Reads the pump of a stem from its full-band level track.
Only beats that the held part of one note covers from start to end
count, so a pluck that decays inside its beat reads no pump and a
release at the end of a beat reads no dip. held holds the start
and end of each held part, in seconds; notes gives the onsets for
the note lock. Each counted beat is binned into PUMP_BINS phase
bins and taken relative to its PUMP_REFERENCE quantile; the
median over the beats is the curve. None with fewer than
PUMP_BEATS_MIN counted beats.
The beats are read on the grid and again at the period, within
about PERIOD_RANGE of it, whose beats fold onto the deepest mean
curve. A second read that locks to the beat replaces the first when
the first:
- locks to the beat, and, when both strip or neither does, the second’s
fold error is under
FOLD_ERROR_SHAREof the first’s andFOLD_ERROR_GAINlower. When only one of them strips, as the periods count different beats, the second must strip and have the lower fold error; - runs free on a line within
FREE_REACH, and the second has a duck’s shape: over a short span, a duck near the search’s end reads free. A gate near a division folds onto one curve as well, but comes back at once; - reads nothing, and the second has a duck’s shape without the level window’s share of the tail: a gate off the tempo often reads no lock on the grid;
- follows the notes.
Sourcepub fn carries(&self, from: f64, to: f64) -> bool
pub fn carries(&self, from: f64, to: f64) -> bool
Returns whether the beats over from to to carry the duck: their
median fall into the dip is at least PHASE_DEPTH of its depth.
A stem can duck in one section only, and stripping a note outside it
would write the curve’s ripple into its envelope. True when no beat
over the span has frames.
Sourcepub fn strips(&self) -> bool
pub fn strips(&self) -> bool
Returns whether the layer strips the pump: it locks to the beat,
and so dips at least PUMP_MIN, over PUMP_STRIP_BEATS or more
counted beats.
Sourcepub fn bpm(&self) -> Bpm
pub fn bpm(&self) -> Bpm
Returns the tempo the pump was read at: the given tempo, or the fitted one when that read replaced the read on the grid.
Sourcepub fn at(&self, t: f64) -> f64
pub fn at(&self, t: f64) -> f64
Returns the curve at time t, linear between bin centres and
wrapping over the beat.
Sourcepub fn strip(&self, track: &mut LevelTrack)
pub fn strip(&self, track: &mut LevelTrack)
Adds the dip back to a level track, so the track shows the note’s own envelope.
Trait Implementations§
impl StructuralPartialEq for Pump
Auto Trait Implementations§
impl Freeze for Pump
impl RefUnwindSafe for Pump
impl Send for Pump
impl Sync for Pump
impl Unpin for Pump
impl UnsafeUnpin for Pump
impl UnwindSafe for Pump
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> CloneAny for T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more