sdenoise.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. speech-denoise -- Speech noise reduction LV2
  3. Copyright 2017 Luciano Dato <lucianodato@gmail.com>
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/
  14. */
  15. /**
  16. * \file sdenoise.c
  17. * \author Luciano Dato
  18. * \brief The main file for host interaction
  19. */
  20. #include <math.h>
  21. #include <float.h>
  22. #include <stdbool.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <time.h>
  26. #include <stdio.h>
  27. #include <limits.h>
  28. #include <rnnoise.h>
  29. #include "lv2/lv2plug.in/ns/lv2core/lv2.h"
  30. #define SDENOISE_URI "https://github.com/lucianodato/speech-denoiser"
  31. #define FRAME_SIZE 480 //Frame default size (For 48 kHz sampling rate)
  32. #define M_PI 3.14159265358979323846f
  33. ///---------------------------------------------------------------------
  34. /**
  35. * Enumeration of LV2 ports.
  36. */
  37. typedef enum
  38. {
  39. NREPEL_ENABLE = 0,
  40. NREPEL_LATENCY = 1,
  41. NREPEL_INPUT = 2,
  42. NREPEL_OUTPUT = 3,
  43. } PortIndex;
  44. /**
  45. * Struct for speech-denoiser instance, the host is going to use.
  46. */
  47. typedef struct
  48. {
  49. const float* input; //input of samples from host (changing size)
  50. float* output; //output of samples to host (changing size)
  51. float samp_rate; //Sample rate received from the host
  52. //Parameters for the algorithm (user input)
  53. float* enable; //For soft bypass (click free bypass)
  54. float* report_latency; //Latency necessary
  55. //Parameters values for RNNoise libray
  56. int frame_size; //RNNOISE frame input size
  57. DenoiseState *st;//RNNoise instance
  58. //Algorithm exta variables
  59. float tau; //time constant for soft bypass
  60. float wet_dry_target; //softbypass target for softbypass
  61. float wet_dry; //softbypass coeff
  62. //Buffers for processing and outputting
  63. int input_latency;
  64. float* in_fifo; //internal input buffer
  65. float* out_fifo; //internal output buffer
  66. float* rnnoise_input_frame;
  67. float* rnnoise_output_frame;
  68. int read_ptr; //buffers read pointer
  69. } SDenoise;
  70. /**
  71. * Instantiates the plugin.
  72. */
  73. static LV2_Handle
  74. instantiate(const LV2_Descriptor* descriptor, double rate, const char* bundle_path,
  75. const LV2_Feature* const* features)
  76. {
  77. //Actual struct declaration
  78. SDenoise* self = (SDenoise*)calloc(1,sizeof(SDenoise));
  79. //Sampling related
  80. self->samp_rate = (float)rate;
  81. //RNNoise related
  82. self->frame_size = FRAME_SIZE;
  83. self->st = rnnoise_create();
  84. //processing buffers
  85. self->in_fifo = (float*)calloc(self->frame_size, sizeof(float));
  86. self->out_fifo = (float*)calloc(self->frame_size, sizeof(float));
  87. self->rnnoise_input_frame = (float*)calloc(self->frame_size, sizeof(float));
  88. self->rnnoise_output_frame = (float*)calloc(self->frame_size, sizeof(float));
  89. self->input_latency = self->frame_size;
  90. self->read_ptr = 0; //the initial position because we are that many samples ahead
  91. //soft bypass
  92. self->tau = (1.f - expf(-2.f * M_PI * 25.f * 64.f / self->samp_rate));
  93. self->wet_dry = 0.f;
  94. return (LV2_Handle)self;
  95. }
  96. /**
  97. * Used by the host to connect the ports of this plugin.
  98. */
  99. static void
  100. connect_port(LV2_Handle instance, uint32_t port, void* data)
  101. {
  102. SDenoise* self = (SDenoise*)instance;
  103. switch ((PortIndex)port)
  104. {
  105. case NREPEL_ENABLE:
  106. self->enable = (float*)data;
  107. break;
  108. case NREPEL_LATENCY:
  109. self->report_latency = (float*)data;
  110. break;
  111. case NREPEL_INPUT:
  112. self->input = (const float*)data;
  113. break;
  114. case NREPEL_OUTPUT:
  115. self->output = (float*)data;
  116. break;
  117. }
  118. }
  119. /**
  120. * Main process function of the plugin.
  121. */
  122. static void
  123. run(LV2_Handle instance, uint32_t n_samples)
  124. {
  125. SDenoise* self = (SDenoise*)instance;
  126. //handy variables
  127. int k;
  128. unsigned int pos;
  129. //Inform latency at run call
  130. *(self->report_latency) = (float) self->input_latency;
  131. //Softbypass targets in case of disabled or enabled
  132. if(*(self->enable) == 0.f)
  133. { //if disabled
  134. self->wet_dry_target = 0.f;
  135. }
  136. else
  137. { //if enabled
  138. self->wet_dry_target = 1.f;
  139. }
  140. //Interpolate parameters over time softly to bypass without clicks or pops
  141. self->wet_dry += self->tau * (self->wet_dry_target - self->wet_dry) + FLT_MIN;
  142. //main loop for processing
  143. for (pos = 0; pos < n_samples; pos++)
  144. {
  145. //Copy samples in the input buffer
  146. self->in_fifo[self->read_ptr] = self->input[pos];
  147. //Output samples in the output buffer
  148. self->output[pos] = self->out_fifo[self->read_ptr];
  149. //Now move the read pointer
  150. self->read_ptr++;
  151. //Once the buffer is full we can do stuff
  152. if (self->read_ptr >= self->frame_size)
  153. {
  154. //Reset the ptr position
  155. self->read_ptr = 0;
  156. //Copy samples to RNNoise input array and scale to short limits
  157. for (k = 0; k < self->frame_size; k++)
  158. {
  159. self->rnnoise_input_frame[k] = self->in_fifo[k];
  160. }
  161. //------------PROCESSING-------------
  162. //Scaling up to short values
  163. for (k = 0; k < self->frame_size; k++)
  164. {
  165. self->rnnoise_input_frame[k] *= SHRT_MAX;
  166. }
  167. //Process input_frame
  168. rnnoise_process_frame(self->st, self->rnnoise_output_frame, self->rnnoise_input_frame);
  169. //Scaling down to float values
  170. for (k = 0; k < self->frame_size; k++)
  171. {
  172. self->rnnoise_output_frame[k] /= SHRT_MAX;
  173. self->rnnoise_input_frame[k] /= SHRT_MAX;
  174. }
  175. //-----------------------------------
  176. //Output processed samples from RNNoise to output fifo considering soft bypass
  177. for (k = 0; k < self->frame_size; k++)
  178. {
  179. self->out_fifo[k] = (1.f-self->wet_dry)*self->rnnoise_input_frame[k] + self->wet_dry*self->rnnoise_output_frame[k];
  180. }
  181. //-------------------------------
  182. }//if
  183. }//main loop
  184. }
  185. /**
  186. * Cleanup and freeing memory.
  187. */
  188. static void
  189. cleanup(LV2_Handle instance)
  190. {
  191. free(instance);
  192. }
  193. /**
  194. * extension for additional interfaces.
  195. */
  196. static const void*
  197. extension_data(const char* uri)
  198. {
  199. return NULL;
  200. }
  201. /**
  202. * Descriptor for linking methods.
  203. */
  204. static const
  205. LV2_Descriptor descriptor =
  206. {
  207. SDENOISE_URI,
  208. instantiate,
  209. connect_port,
  210. NULL,
  211. run,
  212. NULL,
  213. cleanup,
  214. extension_data
  215. };
  216. /**
  217. * Symbol export using the descriptor above.
  218. */
  219. LV2_SYMBOL_EXPORT
  220. const LV2_Descriptor*
  221. lv2_descriptor(uint32_t index)
  222. {
  223. switch (index)
  224. {
  225. case 0:
  226. return &descriptor;
  227. default:
  228. return NULL;
  229. }
  230. }