FreeSWITCH API Documentation  1.7.0
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  for (i = 0; i < samples; i++) {
283  int32_t z = 0;
284  for (j = 0; j < orig_channels; j++) {
285  z += data[i * orig_channels + j];
287  data[i] = (int16_t) z;
288  }
289  }
290  } else if (orig_channels < channels) {
291 
292  /* interesting problem... take a give buffer and double up every sample in the buffer without using any other buffer.....
293  This way beats the other i think bacause there is no malloc but I do have to copy the data twice */
294 #if 1
295  uint32_t k = 0, len = samples * orig_channels;
296 
297  for (i = 0; i < len; i++) {
298  data[i+len] = data[i];
299  }
300 
301  for (i = 0; i < samples; i++) {
302  for (j = 0; j < channels; j++) {
303  data[k++] = data[i + samples];
304  }
305  }
306 
307 #else
308  uint32_t k = 0, len = samples * 2 * orig_channels;
309  int16_t *orig = NULL;
310 
311  switch_zmalloc(orig, len);
312  memcpy(orig, data, len);
313 
314  for (i = 0; i < samples; i++) {
315  for (j = 0; j < channels; j++) {
316  data[k++] = orig[i];
317  }
318  }
319 
320  free(orig);
321 #endif
322 
323  }
324 }
325 
326 SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t samples, int32_t vol)
327 {
328  double newrate = 0;
329  double pos[13] = {1.25, 1.50, 1.75, 2.0, 2.25, 2.50, 2.75, 3.0, 3.25, 3.50, 3.75, 4.0, 4.5};
330  double neg[13] = {.917, .834, .751, .668, .585, .502, .419, .336, .253, .087, .017, .004, 0.0};
331  double *chart;
332  uint32_t i;
333 
334  if (vol == 0) return;
335 
337 
338  if (vol > 0) {
339  chart = pos;
340  } else {
341  chart = neg;
342  }
343 
344  i = abs(vol) - 1;
345 
346  switch_assert(i < 13);
347 
348  newrate = chart[i];
349 
350  if (newrate) {
351  int32_t tmp;
352  uint32_t x;
353  int16_t *fp = data;
354 
355  for (x = 0; x < samples; x++) {
356  tmp = (int32_t) (fp[x] * newrate);
358  fp[x] = (int16_t) tmp;
359  }
360  } else {
361  memset(data, 0, samples * 2);
362  }
363 }
364 
365 SWITCH_DECLARE(void) switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol)
366 {
367  double newrate = 0;
368  double pos[4] = {1.3, 2.3, 3.3, 4.3};
369  double neg[4] = {.80, .60, .40, .20};
370  double *chart;
371  uint32_t i;
372 
373  if (vol == 0) return;
374 
376 
377  if (vol > 0) {
378  chart = pos;
379  } else {
380  chart = neg;
381  }
382 
383  i = abs(vol) - 1;
384 
385  switch_assert(i < 4);
386 
387  newrate = chart[i];
388 
389  if (newrate) {
390  int32_t tmp;
391  uint32_t x;
392  int16_t *fp = data;
393 
394  for (x = 0; x < samples; x++) {
395  tmp = (int32_t) (fp[x] * newrate);
397  fp[x] = (int16_t) tmp;
398  }
399  }
400 }
401 
402 /* For Emacs:
403  * Local Variables:
404  * mode:c
405  * indent-tabs-mode:t
406  * tab-width:4
407  * c-basic-offset:4
408  * End:
409  * For VIM:
410  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
411  */
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
#define MAXSAMPLE
int switch_char_to_float(char *c, float *f, int len)
Convert an array of chars to an array of floats.
void switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t channels, uint32_t divisor)
Generate static noise.
#define switch_resample_calc_buffer_size(_to, _from, _srclen)
void switch_resample_destroy(switch_audio_resampler_t **resampler)
Destroy an existing resampler handle.
void switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol)
Change the volume of a signed linear audio frame.
#define switch_normalize_volume_granular(x)
switch_byte_t switch_byte_t * buf
#define NORMFACT
#define switch_normalize_volume(x)
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.
uintptr_t switch_size_t
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)
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.
Main Library Header.
#define SWITCH_DECLARE(type)
#define switch_normalize_to_16bit(n)
Definition: switch_utils.h:261
Audio Resample Code.
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
#define switch_assert(expr)
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.