|
1 |
| -Experimental C binding for LabSound. |
| 1 | +# LabSound C bindings |
2 | 2 |
|
3 |
| -requires the ls2 branch of LabSound |
| 3 | +These bindings are compatible with top of tree LabSound. They will also work with upcoming release 1.3.0. |
4 | 4 |
|
5 |
| -copyright (c) 2022 Nick Porcino |
| 5 | +copyright (c) 2022- Nick Porcino |
6 | 6 | MIT License
|
7 | 7 |
|
| 8 | +## Getting Started |
| 9 | + |
| 10 | +To build the demo, install LabSound. Installing LabSound will also install libnyquist. Use cmake to configure this project, with a CMAKE_SYSTEM_PREFIX set to the install prefix used for LabSound. |
| 11 | + |
| 12 | +To use the bindings in your own project, include labsound-c.cpp into your project directly, and also link to libnyquist and LabSound. |
| 13 | + |
| 14 | +## Interface |
| 15 | + |
| 16 | +Strings are supplied to labsound-c via string slices. These are compatible with all languages you are likely to bind LabSound to, as there is no requirement that the string be zero terminated. |
| 17 | + |
| 18 | +Although labsound-c.cpp is implemented in C++, the interface in labsound-c.h exposes symbols for C. |
| 19 | + |
| 20 | +```c |
| 21 | +typedef struct { |
| 22 | + const char* start; |
| 23 | + const char* end; |
| 24 | +} ls_StringSlice; |
| 25 | +``` |
| 26 | + |
| 27 | +There's an array of string slices ~ |
| 28 | + |
| 29 | +```c |
| 30 | +typedef struct { |
| 31 | + ls_StringSlice* names; |
| 32 | + int count; |
| 33 | +} ls_NameArray; |
| 34 | +``` |
| 35 | + |
| 36 | +For C users, there is a convenience function ~ |
| 37 | +```c |
| 38 | +#define ls_cstr(s) ls_StringSlice { (s), strlen(s) } |
| 39 | +``` |
| 40 | +
|
| 41 | +Time is passed in a simple struct ~ |
| 42 | +
|
| 43 | +```c |
| 44 | +typedef struct { |
| 45 | + float t; |
| 46 | +} ls_Seconds; |
| 47 | +``` |
| 48 | + |
| 49 | +There are a variety of opaque lsc objects that the labsound-c interfaces will consume. |
| 50 | + |
| 51 | +```c |
| 52 | +struct ls_Pin, ls_Node, ls_Connection, ls_BusData; |
| 53 | +``` |
| 54 | + |
| 55 | +There are a few enumerations ~ |
| 56 | + |
| 57 | +```c |
| 58 | +typedef enum { |
| 59 | + ls_PinInvalid = 0, |
| 60 | + ls_PinInput, ls_PinOutput, ls_PinParam, ls_PinSetting |
| 61 | +} ls_PinKind; |
| 62 | + |
| 63 | +typedef enum { |
| 64 | + ls_Invalid = 0, |
| 65 | + ls_String, ls_Path, ls_Bool, ls_Int, ls_Float, ls_Bus, ls_Enum |
| 66 | +} ls_PinDataType; |
| 67 | +``` |
| 68 | + |
| 69 | +There are some housekeeping routines. You'll need to create and release the LabSoundAPI_1_0 interface object, and once per frame call `ls_idle` to give the engine a chance to do various tasks. |
| 70 | + |
| 71 | +```c |
| 72 | + |
| 73 | +typedef struct { |
| 74 | + void* (*malloc)(size_t); |
| 75 | + void (*free)(void*); |
| 76 | +} ls_Alloc; |
| 77 | +const ls_Alloc ls_default_alloc = { malloc, free }; |
| 78 | + |
| 79 | +struct LabSoundAPI_1_0* ls_create_api_1_0(ls_Alloc); |
| 80 | +void ls_release_api_1_0(struct LabSoundAPI_1_0*); |
| 81 | +void ls_idle(struct LabSoundAPI_1_0*); |
| 82 | +``` |
| 83 | +
|
| 84 | +The interface differs from the C++ interface. The C++ interface is an object oriented API meant to mimic the WebAudio specification's interfaces as closely as possible. The C interfaces however, are opaque, and not object oriented. |
| 85 | +
|
| 86 | +Inputs and outputs from a node are accessed from pins, as are the node's properties. |
| 87 | +
|
| 88 | +Instead, they are built around generic interfaces that rely on LabSounds additional C++ interfaces for querying capabilities and attributes. |
| 89 | +
|
| 90 | +Please refer to the demo for usage examples. |
| 91 | +
|
| 92 | +```c |
| 93 | + // scheduling nodes |
| 94 | + ls_Seconds (*node_get_timing)(struct LabSoundAPI_1_0*, ls_Node); |
| 95 | + ls_Seconds (*node_get_self_timing)(struct LabSoundAPI_1_0*, ls_Node); |
| 96 | + void (*node_start)(struct LabSoundAPI_1_0*, ls_Node, ls_Seconds); |
| 97 | + void (*node_schedule)(struct LabSoundAPI_1_0*, ls_Node, ls_Seconds, int32_t); |
| 98 | + void (*node_stop)(struct LabSoundAPI_1_0*, ls_Node, ls_Seconds); |
| 99 | +
|
| 100 | + // managing nodes |
| 101 | + const ls_NameArray* (*node_names)(struct LabSoundAPI_1_0*); |
| 102 | + ls_Node (*node_create)(struct LabSoundAPI_1_0*, ls_StringSlice name, ls_StringSlice type); |
| 103 | + void (*node_delete)(struct LabSoundAPI_1_0*, ls_Node); |
| 104 | + void (*create_node_output)(struct LabSoundAPI_1_0*, ls_Node, ls_StringSlice name, int channels); |
| 105 | + void (*node_set_on_ended)(struct LabSoundAPI_1_0*, ls_Node, void(*)()); |
| 106 | +
|
| 107 | + // getting pins from nodes |
| 108 | + ls_Pin (*node_named_input)(struct LabSoundAPI_1_0*, ls_Node, ls_StringSlice); |
| 109 | + ls_Pin (*node_indexed_input)(struct LabSoundAPI_1_0*, ls_Node, int); |
| 110 | + ls_Pin (*node_named_output)(struct LabSoundAPI_1_0*, ls_Node, ls_StringSlice); |
| 111 | + ls_Pin (*node_indexed_output)(struct LabSoundAPI_1_0*, ls_Node, int); |
| 112 | + ls_Pin (*node_parameter)(struct LabSoundAPI_1_0*, ls_Node, ls_StringSlice); |
| 113 | + ls_Pin (*node_setting)(struct LabSoundAPI_1_0*, ls_Node, ls_StringSlice); |
| 114 | +
|
| 115 | + // information about pins |
| 116 | + ls_PinKind (*pin_kind)(struct LabSoundAPI_1_0*, ls_Pin); |
| 117 | + ls_PinDataType (*pin_data_type)(struct LabSoundAPI_1_0*, ls_Pin); |
| 118 | +
|
| 119 | + // setting and getting pin values |
| 120 | + // note - these interfaces are going to be prefixed with pin_ |
| 121 | + void (*set_float)(struct LabSoundAPI_1_0*, ls_Pin, float); |
| 122 | + void (*set_enum)(struct LabSoundAPI_1_0*, ls_Pin, uint32_t); |
| 123 | + void (*set_int)(struct LabSoundAPI_1_0*, ls_Pin, uint32_t); |
| 124 | + void (*set_bool)(struct LabSoundAPI_1_0*, ls_Pin, bool); |
| 125 | + void (*set_bus)(struct LabSoundAPI_1_0*, ls_Pin, ls_BusData); |
| 126 | + void (*set_bus_from_file)(struct LabSoundAPI_1_0*, ls_Pin, ls_StringSlice path); |
| 127 | + void (*set_named_enum)(struct LabSoundAPI_1_0*, ls_Pin, ls_StringSlice enum_name); |
| 128 | +
|
| 129 | + // managing busses |
| 130 | + ls_BusData (*bus_create_from_file)(struct LabSoundAPI_1_0*, const char* path, bool mix_to_mono); |
| 131 | +
|
| 132 | + // graph management |
| 133 | + // note - device_node is going to be renamed destination_node |
| 134 | + ls_Node(*device_node)(struct LabSoundAPI_1_0*); |
| 135 | + ls_Connection (*connect_output_to_input)(struct LabSoundAPI_1_0*, ls_Pin input, ls_Pin output); |
| 136 | +
|
| 137 | + // after disconnection, ls_Connection will no longer be valid |
| 138 | + void (*disconnect)(struct LabSoundAPI_1_0*, ls_Connection); |
| 139 | +``` |
0 commit comments