blob: 969563abe871d2146609b8f5e7ee8518b8ff0493 [file] [log] [blame]
Emeric Vigiereebea672012-08-06 17:36:30 -04001/*
2** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
3**
4** This program is free software; you can redistribute it and/or modify
5** it under the terms of the GNU General Public License as published by
6** the Free Software Foundation; either version 2 of the License, or
7** (at your option) any later version.
8**
9** This program is distributed in the hope that it will be useful,
10** but WITHOUT ANY WARRANTY; without even the implied warranty of
11** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12** GNU General Public License for more details.
13**
14** You should have received a copy of the GNU General Public License
15** along with this program; if not, write to the Free Software
16** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17*/
18
19/*
20** This code is part of Secret Rabbit Code aka libsamplerate. A commercial
21** use license for this code is available, please see:
22** http://www.mega-nerd.com/SRC/procedure.html
23*/
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
29#include "config.h"
30
31#include "samplerate.h"
32#include "float_cast.h"
33#include "common.h"
34
35static int psrc_set_converter (SRC_PRIVATE *psrc, int converter_type) ;
36
37
38static inline int
39is_bad_src_ratio (double ratio)
40{ return (ratio < (1.0 / SRC_MAX_RATIO) || ratio > (1.0 * SRC_MAX_RATIO)) ;
41} /* is_bad_src_ratio */
42
43SRC_STATE *
44src_new (int converter_type, int channels, int *error)
45{ SRC_PRIVATE *psrc ;
46
47 if (error)
48 *error = SRC_ERR_NO_ERROR ;
49
50 if (channels < 1)
51 { if (error)
52 *error = SRC_ERR_BAD_CHANNEL_COUNT ;
53 return NULL ;
54 } ;
55
56 if ((psrc = calloc (1, sizeof (*psrc))) == NULL)
57 { if (error)
58 *error = SRC_ERR_MALLOC_FAILED ;
59 return NULL ;
60 } ;
61
62 psrc->channels = channels ;
63 psrc->mode = SRC_MODE_PROCESS ;
64
65 if (psrc_set_converter (psrc, converter_type) != SRC_ERR_NO_ERROR)
66 { if (error)
67 *error = SRC_ERR_BAD_CONVERTER ;
68 free (psrc) ;
69 psrc = NULL ;
70 } ;
71
72 src_reset ((SRC_STATE*) psrc) ;
73
74 return (SRC_STATE*) psrc ;
75} /* src_new */
76
77SRC_STATE*
78src_callback_new (src_callback_t func, int converter_type, int channels, int *error, void* cb_data)
79{ SRC_STATE *src_state ;
80
81 if (func == NULL)
82 { if (error)
83 *error = SRC_ERR_BAD_CALLBACK ;
84 return NULL ;
85 } ;
86
87 if (error != NULL)
88 *error = 0 ;
89
90 if ((src_state = src_new (converter_type, channels, error)) == NULL)
91 return NULL ;
92
93 src_reset (src_state) ;
94
95 ((SRC_PRIVATE*) src_state)->mode = SRC_MODE_CALLBACK ;
96 ((SRC_PRIVATE*) src_state)->callback_func = func ;
97 ((SRC_PRIVATE*) src_state)->user_callback_data = cb_data ;
98
99 return src_state ;
100} /* src_callback_new */
101
102SRC_STATE *
103src_delete (SRC_STATE *state)
104{ SRC_PRIVATE *psrc ;
105
106 psrc = (SRC_PRIVATE*) state ;
107 if (psrc)
108 { if (psrc->private_data)
109 free (psrc->private_data) ;
110 memset (psrc, 0, sizeof (SRC_PRIVATE)) ;
111 free (psrc) ;
112 } ;
113
114 return NULL ;
115} /* src_state */
116
117int
118src_process (SRC_STATE *state, SRC_DATA *data)
119{ SRC_PRIVATE *psrc ;
120 int error ;
121
122 psrc = (SRC_PRIVATE*) state ;
123
124 if (psrc == NULL)
125 return SRC_ERR_BAD_STATE ;
126 if (psrc->vari_process == NULL || psrc->const_process == NULL)
127 return SRC_ERR_BAD_PROC_PTR ;
128
129 if (psrc->mode != SRC_MODE_PROCESS)
130 return SRC_ERR_BAD_MODE ;
131
132 /* Check for valid SRC_DATA first. */
133 if (data == NULL)
134 return SRC_ERR_BAD_DATA ;
135
136 /* And that data_in and data_out are valid. */
137 if (data->data_in == NULL || data->data_out == NULL)
138 return SRC_ERR_BAD_DATA_PTR ;
139
140 /* Check src_ratio is in range. */
141 if (is_bad_src_ratio (data->src_ratio))
142 return SRC_ERR_BAD_SRC_RATIO ;
143
144 if (data->input_frames < 0)
145 data->input_frames = 0 ;
146 if (data->output_frames < 0)
147 data->output_frames = 0 ;
148
149 if (data->data_in < data->data_out)
150 { if (data->data_in + data->input_frames * psrc->channels > data->data_out)
151 { /*-printf ("\n\ndata_in: %p data_out: %p\n",
152 (void*) (data->data_in + data->input_frames * psrc->channels), (void*) data->data_out) ;-*/
153 return SRC_ERR_DATA_OVERLAP ;
154 } ;
155 }
156 else if (data->data_out + data->output_frames * psrc->channels > data->data_in)
157 { /*-printf ("\n\ndata_in : %p ouput frames: %ld data_out: %p\n", (void*) data->data_in, data->output_frames, (void*) data->data_out) ;
158
159 printf ("data_out: %p (%p) data_in: %p\n", (void*) data->data_out,
160 (void*) (data->data_out + data->input_frames * psrc->channels), (void*) data->data_in) ;-*/
161 return SRC_ERR_DATA_OVERLAP ;
162 } ;
163
164 /* Set the input and output counts to zero. */
165 data->input_frames_used = 0 ;
166 data->output_frames_gen = 0 ;
167
168 /* Special case for when last_ratio has not been set. */
169 if (psrc->last_ratio < (1.0 / SRC_MAX_RATIO))
170 psrc->last_ratio = data->src_ratio ;
171
172 /* Now process. */
173 if (fabs (psrc->last_ratio - data->src_ratio) < 1e-15)
174 error = psrc->const_process (psrc, data) ;
175 else
176 error = psrc->vari_process (psrc, data) ;
177
178 return error ;
179} /* src_process */
180
181long
182src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data)
183{ SRC_PRIVATE *psrc ;
184 SRC_DATA src_data ;
185
186 long output_frames_gen ;
187 int error = 0 ;
188
189 if (state == NULL)
190 return 0 ;
191
192 if (frames <= 0)
193 return 0 ;
194
195 psrc = (SRC_PRIVATE*) state ;
196
197 if (psrc->mode != SRC_MODE_CALLBACK)
198 { psrc->error = SRC_ERR_BAD_MODE ;
199 return 0 ;
200 } ;
201
202 if (psrc->callback_func == NULL)
203 { psrc->error = SRC_ERR_NULL_CALLBACK ;
204 return 0 ;
205 } ;
206
207 memset (&src_data, 0, sizeof (src_data)) ;
208
209 /* Check src_ratio is in range. */
210 if (is_bad_src_ratio (src_ratio))
211 { psrc->error = SRC_ERR_BAD_SRC_RATIO ;
212 return 0 ;
213 } ;
214
215 /* Switch modes temporarily. */
216 src_data.src_ratio = src_ratio ;
217 src_data.data_out = data ;
218 src_data.output_frames = frames ;
219
220 src_data.data_in = psrc->saved_data ;
221 src_data.input_frames = psrc->saved_frames ;
222
223 output_frames_gen = 0 ;
224 while (output_frames_gen < frames)
225 { /* Use a dummy array for the case where the callback function
226 ** returns without setting the ptr.
227 */
228 float dummy [1] ;
229
230 if (src_data.input_frames == 0)
231 { float *ptr = dummy ;
232
233 src_data.input_frames = psrc->callback_func (psrc->user_callback_data, &ptr) ;
234 src_data.data_in = ptr ;
235
236 if (src_data.input_frames == 0)
237 src_data.end_of_input = 1 ;
238 } ;
239
240 /*
241 ** Now call process function. However, we need to set the mode
242 ** to SRC_MODE_PROCESS first and when we return set it back to
243 ** SRC_MODE_CALLBACK.
244 */
245 psrc->mode = SRC_MODE_PROCESS ;
246 error = src_process (state, &src_data) ;
247 psrc->mode = SRC_MODE_CALLBACK ;
248
249 if (error != 0)
250 break ;
251
252 src_data.data_in += src_data.input_frames_used * psrc->channels ;
253 src_data.input_frames -= src_data.input_frames_used ;
254
255 src_data.data_out += src_data.output_frames_gen * psrc->channels ;
256 src_data.output_frames -= src_data.output_frames_gen ;
257
258 output_frames_gen += src_data.output_frames_gen ;
259
260 if (src_data.end_of_input == SRC_TRUE && src_data.output_frames_gen == 0)
261 break ;
262 } ;
263
264 psrc->saved_data = src_data.data_in ;
265 psrc->saved_frames = src_data.input_frames ;
266
267 if (error != 0)
268 { psrc->error = error ;
269 return 0 ;
270 } ;
271
272 return output_frames_gen ;
273} /* src_callback_read */
274
275/*==========================================================================
276*/
277
278int
279src_set_ratio (SRC_STATE *state, double new_ratio)
280{ SRC_PRIVATE *psrc ;
281
282 psrc = (SRC_PRIVATE*) state ;
283
284 if (psrc == NULL)
285 return SRC_ERR_BAD_STATE ;
286 if (psrc->vari_process == NULL || psrc->const_process == NULL)
287 return SRC_ERR_BAD_PROC_PTR ;
288
289 if (is_bad_src_ratio (new_ratio))
290 return SRC_ERR_BAD_SRC_RATIO ;
291
292 psrc->last_ratio = new_ratio ;
293
294 return SRC_ERR_NO_ERROR ;
295} /* src_set_ratio */
296
297int
298src_reset (SRC_STATE *state)
299{ SRC_PRIVATE *psrc ;
300
301 if ((psrc = (SRC_PRIVATE*) state) == NULL)
302 return SRC_ERR_BAD_STATE ;
303
304 if (psrc->reset != NULL)
305 psrc->reset (psrc) ;
306
307 psrc->last_position = 0.0 ;
308 psrc->last_ratio = 0.0 ;
309
310 psrc->saved_data = NULL ;
311 psrc->saved_frames = 0 ;
312
313 psrc->error = SRC_ERR_NO_ERROR ;
314
315 return SRC_ERR_NO_ERROR ;
316} /* src_reset */
317
318/*==============================================================================
319** Control functions.
320*/
321
322const char *
323src_get_name (int converter_type)
324{ const char *desc ;
325
326 if ((desc = sinc_get_name (converter_type)) != NULL)
327 return desc ;
328
329 if ((desc = zoh_get_name (converter_type)) != NULL)
330 return desc ;
331
332 if ((desc = linear_get_name (converter_type)) != NULL)
333 return desc ;
334
335 return NULL ;
336} /* src_get_name */
337
338const char *
339src_get_description (int converter_type)
340{ const char *desc ;
341
342 if ((desc = sinc_get_description (converter_type)) != NULL)
343 return desc ;
344
345 if ((desc = zoh_get_description (converter_type)) != NULL)
346 return desc ;
347
348 if ((desc = linear_get_description (converter_type)) != NULL)
349 return desc ;
350
351 return NULL ;
352} /* src_get_description */
353
354const char *
355src_get_version (void)
356{ return PACKAGE "-" VERSION " (c) 2002-2008 Erik de Castro Lopo" ;
357} /* src_get_version */
358
359int
360src_is_valid_ratio (double ratio)
361{
362 if (is_bad_src_ratio (ratio))
363 return SRC_FALSE ;
364
365 return SRC_TRUE ;
366} /* src_is_valid_ratio */
367
368/*==============================================================================
369** Error reporting functions.
370*/
371
372int
373src_error (SRC_STATE *state)
374{ if (state)
375 return ((SRC_PRIVATE*) state)->error ;
376 return SRC_ERR_NO_ERROR ;
377} /* src_error */
378
379const char*
380src_strerror (int error)
381{
382 switch (error)
383 { case SRC_ERR_NO_ERROR :
384 return "No error." ;
385 case SRC_ERR_MALLOC_FAILED :
386 return "Malloc failed." ;
387 case SRC_ERR_BAD_STATE :
388 return "SRC_STATE pointer is NULL." ;
389 case SRC_ERR_BAD_DATA :
390 return "SRC_DATA pointer is NULL." ;
391 case SRC_ERR_BAD_DATA_PTR :
392 return "SRC_DATA->data_out is NULL." ;
393 case SRC_ERR_NO_PRIVATE :
394 return "Internal error. No private data." ;
395
396 case SRC_ERR_BAD_SRC_RATIO :
397 return "SRC ratio outside [1/" SRC_MAX_RATIO_STR ", " SRC_MAX_RATIO_STR "] range." ;
398
399 case SRC_ERR_BAD_SINC_STATE :
400 return "src_process() called without reset after end_of_input." ;
401 case SRC_ERR_BAD_PROC_PTR :
402 return "Internal error. No process pointer." ;
403 case SRC_ERR_SHIFT_BITS :
404 return "Internal error. SHIFT_BITS too large." ;
405 case SRC_ERR_FILTER_LEN :
406 return "Internal error. Filter length too large." ;
407 case SRC_ERR_BAD_CONVERTER :
408 return "Bad converter number." ;
409 case SRC_ERR_BAD_CHANNEL_COUNT :
410 return "Channel count must be >= 1." ;
411 case SRC_ERR_SINC_BAD_BUFFER_LEN :
412 return "Internal error. Bad buffer length. Please report this." ;
413 case SRC_ERR_SIZE_INCOMPATIBILITY :
414 return "Internal error. Input data / internal buffer size difference. Please report this." ;
415 case SRC_ERR_BAD_PRIV_PTR :
416 return "Internal error. Private pointer is NULL. Please report this." ;
417 case SRC_ERR_DATA_OVERLAP :
418 return "Input and output data arrays overlap." ;
419 case SRC_ERR_BAD_CALLBACK :
420 return "Supplied callback function pointer is NULL." ;
421 case SRC_ERR_BAD_MODE :
422 return "Calling mode differs from initialisation mode (ie process v callback)." ;
423 case SRC_ERR_NULL_CALLBACK :
424 return "Callback function pointer is NULL in src_callback_read ()." ;
425 case SRC_ERR_NO_VARIABLE_RATIO :
426 return "This converter only allows constant conversion ratios." ;
427 case SRC_ERR_SINC_PREPARE_DATA_BAD_LEN :
428 return "Internal error : Bad length in prepare_data ()." ;
429
430 case SRC_ERR_MAX_ERROR :
431 return "Placeholder. No error defined for this error number." ;
432
433 default : break ;
434 }
435
436 return NULL ;
437} /* src_strerror */
438
439/*==============================================================================
440** Simple interface for performing a single conversion from input buffer to
441** output buffer at a fixed conversion ratio.
442*/
443
444int
445src_simple (SRC_DATA *src_data, int converter, int channels)
446{ SRC_STATE *src_state ;
447 int error ;
448
449 if ((src_state = src_new (converter, channels, &error)) == NULL)
450 return error ;
451
452 src_data->end_of_input = 1 ; /* Only one buffer worth of input. */
453
454 error = src_process (src_state, src_data) ;
455
456 src_state = src_delete (src_state) ;
457
458 return error ;
459} /* src_simple */
460
461void
462src_short_to_float_array (const short *in, float *out, int len)
463{
464 while (len)
465 { len -- ;
466 out [len] = (float) (in [len] / (1.0 * 0x8000)) ;
467 } ;
468
469 return ;
470} /* src_short_to_float_array */
471
472void
473src_float_to_short_array (const float *in, short *out, int len)
474{ double scaled_value ;
475
476 while (len)
477 { len -- ;
478
479 scaled_value = in [len] * (8.0 * 0x10000000) ;
480 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
481 { out [len] = 32767 ;
482 continue ;
483 } ;
484 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
485 { out [len] = -32768 ;
486 continue ;
487 } ;
488
489 out [len] = (short) (lrint (scaled_value) >> 16) ;
490 } ;
491
492} /* src_float_to_short_array */
493
494void
495src_int_to_float_array (const int *in, float *out, int len)
496{
497 while (len)
498 { len -- ;
499 out [len] = (float) (in [len] / (8.0 * 0x10000000)) ;
500 } ;
501
502 return ;
503} /* src_int_to_float_array */
504
505void
506src_float_to_int_array (const float *in, int *out, int len)
507{ double scaled_value ;
508
509 while (len)
510 { len -- ;
511
512 scaled_value = in [len] * (8.0 * 0x10000000) ;
513 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
514 { out [len] = 0x7fffffff ;
515 continue ;
516 } ;
517 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
518 { out [len] = -1 - 0x7fffffff ;
519 continue ;
520 } ;
521
522 out [len] = lrint (scaled_value) ;
523 } ;
524
525} /* src_float_to_int_array */
526
527/*==============================================================================
528** Private functions.
529*/
530
531static int
532psrc_set_converter (SRC_PRIVATE *psrc, int converter_type)
533{
534 if (sinc_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR)
535 return SRC_ERR_NO_ERROR ;
536
537 if (zoh_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR)
538 return SRC_ERR_NO_ERROR ;
539
540 if (linear_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR)
541 return SRC_ERR_NO_ERROR ;
542
543 return SRC_ERR_BAD_CONVERTER ;
544} /* psrc_set_converter */
545