2019-07-08 17:43:58 +00:00
|
|
|
const std = @import("std");
|
2019-07-09 16:21:07 +00:00
|
|
|
const lv2 = @import("lv2_helpers.zig");
|
2019-07-09 16:55:52 +00:00
|
|
|
const c = lv2.c;
|
2019-07-08 17:43:58 +00:00
|
|
|
|
2019-07-09 03:04:01 +00:00
|
|
|
const plugins = @import("plugin.zig");
|
|
|
|
|
|
|
|
pub const ImageError = error{
|
|
|
|
OpenFail,
|
|
|
|
InvalidPlugin,
|
|
|
|
UnknownPlugin,
|
2019-07-09 16:55:52 +00:00
|
|
|
InvalidSymbol,
|
2019-07-09 03:04:01 +00:00
|
|
|
};
|
2019-07-08 17:43:58 +00:00
|
|
|
|
|
|
|
/// Low level integration function with libsndfile.
|
|
|
|
fn sopen(
|
|
|
|
allocator: *std.mem.Allocator,
|
|
|
|
path: []const u8,
|
|
|
|
mode: i32,
|
|
|
|
fmt: *c.SF_INFO,
|
|
|
|
) !*c.SNDFILE {
|
|
|
|
var cstr_path = try std.cstr.addNullByte(allocator, path);
|
|
|
|
defer allocator.free(cstr_path);
|
|
|
|
|
|
|
|
var file = c.sf_open(cstr_path.ptr, mode, fmt);
|
|
|
|
const st: i32 = c.sf_error(file);
|
|
|
|
|
|
|
|
if (st != 0) {
|
|
|
|
std.debug.warn(
|
|
|
|
"Failed to open {} ({})\n",
|
|
|
|
path,
|
|
|
|
c.sf_error_number(st),
|
|
|
|
);
|
|
|
|
|
|
|
|
return ImageError.OpenFail;
|
|
|
|
}
|
|
|
|
|
|
|
|
return file.?;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub const Image = struct {
|
|
|
|
allocator: *std.mem.Allocator,
|
|
|
|
sndfile: *c.SNDFILE,
|
|
|
|
path: []const u8,
|
|
|
|
|
|
|
|
/// Open a BMP file.
|
|
|
|
pub fn open(allocator: *std.mem.Allocator, path: []const u8) !*Image {
|
|
|
|
var in_fmt = c.SF_INFO{
|
|
|
|
.frames = c_int(0),
|
|
|
|
.samplerate = c_int(44100),
|
|
|
|
.channels = c_int(1),
|
|
|
|
.format = c.SF_FORMAT_ULAW | c.SF_FORMAT_RAW | c.SF_ENDIAN_BIG,
|
|
|
|
.sections = c_int(0),
|
|
|
|
.seekable = c_int(0),
|
|
|
|
};
|
|
|
|
|
|
|
|
var sndfile = try sopen(allocator, path, c.SFM_READ, &in_fmt);
|
|
|
|
var image = try allocator.create(Image);
|
|
|
|
|
|
|
|
image.* = Image{
|
|
|
|
.allocator = allocator,
|
|
|
|
.sndfile = sndfile,
|
|
|
|
.path = path,
|
|
|
|
};
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn close(self: *Image) void {
|
|
|
|
var st: i32 = c.sf_close(self.sndfile);
|
|
|
|
|
|
|
|
if (st != 0) {
|
|
|
|
std.debug.warn(
|
|
|
|
"Failed to close {} ({})\n",
|
|
|
|
self.path,
|
|
|
|
c.sf_error_number(st),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2019-07-09 03:04:01 +00:00
|
|
|
|
|
|
|
pub fn read(self: *Image, file_chans: c_int, buf: []f32) bool {
|
|
|
|
var file = file_opt.?;
|
|
|
|
|
|
|
|
const n_read: c.sf_count_t = c.sf_readf_float(file, buf.ptr, 1);
|
|
|
|
const buf_chans = @intCast(c_int, buf.len);
|
|
|
|
|
|
|
|
var i = file_chans - 1;
|
|
|
|
while (i < buf_chans) : (i += 1) {
|
|
|
|
//buf[@intCast(usize, i)] = buf[i % file_chans];
|
|
|
|
buf[@intCast(usize, i)] = buf[@intCast(usize, @mod(i, file_chans))];
|
|
|
|
}
|
|
|
|
|
|
|
|
return n_read == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn runPlugin(
|
|
|
|
self: *Image,
|
|
|
|
plugin_uri: []const u8,
|
|
|
|
pos: plugins.Position,
|
|
|
|
params: plugins.ParamList,
|
|
|
|
) !void {
|
2019-07-09 16:55:52 +00:00
|
|
|
var ctx = try plugins.makeContext(self.allocator, plugin_uri);
|
|
|
|
std.debug.warn("\tworld: {}\n", ctx.world);
|
|
|
|
std.debug.warn("\tplugin: {}\n", ctx.plugin);
|
|
|
|
|
|
|
|
var ports = try lv2.setupPorts(&ctx);
|
|
|
|
|
|
|
|
if (ctx.n_audio_in != 1) {
|
|
|
|
std.debug.warn("plugin <{}> does not accept mono input.\n", plugin_uri);
|
|
|
|
return ImageError.InvalidPlugin;
|
|
|
|
}
|
|
|
|
|
|
|
|
// now, for each param for the plugin, we find its port, and set
|
|
|
|
// the value for the port there.
|
|
|
|
var it = params.iterator();
|
2019-07-09 16:21:07 +00:00
|
|
|
|
2019-07-09 16:55:52 +00:00
|
|
|
while (it.next()) |param| {
|
|
|
|
var sym_cstr = try std.cstr.addNullByte(self.allocator, param.sym);
|
|
|
|
defer self.allocator.free(sym_cstr);
|
|
|
|
|
|
|
|
var sym = c.lilv_new_string(ctx.world, sym_cstr.ptr);
|
|
|
|
const port = c.lilv_plugin_get_port_by_symbol(ctx.plugin, sym) orelse blk: {
|
|
|
|
std.debug.warn("assert fail: symbol not found on port");
|
|
|
|
return ImageError.InvalidSymbol;
|
|
|
|
};
|
|
|
|
|
|
|
|
c.lilv_node_free(sym);
|
|
|
|
|
|
|
|
var idx = c.lilv_port_get_index(ctx.plugin, port);
|
|
|
|
std.debug.warn(
|
|
|
|
"sym={}, idx={} to val={}\n",
|
|
|
|
param.sym,
|
|
|
|
idx,
|
|
|
|
param.value,
|
|
|
|
);
|
|
|
|
ports[idx].value = param.value;
|
2019-07-09 16:21:07 +00:00
|
|
|
}
|
2019-07-09 03:04:01 +00:00
|
|
|
}
|
2019-07-08 17:43:58 +00:00
|
|
|
};
|