2019-07-13 20:42:46 +00:00
|
|
|
// Custom plugins
|
|
|
|
const std = @import("std");
|
|
|
|
const lv2 = @import("lv2_helpers.zig");
|
|
|
|
const plugins = @import("plugin.zig");
|
2019-10-22 21:16:15 +00:00
|
|
|
const image = @import("image.zig");
|
2019-07-13 20:42:46 +00:00
|
|
|
|
|
|
|
const c = lv2.c;
|
|
|
|
|
2019-07-13 20:49:09 +00:00
|
|
|
const RunBuffers = plugins.RunBuffers;
|
2019-07-13 20:42:46 +00:00
|
|
|
|
|
|
|
pub const RandomNoise = struct {
|
2019-07-13 20:49:09 +00:00
|
|
|
r: std.rand.DefaultPrng,
|
2019-08-14 12:10:09 +00:00
|
|
|
rand_buf: ?[]f32 = null,
|
|
|
|
allocator: ?*std.mem.Allocator = null,
|
2019-07-13 21:17:44 +00:00
|
|
|
cnt: usize = 0,
|
2019-07-13 20:42:46 +00:00
|
|
|
|
|
|
|
pub fn init(
|
|
|
|
allocator: *std.mem.Allocator,
|
2020-07-23 19:31:32 +00:00
|
|
|
params: anytype,
|
2019-07-29 14:51:40 +00:00
|
|
|
) ?RandomNoise {
|
2020-06-01 01:27:11 +00:00
|
|
|
var r = std.rand.DefaultPrng.init(params.seed);
|
2019-07-13 20:49:09 +00:00
|
|
|
|
2020-06-01 01:27:11 +00:00
|
|
|
if (params.fill_bytes > 0) {
|
|
|
|
var rand_buf = allocator.alloc(f32, params.fill_bytes) catch return null;
|
2019-07-13 21:17:44 +00:00
|
|
|
|
|
|
|
for (rand_buf) |_, idx| {
|
|
|
|
rand_buf[idx] = r.random.float(f32);
|
|
|
|
}
|
|
|
|
|
|
|
|
return RandomNoise{
|
|
|
|
.r = r,
|
2019-08-14 12:10:09 +00:00
|
|
|
.allocator = allocator,
|
2019-07-13 21:17:44 +00:00
|
|
|
.rand_buf = rand_buf,
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
return RandomNoise{
|
|
|
|
.r = r,
|
|
|
|
};
|
|
|
|
}
|
2019-07-13 20:42:46 +00:00
|
|
|
}
|
|
|
|
|
2019-08-14 12:10:09 +00:00
|
|
|
pub fn deinit(self: *RandomNoise) void {
|
|
|
|
if (self.allocator == null) return;
|
|
|
|
if (self.rand_buf == null) return;
|
|
|
|
self.allocator.?.free(self.rand_buf.?);
|
|
|
|
}
|
|
|
|
|
2019-07-13 20:49:09 +00:00
|
|
|
pub fn run(self: *RandomNoise, bufs: *RunBuffers) void {
|
2019-07-13 21:17:44 +00:00
|
|
|
if (self.rand_buf) |rand_buf| {
|
|
|
|
if (self.cnt >= rand_buf.len) self.cnt = 0;
|
|
|
|
bufs.out[0] = rand_buf[self.cnt];
|
|
|
|
self.cnt += 1;
|
|
|
|
} else {
|
|
|
|
bufs.out[0] = self.r.random.float(f32);
|
|
|
|
}
|
2019-07-13 20:42:46 +00:00
|
|
|
}
|
|
|
|
};
|
2019-07-13 22:55:57 +00:00
|
|
|
|
|
|
|
pub const WildNoise = struct {
|
|
|
|
r: std.rand.DefaultPrng,
|
2019-08-14 12:10:09 +00:00
|
|
|
rand_buf: ?[]f32 = null,
|
|
|
|
allocator: ?*std.mem.Allocator = null,
|
2019-07-13 22:55:57 +00:00
|
|
|
cnt: usize = 0,
|
|
|
|
|
|
|
|
pub fn init(
|
|
|
|
allocator: *std.mem.Allocator,
|
2020-07-23 19:31:32 +00:00
|
|
|
params: anytype,
|
2019-07-29 14:51:40 +00:00
|
|
|
) ?WildNoise {
|
2020-06-01 01:27:11 +00:00
|
|
|
var r = std.rand.DefaultPrng.init(params.seed);
|
2019-07-13 22:55:57 +00:00
|
|
|
|
2020-06-01 01:27:11 +00:00
|
|
|
if (params.fill_bytes > 0) {
|
|
|
|
var rand_buf = allocator.alloc(f32, params.fill_bytes) catch return null;
|
2019-07-13 22:55:57 +00:00
|
|
|
|
|
|
|
for (rand_buf) |_, idx| {
|
|
|
|
rand_buf[idx] = @intToFloat(f32, r.random.int(u1));
|
|
|
|
}
|
|
|
|
|
|
|
|
return WildNoise{
|
|
|
|
.r = r,
|
|
|
|
.rand_buf = rand_buf,
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
return WildNoise{
|
|
|
|
.r = r,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-14 12:13:06 +00:00
|
|
|
pub fn deinit(self: *WildNoise) void {
|
2019-08-14 12:10:09 +00:00
|
|
|
if (self.allocator == null) return;
|
|
|
|
if (self.rand_buf == null) return;
|
|
|
|
self.allocator.?.free(self.rand_buf.?);
|
|
|
|
}
|
|
|
|
|
2019-07-13 22:55:57 +00:00
|
|
|
pub fn run(self: *WildNoise, bufs: *RunBuffers) void {
|
|
|
|
if (self.rand_buf) |rand_buf| {
|
|
|
|
if (self.cnt >= rand_buf.len) self.cnt = 0;
|
|
|
|
bufs.out[0] = rand_buf[self.cnt];
|
|
|
|
self.cnt += 1;
|
|
|
|
} else {
|
|
|
|
bufs.out[0] = @intToFloat(f32, self.r.random.int(u1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2019-07-29 14:51:40 +00:00
|
|
|
|
2019-08-06 22:25:31 +00:00
|
|
|
/// Write any float to the image.
|
|
|
|
/// Keep in mind that the bit representation of the float will clash with
|
|
|
|
/// the format of BMP pixel data, which means writing 0 everywhere won't give
|
|
|
|
/// you the black color.
|
2019-07-29 14:51:40 +00:00
|
|
|
pub const Write = struct {
|
|
|
|
data: f32,
|
|
|
|
|
|
|
|
pub fn init(
|
|
|
|
allocator: *std.mem.Allocator,
|
2020-07-23 19:31:32 +00:00
|
|
|
params: anytype,
|
2019-07-29 14:51:40 +00:00
|
|
|
) Write {
|
|
|
|
return Write{
|
2020-06-01 01:27:11 +00:00
|
|
|
.data = params.data,
|
2019-07-29 14:51:40 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-08-14 12:13:06 +00:00
|
|
|
pub fn deinit(self: *Write) void {}
|
|
|
|
|
2019-07-29 14:51:40 +00:00
|
|
|
pub fn run(self: *Write, bufs: *RunBuffers) void {
|
|
|
|
bufs.out[0] = self.data;
|
|
|
|
}
|
|
|
|
};
|
2019-10-22 21:16:15 +00:00
|
|
|
|
|
|
|
pub const Embed = struct {
|
|
|
|
allocator: *std.mem.Allocator,
|
|
|
|
filepath: []const u8,
|
|
|
|
|
|
|
|
sndfile: *c.SNDFILE = undefined,
|
2019-10-22 21:23:05 +00:00
|
|
|
buf: []f32 = undefined,
|
2019-10-22 21:16:15 +00:00
|
|
|
|
2020-07-23 19:31:32 +00:00
|
|
|
pub fn init(allocator: *std.mem.Allocator, params: anytype) @This() {
|
2019-10-22 21:16:15 +00:00
|
|
|
return Embed{
|
|
|
|
.allocator = allocator,
|
2020-06-01 01:27:11 +00:00
|
|
|
.filepath = params.path,
|
2019-10-22 21:16:15 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn setup(self: *@This()) !void {
|
|
|
|
var in_fmt = c.SF_INFO{
|
2019-11-10 16:37:59 +00:00
|
|
|
.frames = @as(c_int, 0),
|
|
|
|
.samplerate = @as(c_int, 0),
|
|
|
|
.channels = @as(c_int, 0),
|
|
|
|
.format = @as(c_int, 0),
|
|
|
|
.sections = @as(c_int, 0),
|
|
|
|
.seekable = @as(c_int, 0),
|
2019-10-22 21:16:15 +00:00
|
|
|
};
|
2019-10-22 21:23:05 +00:00
|
|
|
|
2019-10-22 21:16:15 +00:00
|
|
|
self.sndfile = try image.sopen(
|
|
|
|
self.allocator,
|
|
|
|
self.filepath,
|
|
|
|
c.SFM_READ,
|
|
|
|
&in_fmt,
|
|
|
|
);
|
|
|
|
|
2019-10-22 22:16:09 +00:00
|
|
|
image.sseek(self.sndfile, 0);
|
|
|
|
|
2019-10-22 21:23:05 +00:00
|
|
|
self.buf = try self.allocator.alloc(f32, @intCast(usize, in_fmt.channels));
|
2019-10-22 21:16:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn deinit(self: *@This()) void {}
|
|
|
|
|
|
|
|
pub fn run(self: *@This(), bufs: *RunBuffers) void {
|
2019-10-22 21:23:05 +00:00
|
|
|
const read_bytes = c.sf_readf_float(self.sndfile, self.buf.ptr, 1);
|
|
|
|
|
|
|
|
if (read_bytes == 0) {
|
2019-10-22 22:16:09 +00:00
|
|
|
bufs.out[0] = bufs.in[0];
|
2019-10-22 21:23:05 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (read_bytes < 0) {
|
|
|
|
const st: i32 = c.sf_error(self.sndfile);
|
2020-01-15 01:31:20 +00:00
|
|
|
std.debug.warn("Failed to read {} ({})\n", .{
|
2019-10-22 21:23:05 +00:00
|
|
|
self.filepath,
|
|
|
|
c.sf_error_number(st),
|
2020-01-15 01:31:20 +00:00
|
|
|
});
|
2019-10-22 21:23:05 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bufs.out[0] = bufs.in[0] + self.buf[0];
|
2019-10-22 21:16:15 +00:00
|
|
|
}
|
|
|
|
};
|