shimi
Version:
A JS framework for building complex MIDI applications
203 lines (202 loc) • 9.78 kB
TypeScript
import TimeSig from './TimeSig';
import PropertyTracker from './PropertyTracker';
import { ClockChildFinishedEvent, IClockChild } from './Clock';
import { IMetronome, MetronomeBase } from './Metronome';
import ShimiEvent, { ShimiEventData } from './ShimiEvent';
/**
* The Flexinome, much like the Metronome, is an implementation of the IMetronome interface, and is used for converting millisecond updates in time, into beat updates in time.
*
* The Flexinome differs from the Metronome though, in that it fully embraces the IMetronome's concept of separating quarter notes from beats, allowing a lot of flexibility in how bars can be divided up, with some beats stretching out to last longer than others.
*
* This means that if you had a 4 beat clip, it could be played infinitely many ways, just by passing it into a ClipPlayer that's linked to a Flexinome, and altering the time signature that it's using.
*
* To better understand how this works, please take a look at the [IMetronome](https://jamescoyle1989.github.io/shimi/interfaces/IMetronome.html) and [TimeSig](https://jamescoyle1989.github.io/shimi/classes/TimeSig.html) documentation.
*
* @category Timing
*/
export default class Flexinome extends MetronomeBase implements IMetronome, IClockChild {
/** Returns the name of this type. This can be used rather than instanceof which is sometimes unreliable. */
get typeName(): string;
private _tempo;
/** Get the current flexinome tempo. */
get tempo(): number;
/** Set the current flexinome tempo. */
set tempo(value: number);
private _tempoMultiplier;
/**
* Get the tempo multiplier. This allows defining the tempo in terms of other duration values than just quarter notes. For example, if `tempo == 120`:
*
* `tempoMultiplier == 1` means ♩ = 120
*
* `tempoMultiplier == 0.5` means ♪ = 120
*
* `tempoMultiplier == 1.5` means ♩. = 120
*
* The default value is 1.
*/
get tempoMultiplier(): number;
/**
* Set the tempo multiplier. This allows defining the tempo in terms of other duration values than just quarter notes. For example, if `tempo == 120`:
*
* `tempoMultiplier == 1` means ♩ = 120
*
* `tempoMultiplier == 0.5` means ♪ = 120
*
* `tempoMultiplier == 1.5` means ♩. = 120
*
* Valid values are technically all positive numbers, though in reality only numbers that correspond to common musical note durations make sense.
*/
set tempoMultiplier(value: number);
/** Provides a way of identifying flexinomes so they can be easily retrieved later */
get ref(): string;
set ref(value: string);
private _ref;
private _timeSig;
/** Get the current flexinome time signature. */
get timeSig(): TimeSig;
/**
* Set the flexinome time signature.
*
* **Note:** This doesn't actually change the time signature straight away, but instead stores it so that the time signature changes on the start of the next bar.
*/
set timeSig(value: TimeSig);
private _totalQuarterNote;
/**
* How many quarter notes have passed in total since the flexinome started.
*
* This just returns `totalQuarterNoteTracker.value`.
*/
get totalQuarterNote(): number;
/** Records the difference in total quarter notes passed, enabling inspection of the total quarter note change from one update cycle to the next. */
get totalQuarterNoteTracker(): PropertyTracker<number>;
private _totalBeat;
/**
* How many beats have passed in total since the flexinome started.
*
* This just returns `totalBeatTracker.value`.
*/
get totalBeat(): number;
/** Records the difference in total beats passed, enabling inspection of the total beat change from one update cycle to the next. */
get totalBeatTracker(): PropertyTracker<number>;
private _bar;
/**
* Records what bar the flexinome is currently on.
*
* This just returns `barTracker.value`.
*/
get bar(): number;
/** Records the bar number in the previous update vs the current one. */
get barTracker(): PropertyTracker<number>;
private _barQuarterNote;
/**
* Records how many quarter notes have passed within the current bar
*
* This just returns `barQuarterNoteTracker.value`.
*/
get barQuarterNote(): number;
/** Records the difference in bar quarter note values, enabling inspection of the quarter note within the current bar from one update cycle to the next. */
get barQuarterNoteTracker(): PropertyTracker<number>;
private _barBeat;
/**
* Records how many beats have passed within the current bar.
*
* This just returns `barBeatTracker.value`.
*/
get barBeat(): number;
/** Records the difference in bar beat values, enabling inspection of the beat within the current bar from one update cycle to the next. */
get barBeatTracker(): PropertyTracker<number>;
private _enabled;
/** Gets whether the flexinome is currently enabled to run. */
get enabled(): boolean;
/** Sets whether the flexinome is currently enabled to run. */
set enabled(value: boolean);
/** Returns true if the Flexinome has been instructed to stop everything by the `finish()` method. */
get isFinished(): boolean;
private _isFinished;
/** This event fires when the Flexinome finishes. */
get finished(): ClockChildFinishedEvent;
private _finished;
/**
* @param tempo The tempo to run the flexinome at.
* @param timeSig The time signature for the flexinome to use. If not provided then the flexinome defaults to common time (4/4).
*/
constructor(tempo: number, timeSig?: TimeSig);
/**
* This takes in a beat and returns true if the flexinome is currently at it, or has only just passed it in the bar within the last update cycle.
* @param beat The beat to test if we've recently passed.
* @returns
*/
atBarBeat(beat: number): boolean;
/**
* This takes a quarter note and returns true if the flexinome is currently at it, or has only just passed it in the bar within the last update cycle.
* @param quarterNote The quarter note to test if we've recently passed.
* @returns
*/
atBarQuarterNote(quarterNote: number): boolean;
/**
* This takes in a beat division and checks if the metronome is currently at some multiple of that division within the current bar, returning what multiple of the division we're currently at.
* For example: atBarBeatMultiple(0.5) returns 0 if we're at beat 0, 1 if we're at beat 0.5, 2 if we're at beat 1, etc. If not at a multiple of the division, then -1 is returned.
* @param division The beat division to check if the metronome is at a multiple of.
*/
atBarBeatMultiple(division: number): number;
/**
* This takes in a quarter note division and checks if the metronome is currently at some multiple of that division within the current bar, returning what multiple of the division we're currently at.
* For example: atBarQuarterNoteMultiple(0.5) returns 0 if we're at QN 0, 1 if we're at QN 0.5, 2 if we're at QN 1, etc. If not at a multiple of the division, then -1 is returned.
* @param division The beat division to check if the metronome is at a multiple of.
*/
atBarQuarterNoteMultiple(division: number): number;
/**
* This method is intended to be called by a clock to provide regular updates. It should be called by consumers of the library.
* @param msDelta How many milliseconds have passed since the last update cycle.
* @returns
*/
update(msDelta: number): boolean;
/**
* This method is exposed primarily for the TickReceiver, so it can get a metronome to update, using its own calculation of how many quarter notes to update by.
*
* This method should not be called by consumers of the library.
* @param qnDelta The number of quarter notes to update the metronome by.
* @returns
*/
updateFromQuarterNoteDelta(qnDelta: number): boolean;
/** Calling this tells the flexinome to stop whatever it's doing and that it will no longer be used. */
finish(): void;
/**
* Provides a way for setting the ref through a chained function call. For example:
*
* ```
* clock.addChild(new Flexinome(120, TimeSig.commonTime).withRef('metronome'));
* ```
*
* @param ref The ref to set on the object.
* @returns The calling object.
*/
withRef(ref: string): IClockChild;
/**
* This method allows for setting the metronome to a specific position.
*
* Note though, that the bar-related values are calculated under the assumption that the metronome's current time signature is the one that it always has.
* @param totalQuarterNote The new position, as measured in quarter notes.
*/
setSongPosition(totalQuarterNote: number): void;
/**
* Event that fires whenever the metronome is directed to move to a new position.
*/
get positionChanged(): ShimiEvent<ShimiEventData<IMetronome>, IMetronome>;
private _positionChanged;
/**
* Event that fires when the metronome is first started
*/
get started(): ShimiEvent<ShimiEventData<IMetronome>, IMetronome>;
private _started;
/**
* Event that fires when the metronome is allowed to resume running (enabled = true)
*/
get continued(): ShimiEvent<ShimiEventData<IMetronome>, IMetronome>;
private _continued;
/**
* Event that fires when the metronome is instructed to stop running (enabled = false)
*/
get stopped(): ShimiEvent<ShimiEventData<IMetronome>, IMetronome>;
private _stopped;
}