Compare commits
8 commits
005d685723
...
430677fc07
Author | SHA1 | Date | |
---|---|---|---|
430677fc07 | |||
c8b5327634 | |||
1c6ef1d4d5 | |||
6e66850d90 | |||
2d64eaa3ef | |||
612421f7b6 | |||
2e27390058 | |||
87bab879ed |
7 changed files with 102 additions and 10 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
zig-cache/
|
||||
*.mp3
|
||||
*.wav
|
||||
|
|
3
examples/embed.scri
Normal file
3
examples/embed.scri
Normal file
|
@ -0,0 +1,3 @@
|
|||
load :0;
|
||||
embed 3 1 ./file.wav;
|
||||
quicksave;
|
|
@ -2,6 +2,7 @@
|
|||
const std = @import("std");
|
||||
const lv2 = @import("lv2_helpers.zig");
|
||||
const plugins = @import("plugin.zig");
|
||||
const image = @import("image.zig");
|
||||
|
||||
const c = lv2.c;
|
||||
|
||||
|
@ -131,3 +132,63 @@ pub const Write = struct {
|
|||
bufs.out[0] = self.data;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Embed = struct {
|
||||
allocator: *std.mem.Allocator,
|
||||
filepath: []const u8,
|
||||
|
||||
sndfile: *c.SNDFILE = undefined,
|
||||
buf: []f32 = undefined,
|
||||
|
||||
pub fn init(allocator: *std.mem.Allocator, filepath: []const u8) @This() {
|
||||
return Embed{
|
||||
.allocator = allocator,
|
||||
.filepath = filepath,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn setup(self: *@This()) !void {
|
||||
var in_fmt = c.SF_INFO{
|
||||
.frames = c_int(0),
|
||||
.samplerate = c_int(0),
|
||||
.channels = c_int(0),
|
||||
.format = c_int(0),
|
||||
.sections = c_int(0),
|
||||
.seekable = c_int(0),
|
||||
};
|
||||
|
||||
self.sndfile = try image.sopen(
|
||||
self.allocator,
|
||||
self.filepath,
|
||||
c.SFM_READ,
|
||||
&in_fmt,
|
||||
);
|
||||
|
||||
image.sseek(self.sndfile, 0);
|
||||
|
||||
self.buf = try self.allocator.alloc(f32, @intCast(usize, in_fmt.channels));
|
||||
}
|
||||
|
||||
pub fn deinit(self: *@This()) void {}
|
||||
|
||||
pub fn run(self: *@This(), bufs: *RunBuffers) void {
|
||||
const read_bytes = c.sf_readf_float(self.sndfile, self.buf.ptr, 1);
|
||||
|
||||
if (read_bytes == 0) {
|
||||
bufs.out[0] = bufs.in[0];
|
||||
return;
|
||||
}
|
||||
|
||||
if (read_bytes < 0) {
|
||||
const st: i32 = c.sf_error(self.sndfile);
|
||||
std.debug.warn(
|
||||
"Failed to read {} ({})\n",
|
||||
self.filepath,
|
||||
c.sf_error_number(st),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
bufs.out[0] = bufs.in[0] + self.buf[0];
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const std = @import("std");
|
||||
const lv2 = @import("lv2_helpers.zig");
|
||||
const c = lv2.c;
|
||||
const custom = @import("custom.zig");
|
||||
const bmp = @import("bmp_valid.zig");
|
||||
|
||||
const plugins = @import("plugin.zig");
|
||||
|
@ -23,7 +22,7 @@ pub const ImageError = error{
|
|||
};
|
||||
|
||||
/// Low level integration function with libsndfile.
|
||||
fn sopen(
|
||||
pub fn sopen(
|
||||
allocator: *std.mem.Allocator,
|
||||
path: []const u8,
|
||||
mode: i32,
|
||||
|
@ -57,7 +56,7 @@ fn sopen(
|
|||
return file.?;
|
||||
}
|
||||
|
||||
fn swrite(file: *c.SNDFILE, buf: [*]f32, frames: i64) !void {
|
||||
pub fn swrite(file: *c.SNDFILE, buf: [*]f32, frames: i64) !void {
|
||||
const count = c.sf_writef_float(file, buf, frames);
|
||||
|
||||
if (count != frames) {
|
||||
|
@ -66,7 +65,7 @@ fn swrite(file: *c.SNDFILE, buf: [*]f32, frames: i64) !void {
|
|||
}
|
||||
}
|
||||
|
||||
fn sseek(file: *c.SNDFILE, offset: usize) void {
|
||||
pub fn sseek(file: *c.SNDFILE, offset: usize) void {
|
||||
const offset_i64 = @intCast(i64, offset);
|
||||
const frames = c.sf_seek(file, offset_i64, c.SEEK_SET);
|
||||
const frames_current = c.sf_seek(file, 0, c.SEEK_CUR);
|
||||
|
@ -109,7 +108,7 @@ pub fn temporaryName(allocator: *std.mem.Allocator) ![]u8 {
|
|||
return error.TempGenFail;
|
||||
}
|
||||
|
||||
fn mkSfInfo() c.SF_INFO {
|
||||
pub fn mkSfInfo() c.SF_INFO {
|
||||
return c.SF_INFO{
|
||||
.frames = c_int(0),
|
||||
.samplerate = c_int(44100),
|
||||
|
@ -422,9 +421,10 @@ pub const Image = struct {
|
|||
self: *Image,
|
||||
comptime Plugin: type,
|
||||
position: plugins.Position,
|
||||
params: *plugins.ParamMap,
|
||||
comptime ExtraType: type,
|
||||
extra: ExtraType,
|
||||
) !void {
|
||||
var plugin_opt: ?Plugin = Plugin.init(self.allocator, params);
|
||||
var plugin_opt: ?Plugin = Plugin.init(self.allocator, extra);
|
||||
if (plugin_opt == null) {
|
||||
return ImageError.PluginLoadFail;
|
||||
}
|
||||
|
@ -432,6 +432,13 @@ pub const Image = struct {
|
|||
var plugin = plugin_opt.?;
|
||||
defer plugin.deinit();
|
||||
|
||||
const decls = comptime std.meta.declarations(Plugin);
|
||||
inline for (decls) |decl| {
|
||||
if (comptime std.mem.eql(u8, decl.name, "setup")) {
|
||||
try plugin.setup();
|
||||
}
|
||||
}
|
||||
|
||||
// the code here is a copypaste of runPlugin() without the specific
|
||||
// lilv things.
|
||||
var tmpnam = try temporaryName(self.allocator);
|
||||
|
|
|
@ -30,6 +30,7 @@ pub const CommandType = enum {
|
|||
Noise,
|
||||
WildNoise,
|
||||
Write,
|
||||
Embed,
|
||||
|
||||
Rotate,
|
||||
};
|
||||
|
@ -187,6 +188,7 @@ pub const Lang = struct {
|
|||
_ = try self.keywords.put("noise", .Noise);
|
||||
_ = try self.keywords.put("wildnoise", .WildNoise);
|
||||
_ = try self.keywords.put("write", .Write);
|
||||
_ = try self.keywords.put("embed", .Embed);
|
||||
|
||||
// even more custom
|
||||
_ = try self.keywords.put("rotate", .Rotate);
|
||||
|
@ -225,6 +227,7 @@ pub const Lang = struct {
|
|||
"noise",
|
||||
"wildnoise",
|
||||
"write",
|
||||
"embed",
|
||||
"rotate",
|
||||
};
|
||||
|
||||
|
@ -250,6 +253,7 @@ pub const Lang = struct {
|
|||
.Noise,
|
||||
.WildNoise,
|
||||
.Write,
|
||||
.Embed,
|
||||
|
||||
.Rotate,
|
||||
};
|
||||
|
@ -312,6 +316,7 @@ pub const Lang = struct {
|
|||
.WildNoise => try self.expectFloat(4, cmd.args),
|
||||
.Write => try self.expectFloat(3, cmd.args),
|
||||
.Rotate => try self.expectAny(2, cmd.args),
|
||||
.Embed => try self.expectAny(3, cmd.args),
|
||||
else => std.debug.warn("WARN unchecked command {}\n", cmd.command),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ pub fn printList(list: langs.CommandList, stream: var) !void {
|
|||
.Noise => "noise",
|
||||
.WildNoise => "wildnoise",
|
||||
.Write => "write",
|
||||
.Embed => "embed",
|
||||
|
||||
.Rotate => "rotate",
|
||||
};
|
||||
|
|
|
@ -266,17 +266,22 @@ pub const Runner = struct {
|
|||
|
||||
fn noiseCmd(self: *Runner, pos: Position, map: *ParamMap) !void {
|
||||
var image = try self.getImage();
|
||||
try image.runCustomPlugin(custom.RandomNoise, pos, map);
|
||||
try image.runCustomPlugin(custom.RandomNoise, pos, *ParamMap, map);
|
||||
}
|
||||
|
||||
fn wildNoiseCmd(self: *Runner, pos: Position, map: *ParamMap) !void {
|
||||
var image = try self.getImage();
|
||||
try image.runCustomPlugin(custom.WildNoise, pos, map);
|
||||
try image.runCustomPlugin(custom.WildNoise, pos, *ParamMap, map);
|
||||
}
|
||||
|
||||
fn writeCmd(self: *Runner, pos: Position, map: *ParamMap) !void {
|
||||
var image = try self.getImage();
|
||||
try image.runCustomPlugin(custom.Write, pos, map);
|
||||
try image.runCustomPlugin(custom.Write, pos, *ParamMap, map);
|
||||
}
|
||||
|
||||
fn embedCmd(self: *Runner, pos: Position, path: []const u8) !void {
|
||||
var image = try self.getImage();
|
||||
try image.runCustomPlugin(custom.Embed, pos, []const u8, path);
|
||||
}
|
||||
|
||||
fn rotateCmd(
|
||||
|
@ -303,6 +308,8 @@ pub const Runner = struct {
|
|||
.Load => blk: {
|
||||
var path = cmd.args.at(0);
|
||||
try self.loadCmd(path);
|
||||
|
||||
// TODO is this needed?
|
||||
break :blk;
|
||||
},
|
||||
.Quicksave => try self.quicksaveCmd(),
|
||||
|
@ -460,6 +467,12 @@ pub const Runner = struct {
|
|||
try self.writeCmd(pos, &map);
|
||||
},
|
||||
|
||||
.Embed => blk: {
|
||||
const pos = try cmd.consumePosition();
|
||||
const path = cmd.args.at(2);
|
||||
try self.embedCmd(pos, path);
|
||||
},
|
||||
|
||||
.Rotate => blk: {
|
||||
const deg = try cmd.floatArgAt(0);
|
||||
const bgfill = try cmd.argAt(1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue