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