aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfalkTX <falktx@falktx.com>2021-03-10 14:22:10 +0000
committerDavid Robillard <d@drobilla.net>2022-08-08 21:46:08 -0400
commit18c99199deec1b0bbeea4ae659d91aef90a928c3 (patch)
treef9b75c6e9ff002e48b501ae9833b413ba9bdd7a9
parent1c32082b4679a7a4898a20575c0550c8097f6406 (diff)
downloadlv2-18c99199deec1b0bbeea4ae659d91aef90a928c3.tar.xz
eg-sampler: Convert multi-channel audio files to mono
-rw-r--r--plugins/eg-sampler.lv2/sampler.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/plugins/eg-sampler.lv2/sampler.c b/plugins/eg-sampler.lv2/sampler.c
index 779dc05..a3ef5c3 100644
--- a/plugins/eg-sampler.lv2/sampler.c
+++ b/plugins/eg-sampler.lv2/sampler.c
@@ -96,6 +96,23 @@ typedef struct {
} SampleMessage;
/**
+ Convert an interleaved audio buffer to mono.
+
+ This simply ignores the data on all channels but the first.
+*/
+static sf_count_t
+convert_to_mono(float* data, sf_count_t num_input_frames, uint32_t channels)
+{
+ sf_count_t num_output_frames = 0;
+
+ for (sf_count_t i = 0; i < num_input_frames * channels; i += channels) {
+ data[num_output_frames++] = data[i];
+ }
+
+ return num_output_frames;
+}
+
+/**
Load a new sample and return it.
Since this is of course not a real-time safe action, this is called in the
@@ -115,9 +132,8 @@ load_sample(LV2_Log_Logger* logger, const char* path)
bool error = true;
if (!sndfile || !info->frames) {
lv2_log_error(logger, "Failed to open %s\n", path);
- } else if (info->channels != 1) {
- lv2_log_error(logger, "%s has %d channels\n", path, info->channels);
- } else if (!(data = (float*)malloc(sizeof(float) * info->frames))) {
+ } else if (!(data = (float*)malloc(sizeof(float) * info->frames *
+ info->channels))) {
lv2_log_error(logger, "Failed to allocate memory for sample\n");
} else {
error = false;
@@ -131,9 +147,14 @@ load_sample(LV2_Log_Logger* logger, const char* path)
}
sf_seek(sndfile, 0ul, SEEK_SET);
- sf_read_float(sndfile, data, info->frames);
+ sf_read_float(sndfile, data, info->frames * info->channels);
sf_close(sndfile);
+ if (info->channels != 1) {
+ info->frames = convert_to_mono(data, info->frames, info->channels);
+ info->channels = 1;
+ }
+
// Fill sample struct and return it
sample->data = data;
sample->path = (char*)malloc(path_len + 1);