RTS API Documentation  1.10.11
switch_resample.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  *
28  *
29  * switch_resample.c -- Resampler
30  *
31  */
32 
33 #include <switch.h>
34 #include <switch_resample.h>
35 #ifndef WIN32
36 #include <switch_private.h>
37 #endif
38 #include <speex/speex_resampler.h>
39 
40 #define NORMFACT (float)0x8000
41 #define MAXSAMPLE (float)0x7FFF
42 #define MAXSAMPLEC (char)0x7F
43 #define QUALITY 0
44 
45 #ifndef MIN
46 #define MIN(a,b) ((a) < (b) ? (a) : (b))
47 #endif
48 
49 #ifndef MAX
50 #define MAX(a,b) ((a) > (b) ? (a) : (b))
51 #endif
52 
53 #define resample_buffer(a, b, c) a > b ? ((a / 1000) / 2) * c : ((b / 1000) / 2) * c
54 
56  uint32_t from_rate, uint32_t to_rate,
57  uint32_t to_size,
58  int quality, uint32_t channels, const char *file, const char *func, int line)
59 {
60  int err = 0;
61  switch_audio_resampler_t *resampler;
62  double lto_rate, lfrom_rate;
63 
64  switch_zmalloc(resampler, sizeof(*resampler));
65 
66  if (!channels) channels = 1;
67 
68  resampler->resampler = speex_resampler_init(channels, from_rate, to_rate, quality, &err);
69 
70  if (!resampler->resampler) {
71  free(resampler);
72  return SWITCH_STATUS_GENERR;
73  }
74 
75  *new_resampler = resampler;
76  lto_rate = (double) resampler->to_rate;
77  lfrom_rate = (double) resampler->from_rate;
78  resampler->from_rate = from_rate;
79  resampler->to_rate = to_rate;
80  resampler->factor = (lto_rate / lfrom_rate);
81  resampler->rfactor = (lfrom_rate / lto_rate);
82  resampler->channels = channels;
83 
84  //resampler->to_size = resample_buffer(to_rate, from_rate, (uint32_t) to_size);
85 
86  resampler->to_size = switch_resample_calc_buffer_size(resampler->to_rate, resampler->from_rate, to_size) / 2;
87  resampler->to = malloc(resampler->to_size * sizeof(int16_t) * resampler->channels);
88  switch_assert(resampler->to);
89 
90  return SWITCH_STATUS_SUCCESS;
91 }
92 
93 SWITCH_DECLARE(uint32_t) switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
94 {
95  int to_size = switch_resample_calc_buffer_size(resampler->to_rate, resampler->from_rate, srclen) / 2;
96 
97  if (to_size > resampler->to_size) {
98  resampler->to_size = to_size;
99  resampler->to = realloc(resampler->to, resampler->to_size * sizeof(int16_t) * resampler->channels);
100  switch_assert(resampler->to);
101  }
102 
103  resampler->to_len = resampler->to_size;
104  speex_resampler_process_interleaved_int(resampler->resampler, src, &srclen, resampler->to, &resampler->to_len);
105  return resampler->to_len;
106 }
107 
109 {
110 
111  if (resampler && *resampler) {
112  if ((*resampler)->resampler) {
113  speex_resampler_destroy((*resampler)->resampler);
114  }
115  free((*resampler)->to);
116  free(*resampler);
117  *resampler = NULL;
118  }
119 }
120 
122 {
123  switch_size_t i;
124  float ft;
125  for (i = 0; i < len; i++) {
126  ft = f[i] * NORMFACT;
127  if (ft >= 0) {
128  s[i] = (short) (ft + 0.5);
129  } else {
130  s[i] = (short) (ft - 0.5);
131  }
132  if ((float) s[i] > MAXSAMPLE)
133  s[i] = (short) MAXSAMPLE / 2;
134  if (s[i] < (short) -MAXSAMPLE)
135  s[i] = (short) -MAXSAMPLE / 2;
136  }
137  return len;
138 }
139 
140 SWITCH_DECLARE(int) switch_char_to_float(char *c, float *f, int len)
141 {
142  int i;
143 
144  if (len % 2) {
145  return (-1);
146  }
147 
148  for (i = 1; i < len; i += 2) {
149  f[(int) (i / 2)] = (float) (((c[i]) * 0x100) + c[i - 1]);
150  f[(int) (i / 2)] /= NORMFACT;
151  if (f[(int) (i / 2)] > MAXSAMPLE)
152  f[(int) (i / 2)] = MAXSAMPLE;
153  if (f[(int) (i / 2)] < -MAXSAMPLE)
154  f[(int) (i / 2)] = -MAXSAMPLE;
155  }
156  return len / 2;
157 }
158 
159 SWITCH_DECLARE(int) switch_float_to_char(float *f, char *c, int len)
160 {
161  int i;
162  float ft;
163  long l;
164  for (i = 0; i < len; i++) {
165  ft = f[i] * NORMFACT;
166  if (ft >= 0) {
167  l = (long) (ft + 0.5);
168  } else {
169  l = (long) (ft - 0.5);
170  }
171  c[i * 2] = (unsigned char) ((l) & 0xff);
172  c[i * 2 + 1] = (unsigned char) (((l) >> 8) & 0xff);
173  }
174  return len * 2;
175 }
176 
177 SWITCH_DECLARE(int) switch_short_to_float(short *s, float *f, int len)
178 {
179  int i;
180 
181  for (i = 0; i < len; i++) {
182  f[i] = (float) (s[i]) / NORMFACT;
183  /* f[i] = (float) s[i]; */
184  }
185  return len;
186 }
187 
188 
189 SWITCH_DECLARE(void) switch_swap_linear(int16_t *buf, int len)
190 {
191  int i;
192  for (i = 0; i < len; i++) {
193  buf[i] = ((buf[i] >> 8) & 0x00ff) | ((buf[i] << 8) & 0xff00);
194  }
195 }
196 
197 
198 SWITCH_DECLARE(void) switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t channels, uint32_t divisor)
199 {
200  int16_t s;
201  uint32_t x, i, j;
202  int sum_rnd = 0;
203  int16_t rnd2 = (int16_t) switch_micro_time_now() + (int16_t) (intptr_t) data;
204 
205  if (channels == 0) channels = 1;
206 
207  assert(divisor);
208 
209  if (divisor == (uint32_t)-1) {
210  memset(data, 0, samples * 2);
211  return;
212  }
213 
214  for (i = 0; i < samples; i++, sum_rnd = 0) {
215  for (x = 0; x < 6; x++) {
216  rnd2 = rnd2 * 31821U + 13849U;
217  sum_rnd += rnd2;
218  }
219 
220  s = (int16_t) ((int16_t) sum_rnd / (int) divisor);
221 
222  for (j = 0; j < channels; j++) {
223  *data = s;
224  data++;
225  }
226 
227 
228  }
229 }
230 
231 SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels)
232 {
233  int i;
234  int32_t x, z;
235 
236  if (channels == 0) channels = 1;
237 
238  if (samples > other_samples) {
239  x = other_samples;
240  } else {
241  x = samples;
242  }
243 
244  for (i = 0; i < x * channels; i++) {
245  z = data[i] + other_data[i];
247  data[i] = (int16_t) z;
248  }
249 
250  return x;
251 }
252 
253 
254 SWITCH_DECLARE(uint32_t) switch_unmerge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels)
255 {
256  int i;
257  int32_t x;
258 
259  if (channels == 0) channels = 1;
260 
261  if (samples > other_samples) {
262  x = other_samples;
263  } else {
264  x = samples;
265  }
266 
267  for (i = 0; i < x * channels; i++) {
268  data[i] -= other_data[i];
269  }
270 
271  return x;
272 }
273 
274 SWITCH_DECLARE(void) switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
275 {
276  switch_size_t i = 0;
277  uint32_t j = 0;
278 
279  switch_assert(channels < 11);
280 
281  if (orig_channels > channels) {
282  if (channels == 1) {
283  for (i = 0; i < samples; i++) {
284  int32_t z = 0;
285  for (j = 0; j < orig_channels; j++) {
286  z += (int16_t) data[i * orig_channels + j];
287  }
289  data[i] = (int16_t) z;
290  }
291  } else if (channels == 2) {
292  int mark_buf = 0;
293  for (i = 0; i < samples; i++) {
294  int32_t z_left = 0, z_right = 0;
295  for (j = 0; j < orig_channels; j++) {
296  if (j % 2) {
297  z_left += (int16_t) data[i * orig_channels + j];
298  } else {
299  z_right += (int16_t) data[i * orig_channels + j];
300  }
301  }
302  /* mark_buf will always be smaller than the size of data in bytes because orig_channels > channels */
304  data[mark_buf++] = (int16_t) z_left;
305  switch_normalize_to_16bit(z_right);
306  data[mark_buf++] = (int16_t) z_right;
307  }
308  }
309  } else if (orig_channels < channels) {
310 
311  /* interesting problem... take a give buffer and double up every sample in the buffer without using any other buffer.....
312  This way beats the other i think bacause there is no malloc but I do have to copy the data twice */
313 #if 1
314  uint32_t k = 0, len = samples * orig_channels;
315 
316  for (i = 0; i < len; i++) {
317  data[i+len] = data[i];
318  }
319 
320  for (i = 0; i < samples; i++) {
321  for (j = 0; j < channels; j++) {
322  data[k++] = data[i + samples];
323  }
324  }
325 
326 #else
327  uint32_t k = 0, len = samples * 2 * orig_channels;
328  int16_t *orig = NULL;
329 
330  switch_zmalloc(orig, len);
331  memcpy(orig, data, len);
332 
333  for (i = 0; i < samples; i++) {
334  for (j = 0; j < channels; j++) {
335  data[k++] = orig[i];
336  }
337  }
338 
339  free(orig);
340 #endif
341 
342  }
343 }
344 
345 SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t samples, int32_t vol)
346 {
347  double newrate = 0;
348  // change in dB mapped to ratio for output sample
349  // computed as (powf(10.0f, (float)(change_in_dB) / 20.0f))
350  static const double pos[SWITCH_GRANULAR_VOLUME_MAX] = {
351  1.122018, 1.258925, 1.412538, 1.584893, 1.778279, 1.995262, 2.238721, 2.511887, 2.818383, 3.162278,
352  3.548134, 3.981072, 4.466835, 5.011872, 5.623413, 6.309574, 7.079458, 7.943282, 8.912509, 10.000000,
353  11.220183, 12.589254, 14.125375, 15.848933, 17.782795, 19.952621, 22.387213, 25.118862, 28.183832, 31.622776,
354  35.481335, 39.810719, 44.668358, 50.118729, 56.234131, 63.095726, 70.794586, 79.432816, 89.125107, 100.000000,
355  112.201836, 125.892517, 141.253784, 158.489334, 177.827942, 199.526215, 223.872070, 251.188705, 281.838318, 316.227753
356  };
357  static const double neg[SWITCH_GRANULAR_VOLUME_MAX] = {
358  0.891251, 0.794328, 0.707946, 0.630957, 0.562341, 0.501187, 0.446684, 0.398107, 0.354813, 0.316228,
359  0.281838, 0.251189, 0.223872, 0.199526, 0.177828, 0.158489, 0.141254, 0.125893, 0.112202, 0.100000,
360  0.089125, 0.079433, 0.070795, 0.063096, 0.056234, 0.050119, 0.044668, 0.039811, 0.035481, 0.031623,
361  0.028184, 0.025119, 0.022387, 0.019953, 0.017783, 0.015849, 0.014125, 0.012589, 0.011220, 0.010000,
362  0.008913, 0.007943, 0.007079, 0.006310, 0.005623, 0.005012, 0.004467, 0.003981, 0.003548, 0.000000 // NOTE mapped -50 dB ratio to total silence instead of 0.003162
363  };
364  const double *chart;
365  uint32_t i;
366 
367  if (vol == 0) return;
368 
370 
371  if (vol > 0) {
372  chart = pos;
373  } else {
374  chart = neg;
375  }
376 
377  i = abs(vol) - 1;
378 
380 
381  newrate = chart[i];
382 
383  if (newrate) {
384  int32_t tmp;
385  uint32_t x;
386  int16_t *fp = data;
387 
388  for (x = 0; x < samples; x++) {
389  tmp = (int32_t) (fp[x] * newrate);
391  fp[x] = (int16_t) tmp;
392  }
393  } else {
394  memset(data, 0, samples * 2);
395  }
396 }
397 
398 SWITCH_DECLARE(void) switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol)
399 {
400  double newrate = 0;
401  double pos[4] = {1.3, 2.3, 3.3, 4.3};
402  double neg[4] = {.80, .60, .40, .20};
403  double *chart;
404  uint32_t i;
405 
406  if (vol == 0) return;
407 
409 
410  if (vol > 0) {
411  chart = pos;
412  } else {
413  chart = neg;
414  }
415 
416  i = abs(vol) - 1;
417 
418  switch_assert(i < 4);
419 
420  newrate = chart[i];
421 
422  if (newrate) {
423  int32_t tmp;
424  uint32_t x;
425  int16_t *fp = data;
426 
427  for (x = 0; x < samples; x++) {
428  tmp = (int32_t) (fp[x] * newrate);
430  fp[x] = (int16_t) tmp;
431  }
432  }
433 }
434 
435 struct switch_agc_s {
437  uint32_t energy_avg;
438  uint32_t margin;
439  uint32_t change_factor;
440  char *token;
441  int vol;
442  uint32_t score;
443  uint32_t score_count;
444  uint32_t score_sum;
445  uint32_t score_avg;
446  uint32_t score_over;
447  uint32_t score_under;
448  uint32_t period_len;
450 };
451 
452 
454  uint32_t low_energy_point, uint32_t margin, uint32_t change_factor, uint32_t period_len)
455 {
456  agc->energy_avg = energy_avg;
457  agc->margin = margin;
459  agc->period_len = period_len;
461 
462  agc->score = 0;
463  agc->score_count = 0;
464  agc->score_sum = 0;
465  agc->score_avg = 0;
466  agc->score_over = 0;
467  agc->score_under = 0;
468 }
469 
471  uint32_t low_energy_point, uint32_t margin, uint32_t change_factor, uint32_t period_len)
472 {
473  switch_agc_t *agc;
475  char id[80] = "";
476 
477  switch_assert(agcP);
478 
480 
481  agc = switch_core_alloc(pool, sizeof(*agc));
482  agc->pool = pool;
483 
484  switch_agc_set(agc, energy_avg, low_energy_point, margin, change_factor, period_len);
485 
486 
487  switch_snprintf(id, sizeof(id), "%p", (void *)agc);
488  switch_agc_set_token(agc, id);
489 
490  *agcP = agc;
491 
492  return SWITCH_STATUS_SUCCESS;
493 }
494 
496 {
497  switch_agc_t *agc;
498 
499  switch_assert(agcP);
500 
501  agc = *agcP;
502  *agcP = NULL;
503 
504  if (agc) {
507  }
508 }
509 
511 {
512  switch_assert(agc);
513 
514  agc->energy_avg = energy_avg;
515 }
516 
518 {
519  switch_assert(agc);
520 
522 }
523 
525 {
526  agc->token = switch_core_strdup(agc->pool, token);
527 }
528 
529 SWITCH_DECLARE(switch_status_t) switch_agc_feed(switch_agc_t *agc, int16_t *data, uint32_t samples, uint32_t channels)
530 {
531 
532  if (!channels) channels = 1;
533 
534  if (agc->vol) {
535  switch_change_sln_volume_granular(data, samples * channels, agc->vol);
536  }
537 
538  if (agc->energy_avg) {
539  uint32_t energy = 0;
540  int i;
541 
542  for (i = 0; i < samples * channels; i++) {
543  energy += abs(data[i]);
544  }
545 
546  if (samples) {
547  agc->score = energy / samples * channels;
548  }
549  agc->score_sum += agc->score;
550  agc->score_count++;
551 
552  if (agc->score_count > agc->period_len) {
553 
554  agc->score_avg = (int)((double)agc->score_sum / agc->score_count);
555  agc->score_count = 0;
556  agc->score_sum = 0;
557 
558  if (agc->score_avg > agc->energy_avg) {
559  if (agc->score_avg - agc->energy_avg > agc->margin) {
560  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "[%s] OVER++ SCORE AVG: %d ENERGY AVG: %d MARGIN: %d\n",
561  agc->token, agc->score_avg, agc->energy_avg, agc->margin);
562  agc->score_over++;
563  } else {
564  agc->score_over = 0;
565  }
566  } else {
567  agc->score_over = 0;
568  }
569 
570  if (agc->score_avg < agc->low_energy_point) {
571  agc->score_under = agc->change_factor + 1;
572  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "[%s] BELOW LOW POINT, SCORE AVG: %d ENERGY AVG: %d MARGIN: %d\n",
573  agc->token, agc->score_avg, agc->energy_avg, agc->margin);
574  } else if (((agc->score_avg < agc->energy_avg) && (agc->energy_avg - agc->score_avg > agc->margin))) {
575  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "[%s] UNDER++ SCORE AVG: %d ENERGY AVG: %d MARGIN: %d\n",
576  agc->token, agc->score_avg, agc->energy_avg, agc->margin);
577  agc->score_under++;
578  } else {
579  agc->score_under = 0;
580  }
581 
582  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "[%s] AVG %d over: %d under: %d\n",
583  agc->token, agc->score_avg, agc->score_over, agc->score_under);
584 
585  if (agc->score_over > agc->change_factor) {
586  agc->vol--;
588  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "[%s] VOL DOWN %d\n", agc->token, agc->vol);
589  //agc->score_over = 0;
590  } else if (agc->score_under > agc->change_factor) {
591  agc->vol++;
593  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "[%s] VOL UP %d\n", agc->token, agc->vol);
594  //agc->score_under = 0;
595  }
596 
597  }
598 
599  }
600 
601  return SWITCH_STATUS_SUCCESS;
602 }
603 
604 
605 /* For Emacs:
606  * Local Variables:
607  * mode:c
608  * indent-tabs-mode:t
609  * tab-width:4
610  * c-basic-offset:4
611  * End:
612  * For VIM:
613  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
614  */
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:311
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
#define MAXSAMPLE
uint32_t period_len
#define SWITCH_CHANNEL_LOG
uint32_t score_sum
int switch_char_to_float(char *c, float *f, int len)
Convert an array of chars to an array of floats.
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
void switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t channels, uint32_t divisor)
Generate static noise.
void switch_agc_set_token(switch_agc_t *agc, const char *token)
#define SWITCH_GRANULAR_VOLUME_MAX
#define switch_resample_calc_buffer_size(_to, _from, _srclen)
void switch_resample_destroy(switch_audio_resampler_t **resampler)
Destroy an existing resampler handle.
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
void switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol)
Change the volume of a signed linear audio frame.
switch_memory_pool_t * pool
#define switch_normalize_volume_granular(x)
uint32_t score_count
switch_byte_t switch_byte_t * buf
#define NORMFACT
#define switch_normalize_volume(x)
uint32_t change_factor
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
switch_size_t switch_float_to_short(float *f, short *s, switch_size_t len)
Convert an array of floats to an array of shorts.
#define switch_zmalloc(ptr, len)
switch_status_t switch_resample_perform_create(switch_audio_resampler_t **new_resampler, uint32_t from_rate, uint32_t to_rate, uint32_t to_size, int quality, uint32_t channels, const char *file, const char *func, int line)
Prepare a new resampler handle.
uint32_t switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels)
int switch_short_to_float(short *s, float *f, int len)
Convert an array of shorts to an array of floats.
void switch_agc_set_energy_low(switch_agc_t *agc, uint32_t low_energy_point)
uintptr_t switch_size_t
uint32_t energy_avg
void switch_swap_linear(int16_t *buf, int len)
Perform a byteswap on a buffer of 16 bit samples.
uint32_t switch_unmerge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels)
uint32_t low_energy_point
int switch_float_to_char(float *f, char *c, int len)
Convert an array of floats to an array of chars.
An audio resampling handle.
switch_status_t
Common return values.
void switch_change_sln_volume_granular(int16_t *data, uint32_t samples, int32_t vol)
Change the volume of a signed linear audio frame with more granularity.
void switch_agc_set_energy_avg(switch_agc_t *agc, uint32_t energy_avg)
Main Library Header.
#define SWITCH_DECLARE(type)
uint32_t score_avg
switch_status_t switch_agc_feed(switch_agc_t *agc, int16_t *data, uint32_t samples, uint32_t channels)
switch_status_t switch_agc_create(switch_agc_t **agcP, uint32_t energy_avg, uint32_t low_energy_point, uint32_t margin, uint32_t change_factor, uint32_t period_len)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_normalize_to_16bit(n)
Definition: switch_utils.h:292
struct fspr_pool_t switch_memory_pool_t
uint32_t score_over
Audio Resample Code.
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
void switch_agc_destroy(switch_agc_t **agcP)
#define switch_assert(expr)
uint32_t score_under
memset(buf, 0, buflen)
uint32_t switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
Resample one float buffer into another using specifications of a given handle.
void switch_agc_set(switch_agc_t *agc, uint32_t energy_avg, uint32_t low_energy_point, uint32_t margin, uint32_t change_factor, uint32_t period_len)