2 ** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** All rights reserved.
5 ** This code is released under 2-clause BSD license. Please see the
6 ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
15 #include "samplerate.h"
16 #include "float_cast.h"
19 static int psrc_set_converter (SRC_PRIVATE
*psrc
, int converter_type
) ;
23 src_new (int converter_type
, int channels
, int *error
)
27 *error
= SRC_ERR_NO_ERROR
;
31 *error
= SRC_ERR_BAD_CHANNEL_COUNT
;
35 if ((psrc
= calloc (1, sizeof (*psrc
))) == NULL
)
37 *error
= SRC_ERR_MALLOC_FAILED
;
41 psrc
->channels
= channels
;
42 psrc
->mode
= SRC_MODE_PROCESS
;
44 if (psrc_set_converter (psrc
, converter_type
) != SRC_ERR_NO_ERROR
)
46 *error
= SRC_ERR_BAD_CONVERTER
;
51 src_reset ((SRC_STATE
*) psrc
) ;
53 return (SRC_STATE
*) psrc
;
57 src_callback_new (src_callback_t func
, int converter_type
, int channels
, int *error
, void* cb_data
)
58 { SRC_STATE
*src_state
;
62 *error
= SRC_ERR_BAD_CALLBACK
;
69 if ((src_state
= src_new (converter_type
, channels
, error
)) == NULL
)
72 src_reset (src_state
) ;
74 ((SRC_PRIVATE
*) src_state
)->mode
= SRC_MODE_CALLBACK
;
75 ((SRC_PRIVATE
*) src_state
)->callback_func
= func
;
76 ((SRC_PRIVATE
*) src_state
)->user_callback_data
= cb_data
;
79 } /* src_callback_new */
82 src_delete (SRC_STATE
*state
)
85 psrc
= (SRC_PRIVATE
*) state
;
87 { if (psrc
->private_data
)
88 free (psrc
->private_data
) ;
89 memset (psrc
, 0, sizeof (SRC_PRIVATE
)) ;
97 src_process (SRC_STATE
*state
, SRC_DATA
*data
)
101 psrc
= (SRC_PRIVATE
*) state
;
104 return SRC_ERR_BAD_STATE
;
105 if (psrc
->vari_process
== NULL
|| psrc
->const_process
== NULL
)
106 return SRC_ERR_BAD_PROC_PTR
;
108 if (psrc
->mode
!= SRC_MODE_PROCESS
)
109 return SRC_ERR_BAD_MODE
;
111 /* Check for valid SRC_DATA first. */
113 return SRC_ERR_BAD_DATA
;
115 /* And that data_in and data_out are valid. */
116 if (data
->data_in
== NULL
|| data
->data_out
== NULL
)
117 return SRC_ERR_BAD_DATA_PTR
;
119 /* Check src_ratio is in range. */
120 if (is_bad_src_ratio (data
->src_ratio
))
121 return SRC_ERR_BAD_SRC_RATIO
;
123 if (data
->input_frames
< 0)
124 data
->input_frames
= 0 ;
125 if (data
->output_frames
< 0)
126 data
->output_frames
= 0 ;
128 if (data
->data_in
< data
->data_out
)
129 { if (data
->data_in
+ data
->input_frames
* psrc
->channels
> data
->data_out
)
130 { /*-printf ("\n\ndata_in: %p data_out: %p\n",
131 (void*) (data->data_in + data->input_frames * psrc->channels), (void*) data->data_out) ;-*/
132 return SRC_ERR_DATA_OVERLAP
;
135 else if (data
->data_out
+ data
->output_frames
* psrc
->channels
> data
->data_in
)
136 { /*-printf ("\n\ndata_in : %p ouput frames: %ld data_out: %p\n", (void*) data->data_in, data->output_frames, (void*) data->data_out) ;
138 printf ("data_out: %p (%p) data_in: %p\n", (void*) data->data_out,
139 (void*) (data->data_out + data->input_frames * psrc->channels), (void*) data->data_in) ;-*/
140 return SRC_ERR_DATA_OVERLAP
;
143 /* Set the input and output counts to zero. */
144 data
->input_frames_used
= 0 ;
145 data
->output_frames_gen
= 0 ;
147 /* Special case for when last_ratio has not been set. */
148 if (psrc
->last_ratio
< (1.0 / SRC_MAX_RATIO
))
149 psrc
->last_ratio
= data
->src_ratio
;
152 if (fabs (psrc
->last_ratio
- data
->src_ratio
) < 1e-15)
153 error
= psrc
->const_process (psrc
, data
) ;
155 error
= psrc
->vari_process (psrc
, data
) ;
161 src_callback_read (SRC_STATE
*state
, double src_ratio
, long frames
, float *data
)
162 { SRC_PRIVATE
*psrc
;
165 long output_frames_gen
;
174 psrc
= (SRC_PRIVATE
*) state
;
176 if (psrc
->mode
!= SRC_MODE_CALLBACK
)
177 { psrc
->error
= SRC_ERR_BAD_MODE
;
181 if (psrc
->callback_func
== NULL
)
182 { psrc
->error
= SRC_ERR_NULL_CALLBACK
;
186 memset (&src_data
, 0, sizeof (src_data
)) ;
188 /* Check src_ratio is in range. */
189 if (is_bad_src_ratio (src_ratio
))
190 { psrc
->error
= SRC_ERR_BAD_SRC_RATIO
;
194 /* Switch modes temporarily. */
195 src_data
.src_ratio
= src_ratio
;
196 src_data
.data_out
= data
;
197 src_data
.output_frames
= frames
;
199 src_data
.data_in
= psrc
->saved_data
;
200 src_data
.input_frames
= psrc
->saved_frames
;
202 output_frames_gen
= 0 ;
203 while (output_frames_gen
< frames
)
204 { /* Use a dummy array for the case where the callback function
205 ** returns without setting the ptr.
209 if (src_data
.input_frames
== 0)
210 { float *ptr
= dummy
;
212 src_data
.input_frames
= psrc
->callback_func (psrc
->user_callback_data
, &ptr
) ;
213 src_data
.data_in
= ptr
;
215 if (src_data
.input_frames
== 0)
216 src_data
.end_of_input
= 1 ;
220 ** Now call process function. However, we need to set the mode
221 ** to SRC_MODE_PROCESS first and when we return set it back to
222 ** SRC_MODE_CALLBACK.
224 psrc
->mode
= SRC_MODE_PROCESS
;
225 error
= src_process (state
, &src_data
) ;
226 psrc
->mode
= SRC_MODE_CALLBACK
;
231 src_data
.data_in
+= src_data
.input_frames_used
* psrc
->channels
;
232 src_data
.input_frames
-= src_data
.input_frames_used
;
234 src_data
.data_out
+= src_data
.output_frames_gen
* psrc
->channels
;
235 src_data
.output_frames
-= src_data
.output_frames_gen
;
237 output_frames_gen
+= src_data
.output_frames_gen
;
239 if (src_data
.end_of_input
== SRC_TRUE
&& src_data
.output_frames_gen
== 0)
243 psrc
->saved_data
= src_data
.data_in
;
244 psrc
->saved_frames
= src_data
.input_frames
;
247 { psrc
->error
= error
;
251 return output_frames_gen
;
252 } /* src_callback_read */
254 /*==========================================================================
258 src_set_ratio (SRC_STATE
*state
, double new_ratio
)
259 { SRC_PRIVATE
*psrc
;
261 psrc
= (SRC_PRIVATE
*) state
;
264 return SRC_ERR_BAD_STATE
;
265 if (psrc
->vari_process
== NULL
|| psrc
->const_process
== NULL
)
266 return SRC_ERR_BAD_PROC_PTR
;
268 if (is_bad_src_ratio (new_ratio
))
269 return SRC_ERR_BAD_SRC_RATIO
;
271 psrc
->last_ratio
= new_ratio
;
273 return SRC_ERR_NO_ERROR
;
274 } /* src_set_ratio */
277 src_get_channels (SRC_STATE
*state
)
278 { SRC_PRIVATE
*psrc
;
280 psrc
= (SRC_PRIVATE
*) state
;
283 return SRC_ERR_BAD_STATE
;
284 if (psrc
->vari_process
== NULL
|| psrc
->const_process
== NULL
)
285 return SRC_ERR_BAD_PROC_PTR
;
287 return psrc
->channels
;
288 } /* src_get_channels */
291 src_reset (SRC_STATE
*state
)
292 { SRC_PRIVATE
*psrc
;
294 if ((psrc
= (SRC_PRIVATE
*) state
) == NULL
)
295 return SRC_ERR_BAD_STATE
;
297 if (psrc
->reset
!= NULL
)
300 psrc
->last_position
= 0.0 ;
301 psrc
->last_ratio
= 0.0 ;
303 psrc
->saved_data
= NULL
;
304 psrc
->saved_frames
= 0 ;
306 psrc
->error
= SRC_ERR_NO_ERROR
;
308 return SRC_ERR_NO_ERROR
;
311 /*==============================================================================
312 ** Control functions.
316 src_get_name (int converter_type
)
319 if ((desc
= sinc_get_name (converter_type
)) != NULL
)
322 if ((desc
= zoh_get_name (converter_type
)) != NULL
)
325 if ((desc
= linear_get_name (converter_type
)) != NULL
)
332 src_get_description (int converter_type
)
335 if ((desc
= sinc_get_description (converter_type
)) != NULL
)
338 if ((desc
= zoh_get_description (converter_type
)) != NULL
)
341 if ((desc
= linear_get_description (converter_type
)) != NULL
)
345 } /* src_get_description */
348 src_get_version (void)
349 { return PACKAGE
"-" VERSION
" (c) 2002-2008 Erik de Castro Lopo" ;
350 } /* src_get_version */
353 src_is_valid_ratio (double ratio
)
355 if (is_bad_src_ratio (ratio
))
359 } /* src_is_valid_ratio */
361 /*==============================================================================
362 ** Error reporting functions.
366 src_error (SRC_STATE
*state
)
368 return ((SRC_PRIVATE
*) state
)->error
;
369 return SRC_ERR_NO_ERROR
;
373 src_strerror (int error
)
376 { case SRC_ERR_NO_ERROR
:
378 case SRC_ERR_MALLOC_FAILED
:
379 return "Malloc failed." ;
380 case SRC_ERR_BAD_STATE
:
381 return "SRC_STATE pointer is NULL." ;
382 case SRC_ERR_BAD_DATA
:
383 return "SRC_DATA pointer is NULL." ;
384 case SRC_ERR_BAD_DATA_PTR
:
385 return "SRC_DATA->data_out or SRC_DATA->data_in is NULL." ;
386 case SRC_ERR_NO_PRIVATE
:
387 return "Internal error. No private data." ;
389 case SRC_ERR_BAD_SRC_RATIO
:
390 return "SRC ratio outside [1/" SRC_MAX_RATIO_STR
", " SRC_MAX_RATIO_STR
"] range." ;
392 case SRC_ERR_BAD_SINC_STATE
:
393 return "src_process() called without reset after end_of_input." ;
394 case SRC_ERR_BAD_PROC_PTR
:
395 return "Internal error. No process pointer." ;
396 case SRC_ERR_SHIFT_BITS
:
397 return "Internal error. SHIFT_BITS too large." ;
398 case SRC_ERR_FILTER_LEN
:
399 return "Internal error. Filter length too large." ;
400 case SRC_ERR_BAD_CONVERTER
:
401 return "Bad converter number." ;
402 case SRC_ERR_BAD_CHANNEL_COUNT
:
403 return "Channel count must be >= 1." ;
404 case SRC_ERR_SINC_BAD_BUFFER_LEN
:
405 return "Internal error. Bad buffer length. Please report this." ;
406 case SRC_ERR_SIZE_INCOMPATIBILITY
:
407 return "Internal error. Input data / internal buffer size difference. Please report this." ;
408 case SRC_ERR_BAD_PRIV_PTR
:
409 return "Internal error. Private pointer is NULL. Please report this." ;
410 case SRC_ERR_DATA_OVERLAP
:
411 return "Input and output data arrays overlap." ;
412 case SRC_ERR_BAD_CALLBACK
:
413 return "Supplied callback function pointer is NULL." ;
414 case SRC_ERR_BAD_MODE
:
415 return "Calling mode differs from initialisation mode (ie process v callback)." ;
416 case SRC_ERR_NULL_CALLBACK
:
417 return "Callback function pointer is NULL in src_callback_read ()." ;
418 case SRC_ERR_NO_VARIABLE_RATIO
:
419 return "This converter only allows constant conversion ratios." ;
420 case SRC_ERR_SINC_PREPARE_DATA_BAD_LEN
:
421 return "Internal error : Bad length in prepare_data ()." ;
422 case SRC_ERR_BAD_INTERNAL_STATE
:
423 return "Error : Someone is trampling on my internal state." ;
425 case SRC_ERR_MAX_ERROR
:
426 return "Placeholder. No error defined for this error number." ;
434 /*==============================================================================
435 ** Simple interface for performing a single conversion from input buffer to
436 ** output buffer at a fixed conversion ratio.
440 src_simple (SRC_DATA
*src_data
, int converter
, int channels
)
441 { SRC_STATE
*src_state
;
444 if ((src_state
= src_new (converter
, channels
, &error
)) == NULL
)
447 src_data
->end_of_input
= 1 ; /* Only one buffer worth of input. */
449 error
= src_process (src_state
, src_data
) ;
451 src_delete (src_state
) ;
457 src_short_to_float_array (const short *in
, float *out
, int len
)
461 out
[len
] = (float) (in
[len
] / (1.0 * 0x8000)) ;
465 } /* src_short_to_float_array */
468 src_float_to_short_array (const float *in
, short *out
, int len
)
469 { double scaled_value
;
474 scaled_value
= in
[len
] * (8.0 * 0x10000000) ;
475 if (CPU_CLIPS_POSITIVE
== 0 && scaled_value
>= (1.0 * 0x7FFFFFFF))
476 { out
[len
] = 32767 ;
479 if (CPU_CLIPS_NEGATIVE
== 0 && scaled_value
<= (-8.0 * 0x10000000))
480 { out
[len
] = -32768 ;
484 out
[len
] = (short) (lrint (scaled_value
) >> 16) ;
487 } /* src_float_to_short_array */
490 src_int_to_float_array (const int *in
, float *out
, int len
)
494 out
[len
] = (float) (in
[len
] / (8.0 * 0x10000000)) ;
498 } /* src_int_to_float_array */
501 src_float_to_int_array (const float *in
, int *out
, int len
)
502 { double scaled_value
;
507 scaled_value
= in
[len
] * (8.0 * 0x10000000) ;
508 if (CPU_CLIPS_POSITIVE
== 0 && scaled_value
>= (1.0 * 0x7FFFFFFF))
509 { out
[len
] = 0x7fffffff ;
512 if (CPU_CLIPS_NEGATIVE
== 0 && scaled_value
<= (-8.0 * 0x10000000))
513 { out
[len
] = -1 - 0x7fffffff ;
517 out
[len
] = lrint (scaled_value
) ;
520 } /* src_float_to_int_array */
522 /*==============================================================================
523 ** Private functions.
527 psrc_set_converter (SRC_PRIVATE
*psrc
, int converter_type
)
529 if (sinc_set_converter (psrc
, converter_type
) == SRC_ERR_NO_ERROR
)
530 return SRC_ERR_NO_ERROR
;
532 if (zoh_set_converter (psrc
, converter_type
) == SRC_ERR_NO_ERROR
)
533 return SRC_ERR_NO_ERROR
;
535 if (linear_set_converter (psrc
, converter_type
) == SRC_ERR_NO_ERROR
)
536 return SRC_ERR_NO_ERROR
;
538 return SRC_ERR_BAD_CONVERTER
;
539 } /* psrc_set_converter */