Compare commits

..

5 commits

Author SHA1 Message Date
e669b74ffb add CustomCommand function 2020-05-31 21:34:49 -03:00
ca751e58f7 add draft declarations for custom commands 2020-05-31 21:33:19 -03:00
82dc99d7d5 remove unecessary switch 2020-05-31 21:26:27 -03:00
d9358ed794 add lv2 parameter validation 2020-05-31 21:25:25 -03:00
8ce844ceed add validation for split/index args 2020-05-31 21:10:43 -03:00

View file

@ -31,6 +31,23 @@ fn LV2Command(
}; };
} }
fn CustomCommand(
comptime tag: Command.tag,
comptime plugin: type,
comptime parameters: type,
) type {
return struct {
pub const base_tag = tag;
pub const command_type = CommandType.plugin_command;
pub const plugin_type = plugin;
base: Command,
split: usize,
index: usize,
parameters: LV2Parameters,
};
}
pub const Command = struct { pub const Command = struct {
tag: Tag, tag: Tag,
@ -113,6 +130,13 @@ pub const Command = struct {
.saturator => Saturator, .saturator => Saturator,
.vintagedelay => Vintagedelay, .vintagedelay => Vintagedelay,
.noise => Noise,
.wildnoise => Wildnoise,
.write => Write,
.embed => Embed,
.rotate => Rotate,
else => @panic("TODO"), else => @panic("TODO"),
}; };
} }
@ -146,8 +170,37 @@ pub const Command = struct {
pub const RunQS = struct { pub const RunQS = struct {
pub const base_tag = Tag.runqs; pub const base_tag = Tag.runqs;
program: []const u8,
base: Command, base: Command,
program: []const u8,
};
pub const Noise = CustomCommand(Tag.noise, custom.RandomNoise, struct {
seed: f32,
fill_bytes: f32,
});
pub const Wildnoise = CustomCommand(Tag.wildnoise, custom.WildNoise, struct {
seed: f32,
fill_bytes: f32,
});
pub const Write = CustomCommand(Tag.write, custom.Write, struct {
data: f32,
});
pub const Embed = struct {
pub const base_tag = Tag.embed;
base: Command,
split: usize,
index: usize,
path: []const u8,
};
pub const Rotate = struct {
pub const base_tag = Tag.rotate;
base: Command,
deg: f32,
bgfill: []const u8,
}; };
pub const Amp = LV2Command( pub const Amp = LV2Command(
@ -362,9 +415,14 @@ pub const Command = struct {
t4d: f32, t4d: f32,
t4a_db: f32, t4a_db: f32,
}); });
pub const Moddelay = LV2Command(.moddelay, "http://plugin.org.uk/swh-plugins/modDelay", struct {
base: f32, pub const Moddelay = LV2Command(
}); .moddelay,
"http://plugin.org.uk/swh-plugins/modDelay",
struct {
base: f32,
},
);
pub const Multichorus = LV2Command(.multichorus, "http://calf.sourceforge.net/plugins/MultiChorus", struct { pub const Multichorus = LV2Command(.multichorus, "http://calf.sourceforge.net/plugins/MultiChorus", struct {
min_delay: f32, min_delay: f32,
@ -448,7 +506,7 @@ pub const Lang = struct {
self.line = 0; self.line = 0;
} }
fn doError(self: *Lang, comptime fmt: []const u8, args: var) void { fn doError(self: *Lang, comptime fmt: []const u8, args: var) void {
std.debug.warn("error at line {}: ", .{self.line}); std.debug.warn("ERROR! at line {}: ", .{self.line});
std.debug.warn(fmt, args); std.debug.warn(fmt, args);
std.debug.warn("\n", .{}); std.debug.warn("\n", .{});
self.has_error = true; self.has_error = true;
@ -471,23 +529,34 @@ pub const Lang = struct {
// arguments... // arguments...
if (is_lv2_command) { if (is_lv2_command) {
cmd.split = try std.fmt.parseInt(usize, tok_it.next().?, 10); const split = tok_it.next();
cmd.index = try std.fmt.parseInt(usize, tok_it.next().?, 10); if (split == null) {
self.doError("Expected split parameter, got EOL", .{});
return;
}
const index = tok_it.next();
if (index == null) {
self.doError("Expected index parameter, got EOL", .{});
return;
}
cmd.split = try std.fmt.parseInt(usize, split.?, 10);
cmd.index = try std.fmt.parseInt(usize, index.?, 10);
// All parameters for LV2 plugins are f32.
inline for (@typeInfo(@TypeOf(cmd.parameters)).Struct.fields) |cmd_field| { inline for (@typeInfo(@TypeOf(cmd.parameters)).Struct.fields) |cmd_field| {
const arg = tok_it.next().?; const maybe_arg = tok_it.next();
const argument_value = switch (cmd_field.field_type) { if (maybe_arg == null) {
f32 => try std.fmt.parseFloat(f32, arg), self.doError("Expected parameter for {}, got nothing", .{cmd_field.name});
else => @compileError("LV2 parameter struct can only have f32 fields"), return;
}; }
std.debug.warn("parsing {}, arg of type {} => {}\n", .{ const arg = maybe_arg.?;
@typeName(command_struct), if (cmd_field.field_type != f32)
@typeName(@TypeOf(argument_value)), @compileError("LV2 parameter struct can only have f32 fields");
argument_value,
});
@field(cmd.parameters, cmd_field.name) = argument_value; @field(cmd.parameters, cmd_field.name) = try std.fmt.parseFloat(f32, arg);
} }
} else { } else {
inline for (@typeInfo(command_struct).Struct.fields) |cmd_field| { inline for (@typeInfo(command_struct).Struct.fields) |cmd_field| {