diff options
-rw-r--r-- | plugins/eg-sampler.lv2/sampler.c | 29 |
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); |