API Reference
This document is the complete reference for the VelociLoops C API defined in
include/velociloops.h.
Types
VLFile
typedef struct VLFile_s* VLFile;
Opaque handle representing one open REX2 file. Obtained from vl_open(),
vl_open_from_memory(), or vl_create_new(). Must be released with
vl_close() when no longer needed. All functions that accept a VLFile
treat NULL as VL_ERROR_INVALID_HANDLE.
VLError
typedef enum { VL_OK = 0 } VLError;
Return type for all fallible API calls. Zero (VL_OK) is success; every
negative value is a distinct failure reason.
Enumerator |
Value |
Description |
|---|---|---|
|
0 |
Success. |
|
-1 |
NULL or already-closed |
|
-2 |
NULL required pointer or out-of-range number. |
|
-3 |
Path does not exist or cannot be opened. |
|
-4 |
IFF/DWOP structure malformed or mandatory chunks missing. |
|
-5 |
Heap allocation failed. |
|
-6 |
Slice index negative or >= |
|
-7 |
Sample rate zero, negative, or unsupported. |
|
-8 |
|
|
-9 |
File has no CREI chunk. |
|
-10 |
Feature parsed but not yet functional (e.g. resampling). |
|
-11 |
Metadata set attempted after slices were added. |
|
-12 |
File was written by a newer unsupported ReCycle/REX version. |
|
-13 |
File declares no usable loop length. |
|
-14 |
File or chunk size fields are invalid or inconsistent with the payload. |
|
-15 |
Tempo field is zero or outside the supported ReCycle range. |
VLFileInfo
typedef struct { /* fields omitted */ } VLFileInfo;
File-level metadata. Populated by vl_get_info(); supplied to vl_set_info()
when assembling a new file.
Field |
Type |
Description |
|---|---|---|
|
|
1 = mono, 2 = stereo. |
|
|
Native sample rate in Hz. |
|
|
Number of slices. |
|
|
Playback tempo in BPM × 1000 (120 BPM → 120000). |
|
|
Original recording tempo in BPM × 1000 (RECY chunk). |
|
|
Loop length in PPQ ticks (kREXPPQ = 15360 ticks/bar). |
|
|
Time-signature numerator. |
|
|
Time-signature denominator. |
|
|
Source/authored bit depth: 16 or 24. |
|
|
Total PCM frames in the decoded DWOP payload. |
|
|
First PCM frame of the loop region (inclusive). |
|
|
Last PCM frame of the loop region (exclusive). Zero = whole file. |
|
|
Raw GLOB gain (level = gain × 0.000833333354f; 1200 ≈ unity). |
|
|
Non-zero if the transient shaper is active. |
|
|
Transient shaper attack (raw TRSH value). |
|
|
Transient shaper decay (raw TRSH value). |
|
|
Stretch tail length (raw TRSH value). Non-zero extends |
|
|
Non-zero when the GLOB “silence selected” flag is set. |
VLSliceInfo
typedef struct { /* fields omitted */ } VLSliceInfo;
Per-slice metadata. Populated by vl_get_slice_info().
Field |
Type |
Description |
|---|---|---|
|
|
Slice position in PPQ ticks from loop start. |
|
|
Raw PCM frame count (no stretch tail). |
|
|
Frame offset into the decoded PCM buffer. |
|
|
Raw slice-analysis value from the file. |
|
|
Bitmask of |
Slice flags:
Flag |
Meaning |
|---|---|
|
Muted slice state. |
|
Locked slice state. |
|
Selected slice state. |
|
Marker-like raw record that was not promoted to a normal renderable boundary. |
|
Synthetic leading slice inserted by VelociLoops. |
VLCreatorInfo
typedef struct { /* fields omitted */ } VLCreatorInfo;
Optional creator and tag metadata from the REX2 CREI chunk.
Field |
Size |
Description |
|---|---|---|
|
256 bytes |
Creator or artist name (NUL-terminated UTF-8). |
|
256 bytes |
Copyright notice. |
|
256 bytes |
Creator website URL. |
|
256 bytes |
Contact e-mail address. |
|
256 bytes |
Arbitrary free-form text. |
Absent fields are returned as empty strings ("").
VLSuperFluxOptions
typedef struct { /* fields omitted */ } VLSuperFluxOptions;
Tunable parameters for vl_create_from_superflux(). Initialize with
vl_superflux_default_options() and then override individual fields as needed.
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
2048 |
FFT/window size. Must be a power of two. |
|
|
200 |
Onset detection frames per second. |
|
|
24 |
Log-frequency filter bands per octave. |
|
|
3 |
Frequency bins for SuperFlux maximum filtering. |
|
|
0 |
Previous-frame distance; |
|
|
0 |
Minimum samples between slice starts; |
|
|
0 |
Non-zero normalizes triangular filter areas. |
|
|
0 |
Non-zero uses causal framing and peak picking. |
|
|
1.1 |
Peak-picking threshold above the local average. |
|
|
30 |
Suppress detections within this many milliseconds. |
|
|
0.15 |
Seconds before peak for moving average. |
|
|
0.01 |
Seconds before peak for moving maximum. |
|
|
0 |
Seconds after peak for moving average. |
|
|
0.05 |
Seconds after peak for moving maximum. |
|
|
0 |
Detection timestamp offset in milliseconds. |
|
|
0.5 |
Window ratio used to derive |
|
|
30 |
Filterbank minimum frequency in Hz. |
|
|
17000 |
Filterbank maximum frequency in Hz. |
|
|
1 |
Magnitude multiplier before |
|
|
1 |
Positive value added before |
Functions
Open / Close
vl_open
VLFile vl_open(const char* path, VLError* err);
Load and decode a REX2 file from disk.
Parses the IFF/CIFF container, validates mandatory chunks, and decompresses the DWOP bitstream into an internal PCM buffer. Complexity is O(n) in the total frame count.
Parameters
Name |
Description |
|---|---|
|
NUL-terminated path to the |
|
Out-parameter; receives |
Returns A valid VLFile on success, or NULL on failure.
Errors VL_ERROR_FILE_NOT_FOUND, VL_ERROR_FILE_CORRUPT, VL_ERROR_OUT_OF_MEMORY.
vl_open_from_memory
VLFile vl_open_from_memory(const void* data, size_t size, VLError* err);
Load and decode a REX2 file from a caller-owned memory buffer.
Identical to vl_open() except it reads from data. The library copies
whatever internal state it needs; the caller may free data immediately after
this call returns.
Parameters
Name |
Description |
|---|---|
|
Pointer to the raw |
|
Byte length of |
|
Out-parameter for the status code. May be NULL. |
Returns A valid VLFile on success, or NULL on failure.
vl_create_new
VLFile vl_create_new(int32_t channels, int32_t sample_rate,
int32_t tempo, VLError* err);
Create a new, empty file handle for assembling a REX2 loop.
Metadata (via vl_set_info(), vl_set_creator_info()) must be set before the
first vl_add_slice() call; attempts to change metadata afterwards return
VL_ERROR_ALREADY_HAS_DATA.
Parameters
Name |
Description |
|---|---|
|
1 (mono) or 2 (stereo). |
|
Output sample rate in Hz. |
|
Playback tempo in BPM × 1000. |
|
Out-parameter for the status code. May be NULL. |
Returns A valid VLFile on success, or NULL on failure.
vl_superflux_default_options
void vl_superflux_default_options(VLSuperFluxOptions* out);
Fill a caller-allocated VLSuperFluxOptions struct with the defaults used by
vl_create_from_superflux(). Passing NULL is allowed and does nothing.
vl_create_from_superflux
VLFile vl_create_from_superflux(int32_t channels,
int32_t sample_rate,
int32_t tempo,
const float* left,
const float* right,
int32_t frames,
const VLSuperFluxOptions* options,
VLError* err);
Create a new authoring handle from a complete mono or stereo loop. Stereo input
is downmixed for SuperFlux onset detection, while the original left/right
buffers are copied into the resulting slices. The returned handle can be saved
with vl_save() or vl_save_to_memory().
Parameters
Name |
Description |
|---|---|
|
1 (mono) or 2 (stereo). |
|
Input/output sample rate in Hz. |
|
Playback tempo in BPM × 1000. |
|
Left or mono buffer containing |
|
Right buffer for stereo. Must be non-NULL when |
|
Number of PCM frames in each input buffer. |
|
SuperFlux options, or NULL for defaults. |
|
Out-parameter for the status code. May be NULL. |
Returns A valid VLFile on success, or NULL on failure.
vl_close
void vl_close(VLFile file);
Release all resources associated with a VLFile handle.
Safe to call with NULL (no-op). The handle is invalid after this call.
Read: Metadata
vl_get_info
VLError vl_get_info(VLFile file, VLFileInfo* out);
Retrieve file-level metadata.
Parameters
Name |
Description |
|---|---|
|
Open |
|
Caller-allocated |
Returns VL_OK, VL_ERROR_INVALID_HANDLE, or VL_ERROR_INVALID_ARG.
vl_get_creator_info
VLError vl_get_creator_info(VLFile file, VLCreatorInfo* out);
Retrieve creator/tag metadata.
Returns VL_OK on success. VL_ERROR_NO_CREATOR_INFO if the file has no
CREI chunk.
Read: Slice Enumeration
vl_get_slice_info
VLError vl_get_slice_info(VLFile file, int32_t index, VLSliceInfo* out);
Retrieve per-slice metadata by zero-based index.
After the file has been opened or authored, this function performs no heap
allocation and writes only to the caller-supplied out struct.
Returns VL_OK on success. VL_ERROR_INVALID_SLICE if index is out of
range.
vl_set_slice_info
VLError vl_set_slice_info(VLFile file, int32_t index,
int32_t flags, int32_t analysis_points);
Update mutable slice editing state. VL_SLICE_FLAG_MUTED,
VL_SLICE_FLAG_LOCKED, and VL_SLICE_FLAG_SELECTED are serialized to SLCE;
marker and synthetic bits are derived by the reader. Pass a negative
analysis_points value to keep the current value.
Read: Sample Extraction
The realtime-safe read methods are:
vl_get_slice_infovl_get_slice_frame_countvl_decode_slice
After a VLFile has been opened or authored, these methods perform no heap
allocation. They are suitable for audio-thread use when the caller keeps output
buffers preallocated, avoids closing or mutating the same VLFile concurrently,
and performs file loading, slice creation, saving, and buffer allocation outside
the audio callback.
vl_get_slice_frame_count
int32_t vl_get_slice_frame_count(VLFile file, int32_t index);
Return the number of frames vl_decode_slice() will write for a given slice.
Includes any transient-stretch tail frames. Use this to pre-allocate the
left/right buffers. After the file has been opened or authored, this
function performs no heap allocation and only reads immutable slice metadata.
Returns Frame count (>= 1) on success, or a negative VLError cast to
int32_t on failure.
vl_decode_slice
VLError vl_decode_slice(VLFile file, int32_t index,
float* left, float* right,
int32_t frame_offset,
int32_t capacity, int32_t* frames_out);
Decode one slice into caller-supplied float PCM buffers (range [-1.0, 1.0]). After the file has been opened or authored, this function performs no heap allocation, does not resize internal storage, and writes only to caller-supplied buffers.
The rendering pipeline applies:
Processing gain from the GLOB chunk
Transient-stretch tail (reverse-playback loop with linear amplitude decay)
A two-frame read offset matching
REXRenderSlicebehaviour
For mono files the left channel is mirrored to right when right != NULL.
Parameters
Name |
Description |
|---|---|
|
Open |
|
Zero-based slice index. |
|
Output buffer for the left (or mono) channel. Must hold at least |
|
Output buffer for the right channel. May be NULL. |
|
Starting frame inside the rendered slice. Use 0 to decode from the beginning. |
|
Buffer size in frames. Must be >= |
|
If non-NULL, receives the actual frame count written on |
Returns VL_OK on success.
VL_ERROR_BUFFER_TOO_SMALL if capacity is insufficient.
VL_ERROR_INVALID_SLICE for an out-of-range index.
VL_ERROR_INVALID_ARG if left is NULL or frame_offset is outside the
rendered slice.
Write: Assembly
vl_set_info
VLError vl_set_info(VLFile file, const VLFileInfo* info);
Overwrite file-level metadata on a handle from vl_create_new().
Must be called before the first vl_add_slice(). The library ignores
slice_count, total_frames, loop_start, and loop_end (computed from
slices).
Returns VL_OK, VL_ERROR_INVALID_HANDLE, VL_ERROR_INVALID_ARG, or
VL_ERROR_ALREADY_HAS_DATA.
vl_set_creator_info
VLError vl_set_creator_info(VLFile file, const VLCreatorInfo* info);
Set creator/tag metadata. Must be called before vl_add_slice().
Returns Same as vl_set_info().
vl_add_slice
int32_t vl_add_slice(VLFile file, int32_t ppq_pos,
const float* left, const float* right,
int32_t frames);
Append a slice from caller-supplied float audio.
Slices must be added in ascending ppq_pos order. DWOP compression is
deferred until vl_save() or vl_save_to_memory().
Parameters
Name |
Description |
|---|---|
|
Handle from |
|
Slice position in PPQ ticks. |
|
Left (or mono) channel samples in [-1.0, 1.0]. |
|
Right channel samples. May be NULL for mono files. |
|
Number of frames in each buffer. |
Returns Assigned slice index (>= 0) on success, or a negative VLError.
vl_remove_slice
VLError vl_remove_slice(VLFile file, int32_t index);
Remove a slice by index. Subsequent indices are shifted down by one. Invalidates any previously cached rendered lengths.
Returns VL_OK, VL_ERROR_INVALID_HANDLE, or VL_ERROR_INVALID_SLICE.
vl_save
VLError vl_save(VLFile file, const char* path);
Encode all slices with DWOP and write the IFF/CIFF container to disk.
The handle remains open and valid after this call.
Returns VL_OK on success, or a negative VLError on failure.
vl_save_to_memory
VLError vl_save_to_memory(VLFile file, void* buf, size_t* size_out);
Encode and serialise the file to a caller-owned buffer.
Two-call pattern:
size_t sz = 0;
vl_save_to_memory(file, NULL, &sz); /* query */
uint8_t *buf = malloc(sz);
vl_save_to_memory(file, buf, &sz); /* write */
When buf is NULL, writes the required byte count to *size_out and returns
VL_OK. When buf is non-NULL, writes up to *size_out bytes and updates
*size_out with the actual count.
Returns VL_OK on success, or a negative VLError on failure.
Utility
vl_error_string
const char* vl_error_string(VLError err);
Return a static, human-readable description of an error code.
The returned pointer is valid for the lifetime of the process and must not be
freed. Unknown codes return "unknown error".
vl_version_string
const char* vl_version_string(void);
Return the library version string (e.g. "0.1.0").
The returned pointer is valid for the lifetime of the process.