porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h
Go to the documentation of this file.
1 /* Vocoder Library
2 * Voclib version 1.1 - 2019-02-16
3 *
4 * Philip Bennefall - philip@blastbay.com
5 *
6 * See the end of this file for licensing terms.
7 * The filter implementation was derived from public domain code found on musicdsp.org (see the section called "Filters" for more details).
8 *
9 * USAGE
10 *
11 * This is a single-file library. To use it, do something like the following in one .c file.
12 * #define VOCLIB_IMPLEMENTATION
13 * #include "voclib.h"
14 *
15 * You can then #include this file in other parts of the program as you would with any other header file.
16 */
17 
18 #ifndef VOCLIB_H
19 #define VOCLIB_H
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25  /* COMPILE-TIME OPTIONS */
26 
27  /* The maximum number of bands that the vocoder can be initialized with (lower this number to save memory). */
28 #define VOCLIB_MAX_BANDS 96
29 
30  /* The maximum number of filters per vocoder band (lower this number to save memory). */
31 #define VOCLIB_MAX_FILTERS_PER_BAND 8
32 
33  /* PUBLIC API */
34 
36 
37  /* Initialize a voclib_instance structure.
38  *
39  * Call this function to initialize the voclib_instance structure.
40  * bands is the number of bands that the vocoder should use; recommended values are between 12 and 64.
41  * bands must be between 4 and VOCLIB_MAX_BANDS (inclusive).
42  * filters_per_band determines the steapness with which the filterbank divides the signal; a value of 6 is recommended.
43  * filters_per_band must be between 1 and VOCLIB_MAX_FILTERS_PER_BAND (inclusive).
44  * sample_rate is the number of samples per second in hertz, and should be between 8000 and 192000 (inclusive).
45  * carrier_channels is the number of channels that the carrier has, and should be between 1 and 2 (inclusive).
46  * Note: The modulator must always have only one channel.
47  * Returns nonzero (true) on success or 0 (false) on failure.
48  * The function will only fail if one or more of the parameters are invalid.
49  */
50  int voclib_initialize ( voclib_instance* instance, unsigned char bands, unsigned char filters_per_band, unsigned int sample_rate, unsigned char carrier_channels );
51 
52  /* Run the vocoder.
53  *
54  * Call this function continuously to generate your output.
55  * carrier_buffer and modulator_buffer should contain the carrier and modulator signals respectively.
56  * The modulator must always have one channel.
57  * If the carrier has two channels, the samples in carrier_buffer must be interleaved.
58  * output_buffer will be filled with the result, and must be able to hold as many channels as the carrier.
59  * If the carrier has two channels, the output buffer will be filled with interleaved samples.
60  * output_buffer may be the same pointer as either carrier_buffer or modulator_buffer as long as it can hold the same number of channels as the carrier.
61  * The processing is performed in place.
62  * frames specifies the number of sample frames that should be processed.
63  * Returns nonzero (true) on success or 0 (false) on failure.
64  * The function will only fail if one or more of the parameters are invalid.
65  */
66  int voclib_process ( voclib_instance* instance, const float* carrier_buffer, const float* modulator_buffer, float* output_buffer, unsigned int frames );
67 
68  /* Reset the vocoder sample history.
69  *
70  * In order to run smoothly, the vocoder needs to store a few recent samples internally.
71  * This function resets that internal history. This should only be done if you are processing a new stream.
72  * Resetting the history in the middle of a stream will cause clicks.
73  */
74  void voclib_reset_history ( voclib_instance* instance );
75 
76  /* Set the reaction time of the vocoder in seconds.
77  *
78  * The reaction time is the time it takes for the vocoder to respond to a volume change in the modulator.
79  * A value of 0.03 (AKA 30 milliseconds) is recommended for intelligible speech.
80  * Values lower than about 0.02 will make the output sound raspy and unpleasant.
81  * Values above 0.2 or so will make the speech hard to understand, but can be used for special effects.
82  * The value must be between 0.002 and 2.0 (inclusive).
83  * Returns nonzero (true) on success or 0 (false) on failure.
84  * The function will only fail if the parameter is invalid.
85  */
87 
88  /* Get the current reaction time of the vocoder in seconds. */
89  float voclib_get_reaction_time ( const voclib_instance* instance );
90 
91  /* Set the formant shift of the vocoder in octaves.
92  *
93  * Formant shifting changes the size of the speaker's head.
94  * A value of 1.0 leaves the head size unmodified.
95  * Values lower than 1.0 make the head larger, and values above 1.0 make it smaller.
96  * The value must be between 0.25 and 4.0 (inclusive).
97  * Returns nonzero (true) on success or 0 (false) on failure.
98  * The function will only fail if the parameter is invalid.
99  */
100  int voclib_set_formant_shift ( voclib_instance* instance, float formant_shift );
101 
102  /* Get the current formant shift of the vocoder in octaves. */
103  float voclib_get_formant_shift ( const voclib_instance* instance );
104 
105  /* INTERNAL STRUCTURES */
106 
107  /* this holds the data required to update samples thru a filter. */
108  typedef struct
109  {
110  float a0, a1, a2, a3, a4;
111  float x1, x2, y1, y2;
112  } voclib_biquad;
113 
114  /* Stores the state required for our envelope follower. */
115  typedef struct
116  {
117  float coef;
118  float history[4];
119  } voclib_envelope;
120 
121  /* Holds a set of filters required for one vocoder band. */
122  typedef struct
123  {
125  } voclib_band;
126 
127  /* The main instance structure. This is the structure that you will create an instance of when using the vocoder. */
129  {
130  voclib_band analysis_bands[VOCLIB_MAX_BANDS]; /* The filterbank used for analysis (these are applied to the modulator). */
131  voclib_envelope analysis_envelopes[VOCLIB_MAX_BANDS]; /* The envelopes used to smooth the analysis bands. */
132  voclib_band synthesis_bands[VOCLIB_MAX_BANDS * 2]; /* The filterbank used for synthesis (these are applied to the carrier). The second half of the array is only used for stereo carriers. */
133  float reaction_time; /* In seconds. Higher values make the vocoder respond more slowly to changes in the modulator. */
134  float formant_shift; /* In octaves. 1.0 is unchanged. */
135  unsigned int sample_rate; /* In hertz. */
136  unsigned char bands;
137  unsigned char filters_per_band;
138  unsigned char carrier_channels;
139  };
140 
141 #ifdef __cplusplus
142 }
143 #endif
144 #endif /* VOCLIB_H */
145 
146 /* IMPLEMENTATION */
147 
148 #ifdef VOCLIB_IMPLEMENTATION
149 
150 #include <math.h>
151 #include <assert.h>
152 
153 #ifdef _MSC_VER
154 #define VOCLIB_INLINE __forceinline
155 #else
156 #ifdef __GNUC__
157 #define VOCLIB_INLINE inline __attribute__((always_inline))
158 #else
159 #define VOCLIB_INLINE inline
160 #endif
161 #endif
162 
163 /* Filters
164 *
165 * The filter code below was derived from http://www.musicdsp.org/files/biquad.c. The comment at the top of biquad.c file reads:
166 *
167 * Simple implementation of Biquad filters -- Tom St Denis
168  *
169  * Based on the work
170 
171 Cookbook formulae for audio EQ biquad filter coefficients
172 ---------------------------------------------------------
173 by Robert Bristow-Johnson, pbjrbj@viconet.com a.k.a. robert@audioheads.com
174 
175  * Available on the web at
176 
177 http://www.smartelectronix.com/musicdsp/text/filters005.txt
178 
179  * Enjoy.
180  *
181  * This work is hereby placed in the public domain for all purposes, whether
182  * commercial, free [as in speech] or educational, etc. Use the code and please
183  * give me credit if you wish.
184  *
185  * Tom St Denis -- http://tomstdenis.home.dhs.org
186 */
187 
188 #ifndef VOCLIB_M_LN2
189 #define VOCLIB_M_LN2 0.69314718055994530942
190 #endif
191 
192 #ifndef VOCLIB_M_PI
193 #define VOCLIB_M_PI 3.14159265358979323846
194 #endif
195 
196 /* Computes a BiQuad filter on a sample. */
197 static VOCLIB_INLINE float voclib_BiQuad ( float sample, voclib_biquad* b )
198 {
199  float result;
200 
201  /* compute the result. */
202  result = b->a0 * sample + b->a1 * b->x1 + b->a2 * b->x2 -
203  b->a3 * b->y1 - b->a4 * b->y2;
204 
205  /* shift x1 to x2, sample to x1. */
206  b->x2 = b->x1;
207  b->x1 = sample;
208 
209  /* shift y1 to y2, result to y1. */
210  b->y2 = b->y1;
211  b->y1 = result;
212 
213  return result;
214 }
215 
216 /* filter types. */
217 enum
218 {
219  VOCLIB_LPF, /* low pass filter */
220  VOCLIB_HPF, /* High pass filter */
221  VOCLIB_BPF, /* band pass filter */
222  VOCLIB_NOTCH, /* Notch Filter */
223  VOCLIB_PEQ, /* Peaking band EQ filter */
224  VOCLIB_LSH, /* Low shelf filter */
225  VOCLIB_HSH /* High shelf filter */
226 };
227 
228 /* sets up a BiQuad Filter. */
229 static void voclib_BiQuad_new ( voclib_biquad* b, int type, float dbGain, /* gain of filter */
230  float freq, /* center frequency */
231  float srate, /* sampling rate */
232  float bandwidth ) /* bandwidth in octaves */
233 {
234  float A, omega, sn, cs, alpha, beta;
235  float a0, a1, a2, b0, b1, b2;
236 
237  /* setup variables. */
238  A = ( float ) pow ( 10, dbGain / 40.0f );
239  omega = ( float ) ( 2.0 * VOCLIB_M_PI * freq / srate );
240  sn = ( float ) sin ( omega );
241  cs = ( float ) cos ( omega );
242  alpha = sn * ( float ) sinh ( VOCLIB_M_LN2 / 2 * bandwidth * omega / sn );
243  beta = ( float ) sqrt ( A + A );
244 
245  switch ( type )
246  {
247  case VOCLIB_LPF:
248  b0 = ( 1 - cs ) / 2;
249  b1 = 1 - cs;
250  b2 = ( 1 - cs ) / 2;
251  a0 = 1 + alpha;
252  a1 = -2 * cs;
253  a2 = 1 - alpha;
254  break;
255  case VOCLIB_HPF:
256  b0 = ( 1 + cs ) / 2;
257  b1 = - ( 1 + cs );
258  b2 = ( 1 + cs ) / 2;
259  a0 = 1 + alpha;
260  a1 = -2 * cs;
261  a2 = 1 - alpha;
262  break;
263  case VOCLIB_BPF:
264  b0 = alpha;
265  b1 = 0;
266  b2 = -alpha;
267  a0 = 1 + alpha;
268  a1 = -2 * cs;
269  a2 = 1 - alpha;
270  break;
271  case VOCLIB_NOTCH:
272  b0 = 1;
273  b1 = -2 * cs;
274  b2 = 1;
275  a0 = 1 + alpha;
276  a1 = -2 * cs;
277  a2 = 1 - alpha;
278  break;
279  case VOCLIB_PEQ:
280  b0 = 1 + ( alpha * A );
281  b1 = -2 * cs;
282  b2 = 1 - ( alpha * A );
283  a0 = 1 + ( alpha / A );
284  a1 = -2 * cs;
285  a2 = 1 - ( alpha / A );
286  break;
287  case VOCLIB_LSH:
288  b0 = A * ( ( A + 1 ) - ( A - 1 ) * cs + beta * sn );
289  b1 = 2 * A * ( ( A - 1 ) - ( A + 1 ) * cs );
290  b2 = A * ( ( A + 1 ) - ( A - 1 ) * cs - beta * sn );
291  a0 = ( A + 1 ) + ( A - 1 ) * cs + beta * sn;
292  a1 = -2 * ( ( A - 1 ) + ( A + 1 ) * cs );
293  a2 = ( A + 1 ) + ( A - 1 ) * cs - beta * sn;
294  break;
295  case VOCLIB_HSH:
296  b0 = A * ( ( A + 1 ) + ( A - 1 ) * cs + beta * sn );
297  b1 = -2 * A * ( ( A - 1 ) + ( A + 1 ) * cs );
298  b2 = A * ( ( A + 1 ) + ( A - 1 ) * cs - beta * sn );
299  a0 = ( A + 1 ) - ( A - 1 ) * cs + beta * sn;
300  a1 = 2 * ( ( A - 1 ) - ( A + 1 ) * cs );
301  a2 = ( A + 1 ) - ( A - 1 ) * cs - beta * sn;
302  break;
303  default:
304  assert ( 0 ); /* Misuse. */
305  return;
306  }
307 
308  /* precompute the coefficients. */
309  b->a0 = b0 / a0;
310  b->a1 = b1 / a0;
311  b->a2 = b2 / a0;
312  b->a3 = a1 / a0;
313  b->a4 = a2 / a0;
314 }
315 
316 /* Reset the filter history. */
317 static void voclib_BiQuad_reset ( voclib_biquad* b )
318 {
319  b->x1 = b->x2 = 0.0f;
320  b->y1 = b->y2 = 0.0f;
321 }
322 
323 /* Envelope follower. */
324 
325 static void voclib_envelope_configure ( voclib_envelope* envelope, double time_in_seconds, double sample_rate )
326 {
327  envelope->coef = ( float ) ( pow ( 0.01, 1.0 / ( time_in_seconds * sample_rate ) ) );
328 }
329 
330 /* Reset the envelope history. */
331 static void voclib_envelope_reset ( voclib_envelope* envelope )
332 {
333  envelope->history[0] = 0.0f;
334  envelope->history[1] = 0.0f;
335  envelope->history[2] = 0.0f;
336  envelope->history[3] = 0.0f;
337 }
338 
339 static VOCLIB_INLINE float voclib_envelope_tick ( voclib_envelope* envelope, float sample )
340 {
341  const float coef = envelope->coef;
342  envelope->history[0] = ( float ) ( ( 1.0f - coef ) * fabs ( sample ) ) + ( coef * envelope->history[0] );
343  envelope->history[1] = ( ( 1.0f - coef ) * envelope->history[0] ) + ( coef * envelope->history[1] );
344  envelope->history[2] = ( ( 1.0f - coef ) * envelope->history[1] ) + ( coef * envelope->history[2] );
345  envelope->history[3] = ( ( 1.0f - coef ) * envelope->history[2] ) + ( coef * envelope->history[3] );
346  return envelope->history[3];
347 }
348 
349 /* Initialize the vocoder filterbank. */
350 static void voclib_initialize_filterbank ( voclib_instance* instance, int carrier_only )
351 {
352  unsigned char i;
353  double step;
354  double lastfreq = 0.0;
355  double minfreq = 80.0;
356  double maxfreq = instance->sample_rate;
357  if ( maxfreq > 12000.0 )
358  {
359  maxfreq = 12000.0;
360  }
361  step = pow ( ( maxfreq / minfreq ), ( 1.0 / instance->bands ) );
362 
363  for ( i = 0; i < instance->bands; ++i )
364  {
365  unsigned char i2;
366  double bandwidth, nextfreq;
367  double priorfreq = lastfreq;
368  if ( lastfreq > 0.0 )
369  {
370  lastfreq *= step;
371  }
372  else
373  {
374  lastfreq = minfreq;
375  }
376  nextfreq = lastfreq * step;
377  bandwidth = ( nextfreq - priorfreq ) / lastfreq;
378 
379  if ( !carrier_only )
380  {
381  voclib_BiQuad_new ( &instance->analysis_bands[i].filters[0], VOCLIB_BPF, 0.0f, ( float ) lastfreq, ( float ) instance->sample_rate, ( float ) bandwidth );
382  for ( i2 = 1; i2 < instance->filters_per_band; ++i2 )
383  {
384  instance->analysis_bands[i].filters[i2].a0 = instance->analysis_bands[i].filters[0].a0;
385  instance->analysis_bands[i].filters[i2].a1 = instance->analysis_bands[i].filters[0].a1;
386  instance->analysis_bands[i].filters[i2].a2 = instance->analysis_bands[i].filters[0].a2;
387  instance->analysis_bands[i].filters[i2].a3 = instance->analysis_bands[i].filters[0].a3;
388  instance->analysis_bands[i].filters[i2].a4 = instance->analysis_bands[i].filters[0].a4;
389  }
390  }
391 
392  if ( instance->formant_shift != 1.0f )
393  {
394  voclib_BiQuad_new ( &instance->synthesis_bands[i].filters[0], VOCLIB_BPF, 0.0f, ( float ) ( lastfreq * instance->formant_shift ), ( float ) instance->sample_rate, ( float ) bandwidth );
395  }
396  else
397  {
398  instance->synthesis_bands[i].filters[0].a0 = instance->analysis_bands[i].filters[0].a0;
399  instance->synthesis_bands[i].filters[0].a1 = instance->analysis_bands[i].filters[0].a1;
400  instance->synthesis_bands[i].filters[0].a2 = instance->analysis_bands[i].filters[0].a2;
401  instance->synthesis_bands[i].filters[0].a3 = instance->analysis_bands[i].filters[0].a3;
402  instance->synthesis_bands[i].filters[0].a4 = instance->analysis_bands[i].filters[0].a4;
403  }
404 
405  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[0].a0 = instance->synthesis_bands[i].filters[0].a0;
406  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[0].a1 = instance->synthesis_bands[i].filters[0].a1;
407  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[0].a2 = instance->synthesis_bands[i].filters[0].a2;
408  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[0].a3 = instance->synthesis_bands[i].filters[0].a3;
409  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[0].a4 = instance->synthesis_bands[i].filters[0].a4;
410 
411  for ( i2 = 1; i2 < instance->filters_per_band; ++i2 )
412  {
413  instance->synthesis_bands[i].filters[i2].a0 = instance->synthesis_bands[i].filters[0].a0;
414  instance->synthesis_bands[i].filters[i2].a1 = instance->synthesis_bands[i].filters[0].a1;
415  instance->synthesis_bands[i].filters[i2].a2 = instance->synthesis_bands[i].filters[0].a2;
416  instance->synthesis_bands[i].filters[i2].a3 = instance->synthesis_bands[i].filters[0].a3;
417  instance->synthesis_bands[i].filters[i2].a4 = instance->synthesis_bands[i].filters[0].a4;
418 
419  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[i2].a0 = instance->synthesis_bands[i].filters[0].a0;
420  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[i2].a1 = instance->synthesis_bands[i].filters[0].a1;
421  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[i2].a2 = instance->synthesis_bands[i].filters[0].a2;
422  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[i2].a3 = instance->synthesis_bands[i].filters[0].a3;
423  instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[i2].a4 = instance->synthesis_bands[i].filters[0].a4;
424  }
425  }
426 
427 }
428 
429 /* Initialize the vocoder envelopes. */
430 static void voclib_initialize_envelopes ( voclib_instance* instance )
431 {
432  unsigned char i;
433 
434  voclib_envelope_configure ( &instance->analysis_envelopes[0], instance->reaction_time, ( double ) instance->sample_rate );
435  for ( i = 1; i < instance->bands; ++i )
436  {
437  instance->analysis_envelopes[i].coef = instance->analysis_envelopes[0].coef;
438  }
439 }
440 
441 int voclib_initialize ( voclib_instance* instance, unsigned char bands, unsigned char filters_per_band, unsigned int sample_rate, unsigned char carrier_channels )
442 {
443  if ( !instance )
444  {
445  return 0;
446  }
447  if ( bands < 4 || bands > VOCLIB_MAX_BANDS )
448  {
449  return 0;
450  }
451  if ( filters_per_band < 1 || filters_per_band > VOCLIB_MAX_FILTERS_PER_BAND )
452  {
453  return 0;
454  }
455  if ( sample_rate < 8000 || sample_rate > 192000 )
456  {
457  return 0;
458  }
459  if ( carrier_channels < 1 || carrier_channels > 2 )
460  {
461  return 0;
462  }
463 
464  instance->reaction_time = 0.03f;
465  instance->formant_shift = 1.0f;
466  instance->sample_rate = sample_rate;
467  instance->bands = bands;
468  instance->filters_per_band = filters_per_band;
469  instance->carrier_channels = carrier_channels;
470 
471  voclib_reset_history ( instance );
472  voclib_initialize_filterbank ( instance, 0 );
473  voclib_initialize_envelopes ( instance );
474 
475  return 1;
476 }
477 
478 void voclib_reset_history ( voclib_instance* instance )
479 {
480  unsigned char i;
481 
482  for ( i = 0; i < instance->bands; ++i )
483  {
484  unsigned char i2;
485 
486  for ( i2 = 0; i2 < instance->filters_per_band; ++i2 )
487  {
488  voclib_BiQuad_reset ( &instance->analysis_bands[i].filters[i2] );
489  voclib_BiQuad_reset ( &instance->synthesis_bands[i].filters[i2] );
490  voclib_BiQuad_reset ( &instance->synthesis_bands[i + VOCLIB_MAX_BANDS].filters[i2] );
491  }
492  voclib_envelope_reset ( &instance->analysis_envelopes[i] );
493  }
494 }
495 
496 int voclib_process ( voclib_instance* instance, const float* carrier_buffer, const float* modulator_buffer, float* output_buffer, unsigned int frames )
497 {
498  unsigned int i;
499  const unsigned char bands = instance->bands;
500  const unsigned char filters_per_band = instance->filters_per_band;
501 
502  if ( !carrier_buffer )
503  {
504  return 0;
505  }
506  if ( !modulator_buffer )
507  {
508  return 0;
509  }
510  if ( !output_buffer )
511  {
512  return 0;
513  }
514  if ( frames == 0 )
515  {
516  return 0;
517  }
518 
519  if ( instance->carrier_channels == 2 )
520  {
521 
522  /* The carrier has two channels and the modulator has 1. */
523  for ( i = 0; i < frames * 2; i += 2, ++modulator_buffer )
524  {
525  unsigned char i2;
526  float out_left = 0.0f;
527  float out_right = 0.0f;
528 
529  /* Run the bands in parallel and accumulate the output. */
530  for ( i2 = 0; i2 < bands; ++i2 )
531  {
532  unsigned char i3;
533  float analysis_band = voclib_BiQuad ( *modulator_buffer, &instance->analysis_bands[i2].filters[0] );
534  float synthesis_band_left = voclib_BiQuad ( carrier_buffer[i], &instance->synthesis_bands[i2].filters[0] );
535  float synthesis_band_right = voclib_BiQuad ( carrier_buffer[i + 1], &instance->synthesis_bands[i2 + VOCLIB_MAX_BANDS].filters[0] );
536 
537  for ( i3 = 1; i3 < filters_per_band; ++i3 )
538  {
539  analysis_band = voclib_BiQuad ( analysis_band, &instance->analysis_bands[i2].filters[i3] );
540  synthesis_band_left = voclib_BiQuad ( synthesis_band_left, &instance->synthesis_bands[i2].filters[i3] );
541  synthesis_band_right = voclib_BiQuad ( synthesis_band_right, &instance->synthesis_bands[i2 + VOCLIB_MAX_BANDS].filters[i3] );
542  }
543  analysis_band = voclib_envelope_tick ( &instance->analysis_envelopes[i2], analysis_band );
544  out_left += synthesis_band_left * analysis_band;
545  out_right += synthesis_band_right * analysis_band;
546  }
547  output_buffer[i] = out_left;
548  output_buffer[i + 1] = out_right;
549  }
550 
551  }
552  else
553  {
554 
555  /* Both the carrier and the modulator have a single channel. */
556  for ( i = 0; i < frames; ++i )
557  {
558  unsigned char i2;
559  float out = 0.0f;
560 
561  /* Run the bands in parallel and accumulate the output. */
562  for ( i2 = 0; i2 < bands; ++i2 )
563  {
564  unsigned char i3;
565  float analysis_band = voclib_BiQuad ( modulator_buffer[i], &instance->analysis_bands[i2].filters[0] );
566  float synthesis_band = voclib_BiQuad ( carrier_buffer[i], &instance->synthesis_bands[i2].filters[0] );
567 
568  for ( i3 = 1; i3 < filters_per_band; ++i3 )
569  {
570  analysis_band = voclib_BiQuad ( analysis_band, &instance->analysis_bands[i2].filters[i3] );
571  synthesis_band = voclib_BiQuad ( synthesis_band, &instance->synthesis_bands[i2].filters[i3] );
572  }
573  analysis_band = voclib_envelope_tick ( &instance->analysis_envelopes[i2], analysis_band );
574  out += synthesis_band * analysis_band;
575  }
576  output_buffer[i] = out;
577  }
578  }
579 
580  return 1;
581 }
582 
583 int voclib_set_reaction_time ( voclib_instance* instance, float reaction_time )
584 {
585  if ( reaction_time < 0.002f || reaction_time > 2.0f )
586  {
587  return 0;
588  }
589 
590  instance->reaction_time = reaction_time;
591  voclib_initialize_envelopes ( instance );
592  return 1;
593 }
594 
595 float voclib_get_reaction_time ( const voclib_instance* instance )
596 {
597  return instance->reaction_time;
598 }
599 
600 int voclib_set_formant_shift ( voclib_instance* instance, float formant_shift )
601 {
602  if ( formant_shift < 0.25f || formant_shift > 4.0f )
603  {
604  return 0;
605  }
606 
607  instance->formant_shift = formant_shift;
608  voclib_initialize_filterbank ( instance, 1 );
609  return 1;
610 }
611 
612 float voclib_get_formant_shift ( const voclib_instance* instance )
613 {
614  return instance->formant_shift;
615 }
616 
617 #endif /* VOCLIB_IMPLEMENTATION */
618 
619 /* REVISION HISTORY
620 *
621 * Version 1.1 - 2019-02-16
622 * Breaking change: Introduced a new argument to voclib_initialize called carrier_channels. This allows the vocoder to output stereo natively.
623 * Better assignment of band frequencies when using lower sample rates.
624 * The shell now automatically normalizes the output file to match the peak amplitude in the carrier.
625 * Fixed a memory corruption bug in the shell which would occur in response to an error condition.
626 *
627 * Version 1.0 - 2019-01-27
628 * Initial release.
629 */
630 
631 /* LICENSE
632 
633 This software is available under 2 licenses -- choose whichever you prefer.
634 ------------------------------------------------------------------------------
635 ALTERNATIVE A - MIT No Attribution License
636 Copyright (c) 2019 Philip Bennefall
637 
638 Permission is hereby granted, free of charge, to any person obtaining a copy of
639 this software and associated documentation files (the "Software"), to deal in
640 the Software without restriction, including without limitation the rights to
641 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
642 of the Software, and to permit persons to whom the Software is furnished to do
643 so.
644 
645 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
646 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
647 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
648 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
649 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
650 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
651 SOFTWARE.
652 ------------------------------------------------------------------------------
653 ALTERNATIVE B - Public Domain (www.unlicense.org)
654 This is free and unencumbered software released into the public domain.
655 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
656 software, either in source code form or as a compiled binary, for any purpose,
657 commercial or non-commercial, and by any means.
658 
659 In jurisdictions that recognize copyright laws, the author or authors of this
660 software dedicate any and all copyright interest in the software to the public
661 domain. We make this dedication for the benefit of the public at large and to
662 the detriment of our heirs and successors. We intend this dedication to be an
663 overt act of relinquishment in perpetuity of all present and future rights to
664 this software under copyright law.
665 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
666 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
667 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
668 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
669 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
670 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
671 ------------------------------------------------------------------------------
672 */
voclib_instance::bands
unsigned char bands
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:136
voclib_get_formant_shift
float voclib_get_formant_shift(const voclib_instance *instance)
voclib_biquad::a4
float a4
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:110
voclib_biquad::x2
float x2
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:111
VOCLIB_MAX_FILTERS_PER_BAND
#define VOCLIB_MAX_FILTERS_PER_BAND
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:31
voclib_biquad::a2
float a2
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:110
voclib_envelope::history
float history[4]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:118
voclib_reset_history
void voclib_reset_history(voclib_instance *instance)
voclib_initialize
int voclib_initialize(voclib_instance *instance, unsigned char bands, unsigned char filters_per_band, unsigned int sample_rate, unsigned char carrier_channels)
voclib_biquad::y2
float y2
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:111
voclib_instance::reaction_time
float reaction_time
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:133
voclib_get_reaction_time
float voclib_get_reaction_time(const voclib_instance *instance)
voclib_instance::synthesis_bands
voclib_band synthesis_bands[VOCLIB_MAX_BANDS *2]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:132
voclib_band
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:122
voclib_instance::analysis_bands
voclib_band analysis_bands[VOCLIB_MAX_BANDS]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:130
voclib_biquad::a0
float a0
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:110
voclib_envelope
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:115
voclib_biquad::a3
float a3
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:110
voclib_biquad::x1
float x1
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:111
VOCLIB_MAX_BANDS
#define VOCLIB_MAX_BANDS
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:28
voclib_band::filters
voclib_biquad filters[VOCLIB_MAX_FILTERS_PER_BAND]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:124
voclib_process
int voclib_process(voclib_instance *instance, const float *carrier_buffer, const float *modulator_buffer, float *output_buffer, unsigned int frames)
voclib_set_formant_shift
int voclib_set_formant_shift(voclib_instance *instance, float formant_shift)
voclib_biquad
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:108
voclib_instance
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:128
voclib_biquad::a1
float a1
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:110
voclib_instance::formant_shift
float formant_shift
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:134
voclib_set_reaction_time
int voclib_set_reaction_time(voclib_instance *instance, float reaction_time)
voclib_instance::filters_per_band
unsigned char filters_per_band
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:137
voclib_instance::sample_rate
unsigned int sample_rate
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:135
assert.h
voclib_instance::analysis_envelopes
voclib_envelope analysis_envelopes[VOCLIB_MAX_BANDS]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:131
voclib_envelope::coef
float coef
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:117
voclib_biquad::y1
float y1
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:111
voclib_instance::carrier_channels
unsigned char carrier_channels
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/voclib.h:138


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:14:55