Skip to content

Commit b70beff

Browse files
committed
plugin format-defined logging interface
1 parent c81fc39 commit b70beff

File tree

7 files changed

+162
-106
lines changed

7 files changed

+162
-106
lines changed

src/clap/extensions.zig

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/clap/extensions/audio_ports.zig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
const std = @import("std");
2-
const zigplug = @import("zigplug");
32
const c = @import("clap_c");
43

54
pub fn makeAudioPorts(comptime Plugin: type) *const c.clap_plugin_audio_ports_t {

src/clap/extensions/parameters.zig

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ const clap = @import("clap");
55

66
const std = @import("std");
77

8-
const log = std.log.scoped(.zigplug_clap_parameters);
9-
108
pub fn makeParameters(comptime Plugin: type) *const c.clap_plugin_params_t {
119
std.debug.assert(@hasDecl(Plugin, "Parameters"));
1210
const Parameters = Plugin.Parameters;
@@ -87,15 +85,15 @@ pub fn makeParameters(comptime Plugin: type) *const c.clap_plugin_params_t {
8785

8886
switch (param) {
8987
inline else => |p| p.format(writer, @TypeOf(p).fromFloat(value)) catch |e| {
90-
log.err("failed to format parameter '{s}' ({}): {}", .{ p.options.id.?, value, e });
88+
state.plugin.log.err("failed to format parameter '{s}' ({}): {}", .{ p.options.id.?, value, e });
9189
return false;
9290
},
9391
}
9492

9593
const formatted = buffer.toOwnedSlice() catch return false;
9694
defer allocator.free(formatted);
9795
if (formatted.len > out_capacity) {
98-
log.err("parameter value too long: {s}", .{formatted});
96+
state.plugin.log.err("parameter value too long: {s}", .{formatted});
9997
return false;
10098
}
10199

@@ -120,7 +118,7 @@ pub fn makeParameters(comptime Plugin: type) *const c.clap_plugin_params_t {
120118

121119
out.?.* = switch (param) {
122120
inline else => |p| @TypeOf(p).toFloat(p.parse(text) catch |e| {
123-
log.err("failed to parse parameter '{s}' ({s}): '{}'", .{ p.options.id.?, value_text, e });
121+
state.plugin.log.err("failed to parse parameter '{s}' ({s}): '{}'", .{ p.options.id.?, value_text, e });
124122
return false;
125123
}),
126124
};

src/clap/extensions/state.zig

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@ const c = @import("clap_c");
22
const clap = @import("clap");
33

44
const std = @import("std");
5-
const log = std.log.scoped(.zigplug_clap_state);
65

76
pub fn save(clap_plugin: [*c]const c.clap_plugin, stream: [*c]const c.clap_ostream) callconv(.c) bool {
87
var writer = Writer.init(stream);
9-
clap.State.fromClap(clap_plugin).plugin.parameters.?.serialize(&writer.writer) catch |e|
10-
log.err("failed to save parameters: {}", .{e});
8+
const plugin_state = clap.State.fromClap(clap_plugin);
9+
plugin_state.plugin.parameters.?.serialize(&writer.writer) catch |e|
10+
plugin_state.plugin.log.err("failed to save parameters: {}", .{e});
1111

1212
return true;
1313
}
1414

1515
pub fn load(clap_plugin: [*c]const c.clap_plugin, stream: [*c]const c.clap_istream) callconv(.c) bool {
1616
var reader = Reader.init(stream);
17-
clap.State.fromClap(clap_plugin).plugin.parameters.?.deserialize(&reader.reader) catch |e|
18-
log.err("failed to read parameters: {}", .{e});
17+
const plugin_state = clap.State.fromClap(clap_plugin);
18+
plugin_state.plugin.parameters.?.deserialize(&reader.reader) catch |e|
19+
plugin_state.plugin.log.err("failed to read parameters: {}", .{e});
1920

2021
return true;
2122
}
@@ -25,8 +26,6 @@ pub const state = c.clap_plugin_state{
2526
.load = load,
2627
};
2728

28-
// TODO: make Writer and Reader buffered
29-
3029
pub const Writer = struct {
3130
clap_stream: *const c.clap_ostream,
3231
writer: std.Io.Writer,

src/clap/root.zig

Lines changed: 82 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ const std = @import("std");
33
const zigplug = @import("zigplug");
44
pub const c = @import("clap_c");
55

6-
// TODO: use clap.log
7-
pub const log = std.log.scoped(.zigplug_clap);
8-
96
pub const Feature = @import("features.zig").Feature;
107

118
pub const Meta = struct {
@@ -31,6 +28,20 @@ pub fn pluginFromClap(clap_plugin: [*c]const c.clap_plugin_t, comptime T: type)
3128
return @ptrCast(@alignCast(state.plugin.context));
3229
}
3330

31+
pub fn hostLog(context: *anyopaque, level: std.log.Level, text: [:0]const u8) void {
32+
const state: *State = @ptrCast(@alignCast(context));
33+
state.host_log.*.log.?(
34+
state.host,
35+
switch (level) {
36+
.err => c.CLAP_LOG_ERROR,
37+
.warn => c.CLAP_LOG_WARNING,
38+
.info => c.CLAP_LOG_INFO,
39+
.debug => c.CLAP_LOG_DEBUG,
40+
},
41+
text,
42+
);
43+
}
44+
3445
pub const State = struct {
3546
plugin: zigplug.Plugin,
3647
meta: Meta,
@@ -46,6 +57,7 @@ pub const State = struct {
4657
} = null,
4758

4859
host: [*c]const c.clap_host_t = null,
60+
host_log: [*c]const c.clap_host_log_t = null,
4961
host_timer_support: [*c]const c.clap_host_timer_support_t = null,
5062
host_gui: [*c]const c.clap_host_gui_t = null,
5163

@@ -165,7 +177,6 @@ pub const State = struct {
165177
inline else => |*p| {
166178
const value = @TypeOf(p.*).fromFloat(param_event.value);
167179
p.set(value);
168-
zigplug.log.debug("parameter '{s}' = {any}", .{ p.options.id.?, value });
169180
},
170181
}
171182
},
@@ -183,8 +194,7 @@ pub const State = struct {
183194
switch (param.*) {
184195
inline else => |*p| {
185196
const amount = param_event.*.amount;
186-
const modulated = p.modulate(amount);
187-
zigplug.log.debug("parameter '{s}' mod + {any}", .{ p.options.id.?, modulated });
197+
_ = p.modulate(amount);
188198
},
189199
}
190200
},
@@ -195,48 +205,51 @@ pub const State = struct {
195205

196206
fn ClapPlugin(comptime Plugin: type) type {
197207
return extern struct {
198-
fn init(_: [*c]const c.clap_plugin) callconv(.c) bool {
199-
log.debug("init()", .{});
208+
fn init(clap_plugin: [*c]const c.clap_plugin) callconv(.c) bool {
209+
const state = State.fromClap(clap_plugin);
210+
state.plugin.log.debug("clap_plugin.init()", .{});
200211

201212
return true;
202213
}
203214

204215
fn destroy(clap_plugin: [*c]const c.clap_plugin) callconv(.c) void {
205-
log.debug("destroy()", .{});
206-
207216
const state = State.fromClap(clap_plugin);
217+
state.plugin.log.debug("clap_plugin.destroy()", .{});
208218

209219
state.plugin.deinit(Plugin);
210220
std.heap.page_allocator.destroy(state);
211221
std.heap.page_allocator.destroy(@as(*const c.clap_plugin, clap_plugin));
212222
}
213223

214224
fn activate(clap_plugin: [*c]const c.clap_plugin, sample_rate: f64, min_size: u32, max_size: u32) callconv(.c) bool {
215-
log.debug("activate({}, {}, {})", .{ sample_rate, min_size, max_size });
216-
217225
const state = State.fromClap(clap_plugin);
226+
state.plugin.log.debug("clap_plugin.activate({}, {}, {})", .{ sample_rate, min_size, max_size });
218227

219228
state.plugin.sample_rate_hz = @intFromFloat(sample_rate);
220229
state.process_block.sample_rate_hz = state.plugin.sample_rate_hz;
221230

222231
return true;
223232
}
224233

225-
fn deactivate(_: [*c]const c.clap_plugin) callconv(.c) void {
226-
log.debug("deactivate()", .{});
234+
fn deactivate(clap_plugin: [*c]const c.clap_plugin) callconv(.c) void {
235+
const state = State.fromClap(clap_plugin);
236+
state.plugin.log.debug("clap_plugin.deactivate()", .{});
227237
}
228238

229-
fn start_processing(_: [*c]const c.clap_plugin) callconv(.c) bool {
230-
log.debug("start_processing()", .{});
239+
fn start_processing(clap_plugin: [*c]const c.clap_plugin) callconv(.c) bool {
240+
const state = State.fromClap(clap_plugin);
241+
state.plugin.log.debug("clap_plugin.start_processing()", .{});
231242
return true;
232243
}
233244

234-
fn stop_processing(_: [*c]const c.clap_plugin) callconv(.c) void {
235-
log.debug("stop_processing()", .{});
245+
fn stop_processing(clap_plugin: [*c]const c.clap_plugin) callconv(.c) void {
246+
const state = State.fromClap(clap_plugin);
247+
state.plugin.log.debug("clap_plugin.stop_processing()", .{});
236248
}
237249

238-
fn reset(_: [*c]const c.clap_plugin) callconv(.c) void {
239-
log.debug("reset()", .{});
250+
fn reset(clap_plugin: [*c]const c.clap_plugin) callconv(.c) void {
251+
const state = State.fromClap(clap_plugin);
252+
state.plugin.log.debug("clap_plugin.reset()", .{});
240253
}
241254

242255
fn process(clap_plugin: [*c]const c.clap_plugin, clap_process: [*c]const c.clap_process_t) callconv(.c) c.clap_process_status {
@@ -257,7 +270,7 @@ fn ClapPlugin(comptime Plugin: type) type {
257270
end = event.*.time;
258271

259272
state.processAudio(Plugin, clap_process, start, end) catch |e| {
260-
log.err("error while processing: {}", .{e});
273+
state.plugin.log.err("error while processing: {}", .{e});
261274
return c.CLAP_PROCESS_ERROR;
262275
};
263276

@@ -272,26 +285,48 @@ fn ClapPlugin(comptime Plugin: type) type {
272285
}
273286

274287
state.processAudio(Plugin, clap_process, start, end) catch |e| {
275-
log.err("error while processing: {}", .{e});
288+
state.plugin.log.err("error while processing: {}", .{e});
276289
return c.CLAP_PROCESS_ERROR;
277290
};
278291

279292
return c.CLAP_PROCESS_CONTINUE;
280293
}
281294

282295
fn get_extension(clap_plugin: [*c]const c.clap_plugin, id: [*c]const u8) callconv(.c) ?*const anyopaque {
283-
log.debug("get_extension({s})", .{id});
296+
const state = State.fromClap(clap_plugin);
284297
const id_slice = std.mem.span(id);
298+
state.plugin.log.debug("clap_plugin.get_extension({s})", .{id});
285299

286-
const state = State.fromClap(clap_plugin);
287300
if (state.meta.getExtension) |getExtension|
288301
if (getExtension(id_slice)) |ptr|
289302
return ptr;
290-
return @import("extensions.zig").getExtension(Plugin, id_slice);
303+
304+
if (comptime Plugin.meta.audio_ports != null) {
305+
if (std.mem.eql(u8, id_slice, &c.CLAP_EXT_AUDIO_PORTS))
306+
return @import("extensions/audio_ports.zig").makeAudioPorts(Plugin);
307+
}
308+
309+
if (comptime Plugin.meta.note_ports != null) {
310+
if (std.mem.eql(u8, id_slice, &c.CLAP_EXT_NOTE_PORTS))
311+
return @import("extensions/note_ports.zig").makeNotePorts(Plugin);
312+
}
313+
314+
if (@hasDecl(Plugin, "Parameters")) {
315+
if (std.mem.eql(u8, id_slice, &c.CLAP_EXT_PARAMS))
316+
return @import("extensions/parameters.zig").makeParameters(Plugin);
317+
318+
if (std.mem.eql(u8, id_slice, &c.CLAP_EXT_STATE))
319+
return &@import("extensions/state.zig").state;
320+
}
321+
322+
state.plugin.log.warn("host requested unsupported extension '{s}'", .{id});
323+
324+
return null;
291325
}
292326

293-
fn on_main_thread(_: [*c]const c.clap_plugin) callconv(.c) void {
294-
log.debug("on_main_thread()", .{});
327+
fn on_main_thread(clap_plugin: [*c]const c.clap_plugin) callconv(.c) void {
328+
const state = State.fromClap(clap_plugin);
329+
state.plugin.log.debug("clap_plugin.on_main_thread()", .{});
295330
}
296331
};
297332
}
@@ -341,38 +376,32 @@ fn makeClapDescriptor(comptime Plugin: type) std.mem.Allocator.Error!*const c.cl
341376
fn PluginFactory(comptime Plugin: type) type {
342377
return extern struct {
343378
fn get_plugin_count(_: [*c]const c.clap_plugin_factory) callconv(.c) u32 {
344-
log.debug("get_plugin_count()", .{});
345379
return 1;
346380
}
347381

348-
fn get_plugin_descriptor(_: [*c]const c.clap_plugin_factory, index: u32) callconv(.c) [*c]const c.clap_plugin_descriptor_t {
349-
log.debug("get_plugin_descriptor({})", .{index});
350-
351-
return makeClapDescriptor(Plugin) catch |e| {
352-
log.err("failed to allocate descriptor: {}", .{e});
382+
fn get_plugin_descriptor(_: [*c]const c.clap_plugin_factory, _: u32) callconv(.c) [*c]const c.clap_plugin_descriptor_t {
383+
return makeClapDescriptor(Plugin) catch {
353384
return null;
354385
};
355386
}
356387

357388
fn create_plugin(_: [*c]const c.clap_plugin_factory, host: [*c]const c.clap_host_t, plugin_id: [*c]const u8) callconv(.c) [*c]const c.clap_plugin_t {
358-
log.debug("create_plugin({s})", .{plugin_id});
359-
360389
const clap_plugin = ClapPlugin(Plugin);
361390

362-
const plugin = zigplug.Plugin.init(Plugin) catch |e| {
363-
log.err("failed to initialize plugin: {}", .{e});
391+
const plugin = zigplug.Plugin.init(Plugin) catch
364392
return null;
365-
};
393+
394+
plugin.log.debug("clap_plugin_factory.create_plugin({s})", .{plugin_id});
366395

367396
std.debug.assert(host != null);
368397

369398
const plugin_class = std.heap.page_allocator.create(c.clap_plugin_t) catch |e| {
370-
log.err("Plugin allocation failed: {}", .{e});
399+
plugin.log.err("plugin allocation failed: {}", .{e});
371400
return null;
372401
};
373402

374403
const plugin_data = std.heap.page_allocator.create(State) catch |e| {
375-
log.err("Plugin allocation failed: {}", .{e});
404+
plugin.log.err("plugin allocation failed: {}", .{e});
376405
return null;
377406
};
378407

@@ -386,9 +415,19 @@ fn PluginFactory(comptime Plugin: type) type {
386415
},
387416
};
388417

418+
if (host.*.get_extension.?(host, &c.CLAP_EXT_LOG)) |ptr| {
419+
plugin.log.debug("host has clap.log extension", .{});
420+
plugin_data.host_log = @ptrCast(@alignCast(ptr));
421+
plugin_data.plugin.log.* = .{
422+
.context = plugin_data,
423+
.logFn = hostLog,
424+
.allocator = plugin_data.plugin.allocator,
425+
};
426+
}
427+
389428
plugin_class.* = .{
390429
.desc = makeClapDescriptor(Plugin) catch |e| {
391-
log.err("failed to allocate descriptor: {}", .{e});
430+
plugin.log.err("failed to allocate descriptor: {}", .{e});
392431
return null;
393432
},
394433
.plugin_data = plugin_data,
@@ -411,19 +450,13 @@ fn PluginFactory(comptime Plugin: type) type {
411450

412451
fn PluginEntry(factory: c.clap_plugin_factory_t) type {
413452
return extern struct {
414-
fn init(plugin_path: [*c]const u8) callconv(.c) bool {
415-
log.debug("init({s})", .{plugin_path});
416-
453+
fn init(_: [*c]const u8) callconv(.c) bool {
417454
return true;
418455
}
419456

420-
fn deinit() callconv(.c) void {
421-
log.debug("deinit()", .{});
422-
}
457+
fn deinit() callconv(.c) void {}
423458

424459
fn get_factory(factory_id: [*c]const u8) callconv(.c) ?*const anyopaque {
425-
log.debug("get_factory({s})", .{factory_id});
426-
427460
const id = std.mem.span(factory_id);
428461

429462
if (std.mem.eql(u8, id, &c.CLAP_PLUGIN_FACTORY_ID)) {

0 commit comments

Comments
 (0)