add port setup code
This commit is contained in:
parent
8e453298bc
commit
bbf34f1133
3 changed files with 128 additions and 8 deletions
|
@ -1,4 +1,6 @@
|
|||
const std = @import("std");
|
||||
const lv2 = @import("lv2_helpers.zig");
|
||||
|
||||
const c = @cImport({
|
||||
@cInclude("sndfile.h");
|
||||
|
||||
|
@ -101,8 +103,13 @@ pub const Image = struct {
|
|||
pos: plugins.Position,
|
||||
params: plugins.ParamList,
|
||||
) !void {
|
||||
const context = try plugins.makeContext(self.allocator, plugin_uri);
|
||||
var context = try plugins.makeContext(self.allocator, plugin_uri);
|
||||
std.debug.warn("world: {}\n", context.world);
|
||||
std.debug.warn("plugin: {}\n", context.plugin);
|
||||
|
||||
var ports = try lv2.setupPorts(&context);
|
||||
for (ports) |port| {
|
||||
std.debug.warn("port: {}\n", port.*);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
const c = @cImport({
|
||||
const std = @import("std");
|
||||
const plugin = @import("plugin.zig");
|
||||
|
||||
pub const c = @cImport({
|
||||
@cInclude("lilv/lilv.h");
|
||||
@cInclude("lv2/core/lv2.h");
|
||||
});
|
||||
|
@ -37,3 +40,111 @@ pub fn lilv_instance_deactivate(instance: [*c]c.LilvInstance) void {
|
|||
instance.?.*.lv2_descriptor.?.*.deactivate.?(instance.?.*.lv2_handle);
|
||||
}
|
||||
}
|
||||
|
||||
pub const PortType = enum {
|
||||
Control,
|
||||
Audio,
|
||||
};
|
||||
|
||||
pub const Port = struct {
|
||||
lilv_port: ?*const c.LilvPort,
|
||||
ptype: PortType,
|
||||
index: u32,
|
||||
value: f32,
|
||||
is_input: bool,
|
||||
optional: bool,
|
||||
};
|
||||
|
||||
/// Setup ports for a given plugin. Gives an array to pointers of Port structs.
|
||||
/// This setup is required so we link the plugin to the ports later on, and
|
||||
/// also link our buffers, and control values.
|
||||
pub fn setupPorts(ctx: *plugin.Context) ![]*Port {
|
||||
var world = ctx.world;
|
||||
const n_ports: u32 = c.lilv_plugin_get_num_ports(ctx.plugin);
|
||||
|
||||
var ports = try ctx.allocator.alloc(*Port, n_ports);
|
||||
|
||||
for (ports) |port_ptr, idx| {
|
||||
var port = try ctx.allocator.create(Port);
|
||||
port.* = Port{
|
||||
.lilv_port = null,
|
||||
.ptype = .Control,
|
||||
.index = f32(0),
|
||||
.value = f32(0),
|
||||
.is_input = false,
|
||||
.optional = false,
|
||||
};
|
||||
|
||||
ports[idx] = port;
|
||||
}
|
||||
|
||||
var values: []f32 = try ctx.allocator.alloc(f32, n_ports);
|
||||
defer ctx.allocator.free(values);
|
||||
|
||||
c.lilv_plugin_get_port_ranges_float(ctx.plugin, null, null, values.ptr);
|
||||
|
||||
// bad solution, but it really do be like that
|
||||
const LV2_CORE__InputPort = try Lv2Core("#InputPort");
|
||||
const LV2_CORE__OutputPort = try Lv2Core("#OutputPort");
|
||||
const LV2_CORE__AudioPort = try Lv2Core("#AudioPort");
|
||||
const LV2_CORE__ControlPort = try Lv2Core("#ControlPort");
|
||||
const LV2_CORE__connectionOptional = try Lv2Core("#connectionOptional");
|
||||
|
||||
var lv2_InputPort = c.lilv_new_uri(world, LV2_CORE__InputPort.ptr);
|
||||
defer std.heap.c_allocator.destroy(lv2_InputPort);
|
||||
|
||||
var lv2_OutputPort = c.lilv_new_uri(world, LV2_CORE__OutputPort.ptr);
|
||||
defer std.heap.c_allocator.destroy(lv2_OutputPort);
|
||||
|
||||
var lv2_AudioPort = c.lilv_new_uri(world, LV2_CORE__AudioPort.ptr);
|
||||
defer std.heap.c_allocator.destroy(lv2_AudioPort);
|
||||
|
||||
var lv2_ControlPort = c.lilv_new_uri(world, LV2_CORE__ControlPort.ptr);
|
||||
defer std.heap.c_allocator.destroy(lv2_ControlPort);
|
||||
|
||||
var lv2_connectionOptional = c.lilv_new_uri(world, LV2_CORE__connectionOptional.ptr);
|
||||
defer std.heap.c_allocator.destroy(lv2_connectionOptional);
|
||||
|
||||
var i: u32 = 0;
|
||||
while (i < n_ports) : (i += 1) {
|
||||
var port: *Port = ports[i];
|
||||
|
||||
const lport = c.lilv_plugin_get_port_by_index(ctx.plugin, i).?;
|
||||
|
||||
port.lilv_port = lport;
|
||||
port.index = i;
|
||||
|
||||
if (std.math.isNan(values[i])) {
|
||||
port.value = f32(0);
|
||||
} else {
|
||||
port.value = values[i];
|
||||
}
|
||||
|
||||
port.optional = c.lilv_port_has_property(ctx.plugin, lport, lv2_connectionOptional);
|
||||
|
||||
if (c.lilv_port_is_a(ctx.plugin, lport, lv2_InputPort)) {
|
||||
port.is_input = true;
|
||||
} else if (!c.lilv_port_is_a(ctx.plugin, lport, lv2_OutputPort) and !port.optional) {
|
||||
std.debug.warn("Port {} is neither input or output\n", i);
|
||||
return error.UnassignedIOPort;
|
||||
}
|
||||
|
||||
// check if port is an audio or control port
|
||||
if (c.lilv_port_is_a(ctx.plugin, lport, lv2_ControlPort)) {
|
||||
port.ptype = .Control;
|
||||
} else if (c.lilv_port_is_a(ctx.plugin, lport, lv2_AudioPort)) {
|
||||
port.ptype = .Audio;
|
||||
|
||||
if (port.is_input) {
|
||||
ctx.n_audio_in += 1;
|
||||
} else {
|
||||
ctx.n_audio_out += 1;
|
||||
}
|
||||
} else if (!port.optional) {
|
||||
std.debug.warn("Port {} has unsupported type\n", i);
|
||||
return error.UnsupportedPortType;
|
||||
}
|
||||
}
|
||||
|
||||
return ports;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
const std = @import("std");
|
||||
|
||||
const c = @cImport({
|
||||
@cInclude("lilv/lilv.h");
|
||||
@cInclude("lv2/core/lv2.h");
|
||||
});
|
||||
const c = @import("lv2_helpers.zig").c;
|
||||
|
||||
const ImageError = @import("image.zig").ImageError;
|
||||
|
||||
|
@ -27,8 +24,13 @@ pub const Position = struct {
|
|||
|
||||
/// Represents the starting context for a single plugin run.
|
||||
pub const Context = struct {
|
||||
allocator: *std.mem.Allocator,
|
||||
world: *c.LilvWorld,
|
||||
plugin: *const c.LilvPlugin,
|
||||
plugin: ?*const c.LilvPlugin,
|
||||
|
||||
// they should both be 1.
|
||||
n_audio_in: usize = 0,
|
||||
n_audio_out: usize = 0,
|
||||
};
|
||||
|
||||
pub fn makeContext(allocator: *std.mem.Allocator, plugin_uri: []const u8) !Context {
|
||||
|
@ -50,5 +52,5 @@ pub fn makeContext(allocator: *std.mem.Allocator, plugin_uri: []const u8) !Conte
|
|||
|
||||
c.lilv_node_free(uri);
|
||||
|
||||
return Context{ .world = world, .plugin = plugin };
|
||||
return Context{ .allocator = allocator, .world = world, .plugin = plugin };
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue