integrated libsamplerate 0.1.3 source which has various improvements over 4-year-old version 0.1.2
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@895 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
13
ChangeLog
13
ChangeLog
@@ -1,5 +1,18 @@
|
||||
2008-04-07 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* src/3rdparty/samplerate/common.h:
|
||||
* src/3rdparty/samplerate/fastest_coeffs.h:
|
||||
* src/3rdparty/samplerate/float_cast.h:
|
||||
* src/3rdparty/samplerate/high_qual_coeffs.h:
|
||||
* src/3rdparty/samplerate/mid_qual_coeffs.h:
|
||||
* src/3rdparty/samplerate/samplerate.c:
|
||||
* src/3rdparty/samplerate/samplerate.h:
|
||||
* src/3rdparty/samplerate/src_linear.c:
|
||||
* src/3rdparty/samplerate/src_sinc.c:
|
||||
* src/3rdparty/samplerate/src_zoh.c:
|
||||
integrated libsamplerate 0.1.3 source which has various improvements
|
||||
over 4-year-old version 0.1.2
|
||||
|
||||
* src/gui/widgets/combobox.cpp:
|
||||
set correct value for model when selecting an item whose strings
|
||||
occurs multiple times in the combobox
|
||||
|
||||
44
src/3rdparty/samplerate/common.h
vendored
44
src/3rdparty/samplerate/common.h
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
@@ -16,6 +16,12 @@
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This code is part of Secret Rabibt Code aka libsamplerate. A commercial
|
||||
** use license for this code is available, please see:
|
||||
** http://www.mega-nerd.com/SRC/procedure.html
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H_INCLUDED
|
||||
#define COMMON_H_INCLUDED
|
||||
|
||||
@@ -33,8 +39,12 @@ typedef long int32_t ;
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
|
||||
#define OFFSETOF(type,member) ((int) (&((type*) 0)->member))
|
||||
|
||||
#define MAKE_MAGIC(a,b,c,d,e,f) ((a) + ((b) << 4) + ((c) << 8) + ((d) << 12) + ((e) << 16) + ((f) << 20))
|
||||
|
||||
|
||||
#include "samplerate.h"
|
||||
|
||||
enum
|
||||
@@ -67,6 +77,7 @@ enum
|
||||
SRC_ERR_BAD_CALLBACK,
|
||||
SRC_ERR_BAD_MODE,
|
||||
SRC_ERR_NULL_CALLBACK,
|
||||
SRC_ERR_NO_VARIABLE_RATIO,
|
||||
|
||||
/* This must be the last error number. */
|
||||
SRC_ERR_MAX_ERROR
|
||||
@@ -84,7 +95,13 @@ typedef struct SRC_PRIVATE_tag
|
||||
/* Pointer to data to converter specific data. */
|
||||
void *private_data ;
|
||||
|
||||
int (*process) (struct SRC_PRIVATE_tag *psrc, SRC_DATA *data) ;
|
||||
/* Varispeed process function. */
|
||||
int (*vari_process) (struct SRC_PRIVATE_tag *psrc, SRC_DATA *data) ;
|
||||
|
||||
/* Constant speed process function. */
|
||||
int (*const_process) (struct SRC_PRIVATE_tag *psrc, SRC_DATA *data) ;
|
||||
|
||||
/* State reset. */
|
||||
void (*reset) (struct SRC_PRIVATE_tag *psrc) ;
|
||||
|
||||
/* Data specific to SRC_MODE_CALLBACK. */
|
||||
@@ -112,13 +129,20 @@ const char* zoh_get_description (int src_enum) ;
|
||||
|
||||
int zoh_set_converter (SRC_PRIVATE *psrc, int src_enum) ;
|
||||
|
||||
#endif /* COMMON_H_INCLUDED */
|
||||
|
||||
/*
|
||||
** Do not edit or modify anything in this comment block.
|
||||
** The arch-tag line is a file identity tag for the GNU Arch
|
||||
** revision control system.
|
||||
**
|
||||
** arch-tag: 737d46dc-a2f8-4025-bb88-fc8915c69085
|
||||
/*----------------------------------------------------------
|
||||
** Common static inline functions.
|
||||
*/
|
||||
|
||||
static inline double
|
||||
fmod_one (double x)
|
||||
{ double res ;
|
||||
|
||||
res = x - lrint (x) ;
|
||||
if (res < 0.0)
|
||||
return res + 1.0 ;
|
||||
|
||||
return res ;
|
||||
} /* fmod_one */
|
||||
|
||||
#endif /* COMMON_H_INCLUDED */
|
||||
|
||||
|
||||
26
src/3rdparty/samplerate/fastest_coeffs.h
vendored
26
src/3rdparty/samplerate/fastest_coeffs.h
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
@@ -16,6 +16,11 @@
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This code is part of Secret Rabibt Code aka libsamplerate. A commercial
|
||||
** use license for this code is available, please see:
|
||||
** http://www.mega-nerd.com/SRC/procedure.html
|
||||
*/
|
||||
|
||||
/*
|
||||
** f = make_filter (8, 128, 100.3) ;
|
||||
@@ -26,6 +31,12 @@
|
||||
** increment : 128
|
||||
*/
|
||||
|
||||
static const struct fastest_coeffs_s
|
||||
{ int increment ;
|
||||
coeff_t coeffs [2464] ;
|
||||
} fastest_coeffs =
|
||||
{ 128,
|
||||
{
|
||||
8.31472372954840555082e-01,
|
||||
8.31414005540308198583e-01,
|
||||
8.31238918266223869580e-01,
|
||||
@@ -2489,13 +2500,6 @@
|
||||
-3.59691078491283933177e-07,
|
||||
-2.38952398011216803052e-07,
|
||||
-1.22889677382464548894e-07,
|
||||
0 /* Need a final zero coefficient */
|
||||
|
||||
/*
|
||||
** Do not edit or modify anything in this comment block.
|
||||
** The arch-tag line is a file identity tag for the GNU Arch
|
||||
** revision control system.
|
||||
**
|
||||
** arch-tag: 82d149f9-28f4-4c47-b442-77a0a2d752b4
|
||||
*/
|
||||
|
||||
0.0 /* Need a final zero coefficient */
|
||||
}
|
||||
} ; /* fastest_coeffs */
|
||||
|
||||
78
src/3rdparty/samplerate/float_cast.h
vendored
78
src/3rdparty/samplerate/float_cast.h
vendored
@@ -1,23 +1,25 @@
|
||||
/*
|
||||
** Copyright (C) 2001-2003 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 2001-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** it under the terms of the GNU Lesser General Public License as published by
|
||||
** the Free Software Foundation; either version 2.1 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
** GNU Lesser General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** You should have received a copy of the GNU Lesser General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Version 1.3 */
|
||||
/* Version 1.4 */
|
||||
|
||||
#ifndef FLOAT_CAST_HEADER
|
||||
#define FLOAT_CAST_HEADER
|
||||
|
||||
/*============================================================================
|
||||
** On Intel Pentium processors (especially PIII and probably P4), converting
|
||||
@@ -71,10 +73,59 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#elif (defined (__CYGWIN__))
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#undef HAVE_LRINT_REPLACEMENT
|
||||
#define HAVE_LRINT_REPLACEMENT 1
|
||||
|
||||
#undef lrint
|
||||
#undef lrintf
|
||||
|
||||
#define lrint double2int
|
||||
#define lrintf float2int
|
||||
|
||||
/*
|
||||
** The native CYGWIN lrint and lrintf functions are buggy:
|
||||
** http://sourceware.org/ml/cygwin/2005-06/msg00153.html
|
||||
** http://sourceware.org/ml/cygwin/2005-09/msg00047.html
|
||||
** and slow.
|
||||
** These functions (pulled from the Public Domain MinGW math.h header)
|
||||
** replace the native versions.
|
||||
*/
|
||||
|
||||
static inline long double2int (double in)
|
||||
{ long retval ;
|
||||
|
||||
__asm__ __volatile__
|
||||
( "fistpl %0"
|
||||
: "=m" (retval)
|
||||
: "t" (in)
|
||||
: "st"
|
||||
) ;
|
||||
|
||||
return retval ;
|
||||
} /* double2int */
|
||||
|
||||
static inline long float2int (float in)
|
||||
{ long retval ;
|
||||
|
||||
__asm__ __volatile__
|
||||
( "fistpl %0"
|
||||
: "=m" (retval)
|
||||
: "t" (in)
|
||||
: "st"
|
||||
) ;
|
||||
|
||||
return retval ;
|
||||
} /* float2int */
|
||||
|
||||
#elif (defined (WIN32) || defined (_WIN32))
|
||||
|
||||
#undef HAVE_LRINT_REPLACEMENT
|
||||
#define HAVE_LRINT_REPLACEMENT 1
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
@@ -156,7 +207,7 @@
|
||||
#define lrint double2int
|
||||
#define lrintf float2int
|
||||
|
||||
inline static long int
|
||||
inline static long
|
||||
float2int (register float in)
|
||||
{ int res [2] ;
|
||||
|
||||
@@ -171,7 +222,7 @@
|
||||
return res [1] ;
|
||||
} /* lrintf */
|
||||
|
||||
inline static long int
|
||||
inline static long
|
||||
double2int (register double in)
|
||||
{ int res [2] ;
|
||||
|
||||
@@ -200,12 +251,5 @@
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Do not edit or modify anything in this comment block.
|
||||
** The arch-tag line is a file identity tag for the GNU Arch
|
||||
** revision control system.
|
||||
**
|
||||
** arch-tag: 25418b9e-cfe8-4145-a3b3-a92388dd37c5
|
||||
*/
|
||||
#endif /* FLOAT_CAST_HEADER */
|
||||
|
||||
|
||||
357357
src/3rdparty/samplerate/high_qual_coeffs.h
vendored
357357
src/3rdparty/samplerate/high_qual_coeffs.h
vendored
File diff suppressed because it is too large
Load Diff
27755
src/3rdparty/samplerate/mid_qual_coeffs.h
vendored
27755
src/3rdparty/samplerate/mid_qual_coeffs.h
vendored
File diff suppressed because it is too large
Load Diff
84
src/3rdparty/samplerate/samplerate.c
vendored
84
src/3rdparty/samplerate/samplerate.c
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
@@ -16,6 +16,12 @@
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This code is part of Secret Rabibt Code aka libsamplerate. A commercial
|
||||
** use license for this code is available, please see:
|
||||
** http://www.mega-nerd.com/SRC/procedure.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -23,12 +29,17 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "samplerate.h"
|
||||
#include "common.h"
|
||||
#include "float_cast.h"
|
||||
#include "common.h"
|
||||
|
||||
static int psrc_set_converter (SRC_PRIVATE *psrc, int converter_type) ;
|
||||
|
||||
|
||||
static inline int
|
||||
is_bad_src_ratio (double ratio)
|
||||
{ return (ratio < (1.0 / SRC_MAX_RATIO) || ratio > (1.0 * SRC_MAX_RATIO)) ;
|
||||
} /* is_bad_src_ratio */
|
||||
|
||||
SRC_STATE *
|
||||
src_new (int converter_type, int channels, int *error)
|
||||
{ SRC_PRIVATE *psrc ;
|
||||
@@ -111,7 +122,7 @@ src_process (SRC_STATE *state, SRC_DATA *data)
|
||||
|
||||
if (psrc == NULL)
|
||||
return SRC_ERR_BAD_STATE ;
|
||||
if (psrc->process == NULL)
|
||||
if (psrc->vari_process == NULL || psrc->const_process == NULL)
|
||||
return SRC_ERR_BAD_PROC_PTR ;
|
||||
|
||||
if (psrc->mode != SRC_MODE_PROCESS)
|
||||
@@ -122,7 +133,7 @@ src_process (SRC_STATE *state, SRC_DATA *data)
|
||||
return SRC_ERR_BAD_DATA ;
|
||||
|
||||
/* Check src_ratio is in range. */
|
||||
if (data->src_ratio < (1.0 / SRC_MAX_RATIO) || data->src_ratio > (1.0 * SRC_MAX_RATIO))
|
||||
if (is_bad_src_ratio (data->src_ratio))
|
||||
return SRC_ERR_BAD_SRC_RATIO ;
|
||||
|
||||
/* And that data_in and data_out are valid. */
|
||||
@@ -161,7 +172,10 @@ src_process (SRC_STATE *state, SRC_DATA *data)
|
||||
psrc->last_ratio = data->src_ratio ;
|
||||
|
||||
/* Now process. */
|
||||
error = psrc->process (psrc, data) ;
|
||||
if (fabs (psrc->last_ratio - data->src_ratio) < 1e-15)
|
||||
error = psrc->const_process (psrc, data) ;
|
||||
else
|
||||
error = psrc->vari_process (psrc, data) ;
|
||||
|
||||
return error ;
|
||||
} /* src_process */
|
||||
@@ -195,7 +209,7 @@ src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data)
|
||||
memset (&src_data, 0, sizeof (src_data)) ;
|
||||
|
||||
/* Check src_ratio is in range. */
|
||||
if (src_ratio < (1.0 / SRC_MAX_RATIO) || src_ratio > (1.0 * SRC_MAX_RATIO))
|
||||
if (is_bad_src_ratio (src_ratio))
|
||||
{ psrc->error = SRC_ERR_BAD_SRC_RATIO ;
|
||||
return 0 ;
|
||||
} ;
|
||||
@@ -267,9 +281,12 @@ src_set_ratio (SRC_STATE *state, double new_ratio)
|
||||
|
||||
if (psrc == NULL)
|
||||
return SRC_ERR_BAD_STATE ;
|
||||
if (psrc->process == NULL)
|
||||
if (psrc->vari_process == NULL || psrc->const_process == NULL)
|
||||
return SRC_ERR_BAD_PROC_PTR ;
|
||||
|
||||
if (is_bad_src_ratio (new_ratio))
|
||||
return SRC_ERR_BAD_SRC_RATIO ;
|
||||
|
||||
psrc->last_ratio = new_ratio ;
|
||||
|
||||
return SRC_ERR_NO_ERROR ;
|
||||
@@ -334,13 +351,13 @@ src_get_description (int converter_type)
|
||||
|
||||
const char *
|
||||
src_get_version (void)
|
||||
{ return PACKAGE "-" VERSION ;
|
||||
{ return PACKAGE "-" VERSION " (c) 2002-2008 Erik de Castro Lopo" ;
|
||||
} /* src_get_version */
|
||||
|
||||
int
|
||||
src_is_valid_ratio (double ratio)
|
||||
{
|
||||
if (ratio < (1.0 / SRC_MAX_RATIO) || ratio > (1.0 * SRC_MAX_RATIO))
|
||||
if (is_bad_src_ratio (ratio))
|
||||
return SRC_FALSE ;
|
||||
|
||||
return SRC_TRUE ;
|
||||
@@ -401,6 +418,8 @@ src_strerror (int error)
|
||||
return "Calling mode differs from initialisation mode (ie process v callback)." ;
|
||||
case SRC_ERR_NULL_CALLBACK :
|
||||
return "Callback function pointer is NULL in src_callback_read ()." ;
|
||||
case SRC_ERR_NO_VARIABLE_RATIO :
|
||||
return "This converter only allows constant conversion ratios." ;
|
||||
|
||||
case SRC_ERR_MAX_ERROR :
|
||||
return "Placeholder. No error defined for this error number." ;
|
||||
@@ -438,7 +457,7 @@ src_short_to_float_array (const short *in, float *out, int len)
|
||||
{
|
||||
while (len)
|
||||
{ len -- ;
|
||||
out [len] = in [len] / (1.0 * 0x8000) ;
|
||||
out [len] = (float) (in [len] / (1.0 * 0x8000)) ;
|
||||
} ;
|
||||
|
||||
return ;
|
||||
@@ -446,7 +465,7 @@ src_short_to_float_array (const short *in, float *out, int len)
|
||||
|
||||
void
|
||||
src_float_to_short_array (const float *in, short *out, int len)
|
||||
{ float scaled_value ;
|
||||
{ double scaled_value ;
|
||||
|
||||
while (len)
|
||||
{ len -- ;
|
||||
@@ -461,11 +480,44 @@ src_float_to_short_array (const float *in, short *out, int len)
|
||||
continue ;
|
||||
} ;
|
||||
|
||||
out [len] = (lrintf (scaled_value) >> 16) ;
|
||||
out [len] = (short) (lrint (scaled_value) >> 16) ;
|
||||
} ;
|
||||
|
||||
} /* src_float_to_short_array */
|
||||
|
||||
void
|
||||
src_int_to_float_array (const int *in, float *out, int len)
|
||||
{
|
||||
while (len)
|
||||
{ len -- ;
|
||||
out [len] = (float) (in [len] / (8.0 * 0x10000000)) ;
|
||||
} ;
|
||||
|
||||
return ;
|
||||
} /* src_int_to_float_array */
|
||||
|
||||
void
|
||||
src_float_to_int_array (const float *in, int *out, int len)
|
||||
{ double scaled_value ;
|
||||
|
||||
while (len)
|
||||
{ len -- ;
|
||||
|
||||
scaled_value = in [len] * (8.0 * 0x10000000) ;
|
||||
if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
|
||||
{ out [len] = 0x7fffffff ;
|
||||
continue ;
|
||||
} ;
|
||||
if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
|
||||
{ out [len] = -1 - 0x7fffffff ;
|
||||
continue ;
|
||||
} ;
|
||||
|
||||
out [len] = lrint (scaled_value) ;
|
||||
} ;
|
||||
|
||||
} /* src_float_to_int_array */
|
||||
|
||||
/*==============================================================================
|
||||
** Private functions.
|
||||
*/
|
||||
@@ -485,11 +537,3 @@ psrc_set_converter (SRC_PRIVATE *psrc, int converter_type)
|
||||
return SRC_ERR_BAD_CONVERTER ;
|
||||
} /* psrc_set_converter */
|
||||
|
||||
/*
|
||||
** Do not edit or modify anything in this comment block.
|
||||
** The arch-tag line is a file identity tag for the GNU Arch
|
||||
** revision control system.
|
||||
**
|
||||
** arch-tag: a5c5f514-a370-4210-a066-7f2035de67fb
|
||||
*/
|
||||
|
||||
|
||||
21
src/3rdparty/samplerate/samplerate.h
vendored
21
src/3rdparty/samplerate/samplerate.h
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
@@ -16,6 +16,12 @@
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This code is part of Secret Rabibt Code aka libsamplerate. A commercial
|
||||
** use license for this code is available, please see:
|
||||
** http://www.mega-nerd.com/SRC/procedure.html
|
||||
*/
|
||||
|
||||
/*
|
||||
** API documentation is available here:
|
||||
** http://www.mega-nerd.com/SRC/api.html
|
||||
@@ -168,7 +174,7 @@ enum
|
||||
SRC_SINC_MEDIUM_QUALITY = 1,
|
||||
SRC_SINC_FASTEST = 2,
|
||||
SRC_ZERO_ORDER_HOLD = 3,
|
||||
SRC_LINEAR = 4
|
||||
SRC_LINEAR = 4,
|
||||
} ;
|
||||
|
||||
/*
|
||||
@@ -179,6 +185,9 @@ enum
|
||||
void src_short_to_float_array (const short *in, float *out, int len) ;
|
||||
void src_float_to_short_array (const float *in, short *out, int len) ;
|
||||
|
||||
void src_int_to_float_array (const int *in, float *out, int len) ;
|
||||
void src_float_to_int_array (const float *in, int *out, int len) ;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
@@ -186,11 +195,3 @@ void src_float_to_short_array (const float *in, short *out, int len) ;
|
||||
|
||||
#endif /* SAMPLERATE_H */
|
||||
|
||||
/*
|
||||
** Do not edit or modify anything in this comment block.
|
||||
** The arch-tag line is a file identity tag for the GNU Arch
|
||||
** revision control system.
|
||||
**
|
||||
** arch-tag: 5421ef3e-c898-4ec3-8671-ea03d943ee00
|
||||
*/
|
||||
|
||||
|
||||
65
src/3rdparty/samplerate/src_linear.c
vendored
65
src/3rdparty/samplerate/src_linear.c
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
@@ -16,6 +16,12 @@
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This code is part of Secret Rabibt Code aka libsamplerate. A commercial
|
||||
** use license for this code is available, please see:
|
||||
** http://www.mega-nerd.com/SRC/procedure.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -24,7 +30,7 @@
|
||||
#include "float_cast.h"
|
||||
#include "common.h"
|
||||
|
||||
static int linear_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
|
||||
static int linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
|
||||
static void linear_reset (SRC_PRIVATE *psrc) ;
|
||||
|
||||
/*========================================================================================
|
||||
@@ -37,6 +43,7 @@ static void linear_reset (SRC_PRIVATE *psrc) ;
|
||||
typedef struct
|
||||
{ int linear_magic_marker ;
|
||||
int channels ;
|
||||
int reset ;
|
||||
long in_count, in_used ;
|
||||
long out_count, out_gen ;
|
||||
float last_value [1] ;
|
||||
@@ -46,9 +53,9 @@ typedef struct
|
||||
*/
|
||||
|
||||
static int
|
||||
linear_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
{ LINEAR_DATA *linear ;
|
||||
double src_ratio, input_index ;
|
||||
double src_ratio, input_index, rem ;
|
||||
int ch ;
|
||||
|
||||
if (psrc->private_data == NULL)
|
||||
@@ -56,6 +63,13 @@ linear_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
|
||||
linear = (LINEAR_DATA*) psrc->private_data ;
|
||||
|
||||
if (linear->reset)
|
||||
{ /* If we have just been reset, set the last_value data. */
|
||||
for (ch = 0 ; ch < linear->channels ; ch++)
|
||||
linear->last_value [ch] = data->data_in [ch] ;
|
||||
linear->reset = 0 ;
|
||||
} ;
|
||||
|
||||
linear->in_count = data->input_frames * linear->channels ;
|
||||
linear->out_count = data->output_frames * linear->channels ;
|
||||
linear->in_used = linear->out_gen = 0 ;
|
||||
@@ -69,12 +83,12 @@ linear_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
if (linear->in_used + linear->channels * input_index > linear->in_count)
|
||||
break ;
|
||||
|
||||
if (fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
|
||||
src_ratio = psrc->last_ratio + linear->out_gen * (data->src_ratio - psrc->last_ratio) / (linear->out_count - 1) ;
|
||||
if (linear->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
|
||||
src_ratio = psrc->last_ratio + linear->out_gen * (data->src_ratio - psrc->last_ratio) / linear->out_count ;
|
||||
|
||||
for (ch = 0 ; ch < linear->channels ; ch++)
|
||||
{ data->data_out [linear->out_gen] = linear->last_value [ch] + input_index *
|
||||
(data->data_in [ch] - linear->last_value [ch]) ;
|
||||
{ data->data_out [linear->out_gen] = (float) (linear->last_value [ch] + input_index *
|
||||
(data->data_in [ch] - linear->last_value [ch])) ;
|
||||
linear->out_gen ++ ;
|
||||
} ;
|
||||
|
||||
@@ -82,14 +96,15 @@ linear_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
input_index += 1.0 / src_ratio ;
|
||||
} ;
|
||||
|
||||
linear->in_used += linear->channels * lrint (floor (input_index)) ;
|
||||
input_index -= floor (input_index) ;
|
||||
rem = fmod_one (input_index) ;
|
||||
linear->in_used += linear->channels * lrint (input_index - rem) ;
|
||||
input_index = rem ;
|
||||
|
||||
/* Main processing loop. */
|
||||
while (linear->out_gen < linear->out_count && linear->in_used + linear->channels * input_index <= linear->in_count)
|
||||
{
|
||||
if (fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
|
||||
src_ratio = psrc->last_ratio + linear->out_gen * (data->src_ratio - psrc->last_ratio) / (linear->out_count - 1) ;
|
||||
if (linear->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
|
||||
src_ratio = psrc->last_ratio + linear->out_gen * (data->src_ratio - psrc->last_ratio) / linear->out_count ;
|
||||
|
||||
if (SRC_DEBUG && linear->in_used < linear->channels && input_index < 1.0)
|
||||
{ printf ("Whoops!!!! in_used : %ld channels : %d input_index : %f\n", linear->in_used, linear->channels, input_index) ;
|
||||
@@ -97,20 +112,21 @@ linear_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
} ;
|
||||
|
||||
for (ch = 0 ; ch < linear->channels ; ch++)
|
||||
{ data->data_out [linear->out_gen] = data->data_in [linear->in_used - linear->channels + ch] + input_index *
|
||||
(data->data_in [linear->in_used + ch] - data->data_in [linear->in_used - linear->channels + ch]) ;
|
||||
{ data->data_out [linear->out_gen] = (float) (data->data_in [linear->in_used - linear->channels + ch] + input_index *
|
||||
(data->data_in [linear->in_used + ch] - data->data_in [linear->in_used - linear->channels + ch])) ;
|
||||
linear->out_gen ++ ;
|
||||
} ;
|
||||
|
||||
/* Figure out the next index. */
|
||||
input_index += 1.0 / src_ratio ;
|
||||
rem = fmod_one (input_index) ;
|
||||
|
||||
linear->in_used += linear->channels * lrint (floor (input_index)) ;
|
||||
input_index -= floor (input_index) ;
|
||||
linear->in_used += linear->channels * lrint (input_index - rem) ;
|
||||
input_index = rem ;
|
||||
} ;
|
||||
|
||||
if (linear->in_used > linear->in_count)
|
||||
{ input_index += linear->in_used - linear->in_count ;
|
||||
{ input_index += (linear->in_used - linear->in_count) / linear->channels ;
|
||||
linear->in_used = linear->in_count ;
|
||||
} ;
|
||||
|
||||
@@ -127,7 +143,7 @@ linear_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
data->output_frames_gen = linear->out_gen / linear->channels ;
|
||||
|
||||
return SRC_ERR_NO_ERROR ;
|
||||
} /* linear_process */
|
||||
} /* linear_vari_process */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -175,7 +191,8 @@ linear_set_converter (SRC_PRIVATE *psrc, int src_enum)
|
||||
linear->linear_magic_marker = LINEAR_MAGIC_MARKER ;
|
||||
linear->channels = psrc->channels ;
|
||||
|
||||
psrc->process = linear_process ;
|
||||
psrc->const_process = linear_vari_process ;
|
||||
psrc->vari_process = linear_vari_process ;
|
||||
psrc->reset = linear_reset ;
|
||||
|
||||
linear_reset (psrc) ;
|
||||
@@ -194,13 +211,9 @@ linear_reset (SRC_PRIVATE *psrc)
|
||||
if (linear == NULL)
|
||||
return ;
|
||||
|
||||
linear->channels = psrc->channels ;
|
||||
linear->reset = 1 ;
|
||||
|
||||
memset (linear->last_value, 0, sizeof (linear->last_value [0]) * linear->channels) ;
|
||||
} /* linear_reset */
|
||||
/*
|
||||
** Do not edit or modify anything in this comment block.
|
||||
** The arch-tag line is a file identity tag for the GNU Arch
|
||||
** revision control system.
|
||||
**
|
||||
** arch-tag: 7eac3103-3d84-45d3-8bbd-f409c2b2d1a9
|
||||
*/
|
||||
|
||||
|
||||
182
src/3rdparty/samplerate/src_sinc.c
vendored
182
src/3rdparty/samplerate/src_sinc.c
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
@@ -16,6 +16,12 @@
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This code is part of Secret Rabibt Code aka libsamplerate. A commercial
|
||||
** use license for this code is available, please see:
|
||||
** http://www.mega-nerd.com/SRC/procedure.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -26,31 +32,14 @@
|
||||
|
||||
#define SINC_MAGIC_MARKER MAKE_MAGIC (' ', 's', 'i', 'n', 'c', ' ')
|
||||
|
||||
#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
|
||||
|
||||
/*========================================================================================
|
||||
** Macros for handling the index into the array for the filter.
|
||||
** Double precision floating point is not accurate enough so use a 64 bit
|
||||
** fixed point value instead. SHIFT_BITS (current value of 48) is the number
|
||||
** of bits to the right of the decimal point.
|
||||
** The rest of the macros are for retrieving the fractional and integer parts
|
||||
** and for converting floats and ints to the fixed point format or from the
|
||||
** fixed point type back to integers and floats.
|
||||
*/
|
||||
|
||||
#define MAKE_INCREMENT_T(x) ((increment_t) (x))
|
||||
|
||||
#define SHIFT_BITS 16
|
||||
#define SHIFT_BITS 12
|
||||
#define FP_ONE ((double) (((increment_t) 1) << SHIFT_BITS))
|
||||
|
||||
#define DOUBLE_TO_FP(x) (lrint ((x) * FP_ONE))
|
||||
#define INT_TO_FP(x) (((increment_t) (x)) << SHIFT_BITS)
|
||||
|
||||
#define FP_FRACTION_PART(x) ((x) & ((((increment_t) 1) << SHIFT_BITS) - 1))
|
||||
#define FP_INTEGER_PART(x) ((x) & (((increment_t) -1) << SHIFT_BITS))
|
||||
|
||||
#define FP_TO_INT(x) (((x) >> SHIFT_BITS))
|
||||
#define FP_TO_DOUBLE(x) (FP_FRACTION_PART (x) / FP_ONE)
|
||||
#define INV_FP_ONE (1.0 / FP_ONE)
|
||||
|
||||
/*========================================================================================
|
||||
*/
|
||||
@@ -58,13 +47,9 @@
|
||||
typedef int32_t increment_t ;
|
||||
typedef float coeff_t ;
|
||||
|
||||
enum
|
||||
{
|
||||
STATE_BUFFER_START = 101,
|
||||
STATE_DATA_CONTINUE = 102,
|
||||
STATE_BUFFER_END = 103,
|
||||
STATE_FINISHED
|
||||
} ;
|
||||
#include "fastest_coeffs.h"
|
||||
#include "mid_qual_coeffs.h"
|
||||
#include "high_qual_coeffs.h"
|
||||
|
||||
typedef struct
|
||||
{ int sinc_magic_marker ;
|
||||
@@ -74,18 +59,16 @@ typedef struct
|
||||
long out_count, out_gen ;
|
||||
|
||||
int coeff_half_len, index_inc ;
|
||||
int has_diffs ;
|
||||
|
||||
double src_ratio, input_index ;
|
||||
|
||||
int coeff_len ;
|
||||
coeff_t const *coeffs ;
|
||||
|
||||
int b_current, b_end, b_real_end, b_len ;
|
||||
float buffer [1] ;
|
||||
} SINC_FILTER ;
|
||||
|
||||
static int sinc_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
|
||||
static int sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
|
||||
|
||||
static double calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) ;
|
||||
|
||||
@@ -93,20 +76,33 @@ static void prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_c
|
||||
|
||||
static void sinc_reset (SRC_PRIVATE *psrc) ;
|
||||
|
||||
static coeff_t const high_qual_coeffs [] =
|
||||
{
|
||||
#include "high_qual_coeffs.h"
|
||||
} ; /* high_qual_coeffs */
|
||||
static inline increment_t
|
||||
double_to_fp (double x)
|
||||
{ if (sizeof (increment_t) == 8)
|
||||
return (llrint ((x) * FP_ONE)) ;
|
||||
return (lrint ((x) * FP_ONE)) ;
|
||||
} /* double_to_fp */
|
||||
|
||||
static coeff_t const mid_qual_coeffs [] =
|
||||
{
|
||||
#include "mid_qual_coeffs.h"
|
||||
} ; /* mid_qual_coeffs */
|
||||
static inline increment_t
|
||||
int_to_fp (int x)
|
||||
{ return (((increment_t) (x)) << SHIFT_BITS) ;
|
||||
} /* int_to_fp */
|
||||
|
||||
static inline int
|
||||
fp_to_int (increment_t x)
|
||||
{ return (((x) >> SHIFT_BITS)) ;
|
||||
} /* fp_to_int */
|
||||
|
||||
static inline increment_t
|
||||
fp_fraction_part (increment_t x)
|
||||
{ return ((x) & ((((increment_t) 1) << SHIFT_BITS) - 1)) ;
|
||||
} /* fp_fraction_part */
|
||||
|
||||
static inline double
|
||||
fp_to_double (increment_t x)
|
||||
{ return fp_fraction_part (x) * INV_FP_ONE ;
|
||||
} /* fp_to_double */
|
||||
|
||||
static coeff_t const fastest_coeffs [] =
|
||||
{
|
||||
#include "fastest_coeffs.h"
|
||||
} ; /* fastest_coeffs */
|
||||
|
||||
/*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -123,6 +119,8 @@ sinc_get_name (int src_enum)
|
||||
|
||||
case SRC_SINC_FASTEST :
|
||||
return "Fastest Sinc Interpolator" ;
|
||||
|
||||
default: break ;
|
||||
} ;
|
||||
|
||||
return NULL ;
|
||||
@@ -132,14 +130,17 @@ const char*
|
||||
sinc_get_description (int src_enum)
|
||||
{
|
||||
switch (src_enum)
|
||||
{ case SRC_SINC_BEST_QUALITY :
|
||||
return "Band limited sinc interpolation, best quality, 97dB SNR, 96% BW." ;
|
||||
{ case SRC_SINC_FASTEST :
|
||||
return "Band limited sinc interpolation, fastest, 97dB SNR, 80% BW." ;
|
||||
|
||||
case SRC_SINC_MEDIUM_QUALITY :
|
||||
return "Band limited sinc interpolation, medium quality, 97dB SNR, 90% BW." ;
|
||||
return "Band limited sinc interpolation, medium quality, 121dB SNR, 90% BW." ;
|
||||
|
||||
case SRC_SINC_FASTEST :
|
||||
return "Band limited sinc interpolation, fastest, 97dB SNR, 80% BW." ;
|
||||
case SRC_SINC_BEST_QUALITY :
|
||||
return "Band limited sinc interpolation, best quality, 145dB SNR, 96% BW." ;
|
||||
|
||||
default :
|
||||
break ;
|
||||
} ;
|
||||
|
||||
return NULL ;
|
||||
@@ -148,7 +149,8 @@ sinc_get_description (int src_enum)
|
||||
int
|
||||
sinc_set_converter (SRC_PRIVATE *psrc, int src_enum)
|
||||
{ SINC_FILTER *filter, temp_filter ;
|
||||
int count, bits ;
|
||||
increment_t count ;
|
||||
int bits ;
|
||||
|
||||
/* Quick sanity check. */
|
||||
if (SHIFT_BITS >= sizeof (increment_t) * 8 - 1)
|
||||
@@ -167,32 +169,27 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum)
|
||||
temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ;
|
||||
temp_filter.channels = psrc->channels ;
|
||||
|
||||
psrc->process = sinc_process ;
|
||||
psrc->const_process = sinc_vari_process ;
|
||||
psrc->vari_process = sinc_vari_process ;
|
||||
psrc->reset = sinc_reset ;
|
||||
|
||||
switch (src_enum)
|
||||
{ case SRC_SINC_BEST_QUALITY :
|
||||
temp_filter.coeffs = high_qual_coeffs ;
|
||||
temp_filter.coeff_half_len = ARRAY_LEN (high_qual_coeffs) - 1 ;
|
||||
temp_filter.index_inc = 128 ;
|
||||
temp_filter.has_diffs = SRC_FALSE ;
|
||||
temp_filter.coeff_len = ARRAY_LEN (high_qual_coeffs) ;
|
||||
{ case SRC_SINC_FASTEST :
|
||||
temp_filter.coeffs = fastest_coeffs.coeffs ;
|
||||
temp_filter.coeff_half_len = ARRAY_LEN (fastest_coeffs.coeffs) - 1 ;
|
||||
temp_filter.index_inc = fastest_coeffs.increment ;
|
||||
break ;
|
||||
|
||||
case SRC_SINC_MEDIUM_QUALITY :
|
||||
temp_filter.coeffs = mid_qual_coeffs ;
|
||||
temp_filter.coeff_half_len = ARRAY_LEN (mid_qual_coeffs) - 1 ;
|
||||
temp_filter.index_inc = 128 ;
|
||||
temp_filter.has_diffs = SRC_FALSE ;
|
||||
temp_filter.coeff_len = ARRAY_LEN (mid_qual_coeffs) ;
|
||||
temp_filter.coeffs = slow_mid_qual_coeffs.coeffs ;
|
||||
temp_filter.coeff_half_len = ARRAY_LEN (slow_mid_qual_coeffs.coeffs) - 1 ;
|
||||
temp_filter.index_inc = slow_mid_qual_coeffs.increment ;
|
||||
break ;
|
||||
|
||||
case SRC_SINC_FASTEST :
|
||||
temp_filter.coeffs = fastest_coeffs ;
|
||||
temp_filter.coeff_half_len = ARRAY_LEN (fastest_coeffs) - 1 ;
|
||||
temp_filter.index_inc = 128 ;
|
||||
temp_filter.has_diffs = SRC_FALSE ;
|
||||
temp_filter.coeff_len = ARRAY_LEN (fastest_coeffs) ;
|
||||
case SRC_SINC_BEST_QUALITY :
|
||||
temp_filter.coeffs = slow_high_qual_coeffs.coeffs ;
|
||||
temp_filter.coeff_half_len = ARRAY_LEN (slow_high_qual_coeffs.coeffs) - 1 ;
|
||||
temp_filter.index_inc = slow_high_qual_coeffs.increment ;
|
||||
break ;
|
||||
|
||||
default :
|
||||
@@ -204,7 +201,8 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum)
|
||||
** a better way. Need to look at prepare_data () at the same time.
|
||||
*/
|
||||
|
||||
temp_filter.b_len = 1000 + 2 * lrint (0.5 + temp_filter.coeff_len / (temp_filter.index_inc * 1.0) * SRC_MAX_RATIO) ;
|
||||
temp_filter.b_len = 1000 + 2 * lrint (0.5 + 2 * temp_filter.coeff_half_len / (temp_filter.index_inc * 1.0) * SRC_MAX_RATIO) ;
|
||||
temp_filter.b_len = MIN (temp_filter.b_len, 4096) ;
|
||||
temp_filter.b_len *= temp_filter.channels ;
|
||||
|
||||
if ((filter = calloc (1, sizeof (SINC_FILTER) + sizeof (filter->buffer [0]) * (temp_filter.b_len + temp_filter.channels))) == NULL)
|
||||
@@ -218,8 +216,8 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum)
|
||||
sinc_reset (psrc) ;
|
||||
|
||||
count = filter->coeff_half_len ;
|
||||
for (bits = 0 ; (1 << bits) < count ; bits++)
|
||||
count |= (1 << bits) ;
|
||||
for (bits = 0 ; (MAKE_INCREMENT_T (1) << bits) < count ; bits++)
|
||||
count |= (MAKE_INCREMENT_T (1) << bits) ;
|
||||
|
||||
if (bits + SHIFT_BITS - 1 >= (int) (sizeof (increment_t) * 8))
|
||||
return SRC_ERR_FILTER_LEN ;
|
||||
@@ -251,7 +249,7 @@ sinc_reset (SRC_PRIVATE *psrc)
|
||||
*/
|
||||
|
||||
static int
|
||||
sinc_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
{ SINC_FILTER *filter ;
|
||||
double input_index, src_ratio, count, float_increment, terminate, rem ;
|
||||
increment_t increment, start_filter_index ;
|
||||
@@ -283,7 +281,7 @@ sinc_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
input_index = psrc->last_position ;
|
||||
float_increment = filter->index_inc ;
|
||||
|
||||
rem = fmod (input_index, 1.0) ;
|
||||
rem = fmod_one (input_index) ;
|
||||
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
|
||||
input_index = rem ;
|
||||
|
||||
@@ -309,26 +307,26 @@ sinc_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
break ;
|
||||
} ;
|
||||
|
||||
if (fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
|
||||
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / (filter->out_count - 1) ;
|
||||
if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
|
||||
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
|
||||
|
||||
float_increment = filter->index_inc * 1.0 ;
|
||||
if (src_ratio < 1.0)
|
||||
float_increment = filter->index_inc * src_ratio ;
|
||||
|
||||
increment = DOUBLE_TO_FP (float_increment) ;
|
||||
increment = double_to_fp (float_increment) ;
|
||||
|
||||
start_filter_index = DOUBLE_TO_FP (input_index * float_increment) ;
|
||||
start_filter_index = double_to_fp (input_index * float_increment) ;
|
||||
|
||||
for (ch = 0 ; ch < filter->channels ; ch++)
|
||||
{ data->data_out [filter->out_gen] = (float_increment / filter->index_inc) *
|
||||
calc_output (filter, increment, start_filter_index, ch) ;
|
||||
{ data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) *
|
||||
calc_output (filter, increment, start_filter_index, ch)) ;
|
||||
filter->out_gen ++ ;
|
||||
} ;
|
||||
|
||||
/* Figure out the next index. */
|
||||
input_index += 1.0 / src_ratio ;
|
||||
rem = fmod (input_index, 1.0) ;
|
||||
rem = fmod_one (input_index) ;
|
||||
|
||||
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
|
||||
input_index = rem ;
|
||||
@@ -343,7 +341,7 @@ sinc_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
data->output_frames_gen = filter->out_gen / filter->channels ;
|
||||
|
||||
return SRC_ERR_NO_ERROR ;
|
||||
} /* sinc_process */
|
||||
} /* sinc_vari_process */
|
||||
|
||||
/*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -423,22 +421,22 @@ calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filte
|
||||
int data_index, coeff_count, indx ;
|
||||
|
||||
/* Convert input parameters into fixed point. */
|
||||
max_filter_index = INT_TO_FP (filter->coeff_half_len) ;
|
||||
max_filter_index = int_to_fp (filter->coeff_half_len) ;
|
||||
|
||||
/* First apply the left half of the filter. */
|
||||
filter_index = start_filter_index ;
|
||||
coeff_count = (max_filter_index - filter_index) / increment ;
|
||||
filter_index = filter_index + coeff_count * increment ;
|
||||
data_index = filter->b_current - filter->channels * coeff_count ;
|
||||
data_index = filter->b_current - filter->channels * coeff_count + ch ;
|
||||
|
||||
left = 0.0 ;
|
||||
do
|
||||
{ fraction = FP_TO_DOUBLE (filter_index) ;
|
||||
indx = FP_TO_INT (filter_index) ;
|
||||
{ fraction = fp_to_double (filter_index) ;
|
||||
indx = fp_to_int (filter_index) ;
|
||||
|
||||
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
|
||||
|
||||
left += icoeff * filter->buffer [data_index + ch] ;
|
||||
left += icoeff * filter->buffer [data_index] ;
|
||||
|
||||
filter_index -= increment ;
|
||||
data_index = data_index + filter->channels ;
|
||||
@@ -449,16 +447,16 @@ calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filte
|
||||
filter_index = increment - start_filter_index ;
|
||||
coeff_count = (max_filter_index - filter_index) / increment ;
|
||||
filter_index = filter_index + coeff_count * increment ;
|
||||
data_index = filter->b_current + filter->channels * (1 + coeff_count) ;
|
||||
data_index = filter->b_current + filter->channels * (1 + coeff_count) + ch ;
|
||||
|
||||
right = 0.0 ;
|
||||
do
|
||||
{ fraction = FP_TO_DOUBLE (filter_index) ;
|
||||
indx = FP_TO_INT (filter_index) ;
|
||||
{ fraction = fp_to_double (filter_index) ;
|
||||
indx = fp_to_int (filter_index) ;
|
||||
|
||||
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
|
||||
|
||||
right += icoeff * filter->buffer [data_index + ch] ;
|
||||
right += icoeff * filter->buffer [data_index] ;
|
||||
|
||||
filter_index -= increment ;
|
||||
data_index = data_index - filter->channels ;
|
||||
@@ -468,11 +466,3 @@ calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filte
|
||||
return (left + right) ;
|
||||
} /* calc_output */
|
||||
|
||||
/*
|
||||
** Do not edit or modify anything in this comment block.
|
||||
** The arch-tag line is a file identity tag for the GNU Arch
|
||||
** revision control system.
|
||||
**
|
||||
** arch-tag: db8efe06-2fbd-487e-be8f-bfc01e68c19f
|
||||
*/
|
||||
|
||||
|
||||
55
src/3rdparty/samplerate/src_zoh.c
vendored
55
src/3rdparty/samplerate/src_zoh.c
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
** Copyright (C) 2002-2008 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
@@ -16,6 +16,12 @@
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This code is part of Secret Rabibt Code aka libsamplerate. A commercial
|
||||
** use license for this code is available, please see:
|
||||
** http://www.mega-nerd.com/SRC/procedure.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -24,7 +30,7 @@
|
||||
#include "float_cast.h"
|
||||
#include "common.h"
|
||||
|
||||
static int zoh_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
|
||||
static int zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
|
||||
static void zoh_reset (SRC_PRIVATE *psrc) ;
|
||||
|
||||
/*========================================================================================
|
||||
@@ -35,6 +41,7 @@ static void zoh_reset (SRC_PRIVATE *psrc) ;
|
||||
typedef struct
|
||||
{ int zoh_magic_marker ;
|
||||
int channels ;
|
||||
int reset ;
|
||||
long in_count, in_used ;
|
||||
long out_count, out_gen ;
|
||||
float last_value [1] ;
|
||||
@@ -44,9 +51,9 @@ typedef struct
|
||||
*/
|
||||
|
||||
static int
|
||||
zoh_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
{ ZOH_DATA *zoh ;
|
||||
double src_ratio, input_index ;
|
||||
double src_ratio, input_index, rem ;
|
||||
int ch ;
|
||||
|
||||
if (psrc->private_data == NULL)
|
||||
@@ -54,6 +61,13 @@ zoh_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
|
||||
zoh = (ZOH_DATA*) psrc->private_data ;
|
||||
|
||||
if (zoh->reset)
|
||||
{ /* If we have just been reset, set the last_value data. */
|
||||
for (ch = 0 ; ch < zoh->channels ; ch++)
|
||||
zoh->last_value [ch] = data->data_in [ch] ;
|
||||
zoh->reset = 0 ;
|
||||
} ;
|
||||
|
||||
zoh->in_count = data->input_frames * zoh->channels ;
|
||||
zoh->out_count = data->output_frames * zoh->channels ;
|
||||
zoh->in_used = zoh->out_gen = 0 ;
|
||||
@@ -67,8 +81,8 @@ zoh_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
if (zoh->in_used + zoh->channels * input_index >= zoh->in_count)
|
||||
break ;
|
||||
|
||||
if (fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
|
||||
src_ratio = psrc->last_ratio + zoh->out_gen * (data->src_ratio - psrc->last_ratio) / (zoh->out_count - 1) ;
|
||||
if (zoh->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
|
||||
src_ratio = psrc->last_ratio + zoh->out_gen * (data->src_ratio - psrc->last_ratio) / zoh->out_count ;
|
||||
|
||||
for (ch = 0 ; ch < zoh->channels ; ch++)
|
||||
{ data->data_out [zoh->out_gen] = zoh->last_value [ch] ;
|
||||
@@ -79,14 +93,15 @@ zoh_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
input_index += 1.0 / src_ratio ;
|
||||
} ;
|
||||
|
||||
zoh->in_used += zoh->channels * lrint (floor (input_index)) ;
|
||||
input_index -= floor (input_index) ;
|
||||
rem = fmod_one (input_index) ;
|
||||
zoh->in_used += zoh->channels * lrint (input_index - rem) ;
|
||||
input_index = rem ;
|
||||
|
||||
/* Main processing loop. */
|
||||
while (zoh->out_gen < zoh->out_count && zoh->in_used + zoh->channels * input_index <= zoh->in_count)
|
||||
{
|
||||
if (fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
|
||||
src_ratio = psrc->last_ratio + zoh->out_gen * (data->src_ratio - psrc->last_ratio) / (zoh->out_count - 1) ;
|
||||
if (zoh->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
|
||||
src_ratio = psrc->last_ratio + zoh->out_gen * (data->src_ratio - psrc->last_ratio) / zoh->out_count ;
|
||||
|
||||
for (ch = 0 ; ch < zoh->channels ; ch++)
|
||||
{ data->data_out [zoh->out_gen] = data->data_in [zoh->in_used - zoh->channels + ch] ;
|
||||
@@ -95,13 +110,14 @@ zoh_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
|
||||
/* Figure out the next index. */
|
||||
input_index += 1.0 / src_ratio ;
|
||||
rem = fmod_one (input_index) ;
|
||||
|
||||
zoh->in_used += zoh->channels * lrint (floor (input_index)) ;
|
||||
input_index -= floor (input_index) ;
|
||||
zoh->in_used += zoh->channels * lrint (input_index - rem) ;
|
||||
input_index = rem ;
|
||||
} ;
|
||||
|
||||
if (zoh->in_used > zoh->in_count)
|
||||
{ input_index += zoh->in_used - zoh->in_count ;
|
||||
{ input_index += (zoh->in_used - zoh->in_count) / zoh->channels ;
|
||||
zoh->in_used = zoh->in_count ;
|
||||
} ;
|
||||
|
||||
@@ -118,7 +134,7 @@ zoh_process (SRC_PRIVATE *psrc, SRC_DATA *data)
|
||||
data->output_frames_gen = zoh->out_gen / zoh->channels ;
|
||||
|
||||
return SRC_ERR_NO_ERROR ;
|
||||
} /* zoh_process */
|
||||
} /* zoh_vari_process */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -166,7 +182,8 @@ zoh_set_converter (SRC_PRIVATE *psrc, int src_enum)
|
||||
zoh->zoh_magic_marker = ZOH_MAGIC_MARKER ;
|
||||
zoh->channels = psrc->channels ;
|
||||
|
||||
psrc->process = zoh_process ;
|
||||
psrc->const_process = zoh_vari_process ;
|
||||
psrc->vari_process = zoh_vari_process ;
|
||||
psrc->reset = zoh_reset ;
|
||||
|
||||
zoh_reset (psrc) ;
|
||||
@@ -186,15 +203,9 @@ zoh_reset (SRC_PRIVATE *psrc)
|
||||
return ;
|
||||
|
||||
zoh->channels = psrc->channels ;
|
||||
zoh->reset = 1 ;
|
||||
memset (zoh->last_value, 0, sizeof (zoh->last_value [0]) * zoh->channels) ;
|
||||
|
||||
return ;
|
||||
} /* zoh_reset */
|
||||
/*
|
||||
** Do not edit or modify anything in this comment block.
|
||||
** The arch-tag line is a file identity tag for the GNU Arch
|
||||
** revision control system.
|
||||
**
|
||||
** arch-tag: 808e62f8-2e4a-44a6-840f-180a3e41af01
|
||||
*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user