diff --git a/doc/README.md b/doc/README.md index 3182f7d..746b6f1 100644 --- a/doc/README.md +++ b/doc/README.md @@ -62,8 +62,6 @@ Parameters: ## `mbeq split index band_1 band_2 band_3 band_4 band_5 band_6 band_7 band_8 band_9 band_10 band_11 band_12 band_13 band_14 band_15` -Multiband EQ from the SWH plugins. - In respective order, the band arugments represent the: 50Hz, 100Hz, 156Hz, 220Hz, 311Hz, 440Hz, 622Hz, 880Hz 1250Hz, 1750Hz, 2500Hz, 3500Hz, 5000Hz, 10000Hz and 20000Hz frequencies. @@ -71,18 +69,6 @@ In respective order, the band arugments represent the: All of them represent the band's gain in dB. The range is -70 to +30dB, default is 0. -## `chorus split index voices delay_base voice_spread detune law_freq attendb` - -Multivoice Chrorus from the SWH plugins. - -Parameters: - - `voices`: Number of voices (int), 1..8, default 1 - - `delay_base`: Delay base (ms), 10..40, default 10 - - `voice_spread`: Voice separation (ms), 0-2, default 0.5 - - `detune`: Detune (%), 0..5, default 1 - - `law_freq`: LFO frequency (Hz), 2..30, default 9 - - `attendb`: Output attenuation (dB), -20..0, default 0 - ## TODO `echo split index delay` Run an echo filter on the given loaded file. diff --git a/examples/chorus.scri b/examples/chorus.scri deleted file mode 100644 index bf30a1b..0000000 --- a/examples/chorus.scri +++ /dev/null @@ -1,3 +0,0 @@ -load :0; -chorus 3 1 3 10 0.01 0.1 2 0; -quicksave; diff --git a/src/lang.zig b/src/lang.zig index 802ba82..2ad9e9f 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -18,7 +18,6 @@ pub const CommandType = enum { Eq, Phaser, Mbeq, - Chorus, }; pub const Command = struct { @@ -83,19 +82,6 @@ pub const Command = struct { return arr.toSliceConst(); } - - pub fn appendParam( - self: *const Command, - params: *plugin.ParamList, - symbol: []const u8, - idx: usize, - ) !void { - var val = try self.floatArgAt(idx); - try params.append(plugin.Param{ - .sym = symbol, - .value = val, - }); - } }; pub const CommandList = std.ArrayList(*Command); @@ -125,7 +111,6 @@ pub const Lang = struct { _ = try self.keywords.put("eq", .Eq); _ = try self.keywords.put("mbeq", .Mbeq); _ = try self.keywords.put("phaser", .Phaser); - _ = try self.keywords.put("chorus", .Chorus); } pub fn parse(self: *Lang, data: []const u8) !CommandList { diff --git a/src/runner.zig b/src/runner.zig index b0d7c33..ab0cefd 100644 --- a/src/runner.zig +++ b/src/runner.zig @@ -3,9 +3,6 @@ const lang = @import("lang.zig"); const images = @import("image.zig"); const plugin = @import("plugin.zig"); -const Position = plugin.Position; -const ParamList = plugin.ParamList; - const Image = images.Image; pub const RunError = error{ @@ -14,6 +11,10 @@ pub const RunError = error{ ImageRequired, }; +fn appendParam(params: *plugin.ParamList, sym: []const u8, value: f32) !void { + try params.append(plugin.Param{ .sym = sym, .value = value }); +} + pub const Runner = struct { allocator: *std.mem.Allocator, image: ?*Image = null, @@ -153,59 +154,101 @@ pub const Runner = struct { } /// Run the http://lv2plug.in/plugins/eg-amp plugin over the file. - fn ampCmd(self: *Runner, pos: Position, params: ParamList) !void { + fn ampCmd(self: *Runner, split: usize, index: usize, gain: f32) !void { var image = try self.getImage(); - try image.runPlugin("http://lv2plug.in/plugins/eg-amp", pos, params); + + var params = plugin.ParamList.init(self.allocator); + defer params.deinit(); + + try params.append(plugin.Param{ .sym = "gain", .value = gain }); + + // TODO if we could detect that the next command is a quicksave then + // we don't need the temporary file in runPlugin and instead we + // dump it all on the output image for it. + try image.runPlugin( + "http://lv2plug.in/plugins/eg-amp", + plugin.Position{ .split = split, .index = index }, + params, + ); } - fn rFlangerCmd(self: *Runner, pos: Position, params: ParamList) !void { + fn rFlangerCmd( + self: *Runner, + split: usize, + index: usize, + delay_depth_avg: f32, + law_freq: f32, + ) !void { var image = try self.getImage(); - try image.runPlugin("http://plugin.org.uk/swh-plugins/retroFlange", pos, params); + var params = plugin.ParamList.init(self.allocator); + defer params.deinit(); + + try params.append(plugin.Param{ .sym = "delay_depth_avg", .value = delay_depth_avg }); + try params.append(plugin.Param{ .sym = "law_freq", .value = law_freq }); + + try image.runPlugin( + "http://plugin.org.uk/swh-plugins/retroFlange", + plugin.Position{ .split = split, .index = index }, + params, + ); } - fn eqCmd(self: *Runner, position: Position, params: ParamList) !void { + fn eqCmd( + self: *Runner, + position: plugin.Position, + lo: f32, + mid: f32, + high: f32, + ) !void { var image = try self.getImage(); + var params = plugin.ParamList.init(self.allocator); + defer params.deinit(); + + try appendParam(¶ms, "lo", lo); + try appendParam(¶ms, "mid", mid); + try appendParam(¶ms, "hi", high); + try image.runPlugin("http://plugin.org.uk/swh-plugins/dj_eq_mono", position, params); } - fn phaserCmd(self: *Runner, position: Position, params: ParamList) !void { + fn phaserCmd( + self: *Runner, + position: plugin.Position, + lfo_rate: f32, + lfo_depth: f32, + fb: f32, + spread: f32, + ) !void { var image = try self.getImage(); + var params = plugin.ParamList.init(self.allocator); + defer params.deinit(); + + try appendParam(¶ms, "lfo_rate", lfo_rate); + try appendParam(¶ms, "lfo_depth", lfo_depth); + try appendParam(¶ms, "fb", fb); + try appendParam(¶ms, "spread", spread); + try image.runPlugin("http://plugin.org.uk/swh-plugins/lfoPhaser", position, params); } fn mbeqCmd( self: *Runner, - position: Position, + position: plugin.Position, bands: []const f32, ) !void { var image = try self.getImage(); - var params = ParamList.init(self.allocator); + var params = plugin.ParamList.init(self.allocator); defer params.deinit(); for (bands) |band_value, idx| { var sym = try std.fmt.allocPrint(self.allocator, "band_{}", idx + 1); - try params.append(plugin.Param{ - .sym = sym, - .value = band_value, - }); + try appendParam(¶ms, sym, band_value); } try image.runPlugin("http://plugin.org.uk/swh-plugins/mbeq", position, params); } - fn chorusCmd( - self: *Runner, - pos: Position, - params: ParamList, - ) !void { - var image = try self.getImage(); - try image.runPlugin("http://plugin.org.uk/swh-plugins/multivoiceChorus", pos, params); - } - fn runCommand(self: *Runner, cmd: *lang.Command) !void { - var params = ParamList.init(self.allocator); - defer params.deinit(); - return switch (cmd.command) { .Noop => {}, .Load => blk: { @@ -216,36 +259,40 @@ pub const Runner = struct { .Quicksave => try self.quicksaveCmd(), .Amp => blk: { - const pos = try cmd.consumePosition(); - try cmd.appendParam(¶ms, "gain", 2); - try self.ampCmd(pos, params); + const split = try cmd.usizeArgAt(0); + const index = try cmd.usizeArgAt(1); + const gain = try cmd.floatArgAt(2); + try self.ampCmd(split, index, gain); }, .RFlanger => blk: { - const pos = try cmd.consumePosition(); - try cmd.appendParam(¶ms, "delay_depth_avg", 2); - try cmd.appendParam(¶ms, "law_freq", 3); - try self.rFlangerCmd(pos, params); + const split = try cmd.usizeArgAt(0); + const index = try cmd.usizeArgAt(1); + const delay_depth_avg = try cmd.floatArgAt(2); + const law_freq = try cmd.floatArgAt(3); + + try self.rFlangerCmd(split, index, delay_depth_avg, law_freq); }, .Eq => blk: { const pos = try cmd.consumePosition(); - try cmd.appendParam(¶ms, "lo", 2); - try cmd.appendParam(¶ms, "mid", 3); - try cmd.appendParam(¶ms, "hi", 4); - try self.eqCmd(pos, params); + const lo = try cmd.floatArgAt(2); + const mid = try cmd.floatArgAt(3); + const high = try cmd.floatArgAt(4); + + try self.eqCmd(pos, lo, mid, high); }, .Phaser => blk: { const pos = try cmd.consumePosition(); - try cmd.appendParam(¶ms, "lfo_rate", 2); - try cmd.appendParam(¶ms, "lfo_depth", 3); - try cmd.appendParam(¶ms, "fb", 4); - try cmd.appendParam(¶ms, "spread", 5); + const lfo_rate = try cmd.floatArgAt(2); + const lfo_depth = try cmd.floatArgAt(3); + const fb = try cmd.floatArgAt(4); + const spread = try cmd.floatArgAt(5); - try self.phaserCmd(pos, params); + try self.phaserCmd(pos, lfo_rate, lfo_depth, fb, spread); }, .Mbeq => blk: { @@ -254,21 +301,8 @@ pub const Runner = struct { try self.mbeqCmd(pos, bands); }, - .Chorus => blk: { - const pos = try cmd.consumePosition(); - - try cmd.appendParam(¶ms, "voices", 2); - try cmd.appendParam(¶ms, "delay_base", 3); - try cmd.appendParam(¶ms, "voice_spread", 4); - try cmd.appendParam(¶ms, "detune", 5); - try cmd.appendParam(¶ms, "law_freq", 6); - try cmd.appendParam(¶ms, "attendb", 7); - - try self.chorusCmd(pos, params); - }, - else => blk: { - std.debug.warn("Unsupported command: {}\n", cmd.command); + std.debug.warn("Unknown command: {}\n", cmd.command); break :blk RunError.UnknownCommand; }, };