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