Native plugin interface (vive_plugin.h)
Native plugin interface for the ViveSound engine.
To write a native plugin, include this header and implement the four exported functions declared below: vive_plugin_new, vive_plugin_process_frame, vive_plugin_process_message, and vive_plugin_delete. No linking against the engine is required.
Inside these functions the plugin can also call back into the engine through the callbacks provided by the vive_context that is passed to the plugin on creation.
Index
- define VIVE_EXPORT
- struct vive_encoding
- struct vive_frame
- enum vive_message_type
- struct vive_message
- struct vive_context
- typedef vive_plugin
- vive_plugin_new()
- vive_plugin_process_frame()
- vive_plugin_process_message()
- vive_plugin_delete()
define VIVE_EXPORT
#define VIVE_EXPORTMarks a function as exported from the plugin shared library.
Expands to the compiler-specific attribute that makes the symbol visible so the engine can resolve it after loading the library.
struct vive_encoding
typedef struct vive_encoding
{
unsigned int sample_rate;
unsigned int channel_count;
} vive_encoding;Audio encoding.
Defines the format in which audio samples are passed to or from the plugin.
Fields:
-
sample_rate— Number of samples per channel per second, in hertz. -
channel_count— Number of audio channels.
struct vive_frame
typedef struct vive_frame
{
float* samples;
unsigned int n_samples_per_channel;
unsigned int channel_count;
} vive_frame;Batch of audio samples to be processed by the plugin.
Samples are interleaved: the array holds n_samples_per_channel groups, each with one sample per channel, so samples has n_samples_per_channel times channel_count float values.
The frame is owned by the engine. The plugin reads and updates it in place and must not retain the pointer, which is valid only during the call.
Fields:
-
samples— Interleaved audio samples, owned by the engine. -
n_samples_per_channel— Number of samples per channel in this frame. -
channel_count— Number of audio channels in this frame.
enum vive_message_type
typedef enum vive_message_type
{
VIVE_MESSAGE_EMPTY = 0,
VIVE_MESSAGE_PROTOBUF = 1
} vive_message_type;Type of a message payload.
Defines how the out-of-band message passed to or from the plugin is encoded.
Values:
VIVE_MESSAGE_EMPTY— The message has zero length and carries no payload.VIVE_MESSAGE_PROTOBUF— The bytes are a completegoogle.protobuf.Anyin protobuf binary wire format, including both its type URL and its value, not just the inner value. TheAnywraps an arbitrary plugin-specific message: the type URL identifies the message type and the value holds its serialized bytes. The plugin and the application agree out of band on the inner message types.
struct vive_message
typedef struct vive_message
{
vive_message_type type;
const void* bytes;
size_t n_bytes;
} vive_message;Out-of-band control message sent to or from the plugin.
The pointer is valid only until control returns, so the callee must copy the message to keep it: the plugin copies messages passed to it, and the engine copies messages the plugin sends.
Fields:
-
type— How the payload inbytesis encoded. -
bytes— Pointer to the message payload, owned by the caller. -
n_bytes— Size of the payload in bytes.
struct vive_context
typedef struct vive_context
{
vive_encoding (*get_encoding)(vive_context* context);
void (*negotiate_encoding)(vive_context* context, vive_encoding* encoding);
vive_message (*get_custom_config)(vive_context* context);
void (*send_message)(vive_context* context, vive_message* message);
} vive_context;Fields:
-
get_encodingvive_encoding (*get_encoding)(vive_context* context)Returns the audio encoding the plugin should use.
- Parameters:
context— The context of the calling plugin instance.
- Returns:
- The current audio encoding.
- Parameters:
-
negotiate_encodingvoid (*negotiate_encoding)(vive_context* context, vive_encoding* encoding)Negotiates the audio encoding during plugin creation.
- Parameters:
context— The context of the calling plugin instance.encoding— In/out; the requested encoding, updated in place with the resulting values. Owned by the caller.
- Parameters:
-
get_custom_configvive_message (*get_custom_config)(vive_context* context)Returns the custom configuration passed during plugin creation.
- Parameters:
context— The context of the calling plugin instance.
- Returns:
- The custom configuration message.
- Parameters:
-
send_messagevoid (*send_message)(vive_context* context, vive_message* message)Sends an out-of-band message from the plugin to the engine.
- Parameters:
message— The message to send. Owned by the caller.context— The context of the calling plugin instance.
- Parameters:
typedef vive_plugin
typedef void* vive_plugin;Opaque handle to a plugin instance.
Defined by the plugin developer and may be any structure. vive_plugin_new returns a pointer to it that the engine passes back to the other exported functions without ever dereferencing it.
vive_plugin_new()
VIVE_EXPORT vive_plugin* vive_plugin_new(vive_context* context);Creates a plugin instance.
User-defined function. The engine calls it to create a new plugin instance, as the first call in the instance lifetime. From within it the plugin may call vive_context::negotiate_encoding to negotiate the audio encoding, vive_context::get_encoding to read it, and vive_context::get_custom_config to read the custom configuration.
Calls to it are serialized: two instances are never constructed concurrently (but typically are used and destroyed concurrently).
The returned pointer is later passed by the engine to vive_plugin_process_frame, vive_plugin_process_message, and vive_plugin_delete.
Parameters:
context— The context for the new instance. Owned by the engine and valid until vive_plugin_delete returns; the plugin may store it.
Returns:
- An opaque pointer to the new plugin instance, or a null pointer on failure.
vive_plugin_process_frame()
VIVE_EXPORT void vive_plugin_process_frame(vive_plugin* plugin, vive_frame* frame);Processes an audio frame.
User-defined function. The engine calls it to run the plugin over a batch of audio samples, which the plugin reads and updates in place.
It runs on the audio processing thread, serialized with the other methods of the same instance, and must be fast and non-blocking.
Parameters:
plugin— The plugin instance returned by vive_plugin_new.frame— The frame to process. Owned by the engine and valid only for the duration of the call; the plugin must not retain the pointer.
vive_plugin_process_message()
VIVE_EXPORT void vive_plugin_process_message(vive_plugin* plugin, vive_message* message);Processes an out-of-band message received from the application.
User-defined function. The engine calls it to deliver a message to the plugin.
It runs on the same single thread as the other methods of the instance and must be fast and non-blocking.
Parameters:
plugin— The plugin instance returned by vive_plugin_new.message— The message to process. Owned by the engine and valid only for the duration of the call; the plugin must copy it if it needs to keep it.
vive_plugin_delete()
VIVE_EXPORT void vive_plugin_delete(vive_plugin* plugin);Deletes a plugin instance.
User-defined function. The engine calls it as the last call in the instance lifetime, to destroy the instance and release its resources. From within it the plugin may still call context callbacks such as vive_context::send_message. After this call returns, the plugin pointer and its context must no longer be used.
It runs on the same single thread as the other methods of the instance.
Parameters:
plugin— The plugin instance returned by vive_plugin_new.