split in_buf/out_buf into RunBuffers struct

- add basics of RandomNoise custom plugin
This commit is contained in:
Luna 2019-07-13 17:42:46 -03:00
parent aedf47dbe1
commit 16116371f5
5 changed files with 87 additions and 8 deletions

24
src/custom.zig Normal file
View file

@ -0,0 +1,24 @@
// Custom plugins
const std = @import("std");
const lv2 = @import("lv2_helpers.zig");
const plugins = @import("plugin.zig");
const c = lv2.c;
const RunContext = plugins.RunContext;
pub const RandomNoise = struct {
allocator: *std.mem.Allocator,
pub fn init(
allocator: *std.mem.Allocator,
) RandomNoise {
return RandomNoise{
.allocator = allocator,
};
}
pub fn run(self: *RandomNoise, rctx: *RunContext) void {
rctx.in_buf[0] = f32(2);
}
};

View file

@ -292,15 +292,18 @@ pub const Image = struct {
var i: usize = seek_pos.start;
std.debug.warn("\tseek pos start: {} end: {}\n", seek_pos.start, seek_pos.end);
var inbuf = rctx.buffers.in;
var outbuf = rctx.buffers.out;
while (i <= seek_pos.end) : (i += 1) {
const read_bytes = c.sf_readf_float(self.sndfile, rctx.in_buf.ptr, 1);
const read_bytes = c.sf_readf_float(self.sndfile, inbuf.ptr, 1);
if (read_bytes == 0) {
std.debug.warn("WARN! reached EOF at idx={}\n", i);
break;
}
lv2.lilv_instance_run(rctx.instance, 1);
try swrite(out_file, rctx.out_buf.ptr, 1);
try swrite(out_file, outbuf.ptr, 1);
}
_ = c.sf_seek(self.sndfile, @intCast(i64, seek_pos.end), c.SEEK_SET);
@ -326,4 +329,12 @@ pub const Image = struct {
std.debug.warn("saved to '{}'\n", out_path);
try std.fs.copyFile(self.curpath, out_path);
}
pub fn runCustomPlugin(
self: *Image,
comptime Plugin: type,
pos: plugins.Position,
) void {
var plugin = Plugin.init(self.allocator);
}
};

View file

@ -26,6 +26,7 @@ pub const CommandType = enum {
Delay,
Vinyl,
RevDelay,
Noise,
};
pub const Command = struct {
@ -143,6 +144,9 @@ pub const Lang = struct {
_ = try self.keywords.put("delay", .Delay);
_ = try self.keywords.put("vinyl", .Vinyl);
_ = try self.keywords.put("revdelay", .RevDelay);
// custom implementations (not lv2)
_ = try self.keywords.put("noise", .Noise);
}
pub fn parse(self: *Lang, data: []const u8) !CommandList {

View file

@ -57,10 +57,36 @@ pub const Context = struct {
}
};
/// Specific run context for non-plugins.
pub const RunBuffers = struct {
allocator: *std.mem.Allocator,
in: []f32,
out: []f32,
pub fn init(allocator: *std.mem.Allocator) !RunBuffers {
// we allocate []f32 with size 2 to account for stereo plugins, however
// we only use &in_buf[0] and &out_buf[0], and don't use the
// (supposedly) right side of neither input or output.
var in_buf = try allocator.alloc(f32, 2);
std.mem.secureZero(f32, in_buf);
return RunBuffers{
.allocator = allocator,
.in = in_buf,
.out = try allocator.alloc(f32, 2),
};
}
pub fn deinit(self: *RunBuffers) void {
self.allocator.free(self.in);
self.allocator.free(self.out);
}
};
/// Represents the specific run context of plugin instantation.
pub const RunContext = struct {
in_buf: []f32,
out_buf: []f32,
buffers: RunBuffers,
instance: *c.LilvInstance,
pub fn init(
@ -79,20 +105,23 @@ pub const RunContext = struct {
std.mem.secureZero(f32, in_buf);
return RunContext{
.in_buf = in_buf,
.out_buf = try allocator.alloc(f32, 2),
.buffers = try RunBuffers.init(allocator),
.instance = instance.?,
};
}
pub fn deinit(self: *RunContext) void {
c.lilv_instance_free(self.instance);
self.buffers.deinit();
}
pub fn connectPorts(self: *RunContext, ports: []*lv2.Port) void {
var i: usize = 0;
var o: usize = 0;
var in_buf = self.buffers.in;
var out_buf = self.buffers.out;
for (ports) |port, p_idx| {
var p = @intCast(u32, p_idx);
@ -100,10 +129,10 @@ pub const RunContext = struct {
.Control => lv2.lilv_instance_connect_port(self.instance, p, &port.value),
.Audio => blk: {
if (port.is_input) {
lv2.lilv_instance_connect_port(self.instance, p, &self.in_buf[i]);
lv2.lilv_instance_connect_port(self.instance, p, &in_buf[i]);
i += 1;
} else {
lv2.lilv_instance_connect_port(self.instance, p, &self.out_buf[o]);
lv2.lilv_instance_connect_port(self.instance, p, &out_buf[o]);
o += 1;
}
},

View file

@ -2,6 +2,7 @@ const std = @import("std");
const lang = @import("lang.zig");
const images = @import("image.zig");
const plugin = @import("plugin.zig");
const custom = @import("custom.zig");
const Position = plugin.Position;
const ParamList = plugin.ParamList;
@ -245,6 +246,11 @@ pub const Runner = struct {
try image.runPlugin("http://plugin.org.uk/swh-plugins/revdelay", pos, params);
}
fn noiseCmd(self: *Runner, pos: Position, params: ParamList) !void {
var image = try self.getImage();
image.runCustomPlugin(custom.RandomNoise, pos);
}
fn runCommand(self: *Runner, cmd: *lang.Command) !void {
var params = ParamList.init(self.allocator);
defer params.deinit();
@ -384,6 +390,11 @@ pub const Runner = struct {
try self.revDelayCmd(pos, params);
},
.Noise => blk: {
const pos = try cmd.consumePosition();
try self.noiseCmd(pos, params);
},
else => blk: {
std.debug.warn("Unsupported command: {}\n", cmd.command);
break :blk RunError.UnknownCommand;