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
11 static int psrc_set_converter (SRC_PRIVATE
*psrc
, int converter_type
) ;
15 src_new (int converter_type
, int channels
, int *error
)
19 *error
= SRC_ERR_NO_ERROR
;
23 *error
= SRC_ERR_BAD_CHANNEL_COUNT
;
27 if ((psrc
= calloc (1, sizeof (*psrc
))) == NULL
)
29 *error
= SRC_ERR_MALLOC_FAILED
;
33 psrc
->channels
= channels
;
34 psrc
->mode
= SRC_MODE_PROCESS
;
36 if (psrc_set_converter (psrc
, converter_type
) != SRC_ERR_NO_ERROR
)
38 *error
= SRC_ERR_BAD_CONVERTER
;
43 src_reset ((SRC_STATE
*) psrc
) ;
45 return (SRC_STATE
*) psrc
;
49 src_callback_new (src_callback_t func
, int converter_type
, int channels
, int *error
, void* cb_data
)
50 { SRC_STATE
*src_state
;
54 *error
= SRC_ERR_BAD_CALLBACK
;
61 if ((src_state
= src_new (converter_type
, channels
, error
)) == NULL
)
64 src_reset (src_state
) ;
66 ((SRC_PRIVATE
*) src_state
)->mode
= SRC_MODE_CALLBACK
;
67 ((SRC_PRIVATE
*) src_state
)->callback_func
= func
;
68 ((SRC_PRIVATE
*) src_state
)->user_callback_data
= cb_data
;
71 } /* src_callback_new */
74 src_delete (SRC_STATE
*state
)
77 psrc
= (SRC_PRIVATE
*) state
;
79 { if (psrc
->private_data
)
80 free (psrc
->private_data
) ;
81 memset (psrc
, 0, sizeof (SRC_PRIVATE
)) ;
89 src_process (SRC_STATE
*state
, SRC_DATA
*data
)
93 psrc
= (SRC_PRIVATE
*) state
;
96 return SRC_ERR_BAD_STATE
;
97 if (psrc
->vari_process
== NULL
|| psrc
->const_process
== NULL
)
98 return SRC_ERR_BAD_PROC_PTR
;
100 if (psrc
->mode
!= SRC_MODE_PROCESS
)
101 return SRC_ERR_BAD_MODE
;
103 /* Check for valid SRC_DATA first. */
105 return SRC_ERR_BAD_DATA
;
107 /* And that data_in and data_out are valid. */
108 if (data
->data_in
== NULL
|| data
->data_out
== NULL
)
109 return SRC_ERR_BAD_DATA_PTR
;
111 /* Check src_ratio is in range. */
112 if (is_bad_src_ratio (data
->src_ratio
))
113 return SRC_ERR_BAD_SRC_RATIO
;
115 if (data
->input_frames
< 0)
116 data
->input_frames
= 0 ;
117 if (data
->output_frames
< 0)
118 data
->output_frames
= 0 ;
120 if (data
->data_in
< data
->data_out
)
121 { if (data
->data_in
+ data
->input_frames
* psrc
->channels
> data
->data_out
)
122 { /*-printf ("\n\ndata_in: %p data_out: %p\n",
123 (void*) (data->data_in + data->input_frames * psrc->channels), (void*) data->data_out) ;-*/
124 return SRC_ERR_DATA_OVERLAP
;
127 else if (data
->data_out
+ data
->output_frames
* psrc
->channels
> data
->data_in
)
128 { /*-printf ("\n\ndata_in : %p ouput frames: %ld data_out: %p\n", (void*) data->data_in, data->output_frames, (void*) data->data_out) ;
130 printf ("data_out: %p (%p) data_in: %p\n", (void*) data->data_out,
131 (void*) (data->data_out + data->input_frames * psrc->channels), (void*) data->data_in) ;-*/
132 return SRC_ERR_DATA_OVERLAP
;
135 /* Set the input and output counts to zero. */
136 data
->input_frames_used
= 0 ;
137 data
->output_frames_gen
= 0 ;
139 /* Special case for when last_ratio has not been set. */
140 if (psrc
->last_ratio
< (1.0 / SRC_MAX_RATIO
))
141 psrc
->last_ratio
= data
->src_ratio
;
144 if (fabs (psrc
->last_ratio
- data
->src_ratio
) < 1e-15)
145 error
= psrc
->const_process (psrc
, data
) ;
147 error
= psrc
->vari_process (psrc
, data
) ;
153 src_callback_read (SRC_STATE
*state
, double src_ratio
, long frames
, float *data
)
154 { SRC_PRIVATE
*psrc
;
157 long output_frames_gen
;
166 psrc
= (SRC_PRIVATE
*) state
;
168 if (psrc
->mode
!= SRC_MODE_CALLBACK
)
169 { psrc
->error
= SRC_ERR_BAD_MODE
;
173 if (psrc
->callback_func
== NULL
)
174 { psrc
->error
= SRC_ERR_NULL_CALLBACK
;
178 memset (&src_data
, 0, sizeof (src_data
)) ;
180 /* Check src_ratio is in range. */
181 if (is_bad_src_ratio (src_ratio
))
182 { psrc
->error
= SRC_ERR_BAD_SRC_RATIO
;
186 /* Switch modes temporarily. */
187 src_data
.src_ratio
= src_ratio
;
188 src_data
.data_out
= data
;
189 src_data
.output_frames
= frames
;
191 src_data
.data_in
= psrc
->saved_data
;
192 src_data
.input_frames
= psrc
->saved_frames
;
194 output_frames_gen
= 0 ;
195 while (output_frames_gen
< frames
)
196 { /* Use a dummy array for the case where the callback function
197 ** returns without setting the ptr.
201 if (src_data
.input_frames
== 0)
202 { float *ptr
= dummy
;
204 src_data
.input_frames
= psrc
->callback_func (psrc
->user_callback_data
, &ptr
) ;
205 src_data
.data_in
= ptr
;
207 if (src_data
.input_frames
== 0)
208 src_data
.end_of_input
= 1 ;
212 ** Now call process function. However, we need to set the mode
213 ** to SRC_MODE_PROCESS first and when we return set it back to
214 ** SRC_MODE_CALLBACK.
216 psrc
->mode
= SRC_MODE_PROCESS
;
217 error
= src_process (state
, &src_data
) ;
218 psrc
->mode
= SRC_MODE_CALLBACK
;
223 src_data
.data_in
+= src_data
.input_frames_used
* psrc
->channels
;
224 src_data
.input_frames
-= src_data
.input_frames_used
;
226 src_data
.data_out
+= src_data
.output_frames_gen
* psrc
->channels
;
227 src_data
.output_frames
-= src_data
.output_frames_gen
;
229 output_frames_gen
+= src_data
.output_frames_gen
;
231 if (src_data
.end_of_input
== SRC_TRUE
&& src_data
.output_frames_gen
== 0)
235 psrc
->saved_data
= src_data
.data_in
;
236 psrc
->saved_frames
= src_data
.input_frames
;
239 { psrc
->error
= error
;
243 return output_frames_gen
;
244 } /* src_callback_read */
246 /*==========================================================================
250 src_set_ratio (SRC_STATE
*state
, double new_ratio
)
251 { SRC_PRIVATE
*psrc
;
253 psrc
= (SRC_PRIVATE
*) state
;
256 return SRC_ERR_BAD_STATE
;
257 if (psrc
->vari_process
== NULL
|| psrc
->const_process
== NULL
)
258 return SRC_ERR_BAD_PROC_PTR
;
260 if (is_bad_src_ratio (new_ratio
))
261 return SRC_ERR_BAD_SRC_RATIO
;
263 psrc
->last_ratio
= new_ratio
;
265 return SRC_ERR_NO_ERROR
;
266 } /* src_set_ratio */
269 src_get_channels (SRC_STATE
*state
)
270 { SRC_PRIVATE
*psrc
;
272 psrc
= (SRC_PRIVATE
*) state
;
275 return SRC_ERR_BAD_STATE
;
276 if (psrc
->vari_process
== NULL
|| psrc
->const_process
== NULL
)
277 return SRC_ERR_BAD_PROC_PTR
;
279 return psrc
->channels
;
280 } /* src_get_channels */
283 src_reset (SRC_STATE
*state
)
284 { SRC_PRIVATE
*psrc
;
286 if ((psrc
= (SRC_PRIVATE
*) state
) == NULL
)
287 return SRC_ERR_BAD_STATE
;
289 if (psrc
->reset
!= NULL
)
292 psrc
->last_position
= 0.0 ;
293 psrc
->last_ratio
= 0.0 ;
295 psrc
->saved_data
= NULL
;
296 psrc
->saved_frames
= 0 ;
298 psrc
->error
= SRC_ERR_NO_ERROR
;
300 return SRC_ERR_NO_ERROR
;
303 /*==============================================================================
304 ** Control functions.
308 src_get_name (int converter_type
)
311 if ((desc
= sinc_get_name (converter_type
)) != NULL
)
314 if ((desc
= zoh_get_name (converter_type
)) != NULL
)
317 if ((desc
= linear_get_name (converter_type
)) != NULL
)
324 src_get_description (int converter_type
)
327 if ((desc
= sinc_get_description (converter_type
)) != NULL
)
330 if ((desc
= zoh_get_description (converter_type
)) != NULL
)
333 if ((desc
= linear_get_description (converter_type
)) != NULL
)
337 } /* src_get_description */
340 src_get_version (void)
341 { return PACKAGE
"-" VERSION
" (c) 2002-2008 Erik de Castro Lopo" ;
342 } /* src_get_version */
345 src_is_valid_ratio (double ratio
)
347 if (is_bad_src_ratio (ratio
))
351 } /* src_is_valid_ratio */
353 /*==============================================================================
354 ** Error reporting functions.
358 src_error (SRC_STATE
*state
)
360 return ((SRC_PRIVATE
*) state
)->error
;
361 return SRC_ERR_NO_ERROR
;
365 src_strerror (int error
)
368 { case SRC_ERR_NO_ERROR
:
370 case SRC_ERR_MALLOC_FAILED
:
371 return "Malloc failed." ;
372 case SRC_ERR_BAD_STATE
:
373 return "SRC_STATE pointer is NULL." ;
374 case SRC_ERR_BAD_DATA
:
375 return "SRC_DATA pointer is NULL." ;
376 case SRC_ERR_BAD_DATA_PTR
:
377 return "SRC_DATA->data_out or SRC_DATA->data_in is NULL." ;
378 case SRC_ERR_NO_PRIVATE
:
379 return "Internal error. No private data." ;
381 case SRC_ERR_BAD_SRC_RATIO
:
382 return "SRC ratio outside [1/" SRC_MAX_RATIO_STR
", " SRC_MAX_RATIO_STR
"] range." ;
384 case SRC_ERR_BAD_SINC_STATE
:
385 return "src_process() called without reset after end_of_input." ;
386 case SRC_ERR_BAD_PROC_PTR
:
387 return "Internal error. No process pointer." ;
388 case SRC_ERR_SHIFT_BITS
:
389 return "Internal error. SHIFT_BITS too large." ;
390 case SRC_ERR_FILTER_LEN
:
391 return "Internal error. Filter length too large." ;
392 case SRC_ERR_BAD_CONVERTER
:
393 return "Bad converter number." ;
394 case SRC_ERR_BAD_CHANNEL_COUNT
:
395 return "Channel count must be >= 1." ;
396 case SRC_ERR_SINC_BAD_BUFFER_LEN
:
397 return "Internal error. Bad buffer length. Please report this." ;
398 case SRC_ERR_SIZE_INCOMPATIBILITY
:
399 return "Internal error. Input data / internal buffer size difference. Please report this." ;
400 case SRC_ERR_BAD_PRIV_PTR
:
401 return "Internal error. Private pointer is NULL. Please report this." ;
402 case SRC_ERR_DATA_OVERLAP
:
403 return "Input and output data arrays overlap." ;
404 case SRC_ERR_BAD_CALLBACK
:
405 return "Supplied callback function pointer is NULL." ;
406 case SRC_ERR_BAD_MODE
:
407 return "Calling mode differs from initialisation mode (ie process v callback)." ;
408 case SRC_ERR_NULL_CALLBACK
:
409 return "Callback function pointer is NULL in src_callback_read ()." ;
410 case SRC_ERR_NO_VARIABLE_RATIO
:
411 return "This converter only allows constant conversion ratios." ;
412 case SRC_ERR_SINC_PREPARE_DATA_BAD_LEN
:
413 return "Internal error : Bad length in prepare_data ()." ;
414 case SRC_ERR_BAD_INTERNAL_STATE
:
415 return "Error : Someone is trampling on my internal state." ;
417 case SRC_ERR_MAX_ERROR
:
418 return "Placeholder. No error defined for this error number." ;
426 /*==============================================================================
427 ** Simple interface for performing a single conversion from input buffer to
428 ** output buffer at a fixed conversion ratio.
432 src_simple (SRC_DATA
*src_data
, int converter
, int channels
)
433 { SRC_STATE
*src_state
;
436 if ((src_state
= src_new (converter
, channels
, &error
)) == NULL
)
439 src_data
->end_of_input
= 1 ; /* Only one buffer worth of input. */
441 error
= src_process (src_state
, src_data
) ;
443 src_delete (src_state
) ;
449 src_short_to_float_array (const short *in
, float *out
, int len
)
453 out
[len
] = (float) (in
[len
] / (1.0 * 0x8000)) ;
457 } /* src_short_to_float_array */
460 src_float_to_short_array (const float *in
, short *out
, int len
)
461 { double scaled_value
;
466 scaled_value
= in
[len
] * (8.0 * 0x10000000) ;
467 if (CPU_CLIPS_POSITIVE
== 0 && scaled_value
>= (1.0 * 0x7FFFFFFF))
468 { out
[len
] = 32767 ;
471 if (CPU_CLIPS_NEGATIVE
== 0 && scaled_value
<= (-8.0 * 0x10000000))
472 { out
[len
] = -32768 ;
476 out
[len
] = (short) (lrint (scaled_value
) >> 16) ;
479 } /* src_float_to_short_array */
482 src_int_to_float_array (const int *in
, float *out
, int len
)
486 out
[len
] = (float) (in
[len
] / (8.0 * 0x10000000)) ;
490 } /* src_int_to_float_array */
493 src_float_to_int_array (const float *in
, int *out
, int len
)
494 { double scaled_value
;
499 scaled_value
= in
[len
] * (8.0 * 0x10000000) ;
500 if (CPU_CLIPS_POSITIVE
== 0 && scaled_value
>= (1.0 * 0x7FFFFFFF))
501 { out
[len
] = 0x7fffffff ;
504 if (CPU_CLIPS_NEGATIVE
== 0 && scaled_value
<= (-8.0 * 0x10000000))
505 { out
[len
] = -1 - 0x7fffffff ;
509 out
[len
] = lrint (scaled_value
) ;
512 } /* src_float_to_int_array */
514 /*==============================================================================
515 ** Private functions.
519 psrc_set_converter (SRC_PRIVATE
*psrc
, int converter_type
)
521 if (sinc_set_converter (psrc
, converter_type
) == SRC_ERR_NO_ERROR
)
522 return SRC_ERR_NO_ERROR
;
524 if (zoh_set_converter (psrc
, converter_type
) == SRC_ERR_NO_ERROR
)
525 return SRC_ERR_NO_ERROR
;
527 if (linear_set_converter (psrc
, converter_type
) == SRC_ERR_NO_ERROR
)
528 return SRC_ERR_NO_ERROR
;
530 return SRC_ERR_BAD_CONVERTER
;
531 } /* psrc_set_converter */