const std = @import("std"); const lv2 = @import("lv2_helpers.zig"); const c = @cImport({ @cInclude("sndfile.h"); @cInclude("lilv/lilv.h"); @cInclude("lv2/core/lv2.h"); }); const plugins = @import("plugin.zig"); pub const ImageError = error{ OpenFail, InvalidPlugin, UnknownPlugin, }; /// 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), ); } } 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 { 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.*); } } };