optimize main plugin loop
this makes it faster to have the main loop focus on running the actual plugin while pre- and post- parts of the loop become their own thing with bigger buffers.
This commit is contained in:
parent
2d9fe80395
commit
542c239e0c
1 changed files with 67 additions and 12 deletions
|
@ -7,6 +7,9 @@ const plugins = @import("plugin.zig");
|
||||||
/// Approximate size of the BMP header.
|
/// Approximate size of the BMP header.
|
||||||
pub const BMPHeaderSize: usize = 82000;
|
pub const BMPHeaderSize: usize = 82000;
|
||||||
|
|
||||||
|
/// Buffer size for main copying
|
||||||
|
pub const BufferSize: usize = 60000;
|
||||||
|
|
||||||
pub const ImageError = error{
|
pub const ImageError = error{
|
||||||
OpenFail,
|
OpenFail,
|
||||||
InvalidPlugin,
|
InvalidPlugin,
|
||||||
|
@ -155,6 +158,34 @@ pub const Image = struct {
|
||||||
return n_read == 1;
|
return n_read == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn copyBytes(
|
||||||
|
self: *Image,
|
||||||
|
out_file: *c.SNDFILE,
|
||||||
|
buf: []f32,
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
) !void {
|
||||||
|
const total_bytes = end - start;
|
||||||
|
|
||||||
|
var i: usize = start;
|
||||||
|
while (i < end) : (i += buf.len) {
|
||||||
|
const read_bytes = c.sf_readf_float(self.sndfile, buf.ptr, @intCast(i64, buf.len));
|
||||||
|
|
||||||
|
var view: []f32 = buf[0..buf.len];
|
||||||
|
if (i + buf.len > end) {
|
||||||
|
const excess = i + buf.len - end;
|
||||||
|
view = buf[0..excess];
|
||||||
|
_ = c.sf_seek(
|
||||||
|
self.sndfile,
|
||||||
|
-@intCast(i64, excess),
|
||||||
|
c.SEEK_CUR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try swrite(out_file, view.ptr, @intCast(i64, view.len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Run a plugin over the image.
|
/// Run a plugin over the image.
|
||||||
/// This setups a new lilv world/plugin among other things.
|
/// This setups a new lilv world/plugin among other things.
|
||||||
/// The internal SNDFILE pointer is modified to point to the output of the
|
/// The internal SNDFILE pointer is modified to point to the output of the
|
||||||
|
@ -228,28 +259,52 @@ pub const Image = struct {
|
||||||
// make sure we start from 0
|
// make sure we start from 0
|
||||||
_ = c.sf_seek(self.sndfile, 0, c.SEEK_SET);
|
_ = c.sf_seek(self.sndfile, 0, c.SEEK_SET);
|
||||||
|
|
||||||
var i: usize = 0;
|
// there are four main stages:
|
||||||
|
// - the bmp header copy
|
||||||
|
// - pre-plugin
|
||||||
|
// - plugin
|
||||||
|
// - post-plugin
|
||||||
|
|
||||||
while (i < file_end) : (i += 1) {
|
var header_buf = try self.allocator.alloc(f32, BMPHeaderSize);
|
||||||
// if we're still on the bmp header phase, copy bytes
|
defer self.allocator.free(header_buf);
|
||||||
// if we aren't in the range from seek_pos, copy bytes
|
|
||||||
// if we are in the range, run lilv plugin
|
|
||||||
|
|
||||||
// TODO speed this up by not reading byte-by-byte.
|
var file_copy_buf = try self.allocator.alloc(f32, BufferSize);
|
||||||
|
defer self.allocator.free(file_copy_buf);
|
||||||
|
|
||||||
|
// bmp header copy
|
||||||
|
const header_len = @intCast(i64, header_buf.len);
|
||||||
|
_ = c.sf_readf_float(self.sndfile, header_buf.ptr, header_len);
|
||||||
|
try swrite(out_file, header_buf.ptr, header_len);
|
||||||
|
|
||||||
|
// pre-plugin copy
|
||||||
|
try self.copyBytes(
|
||||||
|
out_file,
|
||||||
|
file_copy_buf,
|
||||||
|
BMPHeaderSize,
|
||||||
|
seek_pos.start,
|
||||||
|
);
|
||||||
|
|
||||||
|
var i: usize = seek_pos.start;
|
||||||
|
|
||||||
|
while (i < seek_pos.end) : (i += 1) {
|
||||||
const read_bytes = c.sf_readf_float(self.sndfile, rctx.in_buf.ptr, 1);
|
const read_bytes = c.sf_readf_float(self.sndfile, rctx.in_buf.ptr, 1);
|
||||||
if (read_bytes == 0) {
|
if (read_bytes == 0) {
|
||||||
std.debug.warn("WARN! reached EOF at idx={}\n", i);
|
std.debug.warn("WARN! reached EOF at idx={}\n", i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < BMPHeaderSize or !seek_pos.contains(i)) {
|
lv2.lilv_instance_run(rctx.instance, 1);
|
||||||
try swrite(out_file, rctx.in_buf.ptr, 1);
|
try swrite(out_file, rctx.out_buf.ptr, 1);
|
||||||
} else {
|
|
||||||
lv2.lilv_instance_run(rctx.instance, 1);
|
|
||||||
try swrite(out_file, rctx.out_buf.ptr, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// post-plugin copy
|
||||||
|
try self.copyBytes(
|
||||||
|
out_file,
|
||||||
|
file_copy_buf,
|
||||||
|
seek_pos.end,
|
||||||
|
file_end,
|
||||||
|
);
|
||||||
|
|
||||||
c.sf_write_sync(out_file);
|
c.sf_write_sync(out_file);
|
||||||
_ = c.sf_close(out_file);
|
_ = c.sf_close(out_file);
|
||||||
_ = c.sf_close(self.sndfile);
|
_ = c.sf_close(self.sndfile);
|
||||||
|
|
Loading…
Reference in a new issue