Do whatever

This commit is contained in:
Minecon724 2025-06-10 19:28:33 +02:00
commit 60ef2dc0be
Signed by untrusted user who does not match committer: m724
GPG key ID: A02E6E67AB961189
14 changed files with 513 additions and 195 deletions

View file

@ -1,8 +0,0 @@
#ifndef EASY_H
#define EASY_H
#include <lilv/lilv.h>
const LilvPlugin* easy_load_plugin(LilvWorld* world, const char* uri);
#endif

8
include/plugin.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef PLUGIN_H
#define PLUGIN_H
#include <lilv/lilv.h>
const LilvPlugin* load_plugin(LilvWorld *world, const LilvPlugins *plugins, const char *uri);
#endif

11
include_old/audiofile.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef AUDIOFILE_H
#define AUDIOFILE_H
#include <sndfile.h>
#include <stdlib.h>
SNDFILE *audiofile_read(const char *path, SF_INFO *sfinfo);
SNDFILE *audiofile_open_for_write(const char *path, SF_INFO *og_info);
int audiofile_copy_metadata(SNDFILE *source, SNDFILE *target);
#endif

10
include_old/instances.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef INSTANCES_H
#define INSTANCES_H
#include <lilv/lilv.h>
#include "plugin.h"
LilvInstance *create_bass_enhancer_instance(LilvWorld *world, double sample_rate, float *input_left, float *input_right, float *output_left, float *output_right);
LilvInstance *create_delay_instance(LilvWorld *world, double sample_rate, float *input_left, float *input_right, float *output_left, float *output_right);
#endif

8
include_old/plugin.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef EASY_H
#define EASY_H
#include <lilv/lilv.h>
const LilvPlugin* load_plugin(LilvWorld* world, const char* uri);
#endif

111
main.py
View file

