Loading...
Searching...
No Matches
Nodes::Looper Namespace Reference

Detailed Description

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.

Classes

struct  after_overdub_selector
 
struct  after_record_selector
 
struct  at_max_layers_selector
 
struct  audio_layer
 
struct  audio_layers
 
struct  audio_seam_end
 
struct  audio_snapshot
 
struct  audio_stop_take
 
struct  capture_window
 
struct  double_speed_button
 
struct  enum_combobox
 An enumeration shown as a combobox: compact where the choices are many. More...
 
struct  erase_layer_button
 
struct  erase_request
 
struct  export_buffer
 
struct  half_speed_button
 
struct  held_scratch
 
struct  held_timeline
 
struct  item_in_columns
 
struct  layer_action
 
struct  layers_tab
 
struct  loop_input
 
struct  loop_period
 
struct  looper_node
 
struct  looper_view
 
struct  looper_view_item
 
struct  merge_log
 
struct  midi_control
 A controller, pitch bend or pressure value. More...
 
struct  midi_export
 
struct  midi_loop
 
struct  midi_note
 
struct  midi_stop_take
 
struct  midi_take_job
 
struct  mute_layer_button
 
struct  new_layer_button
 
struct  next_layer_button
 
struct  note_grid_selector
 
struct  overdub_button
 
struct  pass_stack
 
struct  play_button
 
struct  play_stop_button
 
struct  previous_layer_button
 
struct  quantif_selector
 The grid a change of mode waits for. The Quantif of older scores. More...
 
struct  rec_play_dub_button
 
struct  record_button
 
struct  retrigger_button
 
struct  reverse_button
 
struct  rgba
 A colour, handed to the painter as {r, g, b, a}. More...
 
struct  solo_layer_button
 
struct  solo_memory
 The mutes the layers had before a solo, to give them back. More...
 
struct  speed_selector
 
struct  speed_tab
 
struct  start_from_selector
 
struct  stop_at_selector
 
struct  stop_button
 
struct  stop_take_notice
 
struct  switches
 
struct  switches_tab
 
struct  tagged_material
 
struct  tagged_pass
 What a loop whose material is kept apart keeps of a pass besides it. More...
 
struct  tagged_pass_stack
 
struct  take_job
 
struct  take_writer
 
struct  transport
 
struct  transport_settings
 
struct  value_event
 A value of the loop. More...
 
struct  value_export
 
struct  value_loop
 
class  value_slot
 
struct  value_stop_take
 
struct  value_stretch
 
struct  value_take_job
 
struct  view_message
 
struct  view_note
 

Typedefs

using midi_pass = tagged_pass
 What the MIDI loop keeps of a pass besides its events.
 

Enumerations

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.
 

Functions

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)
 

Variables

constexpr int max_audio_layers = 32
 
constexpr AfterOverdub after_overdub_default = AfterOverdub::Play
 What Rec / Play / Dub does while overdubbing until the setting is changed.
 
constexpr halp::grid_setup note_grid
 The note values the MIDI looper's notes are pulled to.
 
constexpr std::array< std::pair< const char *, float >, 5 > speeds
 The speeds a loop is played at, as a tape: the pitch follows.
 
constexpr halp::grid_setup quantif_grid
 The units Quantize offers: a time, a note value, bars, or the loop itself.
 

Enumeration Type Documentation

◆ AfterOverdub

enum class Nodes::Looper::AfterOverdub
strong

What Rec / Play / Dub does while overdubbing.

Enumerator
Play 

Plays the loop.

NewLayer 

Goes on overdubbing in a new layer, as New layer does.

◆ AfterRecord

enum class Nodes::Looper::AfterRecord
strong

What a recording gives way to when it ends: its bars running out, a full buffer, Rec / Play / Dub. An overdub starts on the frame the recording ends on.

Order matters: this is the Post-action of older scores.

◆ AtMaxLayers

enum class Nodes::Looper::AtMaxLayers
strong

What a pass that would make more layers than Max layers does.

Enumerator
MergeOldest 

The two oldest layers are merged into one.

MergeIntoNewest 

The pass is merged into the newest layer once it ends.

ReplaceMuted 

The pass takes the place of the oldest muted layer, else of the newest one.

◆ HeldNotes

enum class Nodes::Looper::HeldNotes
strong

A note still held at the end of the loop.

Enumerator
Wrap 

Carries on from the loop's start.

Truncate 

Ends with the loop.

◆ merge_mark

enum Nodes::Looper::merge_mark : uint8_t

What became of a piece of material when the last pass was merged into the newest one, for undo to take it apart again.

Enumerator
from_upper 

It is of the upper pass.

replaced_by_lower 

The lower pass replaced it.

replaced_by_upper 

The upper pass replaced it.

◆ OverdubMode

enum class Nodes::Looper::OverdubMode
strong

What the MIDI looper does with notes of earlier passes under an overdub.

Enumerator
Merge 

Every pass is heard.

Replace 

A pitch played in a pass silences that pitch of earlier ones where the pass went.

◆ Passes

enum class Nodes::Looper::Passes
strong

What an overdub that goes round the loop several times leaves.

Enumerator
Whole 

One pass, from when the overdub starts to when it stops.

PerCycle 

