Zrythm
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
Cyaml Schemas

Introduction

Zrythm uses libcyaml to save projects into YAML. Cyaml can serialize C structs, given that you provide it with the schemas of each struct. This page has some tips on writing schemas.

Note
Some examples are no longer in the code base and are used only for demonstration purposes

Fields

For all fields, use the

CYAML_FLAG_OPTIONAL

flag to indicate that a variable can be NULL.

Ints

Use

CYAML_FIELD_INT

with the

CYAML_FLAG_DEFAULT

flag.

Example, having an 'enabled' flag inside a Plugin:

CYAML_FIELD_INT (
"enabled", CYAML_FLAG_DEFAULT,
Plugin, enabled),
The base plugin Inheriting plugins must have this as a child.
Definition plugin.h:74

Enums

Use

CYAML_FIELD_ENUM

with the

CYAML_FLAG_DEFAULT

flag.

Example, RegionType inside a Region:

CYAML_FIELD_ENUM (
"type", CYAML_FLAG_DEFAULT,
Region, type, region_type_strings,
CYAML_ARRAY_LEN (region_type_strings)),
A region (clip) is an object on the timeline that contains either MidiNote's or AudioClip's.
Definition region.h:72

Enums also need a cyaml_strval_t argument:

static const cyaml_strval_t
region_type_strings[] =
{
{ "Midi", REGION_TYPE_MIDI },
{ "Audio", REGION_TYPE_AUDIO },
};

String Pointers (char *)

Use

CYAML_FIELD_STRING_PTR

with the

CYAML_FLAG_POINTER

flag.

Example, Region name:

CYAML_FIELD_STRING_PTR (
"name", CYAML_FLAG_POINTER,
Region, name,
0, CYAML_UNLIMITED),

Direct struct (not pointer) inside

another struct

Use

CYAML_FIELD_MAPPING

with the

CYAML_FLAG_DEFAULT

flag.

Example, having a plain Position inside a MidiNote:

CYAML_FIELD_MAPPING (
"start_pos",
CYAML_FLAG_DEFAULT,
MidiNote, start_pos, position_fields_schema)
A MIDI note inside a Region shown in the piano roll.
Definition midi_note.h:49

Pointer to Struct

Use

CYAML_FIELD_MAPPING_PTR

with the

CYAML_FLAG_POINTER

flag.

Example, having a pointer to an Lv2Plugin inside a Plugin:

CYAML_FIELD_MAPPING_PTR (
"lv2", CYAML_FLAG_POINTER,
Plugin, lv2,
lv2_plugin_fields_schema),

Array of primitives

For fixed-size arrays without a counter,

CYAML_FIELD_SEQUENCE_FIXED (
"midi_channels", CYAML_FLAG_DEFAULT,
Channel, midi_channels,
&int_schema, 16),
A Channel is part of a Track (excluding Tracks that don't have Channels) and contains information rel...
Definition channel.h:57

Arrays of Pointers (variable

count)

There are two cases. Fixed-width arrays, like below. In this case, use the

CYAML_FLAG_DEFAULT

flag.

MyStruct * my_structs[MAX_STRUCTS];
int num_my_structs;

The other case is dynamic arrays, like below. In this case use

@CYAML_FLAG_POINTER

.

int num_ats;
int ats_size;

Use

CYAML_FIELD_SEQUENCE_COUNT

with the

CYAML_FLAG_DEFAULT

or

CYAML_FLAG_POINTER

flag as described above.

Use

CYAML_FLAG_POINTER

when declaring the schema of the child struct.

Example, fixed-size array of MidiNote pointers inside a Region:

CYAML_FIELD_SEQUENCE_COUNT (
"midi_notes", CYAML_FLAG_DEFAULT,
Region, midi_notes, num_midi_notes,
&midi_note_schema, 0, CYAML_UNLIMITED),

Example, dynamic array of AutomationTrack pointers in AutomationTracklist:

CYAML_FIELD_SEQUENCE_COUNT (
"ats", CYAML_FLAG_POINTER,
AutomationTracklist, ats, num_ats,
&automation_track_schema, 0, CYAML_UNLIMITED),
Each track has an automation tracklist with automation tracks to be generated at runtime,...

Arrays of Pointers (fixed count)

MyStruct * my_structs[9];

Use

CYAML_FIELD_SEQUENCE_FIXED

with the

CYAML_FLAG_DEFAULT

flag.

Example:

CYAML_FIELD_SEQUENCE_FIXED (
"plugins", CYAML_FLAG_DEFAULT,
Channel, plugins,
&plugin_schema, STRIP_SIZE),
#define STRIP_SIZE
Number of plugin slots per channel.
Definition audio.h:75

Arrays of Structs (variable

count)

MyStruct my_structs[MAX_MY_STRUCTS];
int num_my_structs;

Use

CYAML_FIELD_SEQUENCE_COUNT

with the

CYAML_FLAG_DEFAULT

flag.

Use

CYAML_FLAG_DEFAULT

when declaring the schema of the child struct.

Example, destination PortIdentifier's of a Port:

static const cyaml_schema_value_t
port_identifier_schema_default = {
CYAML_VALUE_MAPPING (
CYAML_FLAG_DEFAULT, // note the flag
port_identifier_fields_schema),
};
CYAML_FIELD_SEQUENCE_COUNT (
"dest_ids", CYAML_FLAG_DEFAULT,
Port, dest_ids, num_dests,
&port_identifier_schema_default,
0, CYAML_UNLIMITED),
Struct used to identify Ports in the project.
Must ONLY be created via port_new()
Definition port.h:136

Bitfields

typedef enum PortFlags
{
PORT_FLAG_STEREO_L = 0x01,
PORT_FLAG_STEREO_R = 0x02,
PORT_FLAG_PIANO_ROLL = 0x04,
PORT_FLAG_SIDECHAIN = 0x08,
PORT_FLAG_MAIN_PORT = 0x10,
OPT_F = 0x20,
} PortFlags;

First, declare the bitfield definitions.

static const cyaml_bitdef_t
flags_bitvals[] =
{
{ .name = "stereo_l", .offset = 0, .bits = 1 },
{ .name = "stereo_r", .offset = 1, .bits = 1 },
{ .name = "piano_roll", .offset = 2, .bits = 1 },
{ .name = "sidechain", .offset = 3, .bits = 1 },
{ .name = "main_port", .offset = 4, .bits = 1 },
{ .name = "opt_f", .offset = 5, .bits = 1 },
};

Use

CYAML_FIELD_BITFIELD

with the

CYAML_FLAG_DEFAULT

flag.

Example, PortFlags:

CYAML_FIELD_BITFIELD (
"flags", CYAML_FLAG_DEFAULT,
PortIdentifier, flags, flags_bitvals,
CYAML_ARRAY_LEN (flags_bitvals)),

Schema Values

Schemas will normally be

CYAML_VALUE_MAPPING

with a

CYAML_FLAG_POINTER

flag. Use the

CYAML_FLAG_DEFAULT

if the struct will be used directly in another struct (not as a pointer).