@ -3,74 +3,85 @@ import soundfile
CHUNK_SIZE = 1024
frames, sample_rate = soundfile.read('a.flac')
num_frames = len(frames)
print(f"{sample_rate}Hz | {int(num_frames/sample_rate/60)}:{int(num_frames/sample_rate%60)}")
frames = frames.astype(numpy.float32)
def create_delay_instance(plugins, frames, sample_rate,
input_left, input_right,
output_left, output_right) -> lilv.Instance:
plugin = plugins.get_by_uri("http://lsp-plug.in/plugins/lv2/comp_delay_x2_stereo")
if plugin is None:
raise Exception("Plugin comp_delay_x2_stereo not found")
print("Using:", plugin.get_name())
world = lilv.World()
world.load_all()
for i in range(plugin.get_num_ports()):
port = plugin.get_port(i)
#print(f"Port {i}: {port.get_name()} = {port.get_range()[0]}")
plugins = world.get_all_plugins()
instance = lilv.Instance(plugin, sample_rate)
plugin = plugins.get_by_uri("http://lsp-plug.in/plugins/lv2/comp_delay_x2_stereo")
if plugin is None:
print("No plugin comp_delay_x2_stereo")
exit()
instance.connect_port(4, numpy.array([1], dtype=numpy.float32)) # while 1 is default it needs to be set as int32 for whatever reason
print("Using:", plugin.get_name())
knob_mode = numpy.array([2], dtype=numpy.float32)
instance.connect_port(16, knob_mode)
for i in range(plugin.get_num_ports()):
port = plugin.get_port(i)
#print(f"Port {i}: {port.get_name()} = {port.get_range()[0]}")
knob_time = numpy.array([100.0], dtype=numpy.float32)
instance.connect_port(22, knob_time)
instance = lilv.Instance(plugin, sample_rate)
instance.connect_port(0, input_left)
instance.connect_port(1, input_right)
instance.connect_port(2, output_left)
instance.connect_port(3, output_right)
instance.connect_port(4, numpy.array([1], dtype=numpy.int32)) # while 1 is default it needs to be set as int32 for whatever reason
return instance
knob_mode = numpy.array([2], dtype=numpy.float32) # by the way, this can't be put into connect_port, even if just the number is a variable
instance.connect_port(16, knob_mode)
def main():
frames, sample_rate = soundfile.read('source.flac')
num_frames = len(frames)
print(f"{sample_rate}Hz | {int(num_frames/sample_rate/60)}:{int(num_frames/sample_rate%60)}")
frames = frames.astype(numpy.float32)
knob_time = numpy.array([10.0], dtype=numpy.float32) # but this can?????? it can be any of the three
instance.connect_port(22, knob_time)
world = lilv.World()
world.load_all()
output = numpy.zeros((num_frames, 2), frames.dtype)
plugins = world.get_all_plugins()
input_left_chunk = numpy.zeros(CHUNK_SIZE, frames.dtype)
input_right_chunk = numpy.zeros(CHUNK_SIZE, frames.dtype)
output_left_chunk = numpy.zeros(CHUNK_SIZE, frames.dtype)
output_right_chunk = numpy.zeros(CHUNK_SIZE, frames.dtype)
input_left_chunk = numpy.zeros(CHUNK_SIZE, frames.dtype)
input_right_chunk = numpy.zeros(CHUNK_SIZE, frames.dtype)
instance.connect_port(0, input_left_chunk)
instance.connect_port(1, input_right_chunk)
instance.connect_port(2, output_left_chunk)
instance.connect_port(3, output_right_chunk)
output_left_chunk = numpy.zeros(CHUNK_SIZE, frames.dtype)
output_right_chunk = numpy.zeros(CHUNK_SIZE, frames.dtype)
instance = create_delay_instance(plugins, frames, sample_rate, input_left_chunk, input_right_chunk, output_left_chunk, output_right_chunk)
instance.activate()
instance.activate()
print(f"\nFrames: {num_frames}")
print(f"Chunk size: {CHUNK_SIZE}")
print(f"So {int(numpy.ceil(num_frames/CHUNK_SIZE))} iterations\n")
print(f"\nFrames: {num_frames}")
print(f"Chunk size: {CHUNK_SIZE}")
print(f"We will perform {int(numpy.ceil(num_frames/CHUNK_SIZE))} iterations\n")
for start in range(0, num_frames, CHUNK_SIZE):
end = min(start + CHUNK_SIZE, num_frames)
chunk_size = end - start
print(start, chunk_size, end, " \033[F")
output_total = numpy.zeros_like(frames)
input_left_chunk[:chunk_size] = frames[start:end, 0]
input_right_chunk[:chunk_size] = frames[start:end, 1]
output_left_chunk.fill(0)
output_right_chunk.fill(0)
for start in range(0, num_frames, CHUNK_SIZE):
end = min(start + CHUNK_SIZE, num_frames)
chunk_size = end - start
print(start, chunk_size, end, " \033[F")
instance.run(chunk_size)
input_left_chunk[:chunk_size] = frames[start:end, 0]
input_right_chunk[:chunk_size] = frames[start:end, 1]
output_left_chunk.fill(0)
output_right_chunk.fill(0)
output[start:end, 0] = output_left_chunk[:chunk_size]
output[start:end, 1] = output_right_chunk[:chunk_size]
instance.run(chunk_size)
print("done processing ")
instance.deactivate()
output_total[start:end, 0] = output_left_chunk[:chunk_size]
output_total[start:end, 1] = output_right_chunk[:chunk_size]
if numpy.allclose(frames, output, rtol=0.5, atol=0.5):
print("Warning: output is identical")
print("done processing ")
instance.deactivate()
soundfile.write('aoutt.flac', output, sample_rate)
if numpy.allclose(frames, output_total, rtol=0.5, atol=0.5):
print("Warning: output is identical")
soundfile.write('aoutt.flac', output_total, sample_rate)
if __name__ == "__main__":
main()

View file

@ -1,4 +1,4 @@
#include <audiofile.h>
#include "audiofile.h"
SNDFILE *audiofile_read(const char *path, SF_INFO *sfinfo) {
printf("Input file: \"%s\"\n", path);

View file

@ -1,40 +0,0 @@
#include "easy.h"
const LilvPlugin* easy_load_plugin(LilvWorld* world, const char* uri) {
const LilvPlugins* plugin_list = lilv_world_get_all_plugins(world);
LilvNode* plugin_uri = lilv_new_uri(world, uri);
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugin_list, plugin_uri);
lilv_node_free(plugin_uri);
if (plugin != NULL) {
LilvNode *plugin_name = lilv_plugin_get_name(plugin);
printf("Loaded plugin \"%s\"\n", lilv_node_as_string(plugin_name));
lilv_node_free(plugin_name);
uint32_t nPorts = lilv_plugin_get_num_ports(plugin);
for (uint32_t i = 0; i < nPorts; i++) {
const LilvPort* port = lilv_plugin_get_port_by_index(plugin, i);
LilvNode *nameNode = lilv_port_get_name(plugin, port);
const char* name = lilv_node_as_string(nameNode);
lilv_node_free(nameNode);
LilvNode* defNode = NULL;
lilv_port_get_range(plugin, port, &defNode, NULL, NULL);
float defaultValue = lilv_node_as_float(defNode);
lilv_node_free(defNode);
printf("Port %d: %s = %f\n", i, name, defaultValue);
LilvNodes *classes = lilv_port_get_classes(plugin, port);
LILV_FOREACH(nodes, i, classes) {
LilvNode *n = lilv_nodes_get(classes, i);
printf(" %s\n", lilv_node_as_uri(n));
}
}
}
return plugin;
}

