The actions of the loopers' Switches tab, made for footswitches, and the settings that say what they and the transport do.
Mode is the state: it shows what the looper does or is about to do, whatever changed it. Play, Stop, Record and Overdub set it, as setting it by hand does. The other actions say what no value can: "the next thing", "a new layer", "from the start", "this layer". Everything that changes what is heard waits for the next point of the grid, as a change of Mode does; Undo, Redo and Clear act at once, and selecting a layer as well.
The looper (the Engine below) provides, besides the transport's engine:
int looper_passes() const; // passes heard bool looper_muted(int pass) const; void looper_set_muted(int pass, bool muted); void looper_mute(int pass); // toggles void looper_erase(int pass);
What the audio and the MIDI looper share: when they record, overdub, play or stop, sample by sample.
The loopers ask for a mode; the transport waits for the next point of the quantification grid before taking it up, splits the tick there, and hands the looper the spans of the tick with the mode each of them is in. A recording can end on its own after a number of bars, into After record.
The looper (the Engine below) provides:
// Does what transport.actualMode says over [start; start + length[ of // the tick, relative to the tick's first sample. Returns the frames it // did: fewer when it ended a recording itself, with end_recording(), // and the rest is run again once the take is closed. int64_t looper_run(int64_t start, int64_t length);
// Something was recorded or overdubbed since the last call, and the // mode is changing: the take is complete. mode is what was taking in // (Record or Overdub). void looper_close_take(
const ossia::token_request& tk, Looper::LoopMode mode,
bool ended_by_postaction);
// A recording stopped this many frames after a grid point ends on that // point: what was recorded since is dropped. void looper_trim_recording(int64_t frames);
// An overdub that made the loop longer is stopped: when the playhead is // at most max_frames into the part the loop last grew by, that part is // dropped and the frames the playhead is into it are returned, else -1. int64_t looper_trim_extension(int64_t max_frames);
// StartFrom::InPhase: the loop starts being heard again, at the start of // the span of tk; the looper puts the playhead where the loop would be // had it kept playing since it was made, by the timeline's clock. void looper_rephase(const ossia::token_request& tk);
// What the looper asked request_point() for is done now, on the grid // point the transport takes its requests up on. void looper_point();
// Frames until the playhead reaches the end of the loop, the way it goes, // or -1 when it is not going round a loop. int64_t looper_frames_to_end() const;
// The loop as the period of Quantize's Loop grid, at the start of the // span of tk; see loop_period. Looper::loop_period looper_period(const ossia::token_request& tk) const;
The looper calls transport.taking(mode) whenever it records or overdubs.
|
| enum class | TakeFiles { Mix
, Layers
, Both
} |
| |
| enum class | OverdubMode { Merge
, Replace
} |
| | What the MIDI looper does with notes of earlier passes under an overdub. More...
|
| |
| enum class | HeldNotes { Wrap
, Truncate
} |
| | A note still held at the end of the loop. More...
|
| |
| enum | merge_mark : uint8_t { from_upper = 1
, replaced_by_lower = 2
, replaced_by_upper = 4
} |
| |
| enum class | LoopMode { Play
, Record
, Overdub
, Stop
} |
| |
| enum class | AfterRecord { Play
, Overdub
} |
| |
| enum class | StopAt { Grid
, LoopEnd
, Now
} |
| | When a stop is taken up. More...
|
| |
| enum class | AfterOverdub { Play
, NewLayer
} |
| | What Rec / Play / Dub does while overdubbing. More...
|
| |
| enum class | TransportAction { RecPlayDub
, PlayStop
, NewLayer
, Retrigger
} |
| |
| enum class | StartFrom { LoopStart
, WhereItWas
, InPhase
} |
| |
| enum class | Passes { Whole
, PerCycle
} |
| | What an overdub that goes round the loop several times leaves. More...
|
| |
| enum class | AtMaxLayers { MergeOldest
, MergeIntoNewest
, ReplaceMuted
} |
| | What a pass that would make more layers than Max layers does. More...
|
| |
| enum class | Passthrough { None
, Record
, Full
} |
| |
| enum class | PastEnd { Wrap
, Extend
} |
| | What an overdub does at the end of the loop. More...
|
| |
| enum class | FollowTempo {
Off
, Repitch
, RepitchFast
, Timestretch
,
TimestretchPercussive
} |
| | How an audio loop follows the tempo of the score, as sound files do.
|
| |
|
| template<typename Data > |
| void | mix_passes (Data &&data, const audio_layer *passes, int count, int c, int64_t len, int64_t from, int64_t to, float *dst) |
| |
|
ossia::audio_stretch_mode | stretch_mode (FollowTempo f) noexcept |
| |
|
halp::clip_stretch | clip_stretch (FollowTempo f) noexcept |
| | How a take made with f asks the timeline to play it: as the loop was.
|
| |
| template<typename Place > |
| void | fill_midi_export (const midi_loop &snap, int item, int64_t pos, OverdubMode mode, Place &&place, midi_export &e) |
| |
| constexpr uint64_t | without_pass (uint64_t m, int k) noexcept |
| |
| constexpr uint64_t | with_room_at (uint64_t m, int k) noexcept |
| |
|
std::string_view | mode_label (LoopMode m) noexcept |
| | The name Mode shows a mode by.
|
| |
|
template<typename Field , typename V > |
| void | show_control (Field &f, V v) |
| | Sets a control from the audio thread, and shows it in the UI.
|
| |
|
template<typename Field > |
| void | show_mode (Field &f, LoopMode m) |
| |
|
template<typename Field > |
| void | read_loop (Field &f, transport &t, loop_input &l, bool empty) |
| |
|
template<typename Field > |
| void | show_loop (Field &f, const transport &t, loop_input &l) |
| | Mode shows what is asked for, once the tick has run.
|
| |
|
double | clamp_speed (float s) noexcept |
| | A speed the loopers can play at, whatever a port sends.
|
| |
|
bool | no_grid (const halp::grid_value &g) noexcept |
| | A grid that never waits: none, or nothing the transport can find points of.
|
| |
| int64_t | loop_round (int64_t len, double rate) noexcept |
| |
| int64_t | frames_to_loop_end (double y, int64_t len, double rate) noexcept |
| |
| transport::timeline_point | timeline_start (const ossia::token_request &tk, ossia::exec_state_facade st) noexcept |
| |
| void | fill_value_export (const value_loop &snap, int item, held_timeline &tl, held_scratch &scratch, value_export &e) |
| |