The sampler-looper system gives each track a way to capture audio, turn the capture into a loop-aligned sample, and make that sample available through the normal sample-source path.
Each track has three related pieces:
The recording buffer is fixed per voice and lives next to the component that will
play it back. A track also has a configurable recording source. That source
selects which trio/lane output should feed the track’s own recording buffer while
recording. The sample source plays back from an AudioBufferBank. The sample
directory is the persistent directory backing that bank. This complexity mirrors
the Octatrack’s flex buffers, where recording buffers and playback assignments
are related but not the same object.
Recording is routed through RecordingConfig. A track’s source selection chooses
which trio’s same-lane voice should provide audio. For example, lane 2 on a track
configured for Water records Water lane 2’s output into that track’s own
recording buffer. A voice can select one of the internal trio sources:
WaterEarthFireNoneInternal recording uses RecordingBufferWriter on the selected source voice to
fan out source samples to every active destination RecordingBuffer. External
sampling is a planned extension of the same model: an external source writer
should feed selected destination buffers, which then persist into sample
directories and reload sample banks after saved files appear on disk.
RecordingManager coordinates recording by voice or by trio. It resolves each
voice’s selected source writer, starts or stops the voice’s own recording buffer,
and registers or deregisters that buffer with the source writer.
RecordingBuffer is a mono in-memory capture buffer. It has a fixed capacity and
an explicit state machine:
IdleRecordingDoneErrorOn start, a buffer in Idle clears previous audio and stores the current unwound
master-loop position from TheoryOfTime. While recording, the selected source
voice’s RecordingBufferWriter pushes one sample into every registered
destination buffer each audio tick. On stop, the destination buffer stores the
stop position and computes how the captured span relates to the available
TheoryOfTime loops.
This start/stop phase information is what lets a recording become a loop rather
than a raw slice of audio. If the recording span does not map cleanly into the
supported loop range, the buffer enters Error instead of producing a file.
When a recording is persisted, RecordingBuffer::WriteToFile() writes a mono WAV
through MultichannelWavWriter.
The write is phase-aware:
The result is a sample that fits exactly one full loop of the selected time
relationship, so the sample source can play it back as part of the same
TheoryOfTime structure.
Sample directories are relative to the configured sample root. A track with an existing sample directory writes its recording into that directory. A track without an existing directory can create a UUID-named directory under the sample root and use that directory as its sample bank.
Recorded files use the name form _recording_NNNNN.wav. The number is based on
the count of regular files already in the target directory, so each recording is
appended as the next sample in that directory.
Multiple tracks may share one sample directory. After recording, the system reloads known sample directories instead of trying to identify every track that points at the changed directory. Reloading is inexpensive, and the simpler rule keeps shared-directory behavior predictable.
AudioBufferBank stores each loaded sample with its source file name. Directory
reloads can reuse buffers whose file names are still present, preserve the bank
position, and add newly recorded files.
The sample source reads from the track’s AudioBufferBank. SampleBankPosition
selects or blends between files in the directory, while SampleLoopIndex,
SampleStart, SampleLength, and SampleReadSpeed control how the selected
sample is read through the grain engine.
The looper side and the sample source both use TheoryOfTime loop information.
Recordings use the master loop to define their captured span, and sample playback
uses selected Theory of Time loops for synchronized playback phase.