From 87bab879ed60db02d6c7db4673c1920e15ac9e40 Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 22 Oct 2019 17:08:19 -0300 Subject: [PATCH 1/8] add embed cmd --- src/lang.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lang.zig b/src/lang.zig index a75193b..d926d77 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -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); From 2e273900581139ee11604c6ca6c4cf3f67e4f33c Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 22 Oct 2019 18:16:15 -0300 Subject: [PATCH 2/8] add the rest for embed command - allow any extra param as a generic to custom plugin init --- src/custom.zig | 42 ++++++++++++++++++++++++++++++++++++++++++ src/image.zig | 19 +++++++++++++------ src/lang.zig | 3 +++ src/printer.zig | 1 + src/runner.zig | 19 ++++++++++++++++--- 5 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/custom.zig b/src/custom.zig index 3f57a4b..7d3eb23 100644 --- a/src/custom.zig +++ b/src/custom.zig @@ -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,44 @@ pub const Write = struct { bufs.out[0] = self.data; } }; + +pub const Embed = struct { + allocator: *std.mem.Allocator, + filepath: []const u8, + + sndfile: *c.SNDFILE = undefined, + + // TODO add its own read buffers from snd file + + 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, + ); + + // TODO allocate 1 or 2 in read buffer, but only use 1 + } + + pub fn deinit(self: *@This()) void {} + + pub fn run(self: *@This(), bufs: *RunBuffers) void { + bufs.out[0] = 0; + } +}; diff --git a/src/image.zig b/src/image.zig index 2b2a38a..3badd58 100644 --- a/src/image.zig +++ b/src/image.zig @@ -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) { @@ -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); diff --git a/src/lang.zig b/src/lang.zig index d926d77..02dbf3b 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -227,6 +227,7 @@ pub const Lang = struct { "noise", "wildnoise", "write", + "embed", "rotate", }; @@ -252,6 +253,7 @@ pub const Lang = struct { .Noise, .WildNoise, .Write, + .Embed, .Rotate, }; @@ -314,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), } } diff --git a/src/printer.zig b/src/printer.zig index 2a30f8e..f198579 100644 --- a/src/printer.zig +++ b/src/printer.zig @@ -24,6 +24,7 @@ pub fn printList(list: langs.CommandList, stream: var) !void { .Noise => "noise", .WildNoise => "wildnoise", .Write => "write", + .Embed => "embed", .Rotate => "rotate", }; diff --git a/src/runner.zig b/src/runner.zig index ede7b3b..5ae666c 100644 --- a/src/runner.zig +++ b/src/runner.zig @@ -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); From 612421f7b6ff34223a41a19abef4d6a1fb2b6cd8 Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 22 Oct 2019 18:23:05 -0300 Subject: [PATCH 3/8] add embed code --- src/custom.zig | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/custom.zig b/src/custom.zig index 7d3eb23..4c8c611 100644 --- a/src/custom.zig +++ b/src/custom.zig @@ -138,8 +138,7 @@ pub const Embed = struct { filepath: []const u8, sndfile: *c.SNDFILE = undefined, - - // TODO add its own read buffers from snd file + buf: []f32 = undefined, pub fn init(allocator: *std.mem.Allocator, filepath: []const u8) @This() { return Embed{ @@ -157,6 +156,7 @@ pub const Embed = struct { .sections = c_int(0), .seekable = c_int(0), }; + self.sndfile = try image.sopen( self.allocator, self.filepath, @@ -164,12 +164,29 @@ pub const Embed = struct { &in_fmt, ); - // TODO allocate 1 or 2 in read buffer, but only use 1 + 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 { - bufs.out[0] = 0; + const read_bytes = c.sf_readf_float(self.sndfile, self.buf.ptr, 1); + + if (read_bytes == 0) { + std.debug.warn("WARN! reached EOF for embed\n"); + 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]; } }; From 2d64eaa3efd14f71d07b381550df9c0b09f8106a Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 22 Oct 2019 18:30:55 -0300 Subject: [PATCH 4/8] add embed example script --- .gitignore | 1 + examples/embed.scri | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 examples/embed.scri diff --git a/.gitignore b/.gitignore index 3cef7be..3fa9744 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ zig-cache/ +*.mp3 diff --git a/examples/embed.scri b/examples/embed.scri new file mode 100644 index 0000000..d9c7efa --- /dev/null +++ b/examples/embed.scri @@ -0,0 +1,3 @@ +load :0; +embed 3 1 ./file.mp3 +quicksave; From 6e66850d905c3aaf646d8add316c78e591183f59 Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 22 Oct 2019 18:57:36 -0300 Subject: [PATCH 5/8] use sf_open_fd --- examples/embed.scri | 2 +- src/image.zig | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/embed.scri b/examples/embed.scri index d9c7efa..eb26536 100644 --- a/examples/embed.scri +++ b/examples/embed.scri @@ -1,3 +1,3 @@ load :0; -embed 3 1 ./file.mp3 +embed 3 1 file.mp3 quicksave; diff --git a/src/image.zig b/src/image.zig index 3badd58..4b275f9 100644 --- a/src/image.zig +++ b/src/image.zig @@ -31,14 +31,17 @@ pub fn sopen( var cstr_path = try std.cstr.addNullByte(allocator, path); defer allocator.free(cstr_path); - var file = c.sf_open(cstr_path.ptr, mode, fmt); + var fs_file = try std.fs.File.openRead(path); + + var file = c.sf_open_fd(fs_file.handle, mode, fmt, 1); const st: i32 = c.sf_error(file); if (st != 0) { + var msg = c.sf_error_number(st); std.debug.warn( "Failed to open {} ({})\n", path, - c.sf_error_number(st), + msg[0..std.mem.len(u8, msg)], ); return ImageError.OpenFail; From 1c6ef1d4d5fcc6798ea5539de1517306cbf6e054 Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 22 Oct 2019 19:08:38 -0300 Subject: [PATCH 6/8] Revert "use sf_open_fd" This reverts commit 6e66850d905c3aaf646d8add316c78e591183f59. --- examples/embed.scri | 2 +- src/image.zig | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/examples/embed.scri b/examples/embed.scri index eb26536..d9c7efa 100644 --- a/examples/embed.scri +++ b/examples/embed.scri @@ -1,3 +1,3 @@ load :0; -embed 3 1 file.mp3 +embed 3 1 ./file.mp3 quicksave; diff --git a/src/image.zig b/src/image.zig index 4b275f9..3badd58 100644 --- a/src/image.zig +++ b/src/image.zig @@ -31,17 +31,14 @@ pub fn sopen( var cstr_path = try std.cstr.addNullByte(allocator, path); defer allocator.free(cstr_path); - var fs_file = try std.fs.File.openRead(path); - - var file = c.sf_open_fd(fs_file.handle, mode, fmt, 1); + var file = c.sf_open(cstr_path.ptr, mode, fmt); const st: i32 = c.sf_error(file); if (st != 0) { - var msg = c.sf_error_number(st); std.debug.warn( "Failed to open {} ({})\n", path, - msg[0..std.mem.len(u8, msg)], + c.sf_error_number(st), ); return ImageError.OpenFail; From c8b5327634a94a42c76d25b14c5221751755c91b Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 22 Oct 2019 19:09:05 -0300 Subject: [PATCH 7/8] libsndfile cant open mp3s --- .gitignore | 1 + examples/embed.scri | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3fa9744..b43912f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ zig-cache/ *.mp3 +*.wav diff --git a/examples/embed.scri b/examples/embed.scri index d9c7efa..b78f7c9 100644 --- a/examples/embed.scri +++ b/examples/embed.scri @@ -1,3 +1,3 @@ load :0; -embed 3 1 ./file.mp3 +embed 3 1 ./file.wav; quicksave; From 430677fc07655e190bcea7951bd11075b2911445 Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 22 Oct 2019 19:16:09 -0300 Subject: [PATCH 8/8] enhance embed custom plugin - seek to 0 on setup - ignore and copy original bytes if we reached end of audio file --- src/custom.zig | 4 +++- src/image.zig | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/custom.zig b/src/custom.zig index 4c8c611..0727113 100644 --- a/src/custom.zig +++ b/src/custom.zig @@ -164,6 +164,8 @@ pub const Embed = struct { &in_fmt, ); + image.sseek(self.sndfile, 0); + self.buf = try self.allocator.alloc(f32, @intCast(usize, in_fmt.channels)); } @@ -173,7 +175,7 @@ pub const Embed = struct { const read_bytes = c.sf_readf_float(self.sndfile, self.buf.ptr, 1); if (read_bytes == 0) { - std.debug.warn("WARN! reached EOF for embed\n"); + bufs.out[0] = bufs.in[0]; return; } diff --git a/src/image.zig b/src/image.zig index 3badd58..9748bc9 100644 --- a/src/image.zig +++ b/src/image.zig @@ -65,7 +65,7 @@ pub 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);