Bedtime. /Tape API

Tape API

Access to tape state and transport controls

The tape API provides access to the global tape storage and transport state. TAPPs can query tape state and control playback/recording.

Tape States

tape_t* tape_get(void)

Get the global tape instance

Returns — Pointer to tape (never NULL after system init)

tape_state_t tape_get_state(const tape_t* tape)

Get current tape state

const tape_t*tapeTape instance from tape_get()

Returns — Current state (TAPE_STATE_UNMOUNTED, TAPE_STATE_IDLE, etc.)

bool tape_is_idle(const tape_t* tape)

Check if tape is idle (not playing or recording)

const tape_t*tapeTape instance from tape_get()

Returns — true if tape is idle

uint32_t tape_size(const tape_t* tape)

Get tape length in tape positions (SD sectors)

const tape_t*tapeTape instance from tape_get()

Returns — Tape length in positions. 1 position = 1 sector = 64 stereo frames, so multiply by 64 to compare against tape_read()/tape_write() frames.

tape_rec_t* tape_rec_begin(tape_t* tape, uint32_t pos, bool reverse)

Begin recording session

tape_t*tapeTape instance from tape_get()
uint32_tposStarting position in tape POSITIONS (SD sectors), NOT frames. tape_get_position() returns frames — divide by 64.
boolreverseTrue for reverse direction

Returns — Recording handle, or NULL if already recording

Note — This only brackets the take (undo, timeline, mark). It writes NO audio — your engine callback has replaced the one that normally does. Stream your output to the tape with tape_write() between begin and commit.

uint32_t tape_rec_commit(tape_rec_t* rec, uint32_t end_pos)

Commit recording session

tape_rec_t*recRecording handle from tape_rec_begin()
uint32_tend_posEnd position of recorded region

Returns — Final end position

void tape_rec_abort(tape_rec_t* rec)

Abort recording (discard without creating marks)

tape_rec_t*recRecording handle
bool tape_rec_undo_available(const tape_t* tape)

Check if undo is available for last recording

const tape_t*tapeTape instance from tape_get()

Returns — true if undo data is valid

bool tape_rec_undo_execute(tape_t* tape)

Execute undo - restore original audio from last recording

tape_t*tapeTape instance from tape_get()

Returns — true on success

uint32_t tape_marks_count(const tape_t* tape)

Number of recording marks on the tape

const tape_t*tapeTape instance from tape_get()

Returns — Mark count (0 if none / no tape)

bool tape_marks_get(const tape_t* tape, uint32_t idx, uint32_t* start_frame, uint32_t* end_frame)

Get the start/end of mark `idx`

const tape_t*tapeTape instance from tape_get()
uint32_tidxMark index (0 .. tape_marks_count()-1)
uint32_t*start_frameOutput: region start, in stereo frames
uint32_t*end_frameOutput: region end, in stereo frames

Returns — true if idx is valid and outputs were written

uint32_t tape_read(const tape_t* tape, uint32_t pos_frame, float* dst, uint32_t n_frames)

Read recorded audio into a RAM buffer (stereo-interleaved L,R,...)

const tape_t*tapeTape instance from tape_get()
uint32_tpos_frameStart position in stereo frames
float*dstDestination buffer (must hold 2*n_frames floats)
uint32_tn_framesNumber of stereo frames to read

Returns — Number of stereo frames actually read

Warning — Blocks on SD DMA. Call from tick()/init() (main thread), NEVER from the audio process() callback. Sequence the slices yourself in process().

uint32_t tape_write(tape_t* tape, uint32_t pos_frame, const float* src, uint32_t n_frames)

Write audio to the tape (stereo-interleaved L,R,...)

tape_t*tapeTape instance from tape_get()
uint32_tpos_frameStart position in stereo frames
const float*srcSource buffer (2*n_frames floats)
uint32_tn_framesNumber of stereo frames to write

Returns — Number of stereo frames actually written

Warning — Blocks on SD DMA. Call from tick()/init() (main thread), NEVER from the audio process() callback.

bool tape_cue_add(tape_t* tape, uint32_t start_frame, uint32_t end_frame)

Add a cue (a navigable point of interest) spanning [start, end) frames

tape_t*tape
uint32_tstart_frame
uint32_tend_frame

Returns — false if the span is empty, shorter than one 64-frame sector, ends past the end of the tape, or the tape already holds 255 cues

uint32_t tape_cues_count(tape_t* tape)

Number of cues on the tape

tape_t*tape
bool tape_cue_get(tape_t* tape, uint32_t idx, uint32_t* start_frame, uint32_t* end_frame)

Read cue `idx` (0..tape_cues_count-1), in stereo frames

tape_t*tape
uint32_tidx
uint32_t*start_frame
uint32_t*end_frame

Returns — false if idx is out of range

bool tape_erase(tape_t* tape, uint32_t start_frame, uint32_t end_frame)

Erase [start_frame, end_frame): audio, marks, and cues

tape_t*tape
uint32_tstart_frame
uint32_tend_frame

Returns — false if the span is empty, off-tape, or a take is open

uint32_t tape_get_position(const tape_t* tape)

Current tape playhead position, in stereo frames

const tape_t*tapeTape instance from tape_get()

Returns — Playhead position (frames)