View file

@ -1,73 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include <sndfile.h>
#include <string.h>
#include <lilv/lilv.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include "easy.h"
#include "audiofile.h"
#include "plugin.h"
#define BUFFER_SIZE 8192 // this is per channel
#define BUFFER_SIZE 8192 // per channel
/*
http://lsp-plug.in/plugins/lv2/comp_delay_x2_stereo
http://lsp-plug.in/plugins/lv2/para_equalizer_x32_lr
http://calf.sourceforge.net/plugins/BassEnhancer
*/
static int knob_mode = 2;
static float knob_time = 100.0f; // milliseconds
LilvInstance *instance_two(LilvWorld *world, double sample_rate, float *input_left, float *input_right, float *output_left, float *output_right) {
const LilvPlugin* plugin = easy_load_plugin(world, "http://calf.sourceforge.net/plugins/BassEnhancer");
if (plugin == NULL) {
fprintf(stderr, "Plugin not found: BassEnhancer (from calf.sourceforge.net)\n");
return NULL;
}
LilvInstance *new_delay_instance(LilvWorld *world, const LilvPlugins* plugins, double sample_rate, float *input_left, float *input_right, float *output_left, float *output_right) {
const LilvPlugin* plugin = load_plugin(world, plugins, "http://lsp-plug.in/plugins/lv2/comp_delay_x2_stereo");
LilvInstance *instance = lilv_plugin_instantiate(plugin, sample_rate, NULL);
if (instance == NULL) {
fprintf(stderr, "Failed to initialize instance two\n");
return NULL;
}
lilv_instance_connect_port(instance, 0, input_left); // Input L
lilv_instance_connect_port(instance, 1, input_right); // Input R
lilv_instance_connect_port(instance, 2, output_left); // Output L
lilv_instance_connect_port(instance, 3, output_right); // Output R
lilv_instance_activate(instance);
return instance;
}
LilvInstance *instance_three(LilvWorld *world, double sample_rate, float *input_left, float *input_right, float *output_left, float *output_right) {
const LilvPlugin* plugin = easy_load_plugin(world, "http://lsp-plug.in/plugins/lv2/comp_delay_x2_stereo");
if (plugin == NULL) {
fprintf(stderr, "Plugin not found: comp_delay_x2_stereo (from lsp-plug.in)\n");
return NULL;
}
float *knob_enabled = malloc(sizeof(float));
*knob_enabled = 1.0f;
float *knob_mode = malloc(sizeof(float));
*knob_mode = 2.0f;
float *knob_time = malloc(sizeof(float));
*knob_time = 100.0f; // ms
LilvInstance *instance = lilv_plugin_instantiate(plugin, sample_rate, NULL);
if (instance == NULL) {
fprintf(stderr, "Failed to initialize instance three\n");
return NULL;
}
lilv_instance_connect_port(instance, 4, knob_enabled);
lilv_instance_connect_port(instance, 16, knob_mode);
lilv_instance_connect_port(instance, 22, knob_time);
lilv_instance_connect_port(instance, 0, input_left); // Input L
lilv_instance_connect_port(instance, 1, input_right); // Input R
lilv_instance_connect_port(instance, 2, output_left); // Output L
lilv_instance_connect_port(instance, 3, output_right); // Output R
lilv_instance_connect_port(instance, 0, input_left);
lilv_instance_connect_port(instance, 1, input_right);
lilv_instance_connect_port(instance, 2, output_left);
lilv_instance_connect_port(instance, 3, output_right);
lilv_instance_connect_port(instance, 16, &knob_mode);
lilv_instance_connect_port(instance, 22, &knob_time);
lilv_instance_activate(instance);
@ -75,62 +38,55 @@ LilvInstance *instance_three(LilvWorld *world, double sample_rate, float *input_
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <input> [output]\n", argv[0]);
printf("Welcome to new version\n");
if (argc < 3) {
printf("Usage: %s <input> <output>\n", argv[0]);
return 2;
}
// so here we create the pointers for the input and output filenames
char *input_filename = argv[1];
char *output_filename;
char *output_filename = argv[2];
if (argc < 3) {
output_filename = malloc((strlen(input_filename) + 5) * sizeof(char));
strcpy(output_filename, "out-");
strcat(output_filename, input_filename);
} else {
output_filename = argv[2];
}
// Create lilv world. Think of it as the container for everything LV2.
LilvWorld *world = lilv_world_new();
lilv_world_load_all(world);
// load audio file
const LilvPlugins *plugins = lilv_world_get_all_plugins(world);
// Load the audio file, create the output file and copy metadata to it
SF_INFO sfinfo = {0};
SNDFILE *in_sndfile;
if ((in_sndfile = audiofile_read(input_filename, &sfinfo)) == NULL) {
lilv_world_free(world);
return 1;
}
SNDFILE *out_sndfile;
if ((out_sndfile = audiofile_open_for_write(output_filename, &sfinfo)) == NULL) {
sf_close(in_sndfile);
lilv_world_free(world);
return 1;
}
audiofile_copy_metadata(in_sndfile, out_sndfile);
// prepare lilv instance
// Create buffers for processing
float input_left[BUFFER_SIZE];
float input_right[BUFFER_SIZE];
float output_left[BUFFER_SIZE];
float output_right[BUFFER_SIZE];
const int instancesCount = 2;
LilvInstance **instances = malloc(instancesCount * sizeof(LilvInstance*));
if (instances == NULL) {
fprintf(stderr, "mallocing instances failed: %s\n", strerror(errno));
LilvInstance *instance = new_delay_instance(world, plugins, sfinfo.samplerate, input_left, input_right, output_left, output_right);
if (instance == NULL) {
sf_close(in_sndfile);
sf_close(out_sndfile);
lilv_world_free(world);
return 1;
}
//
instances[0] = instance_two(world, sfinfo.samplerate, input_left, input_right, output_left, output_right);
instances[1] = instance_three(world, sfinfo.samplerate, input_left, input_right, output_left, output_right);
// start processing
printf("Now processing\n");
clock_t start = clock();
@ -138,21 +94,17 @@ int main(int argc, char *argv[]) {
float output_buffer[BUFFER_SIZE * 2];
int frames_read;
while ((frames_read = sf_readf_float(in_sndfile, input_buffer, BUFFER_SIZE))) {
// a frame is 2 samples and a sample is a number basically and it go left right left right (or how many channels)
// De-interleave input file data into planar buffers (idk whatever that means but ai suggested it)
// Basically a frame is samples * channels (2 if stereo) and a sample is a number basically and it go through each channel. In case of stereo it goes left right left right and so on.
for (sf_count_t i = 0; i < frames_read; i++) {
input_left[i] = input_buffer[i * 2];
input_right[i] = input_buffer[i * 2 + 1];
}
lilv_instance_run(instance, frames_read);
for (int i=0; i<instancesCount; i++) {
lilv_instance_run(instances[i], frames_read);
if (i + 1 != instancesCount) {
memcpy(input_left, output_left, frames_read * sizeof(float));
memcpy(input_right, output_right, frames_read * sizeof(float));
}
}
// Interleave the final output for writing to the file
// In other words, undo the above
for (sf_count_t i = 0; i < frames_read; i++) {
output_buffer[i * 2] = output_left[i];
output_buffer[i * 2 + 1] = output_right[i];
@ -164,18 +116,15 @@ int main(int argc, char *argv[]) {
clock_t end = clock();
printf("Done processing. Took %ldms\n", (clock_t)((double)(end - start) / CLOCKS_PER_SEC * 1000));
// end processing
// Free resources
for (int i=0; i<instancesCount; i++) {
LilvInstance *instance = instances[i];
lilv_instance_deactivate(instance);
lilv_instance_free(instance);
}
free(instances);
lilv_instance_deactivate(instance);
lilv_instance_free(instance);
lilv_world_free(world);
sf_close(in_sndfile);
sf_close(out_sndfile);
}
return 0;
}

62
src/plugin.c Normal file
View file

@ -0,0 +1,62 @@
#include "plugin.h"
inline void print_plugin_info(const LilvPlugin* plugin) {
LilvNode *plugin_name = lilv_plugin_get_name(plugin);
printf("Loaded plugin \"%s\"\n", lilv_node_as_string(plugin_name));
lilv_node_free(plugin_name);
uint32_t nPorts = lilv_plugin_get_num_ports(plugin);
for (uint32_t i = 0; i < nPorts; i++) {
const LilvPort* port = lilv_plugin_get_port_by_index(plugin, i);
LilvNode *nameNode = lilv_port_get_name(plugin, port);
const char* name = lilv_node_as_string(nameNode);
lilv_node_free(nameNode);
const LilvNode *symbolNode = lilv_port_get_symbol(plugin, port);
const char* symbol = lilv_node_as_string(symbolNode);
printf("Port %d: %s (%s) = ", i, name, symbol);
LilvNode* minValueNode = NULL;
LilvNode* maxValueNode = NULL;
LilvNode* defaultValueNode = NULL;
lilv_port_get_range(plugin, port, &defaultValueNode, &minValueNode, &maxValueNode);
if (lilv_node_is_float(defaultValueNode)) {
printf("%f (%f - %f) (Float)", lilv_node_as_float(defaultValueNode), lilv_node_as_float(minValueNode), lilv_node_as_float(maxValueNode));
} else if (lilv_node_is_int(defaultValueNode)) {
printf("%d (%d - %d) (Integer)", lilv_node_as_int(defaultValueNode), lilv_node_as_int(minValueNode), lilv_node_as_int(maxValueNode));
} else if (lilv_node_is_bool(defaultValueNode)) {
printf("%s (Boolean)", lilv_node_as_bool(defaultValueNode) ? "true" : "false");
} else if (lilv_node_is_string(defaultValueNode)) {
printf("\"%s\" (String)", lilv_node_as_string(defaultValueNode));
} else {
printf("unknown (Other)");
}
lilv_node_free(minValueNode);
lilv_node_free(maxValueNode);
lilv_node_free(defaultValueNode);
printf("\n");
const LilvNodes *classes = lilv_port_get_classes(plugin, port);
LILV_FOREACH(nodes, i, classes) {
const LilvNode *n = lilv_nodes_get(classes, i);
printf(" %s\n", lilv_node_as_uri(n));
}
}
}
const LilvPlugin* load_plugin(LilvWorld* world, const LilvPlugins *plugins, const char* uri) {
LilvNode* plugin_uri = lilv_new_uri(world, uri);
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
lilv_node_free(plugin_uri);
if (plugin != NULL) {
print_plugin_info(plugin);
}
return plugin;
}

68
src_old/audiofile.c Normal file
View file

@ -0,0 +1,68 @@
#include "audiofile.h"
SNDFILE *audiofile_read(const char *path, SF_INFO *sfinfo) {
printf("Input file: \"%s\"\n", path);
SNDFILE *sndfile = sf_open(path, SFM_READ, sfinfo);
if (sndfile == NULL) {
fprintf(stderr, "Failed to open audio file: %s\n", sf_strerror(NULL));
return NULL;
}
if (sfinfo->channels != 2) {
fprintf(stderr, "File must have 2 channels\n");
sf_close(sndfile);
return NULL;
}
int seconds = (double)sfinfo->frames / sfinfo->samplerate;
int minutes = seconds / 60;
printf("Duration: %d:%d\n", minutes, seconds % 60);
printf("Sample rate: %dHz\n", sfinfo->samplerate);
return sndfile;
}
SNDFILE *audiofile_open_for_write(const char *path, SF_INFO *og_info) {
printf("Output file: \"%s\"\n", path);
SF_INFO sfinfo = {0};
sfinfo.samplerate = og_info->samplerate;
sfinfo.format = og_info->format;
sfinfo.channels = og_info->channels;
SNDFILE *sndfile = sf_open(path, SFM_WRITE, &sfinfo);
if (sndfile == NULL) {
fprintf(stderr, "Failed to open audio file: %s\n", sf_strerror(NULL));
return NULL;
}
return sndfile;
}
int audiofile_copy_metadata(SNDFILE *source, SNDFILE *target) {
int err;
SF_BROADCAST_INFO binfo;
if ((err = sf_command(source, SFC_GET_BROADCAST_INFO, &binfo, sizeof(binfo))) != 0) {
printf("Failed reading BROADCAST_INFO: %s\n", sf_error_number(err));
return 1;
}
if ((err = sf_command(target, SFC_SET_BROADCAST_INFO, &binfo, sizeof(binfo))) != 0) {
printf("Failed writing BROADCAST_INFO: %s\n", sf_error_number(err));
return 1;
}
for (int i=SF_STR_FIRST; i<=SF_STR_LAST; i++) {
const char *data = sf_get_string(source, i);
if (data != NULL) {
if ((err = sf_set_string(target, i, data)) != 0) {
printf("Failed writing metadata %d (%s): %s\n", i, data, sf_error_number(err));
return 1;
}
}
}
return 0;
}

60
src_old/instances.c Normal file
View file

@ -0,0 +1,60 @@
#include "instances.h"
/*
http://lsp-plug.in/plugins/lv2/comp_delay_x2_stereo
http://lsp-plug.in/plugins/lv2/para_equalizer_x32_lr
http://calf.sourceforge.net/plugins/BassEnhancer
*/
LilvInstance *create_bass_enhancer_instance(LilvWorld *world, double sample_rate, float *input_left, float *input_right, float *output_left, float *output_right) {
const LilvPlugin* plugin = load_plugin(world, "http://calf.sourceforge.net/plugins/BassEnhancer");
if (plugin == NULL) {
fprintf(stderr, "Plugin not found: BassEnhancer (from calf.sourceforge.net)\n");
return NULL;
}
LilvInstance *instance = lilv_plugin_instantiate(plugin, sample_rate, NULL);
if (instance == NULL) {
fprintf(stderr, "Failed to initialize instance two\n");
return NULL;
}
lilv_instance_connect_port(instance, 0, input_left);
lilv_instance_connect_port(instance, 1, input_right);
lilv_instance_connect_port(instance, 2, output_left);
lilv_instance_connect_port(instance, 3, output_right);
lilv_instance_activate(instance);
return instance;
}
LilvInstance *create_delay_instance(LilvWorld *world, double sample_rate, float *input_left, float *input_right, float *output_left, float *output_right) {
const LilvPlugin* plugin = load_plugin(world, "http://lsp-plug.in/plugins/lv2/comp_delay_x2_stereo");
if (plugin == NULL) {
fprintf(stderr, "Plugin not found: comp_delay_x2_stereo (from lsp-plug.in)\n");
return NULL;
}
LilvInstance *instance = lilv_plugin_instantiate(plugin, sample_rate, NULL);
if (instance == NULL) {
fprintf(stderr, "Failed to initialize instance three\n");
return NULL;
}
lilv_instance_connect_port(instance, 0, input_left);
lilv_instance_connect_port(instance, 1, input_right);
lilv_instance_connect_port(instance, 2, output_left);
lilv_instance_connect_port(instance, 3, output_right);
static float knob_mode = 2.0f;
static float knob_time = 100.0f; // milliseconds
lilv_instance_connect_port(instance, 16, &knob_mode);
lilv_instance_connect_port(instance, 22, &knob_time);
lilv_instance_activate(instance);
return instance;
}

130
src_old/main.c Normal file
View file

@ -0,0 +1,130 @@
#include <stdio.h>
#include <stdlib.h>
#include <sndfile.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include "audiofile.h"
#include "instances.h"
#define BUFFER_SIZE 8192 // this is per channel
int man(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <input> [output]\n", argv[0]);
return 2;
}
// so here we create the pointers for the input and output filenames
char *input_filename = argv[1];
char *output_filename;
// here we check if the output filename is provided, if not we create a default one
if (argc < 3) {
output_filename = malloc((strlen(input_filename) + 5) * sizeof(char));
strcpy(output_filename, "out-");
strcat(output_filename, input_filename);
} else {
output_filename = argv[2];
}
// Create lilv world. Think of it as the container for everything LV2.
LilvWorld *world = lilv_world_new();
lilv_world_load_all(world);
// Load the audio file, create the output file and copy metadata to it
SF_INFO sfinfo = {0};
SNDFILE *in_sndfile;
if ((in_sndfile = audiofile_read(input_filename, &sfinfo)) == NULL) {
return 1;
}
SNDFILE *out_sndfile;
if ((out_sndfile = audiofile_open_for_write(output_filename, &sfinfo)) == NULL) {
sf_close(in_sndfile);
return 1;
}
audiofile_copy_metadata(in_sndfile, out_sndfile);
// Create buffers for processing
float input_left[BUFFER_SIZE];
float input_right[BUFFER_SIZE];
float output_left[BUFFER_SIZE];
float output_right[BUFFER_SIZE];
// Intermediate buffers are used for chaining
float imm_buf_left[BUFFER_SIZE];
float imm_buf_right[BUFFER_SIZE];
// Instantiate the instances
const int instancesCount = 2;
LilvInstance **instances = malloc(instancesCount * sizeof(LilvInstance*));
if (instances == NULL) {
fprintf(stderr, "mallocing instances failed: %s\n", strerror(errno));
sf_close(in_sndfile);
sf_close(out_sndfile);
return 1;
}
// Create instances of the plugins
instances[0] = create_bass_enhancer_instance(world, sfinfo.samplerate, input_left, input_right, imm_buf_left, imm_buf_right);
instances[1] = create_delay_instance(world, sfinfo.samplerate, input_left, input_right, output_left, output_right);
// Start the processing finally
printf("Now processing\n");
clock_t start = clock();
float input_buffer[BUFFER_SIZE * 2];
float output_buffer[BUFFER_SIZE * 2];
int frames_read;
while ((frames_read = sf_readf_float(in_sndfile, input_buffer, BUFFER_SIZE))) {
// De-interleave input file data into planar buffers (idk whatever that means but ai suggested it)
// Basically a frame is samples * channels (2 if stereo) and a sample is a number basically and it go through each channel. In case of stereo it goes left right left right and so on.
for (sf_count_t i = 0; i < frames_read; i++) {
input_left[i] = input_buffer[i * 2];
input_right[i] = input_buffer[i * 2 + 1];
}
//printf("Running instance 0\n");
//lilv_instance_run(instances[0], frames_read);
//printf("Running instance 1\n");
//lilv_instance_run(instances[1], frames_read);
// Interleave the final output for writing to the file
// In other words, undo the above
for (sf_count_t i = 0; i < frames_read; i++) {
output_buffer[i * 2] = output_left[i];
output_buffer[i * 2 + 1] = output_right[i];
}
sf_writef_float(out_sndfile, output_buffer, frames_read);
}
clock_t end = clock();
printf("Done processing. Took %ldms\n", (clock_t)((double)(end - start) / CLOCKS_PER_SEC * 1000));
// Free resources
for (int i=0; i<instancesCount; i++) {
lilv_instance_deactivate(instances[i]);
lilv_instance_free(instances[i]);
}
free(instances);
lilv_world_free(world);
sf_close(in_sndfile);
sf_close(out_sndfile);
return 0;
}

49
src_old/plugin.c Normal file
View file

@ -0,0 +1,49 @@
#include "plugin.h"
const LilvPlugin* load_plugin(LilvWorld *world, const LilvPlugins *plugins, const char *uri) {
LilvNode* plugin_uri = lilv_new_uri(world, uri);
const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
lilv_node_free(plugin_uri);
if (plugin != NULL) {
print_plugin_info(plugin);
}
return plugin;
}
inline print_plugin_info(const LilvPlugin* plugin) {
LilvNode *plugin_name = lilv_plugin_get_name(plugin);
printf("Loaded plugin \"%s\"\n", lilv_node_as_string(plugin_name));
lilv_node_free(plugin_name);
uint32_t nPorts = lilv_plugin_get_num_ports(plugin);
for (uint32_t i = 0; i < nPorts; i++) {
const LilvPort* port = lilv_plugin_get_port_by_index(plugin, i);
LilvNode *nameNode = lilv_port_get_name(plugin, port);
const char* name = lilv_node_as_string(nameNode);
lilv_node_free(nameNode);
LilvNode* defNode = NULL;
lilv_port_get_range(plugin, port, &defNode, NULL, NULL);
float defaultValue = lilv_node_as_float(defNode);
lilv_node_free(defNode);
printf("Port %d: %s = %f\n", i, name, defaultValue);
if (lilv_node_is_float(defNode)) {
printf(" Type: Float\n");
} else if (lilv_node_is_int(defNode)) {
printf(" Type: Integer\n");
} else {
printf(" Type: Other\n");
}
const LilvNodes *classes = lilv_port_get_classes(plugin, port);
LILV_FOREACH(nodes, i, classes) {
const LilvNode *n = lilv_nodes_get(classes, i);
printf(" %s\n", lilv_node_as_uri(n));
}
}
}