A pass for each time it goes round, cut on the loop's start.

◆ Passthrough

enum class Nodes::Looper::Passthrough
strong
Enumerator
None 

The input is never heard, in any mode.

Record 

Heard while recording and overdubbing; playback is the loop alone.

Full 

Always heard, mixed over the loop during playback.

◆ PastEnd

enum class Nodes::Looper::PastEnd
strong

What an overdub does at the end of the loop.

Enumerator
Wrap 

Goes round the loop again.

Extend 

Makes the loop longer by the loop's length, the passes under it repeating.

◆ StartFrom

enum class Nodes::Looper::StartFrom
strong

Where the loop is read from when the mode changes.

Order matters: this is the Restart of older scores, whose Always, Recording and In phase these are.

Enumerator
LoopStart 

Every change of mode reads the loop from its beginning again.

WhereItWas 

Only a recording does; playing and overdubbing carry straight on.

InPhase 

As WhereItWas, and a loop heard again after a stop, a transport start or a jump of the timeline is where it would be had it kept playing.

◆ StopAt

enum class Nodes::Looper::StopAt
strong

When a stop is taken up.

Enumerator
Grid 

On the next point of the grid, as any change of mode.

LoopEnd 

When the loop has played to its end.

Now 

At once.

◆ TakeFiles

enum class Nodes::Looper::TakeFiles
strong

The files of a take Send places: the loop as it is heard, each of its passes in a file of its own, or both.

◆ TransportAction

enum class Nodes::Looper::TransportAction
strong

The actions that are not "set Mode to a mode". Each is taken up on the next grid point, as a change of Mode is.

Enumerator
RecPlayDub 

Records an empty loop, then plays, overdubs, plays again.

PlayStop 

Plays a stopped loop, stops anything else.

NewLayer 

While overdubbing, ends the layer and starts another.

Retrigger 

Back to the loop's start, in the same mode.

Function Documentation

◆ fill_midi_export()

template<typename Place >
void Nodes::Looper::fill_midi_export ( const midi_loop &  snap,
int  item,
int64_t  pos,
OverdubMode  mode,
Place &&  place,
midi_export &  e 
)

What is heard of snap (item -1), or of one of its passes, into e: each note where place(note, period) puts it, a note still held lasting until pos.

◆ fill_value_export()

void Nodes::Looper::fill_value_export ( const value_loop &  snap,
int  item,
held_timeline &  tl,
held_scratch &  scratch,
value_export &  e 
)
inline

What is heard of snap (item -1), or of one of its passes, into e: the held values where they change, and the impulses. tl and scratch are where it is worked out.

◆ frames_to_loop_end()

int64_t Nodes::Looper::frames_to_loop_end ( double  y,
int64_t  len,
double  rate 
)
inlinenoexcept

Frames until a playhead at y of a loop of len positions, going rate of them a frame, reaches the loop's end: none at its start, which is its end as well.

◆ loop_round()

int64_t Nodes::Looper::loop_round ( int64_t  len,
double  rate 
)
inlinenoexcept

Frames a round of a loop of len positions takes, its playhead going rate of them a frame.

◆ mix_passes()

template<typename Data >
void Nodes::Looper::mix_passes ( Data &&  data,
const audio_layer *  passes,
int  count,
int  c,
int64_t  len,
int64_t  from,
int64_t  to,
float *  dst 
)

Frames [from; to[ of channel c of what is heard of count passes of a loop of len frames, into dst; data(slot, c) is where a buffer is.

◆ timeline_start()

transport::timeline_point Nodes::Looper::timeline_start ( const ossia::token_request &  tk,
ossia::exec_state_facade  st 
)
inlinenoexcept

Where the timeline is at the start of a tick, before the transport has run it.

◆ with_room_at()

constexpr uint64_t Nodes::Looper::with_room_at ( uint64_t  m,
int  k 
)
inlineconstexprnoexcept

A set of passes with room made for a pass at k: the passes from k on move up a place.

◆ without_pass()

constexpr uint64_t Nodes::Looper::without_pass ( uint64_t  m,
int  k 
)
inlineconstexprnoexcept

A set of passes, a bit each, without pass k: the passes over it move down a place.

Variable Documentation

◆ note_grid

constexpr halp::grid_setup Nodes::Looper::note_grid
inlineconstexpr
Initial value:
{
.units = halp::grid_units::note, .init = halp::grid_value::note(0.25)}

The note values the MIDI looper's notes are pulled to.

◆ quantif_grid

constexpr halp::grid_setup Nodes::Looper::quantif_grid
inlineconstexpr
Initial value:
{
.units = halp::grid_units::free | halp::grid_units::note | halp::grid_units::bars
| halp::grid_units::period,
.init = halp::grid_value::note(0.25),
.max_bars = 16}

The units Quantize offers: a time, a note value, bars, or the loop itself.

◆ speeds

constexpr std::array<std::pair<const char*, float>, 5> Nodes::Looper::speeds
inlineconstexpr
Initial value:
{
{{"x1/4", 0.25f}, {"x1/2", 0.5f}, {"x1", 1.f}, {"x2", 2.f}, {"x4", 4.f}}}

The speeds a loop is played at, as a tape: the pitch follows.