From c534721e883c026edd3102d209e8c25724460f26 Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 10 Jul 2019 14:44:22 -0300 Subject: [PATCH 1/4] use a hashmap for CommandType conversion --- src/lang.zig | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/lang.zig b/src/lang.zig index f3c9c71..5d20a6f 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -52,33 +52,32 @@ pub const Command = struct { pub const CommandList = std.ArrayList(*Command); pub const ArgList = std.ArrayList([]const u8); -pub fn commandToCmdType(command: []const u8) ParseError!CommandType { - // TODO make a hashmap for those - if (std.mem.eql(u8, command, "noop")) { - return CommandType.Noop; - } else if (std.mem.eql(u8, command, "load")) { - return CommandType.Load; - } else if (std.mem.eql(u8, command, "amp")) { - return CommandType.Amp; - } else if (std.mem.eql(u8, command, "rflanger")) { - return CommandType.RFlanger; - } else if (std.mem.eql(u8, command, "quicksave")) { - return CommandType.Quicksave; - } else { - std.debug.warn("Unknown command: '{}'\n", command); - return ParseError.UnknownCommand; - } -} +pub const PluginKeywords = [_]CommandType{ .Amp, .RFlanger }; +pub const KeywordMap = std.AutoHashMap([]const u8, CommandType); pub const Lang = struct { allocator: *std.mem.Allocator, + keywords: KeywordMap, pub fn init(allocator: *std.mem.Allocator) Lang { - return Lang{ .allocator = allocator }; + return Lang{ + .allocator = allocator, + .keywords = KeywordMap.init(allocator), + }; + } + + fn fillKeywords(self: *Lang) !void { + _ = try self.keywords.put("noop", .Noop); + _ = try self.keywords.put("load", .Load); + _ = try self.keywords.put("quicksave", .Quicksave); + + _ = try self.keywords.put("amp", .Amp); + _ = try self.keywords.put("rflanger", .RFlanger); } pub fn parse(self: *Lang, data: []const u8) !CommandList { var splitted_it = std.mem.separate(data, ";"); + try self.fillKeywords(); var cmds = CommandList.init(self.allocator); while (splitted_it.next()) |stmt_orig| { @@ -93,9 +92,17 @@ pub const Lang = struct { var cmd_opt = tok_it.next(); if (cmd_opt == null) return ParseError.NoCommandGiven; - var command = cmd_opt.?; - var ctype = try commandToCmdType(command); + + var kv_opt = self.keywords.get(command); + var ctype: CommandType = undefined; + if (kv_opt) |kv| { + ctype = kv.value; + } else { + std.debug.warn("Unknown command: '{}'\n", command); + return ParseError.UnknownCommand; + } + var args = ArgList.init(self.allocator); while (tok_it.next()) |arg| { From 9a5d4f14e5f485276c10a104b2e781263cc67a7d Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 10 Jul 2019 16:06:44 -0300 Subject: [PATCH 2/4] add eq command --- examples/eq.scri | 4 ++++ src/image.zig | 2 +- src/lang.zig | 14 +++++++++++++- src/runner.zig | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 examples/eq.scri diff --git a/examples/eq.scri b/examples/eq.scri new file mode 100644 index 0000000..08ac2b4 --- /dev/null +++ b/examples/eq.scri @@ -0,0 +1,4 @@ +load :0; +eq 3 1 2 -0.3 0.7; +eq 10 3 3 -0.9 2; +quicksave; diff --git a/src/image.zig b/src/image.zig index 06bc739..c11e3fd 100644 --- a/src/image.zig +++ b/src/image.zig @@ -187,7 +187,7 @@ pub const Image = struct { var sym = c.lilv_new_string(ctx.world, sym_cstr.ptr); const port = c.lilv_plugin_get_port_by_symbol(ctx.plugin, sym) orelse blk: { - std.debug.warn("assert fail: symbol not found on port"); + std.debug.warn("assert fail: symbol {} not found on port\n", param.sym); return ImageError.InvalidSymbol; }; diff --git a/src/lang.zig b/src/lang.zig index 5d20a6f..ddd4ba5 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -1,5 +1,7 @@ const std = @import("std"); +const plugin = @import("plugin.zig"); + pub const ParseError = error{ NoCommandGiven, UnknownCommand, @@ -9,9 +11,11 @@ pub const ParseError = error{ pub const CommandType = enum { Noop, Load, + Quicksave, + Amp, RFlanger, - Quicksave, + Eq, }; pub const Command = struct { @@ -38,6 +42,13 @@ pub const Command = struct { return try std.fmt.parseInt(usize, arg, 10); } + pub fn consumePosition(self: *const Command) !plugin.Position { + return plugin.Position{ + .split = try self.usizeArgAt(0), + .index = try self.usizeArgAt(1), + }; + } + pub fn intArgAt(self: *const Command, idx: usize) !i32 { var arg = try self.argAt(idx); return try std.fmt.parseInt(i32, arg, 10); @@ -73,6 +84,7 @@ pub const Lang = struct { _ = try self.keywords.put("amp", .Amp); _ = try self.keywords.put("rflanger", .RFlanger); + _ = try self.keywords.put("eq", .Eq); } pub fn parse(self: *Lang, data: []const u8) !CommandList { diff --git a/src/runner.zig b/src/runner.zig index baeedfe..d71062b 100644 --- a/src/runner.zig +++ b/src/runner.zig @@ -11,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, @@ -189,6 +193,24 @@ pub const Runner = struct { ); } + 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 runCommand(self: *Runner, cmd: *lang.Command) !void { return switch (cmd.command) { .Noop => {}, @@ -215,6 +237,16 @@ pub const Runner = struct { try self.rFlangerCmd(split, index, delay_depth_avg, law_freq); }, + .Eq => blk: { + const pos = try cmd.consumePosition(); + + 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); + }, + else => blk: { std.debug.warn("Unknown command: {}\n", cmd.command); break :blk RunError.UnknownCommand; From 20aeedeef294086a37abb9d0fec66808bfe06024 Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 10 Jul 2019 16:13:15 -0300 Subject: [PATCH 3/4] add eq command to doc --- doc/README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/README.md b/doc/README.md index 5895910..df545b4 100644 --- a/doc/README.md +++ b/doc/README.md @@ -34,7 +34,18 @@ Run the eg-amp plugin over the given slice of the file. ## `rflanger split index delay_depth_avg law_freq` -Runs the Retro Flanger script from the SWH plugins. +Run the Retro Flanger script from the SWH plugins. + + - `delay_depth_avg` is for the `Average stall (ms)` parameter of the plugin. + - `law_freq` is for the `Flange frequency` parameter of the plugin. + +## `eq split index lo mid hi` + +Run the DJ EQ plugin from the SWH plugins. + +`lo`, `mid`, and `hi` are the respective dB gains for each frequency range. + +All three ranges accept gains from -70dB to +6dB. ## TODO `echo split index delay` From 6bc54f8e464efb0b2679664df95ede3fa73e3a61 Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 10 Jul 2019 16:24:43 -0300 Subject: [PATCH 4/4] add phaser cmd --- doc/README.md | 13 +++++++++++++ examples/phaser.scri | 3 +++ src/lang.zig | 2 ++ src/runner.zig | 31 +++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 examples/phaser.scri diff --git a/doc/README.md b/doc/README.md index df545b4..fe22674 100644 --- a/doc/README.md +++ b/doc/README.md @@ -23,6 +23,8 @@ where in the file you want the plugin to be ran. so, if you did `plugin 3 1...`, it would split the file in 3, then get the part that is of index 1 (starting at 0). +**Keep in mind parts start from the bottom of the file.** + ## `load path_or_arg` Load a file into memory. The file MUST end with the bmp extension (and so MUST @@ -46,6 +48,17 @@ Run the DJ EQ plugin from the SWH plugins. `lo`, `mid`, and `hi` are the respective dB gains for each frequency range. All three ranges accept gains from -70dB to +6dB. +Default is 0 for all (no action taken). + +## `phaser split index lfo_rate lfo_depth fb spread` + +Run the LFO Phaser plugin from the SWH plugins. + +Parameters: + - `lfo_rate`: LFO Rate (Hz), 0..100, default 25 + - `lfo_depth`: LFO depth, 0..1, default 0.25 + - `fb`: Feedback, -1..1, default 0 + - `spread`: Spread (octaves), 0..2, default 1 ## TODO `echo split index delay` diff --git a/examples/phaser.scri b/examples/phaser.scri new file mode 100644 index 0000000..9e8f2ce --- /dev/null +++ b/examples/phaser.scri @@ -0,0 +1,3 @@ +load :0; +phaser 3 1 25 0.25 0 1; +quicksave; diff --git a/src/lang.zig b/src/lang.zig index ddd4ba5..dc7010c 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -16,6 +16,7 @@ pub const CommandType = enum { Amp, RFlanger, Eq, + Phaser, }; pub const Command = struct { @@ -85,6 +86,7 @@ pub const Lang = struct { _ = try self.keywords.put("amp", .Amp); _ = try self.keywords.put("rflanger", .RFlanger); _ = try self.keywords.put("eq", .Eq); + _ = try self.keywords.put("phaser", .Phaser); } pub fn parse(self: *Lang, data: []const u8) !CommandList { diff --git a/src/runner.zig b/src/runner.zig index d71062b..0299838 100644 --- a/src/runner.zig +++ b/src/runner.zig @@ -211,6 +211,26 @@ pub const Runner = struct { try image.runPlugin("http://plugin.org.uk/swh-plugins/dj_eq_mono", position, params); } + 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 runCommand(self: *Runner, cmd: *lang.Command) !void { return switch (cmd.command) { .Noop => {}, @@ -247,6 +267,17 @@ pub const Runner = struct { try self.eqCmd(pos, lo, mid, high); }, + .Phaser => blk: { + const pos = try cmd.consumePosition(); + + 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, lfo_rate, lfo_depth, fb, spread); + }, + else => blk: { std.debug.warn("Unknown command: {}\n", cmd.command); break :blk RunError.UnknownCommand;