External, Non-PPA KXStudio Repository
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.8KB

  1. From b0e2fc1a4724ed153d3ffebb04e67faff50766d5 Mon Sep 17 00:00:00 2001
  2. From: falkTX <falktx@falktx.com>
  3. Date: Mon, 15 Mar 2021 11:09:48 +0000
  4. Subject: [PATCH] eg-sampler: add resampling via libsamplerate
  5. ---
  6. plugins/eg-sampler.lv2/sampler.c | 36 +++++++++++++++++++++++++++++---
  7. plugins/eg-sampler.lv2/wscript | 1 +
  8. 2 files changed, 34 insertions(+), 3 deletions(-)
  9. diff --git a/plugins/eg-sampler.lv2/sampler.c b/plugins/eg-sampler.lv2/sampler.c
  10. index 9675003d..21a28c8d 100644
  11. --- a/plugins/eg-sampler.lv2/sampler.c
  12. +++ b/plugins/eg-sampler.lv2/sampler.c
  13. @@ -34,6 +34,7 @@
  14. #include "lv2/worker/worker.h"
  15. #include <sndfile.h>
  16. +#include <samplerate.h>
  17. #include <math.h>
  18. #include <stdbool.h>
  19. @@ -80,6 +81,7 @@ typedef struct {
  20. bool activated;
  21. bool gain_changed;
  22. bool sample_changed;
  23. + int sample_rate;
  24. } Sampler;
  25. /**
  26. @@ -120,7 +122,7 @@ convert_to_mono(float *data, sf_count_t num_input_frames, uint32_t channels)
  27. not modified.
  28. */
  29. static Sample*
  30. -load_sample(LV2_Log_Logger* logger, const char* path)
  31. +load_sample(LV2_Log_Logger* logger, const char* path, int sample_rate)
  32. {
  33. lv2_log_trace(logger, "Loading %s\n", path);
  34. @@ -154,6 +156,33 @@ load_sample(LV2_Log_Logger* logger, const char* path)
  35. info->channels = 1;
  36. }
  37. + if (info->samplerate != sample_rate) {
  38. + lv2_log_trace(logger, "Converting sample rate..\n");
  39. +
  40. + const double src_ratio = (double)sample_rate/(double)info->samplerate;
  41. + const int output_size = ceil(info->frames * src_ratio);
  42. + float* const output_buffer = malloc(sizeof(float) * output_size);
  43. +
  44. + SRC_DATA src_data;
  45. + src_data.data_in = data;
  46. + src_data.data_out = output_buffer;
  47. + src_data.input_frames = info->frames;
  48. + src_data.output_frames = output_size;
  49. + src_data.src_ratio = src_ratio;
  50. +
  51. + if (src_simple(&src_data, SRC_SINC_BEST_QUALITY, 1) != 0) {
  52. + lv2_log_error(logger, "Sample rate conversion failed, eg-sampler will use unconverted sample\n");
  53. + free(output_buffer);
  54. + } else {
  55. + // set new amount of frames
  56. + info->frames = src_data.output_frames_gen;
  57. + // swap buffers
  58. + free(data);
  59. + data = output_buffer;
  60. + lv2_log_trace(logger, "Conversion finished\n");
  61. + }
  62. + }
  63. +
  64. // Fill sample struct and return it
  65. sample->data = data;
  66. sample->path = (char*)malloc(path_len + 1);
  67. @@ -204,7 +233,7 @@ work(LV2_Handle instance,
  68. }
  69. // Load sample.
  70. - Sample* sample = load_sample(&self->logger, path);
  71. + Sample* sample = load_sample(&self->logger, path, self->sample_rate);
  72. if (sample) {
  73. // Send new sample to run() to be applied
  74. respond(handle, sizeof(Sample*), &sample);
  75. @@ -298,6 +327,7 @@ instantiate(const LV2_Descriptor* descriptor,
  76. self->gain = 1.0f;
  77. self->gain_dB = 0.0f;
  78. + self->sample_rate = (int)rate;
  79. return (LV2_Handle)self;
  80. }
  81. @@ -585,7 +615,7 @@ restore(LV2_Handle instance,
  82. if (!self->activated || !schedule) {
  83. // No scheduling available, load sample immediately
  84. lv2_log_trace(&self->logger, "Synchronous restore\n");
  85. - Sample* sample = load_sample(&self->logger, path);
  86. + Sample* sample = load_sample(&self->logger, path, self->sample_rate);
  87. if (sample) {
  88. free_sample(self, self->sample);
  89. self->sample = sample;
  90. diff --git a/plugins/eg-sampler.lv2/wscript b/plugins/eg-sampler.lv2/wscript
  91. index 8c640c10..4d9debc6 100644
  92. --- a/plugins/eg-sampler.lv2/wscript
  93. +++ b/plugins/eg-sampler.lv2/wscript
  94. @@ -22,6 +22,7 @@ def configure(conf):
  95. conf.check_pkg('lv2 >= 1.2.1', uselib_store='LV2')
  96. conf.check_pkg('sndfile >= 1.0.0', uselib_store='SNDFILE')
  97. + conf.check_pkg('samplerate >= 0.1.0', uselib_store='SAMPLERATE')
  98. conf.check_pkg('gtk+-2.0 >= 2.18.0',
  99. uselib_store='GTK2',
  100. system=True,