Add in tree aubio
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
0d952f80af
commit
2ae7009b0e
48 changed files with 8937 additions and 1 deletions
208
deps/aubio/src/aubio.h
vendored
Normal file
208
deps/aubio/src/aubio.h
vendored
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \mainpage
|
||||
|
||||
\section introduction Introduction
|
||||
|
||||
aubio is a library to extract annotations from audio signals: it provides a
|
||||
set of functions that take an input audio signal, and output pitch estimates,
|
||||
attack times (onset), beat location estimates, and other annotation tasks.
|
||||
|
||||
\section basics Basics
|
||||
|
||||
All object structures in aubio share the same function prefixes and suffixes:
|
||||
|
||||
- \p new_aubio_foo creates the object \p foo
|
||||
- \p aubio_foo_do executes the object \p foo
|
||||
- \p del_aubio_foo destroys the object \p foo
|
||||
|
||||
All memory allocation and deallocation take place in the \p new_ and \p del_
|
||||
functions. Optionally, more than one \p _do methods are available.
|
||||
Additional parameters can be adjusted and observed using:
|
||||
|
||||
- \p aubio_foo_get_param, getter function, gets the value of a parameter
|
||||
- \p aubio_foo_set_param, setter function, changes the value of a parameter
|
||||
|
||||
Unless specified in its documentation, no memory operations take place in the
|
||||
getter functions. However, memory resizing can take place in setter
|
||||
functions.
|
||||
|
||||
\subsection vectors Vectors
|
||||
|
||||
Two basic structures are being used in aubio: ::fvec_t and ::cvec_t. The
|
||||
::fvec_t structures are used to store vectors of floating pointer number.
|
||||
::cvec_t are used to store complex number, as two vectors of norm and phase
|
||||
elements.
|
||||
|
||||
Additionally, the ::lvec_t structure can be used to store floating point
|
||||
numbers in double precision. They are mostly used to store filter
|
||||
coefficients, to avoid instability.
|
||||
|
||||
\subsection objects Available objects
|
||||
|
||||
Here is a list of some of the most common objects for aubio:
|
||||
|
||||
\code
|
||||
|
||||
// fast Fourier transform (FFT)
|
||||
aubio_fft_t *fft = new_aubio_fft (winsize);
|
||||
// phase vocoder
|
||||
aubio_pvoc_t *pv = new_aubio_pvoc (winsize, stepsize);
|
||||
// onset detection
|
||||
aubio_onset_t *onset = new_aubio_onset (method, winsize, stepsize, samplerate);
|
||||
// pitch detection
|
||||
aubio_pitch_t *pitch = new_aubio_pitch (method, winsize, stepsize, samplerate);
|
||||
// beat tracking
|
||||
aubio_tempo_t *tempo = new_aubio_tempo (method, winsize, stepsize, samplerate);
|
||||
|
||||
\endcode
|
||||
|
||||
See the <a href="globals_type.html">list of typedefs</a> for a complete list.
|
||||
|
||||
\subsection example Example
|
||||
|
||||
Here is a simple example that creates an A-Weighting filter and applies it to a
|
||||
vector.
|
||||
|
||||
\code
|
||||
|
||||
// set window size, and sampling rate
|
||||
uint_t winsize = 1024, sr = 44100;
|
||||
// create a vector
|
||||
fvec_t *this_buffer = new_fvec (winsize);
|
||||
// create the a-weighting filter
|
||||
aubio_filter_t *this_filter = new_aubio_filter_a_weighting (sr);
|
||||
|
||||
while (running) {
|
||||
// here some code to put some data in this_buffer
|
||||
// ...
|
||||
|
||||
// apply the filter, in place
|
||||
aubio_filter_do (this_filter, this_buffer);
|
||||
|
||||
// here some code to get some data from this_buffer
|
||||
// ...
|
||||
}
|
||||
|
||||
// and free the structures
|
||||
del_aubio_filter (this_filter);
|
||||
del_fvec (this_buffer);
|
||||
|
||||
\endcode
|
||||
|
||||
Several examples of C programs are available in the \p examples/ and \p tests/src
|
||||
directories of the source tree.
|
||||
|
||||
Some examples:
|
||||
- @ref spectral/test-fft.c
|
||||
- @ref spectral/test-phasevoc.c
|
||||
- @ref onset/test-onset.c
|
||||
- @ref pitch/test-pitch.c
|
||||
- @ref tempo/test-tempo.c
|
||||
- @ref test-fvec.c
|
||||
- @ref test-cvec.c
|
||||
|
||||
\subsection unstable_api Unstable API
|
||||
|
||||
Several more functions are available and used within aubio, but not
|
||||
documented here, either because they are not considered useful to the user,
|
||||
or because they may need to be changed in the future. However, they can still
|
||||
be used by defining AUBIO_UNSTABLE to 1 before including the aubio header:
|
||||
|
||||
\code
|
||||
#define AUBIO_UNSTABLE 1
|
||||
#include <aubio/aubio.h>
|
||||
\endcode
|
||||
|
||||
Future versions of aubio could break API compatibility with these functions
|
||||
without warning. If you choose to use functions in AUBIO_UNSTABLE, you are on
|
||||
your own.
|
||||
|
||||
\section download Download
|
||||
|
||||
Latest versions, further documentation, examples, wiki, and mailing lists can
|
||||
be found at https://aubio.org .
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_H
|
||||
#define AUBIO_H
|
||||
|
||||
/** @file aubio.h Global aubio include file.
|
||||
|
||||
You will want to include this file as:
|
||||
|
||||
@code
|
||||
#include <aubio/aubio.h>
|
||||
@endcode
|
||||
|
||||
To access headers with unstable prototypes, use:
|
||||
|
||||
@code
|
||||
#define AUBIO_UNSTABLE 1
|
||||
#include <aubio/aubio.h>
|
||||
@endcode
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* in this order */
|
||||
#include "types.h"
|
||||
#include "fvec.h"
|
||||
// #include "cvec.h"
|
||||
// #include "lvec.h"
|
||||
// // #include "fmat.h"
|
||||
// #include "musicutils.h"
|
||||
// // #include "vecutils.h"
|
||||
// #include "temporal/resampler.h"
|
||||
// #include "temporal/filter.h"
|
||||
// #include "temporal/biquad.h"
|
||||
// #include "temporal/a_weighting.h"
|
||||
// #include "temporal/c_weighting.h"
|
||||
// #include "spectral/fft.h"
|
||||
// // #include "spectral/dct.h"
|
||||
// #include "spectral/phasevoc.h"
|
||||
// // #include "spectral/filterbank.h"
|
||||
// // #include "spectral/filterbank_mel.h"
|
||||
// // #include "spectral/mfcc.h"
|
||||
// // #include "spectral/specdesc.h"
|
||||
// // #include "spectral/awhitening.h"
|
||||
// // #include "spectral/tss.h"
|
||||
#include "pitch/pitch.h"
|
||||
// // #include "onset/onset.h"
|
||||
// // #include "tempo/tempo.h"
|
||||
// // #include "notes/notes.h"
|
||||
// // #include "io/source.h"
|
||||
// // #include "io/sink.h"
|
||||
// // #include "synth/sampler.h"
|
||||
// // #include "synth/wavetable.h"
|
||||
// // #include "utils/parameter.h"
|
||||
// #include "utils/log.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
359
deps/aubio/src/aubio_priv.h
vendored
Normal file
359
deps/aubio/src/aubio_priv.h
vendored
Normal file
|
@ -0,0 +1,359 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* Private include file
|
||||
*
|
||||
* This file is for inclusion from _within_ the library only.
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PRIV_H
|
||||
#define AUBIO_PRIV_H
|
||||
|
||||
/*********************
|
||||
*
|
||||
* External includes
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* must be included before fftw3.h */
|
||||
#ifdef HAVE_COMPLEX_H
|
||||
#include <complex.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FFTW3) || defined(HAVE_FFTW3F)
|
||||
#include <fftw3.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MATH_H
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h> // for CHAR_BIT, in C99 standard
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACCELERATE
|
||||
#define HAVE_ATLAS 1
|
||||
#include <Accelerate/Accelerate.h>
|
||||
#elif defined(HAVE_ATLAS_CBLAS_H)
|
||||
#define HAVE_ATLAS 1
|
||||
#include <atlas/cblas.h>
|
||||
#else
|
||||
#undef HAVE_ATLAS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACCELERATE
|
||||
#include <Accelerate/Accelerate.h>
|
||||
#ifndef HAVE_AUBIO_DOUBLE
|
||||
#define aubio_vDSP_mmov vDSP_mmov
|
||||
#define aubio_vDSP_vmul vDSP_vmul
|
||||
#define aubio_vDSP_vfill vDSP_vfill
|
||||
#define aubio_vDSP_meanv vDSP_meanv
|
||||
#define aubio_vDSP_sve vDSP_sve
|
||||
#define aubio_vDSP_maxv vDSP_maxv
|
||||
#define aubio_vDSP_maxvi vDSP_maxvi
|
||||
#define aubio_vDSP_minv vDSP_minv
|
||||
#define aubio_vDSP_minvi vDSP_minvi
|
||||
#define aubio_vDSP_dotpr vDSP_dotpr
|
||||
#define aubio_vDSP_vclr vDSP_vclr
|
||||
#else /* HAVE_AUBIO_DOUBLE */
|
||||
#define aubio_vDSP_mmov vDSP_mmovD
|
||||
#define aubio_vDSP_vmul vDSP_vmulD
|
||||
#define aubio_vDSP_vfill vDSP_vfillD
|
||||
#define aubio_vDSP_meanv vDSP_meanvD
|
||||
#define aubio_vDSP_sve vDSP_sveD
|
||||
#define aubio_vDSP_maxv vDSP_maxvD
|
||||
#define aubio_vDSP_maxvi vDSP_maxviD
|
||||
#define aubio_vDSP_minv vDSP_minvD
|
||||
#define aubio_vDSP_minvi vDSP_minviD
|
||||
#define aubio_vDSP_dotpr vDSP_dotprD
|
||||
#define aubio_vDSP_vclr vDSP_vclrD
|
||||
#endif /* HAVE_AUBIO_DOUBLE */
|
||||
#endif /* HAVE_ACCELERATE */
|
||||
|
||||
#ifdef HAVE_ATLAS
|
||||
#ifndef HAVE_AUBIO_DOUBLE
|
||||
#define aubio_catlas_set catlas_sset
|
||||
#define aubio_cblas_copy cblas_scopy
|
||||
#define aubio_cblas_swap cblas_sswap
|
||||
#define aubio_cblas_dot cblas_sdot
|
||||
#else /* HAVE_AUBIO_DOUBLE */
|
||||
#define aubio_catlas_set catlas_dset
|
||||
#define aubio_cblas_copy cblas_dcopy
|
||||
#define aubio_cblas_swap cblas_dswap
|
||||
#define aubio_cblas_dot cblas_ddot
|
||||
#endif /* HAVE_AUBIO_DOUBLE */
|
||||
#endif /* HAVE_ATLAS */
|
||||
|
||||
#if defined HAVE_INTEL_IPP
|
||||
#include <ippcore.h>
|
||||
#include <ippvm.h>
|
||||
#include <ipps.h>
|
||||
#ifndef HAVE_AUBIO_DOUBLE
|
||||
#define aubio_ippsSet ippsSet_32f
|
||||
#define aubio_ippsZero ippsZero_32f
|
||||
#define aubio_ippsCopy ippsCopy_32f
|
||||
#define aubio_ippsMul ippsMul_32f
|
||||
#define aubio_ippsMulC ippsMulC_32f
|
||||
#define aubio_ippsAddC ippsAddC_32f
|
||||
#define aubio_ippsLn ippsLn_32f_A21
|
||||
#define aubio_ippsMean(a,b,c) ippsMean_32f(a, b, c, ippAlgHintFast)
|
||||
#define aubio_ippsSum(a,b,c) ippsSum_32f(a, b, c, ippAlgHintFast)
|
||||
#define aubio_ippsMax ippsMax_32f
|
||||
#define aubio_ippsMin ippsMin_32f
|
||||
#else /* HAVE_AUBIO_DOUBLE */
|
||||
#define aubio_ippsSet ippsSet_64f
|
||||
#define aubio_ippsZero ippsZero_64f
|
||||
#define aubio_ippsCopy ippsCopy_64f
|
||||
#define aubio_ippsMul ippsMul_64f
|
||||
#define aubio_ippsMulC ippsMulC_64f
|
||||
#define aubio_ippsAddC ippsAddC_64f
|
||||
#define aubio_ippsLn ippsLn_64f_A26
|
||||
#define aubio_ippsMean ippsMean_64f
|
||||
#define aubio_ippsSum ippsSum_64f
|
||||
#define aubio_ippsMax ippsMax_64f
|
||||
#define aubio_ippsMin ippsMin_64f
|
||||
#endif /* HAVE_AUBIO_DOUBLE */
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_MEMCPY_HACKS) && !defined(HAVE_ACCELERATE) && !defined(HAVE_ATLAS) && !defined(HAVE_INTEL_IPP)
|
||||
#define HAVE_NOOPT 1
|
||||
#else
|
||||
#undef HAVE_NOOPT
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define AUBIO_UNSTABLE 1
|
||||
|
||||
#include "mathutils.h"
|
||||
|
||||
/****
|
||||
*
|
||||
* SYSTEM INTERFACE
|
||||
*
|
||||
*/
|
||||
|
||||
/* Memory management */
|
||||
#define AUBIO_MALLOC(_n) malloc(_n)
|
||||
#define AUBIO_REALLOC(_p,_n) realloc(_p,_n)
|
||||
#define AUBIO_NEW(_t) (_t*)calloc(sizeof(_t), 1)
|
||||
#define AUBIO_ARRAY(_t,_n) (_t*)calloc((_n)*sizeof(_t), 1)
|
||||
#define AUBIO_MEMCPY(_dst,_src,_n) memcpy(_dst,_src,_n)
|
||||
#define AUBIO_MEMSET(_dst,_src,_t) memset(_dst,_src,_t)
|
||||
#define AUBIO_FREE(_p) free(_p)
|
||||
|
||||
|
||||
/* file interface */
|
||||
#define AUBIO_FOPEN(_f,_m) fopen(_f,_m)
|
||||
#define AUBIO_FCLOSE(_f) fclose(_f)
|
||||
#define AUBIO_FREAD(_p,_s,_n,_f) fread(_p,_s,_n,_f)
|
||||
#define AUBIO_FSEEK(_f,_n,_set) fseek(_f,_n,_set)
|
||||
|
||||
/* strings */
|
||||
#define AUBIO_STRLEN(_s) strlen(_s)
|
||||
#define AUBIO_STRCMP(_s,_t) strcmp(_s,_t)
|
||||
#define AUBIO_STRNCMP(_s,_t,_n) strncmp(_s,_t,_n)
|
||||
#define AUBIO_STRCPY(_dst,_src) strcpy(_dst,_src)
|
||||
#define AUBIO_STRCHR(_s,_c) strchr(_s,_c)
|
||||
#ifdef strdup
|
||||
#define AUBIO_STRDUP(s) strdup(s)
|
||||
#else
|
||||
#define AUBIO_STRDUP(s) AUBIO_STRCPY(AUBIO_MALLOC(AUBIO_STRLEN(s) + 1), s)
|
||||
#endif
|
||||
|
||||
|
||||
/* Error reporting */
|
||||
typedef enum {
|
||||
AUBIO_OK = 0,
|
||||
AUBIO_FAIL = 1
|
||||
} aubio_status;
|
||||
|
||||
/* Logging */
|
||||
|
||||
#include "utils/log.h"
|
||||
|
||||
/** internal logging function, defined in utils/log.c */
|
||||
uint_t aubio_log(sint_t level, const char_t *fmt, ...);
|
||||
|
||||
#ifdef HAVE_C99_VARARGS_MACROS
|
||||
#define AUBIO_ERR(...) aubio_log(AUBIO_LOG_ERR, "AUBIO ERROR: " __VA_ARGS__)
|
||||
#define AUBIO_INF(...) aubio_log(AUBIO_LOG_INF, "AUBIO INFO: " __VA_ARGS__)
|
||||
#define AUBIO_MSG(...) aubio_log(AUBIO_LOG_MSG, __VA_ARGS__)
|
||||
#define AUBIO_DBG(...) aubio_log(AUBIO_LOG_DBG, __VA_ARGS__)
|
||||
#define AUBIO_WRN(...) aubio_log(AUBIO_LOG_WRN, "AUBIO WARNING: " __VA_ARGS__)
|
||||
#else
|
||||
#define AUBIO_ERR(format, args...) aubio_log(AUBIO_LOG_ERR, "AUBIO ERROR: " format , ##args)
|
||||
#define AUBIO_INF(format, args...) aubio_log(AUBIO_LOG_INF, "AUBIO INFO: " format , ##args)
|
||||
#define AUBIO_MSG(format, args...) aubio_log(AUBIO_LOG_MSG, format , ##args)
|
||||
#define AUBIO_DBG(format, args...) aubio_log(AUBIO_LOG_DBG, format , ##args)
|
||||
#define AUBIO_WRN(format, args...) aubio_log(AUBIO_LOG_WRN, "AUBIO WARNING: " format, ##args)
|
||||
#endif
|
||||
|
||||
#define AUBIO_ERROR AUBIO_ERR
|
||||
|
||||
#define AUBIO_QUIT(_s) exit(_s)
|
||||
#define AUBIO_SPRINTF sprintf
|
||||
|
||||
#define AUBIO_MAX_SAMPLERATE (192000*8)
|
||||
#define AUBIO_MAX_CHANNELS 1024
|
||||
|
||||
/* pi and 2*pi */
|
||||
#ifndef M_PI
|
||||
#define PI (3.14159265358979323846)
|
||||
#else
|
||||
#define PI (M_PI)
|
||||
#endif
|
||||
#define TWO_PI (PI*2.)
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
/* aliases to math.h functions */
|
||||
#if !HAVE_AUBIO_DOUBLE
|
||||
#define EXP expf
|
||||
#define COS cosf
|
||||
#define SIN sinf
|
||||
#define ABS fabsf
|
||||
#define POW powf
|
||||
#define SQRT sqrtf
|
||||
#define LOG10 log10f
|
||||
#define LOG logf
|
||||
#define FLOOR floorf
|
||||
#define CEIL ceilf
|
||||
#define ATAN atanf
|
||||
#define ATAN2 atan2f
|
||||
#else
|
||||
#error using double
|
||||
#define EXP exp
|
||||
#define COS cos
|
||||
#define SIN sin
|
||||
#define ABS fabs
|
||||
#define POW pow
|
||||
#define SQRT sqrt
|
||||
#define LOG10 log10
|
||||
#define LOG log
|
||||
#define FLOOR floor
|
||||
#define CEIL ceil
|
||||
#define ATAN atan
|
||||
#define ATAN2 atan2
|
||||
#endif
|
||||
#define ROUND(x) FLOOR(x+.5)
|
||||
|
||||
/* aliases to complex.h functions */
|
||||
#if HAVE_AUBIO_DOUBLE || !defined(HAVE_COMPLEX_H) || defined(WIN32)
|
||||
/* mingw32 does not know about c*f functions */
|
||||
#define EXPC cexp
|
||||
/** complex = CEXPC(complex) */
|
||||
#define CEXPC cexp
|
||||
/** sample = ARGC(complex) */
|
||||
#define ARGC carg
|
||||
/** sample = ABSC(complex) norm */
|
||||
#define ABSC cabs
|
||||
/** sample = REAL(complex) */
|
||||
#define REAL creal
|
||||
/** sample = IMAG(complex) */
|
||||
#define IMAG cimag
|
||||
#else
|
||||
/** sample = EXPC(complex) */
|
||||
#define EXPC cexpf
|
||||
/** complex = CEXPC(complex) */
|
||||
#define CEXPC cexp
|
||||
/** sample = ARGC(complex) */
|
||||
#define ARGC cargf
|
||||
/** sample = ABSC(complex) norm */
|
||||
#define ABSC cabsf
|
||||
/** sample = REAL(complex) */
|
||||
#define REAL crealf
|
||||
/** sample = IMAG(complex) */
|
||||
#define IMAG cimagf
|
||||
#endif
|
||||
|
||||
/* avoid unresolved symbol with msvc 9 */
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
#define isnan _isnan
|
||||
#endif
|
||||
|
||||
/* handy shortcuts */
|
||||
#define DB2LIN(g) (POW(10.0,(g)*0.05f))
|
||||
#define LIN2DB(v) (20.0*LOG10(v))
|
||||
#define SQR(_a) ((_a)*(_a))
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#endif /* MAX */
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif /* MIN */
|
||||
|
||||
#define ELEM_SWAP(a,b) { register smpl_t t=(a);(a)=(b);(b)=t; }
|
||||
|
||||
#define VERY_SMALL_NUMBER 2.e-42 //1.e-37
|
||||
|
||||
/** if ABS(f) < VERY_SMALL_NUMBER, returns 1, else 0 */
|
||||
#define IS_DENORMAL(f) ABS(f) < VERY_SMALL_NUMBER
|
||||
|
||||
/** if ABS(f) < VERY_SMALL_NUMBER, returns 0., else f */
|
||||
#define KILL_DENORMAL(f) IS_DENORMAL(f) ? 0. : f
|
||||
|
||||
/** if f > VERY_SMALL_NUMBER, returns f, else returns VERY_SMALL_NUMBER */
|
||||
#define CEIL_DENORMAL(f) f < VERY_SMALL_NUMBER ? VERY_SMALL_NUMBER : f
|
||||
|
||||
#define SAFE_LOG10(f) LOG10(CEIL_DENORMAL(f))
|
||||
#define SAFE_LOG(f) LOG(CEIL_DENORMAL(f))
|
||||
|
||||
/** silence unused parameter warning by adding an attribute */
|
||||
#if defined(__GNUC__)
|
||||
#define UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define UNUSED
|
||||
#endif
|
||||
|
||||
/* are we using gcc -std=c99 ? */
|
||||
#if defined(__STRICT_ANSI__)
|
||||
#define strnlen(a,b) MIN(strlen(a),b)
|
||||
#if !HAVE_AUBIO_DOUBLE
|
||||
#define floorf floor
|
||||
#endif
|
||||
#endif /* __STRICT_ANSI__ */
|
||||
|
||||
#endif /* AUBIO_PRIV_H */
|
169
deps/aubio/src/cvec.c
vendored
Normal file
169
deps/aubio/src/cvec.c
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "cvec.h"
|
||||
|
||||
cvec_t * new_cvec(uint_t length) {
|
||||
cvec_t * s;
|
||||
if ((sint_t)length <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
s = AUBIO_NEW(cvec_t);
|
||||
s->length = length/2 + 1;
|
||||
s->norm = AUBIO_ARRAY(smpl_t,s->length);
|
||||
s->phas = AUBIO_ARRAY(smpl_t,s->length);
|
||||
return s;
|
||||
}
|
||||
|
||||
void del_cvec(cvec_t *s) {
|
||||
AUBIO_FREE(s->norm);
|
||||
AUBIO_FREE(s->phas);
|
||||
AUBIO_FREE(s);
|
||||
}
|
||||
|
||||
void cvec_norm_set_sample (cvec_t *s, smpl_t data, uint_t position) {
|
||||
s->norm[position] = data;
|
||||
}
|
||||
|
||||
void cvec_phas_set_sample (cvec_t *s, smpl_t data, uint_t position) {
|
||||
s->phas[position] = data;
|
||||
}
|
||||
|
||||
smpl_t cvec_norm_get_sample (cvec_t *s, uint_t position) {
|
||||
return s->norm[position];
|
||||
}
|
||||
|
||||
smpl_t cvec_phas_get_sample (cvec_t *s, uint_t position) {
|
||||
return s->phas[position];
|
||||
}
|
||||
|
||||
smpl_t * cvec_norm_get_data (const cvec_t *s) {
|
||||
return s->norm;
|
||||
}
|
||||
|
||||
smpl_t * cvec_phas_get_data (const cvec_t *s) {
|
||||
return s->phas;
|
||||
}
|
||||
|
||||
/* helper functions */
|
||||
|
||||
void cvec_print(const cvec_t *s) {
|
||||
uint_t j;
|
||||
AUBIO_MSG("norm: ");
|
||||
for (j=0; j< s->length; j++) {
|
||||
AUBIO_MSG(AUBIO_SMPL_FMT " ", s->norm[j]);
|
||||
}
|
||||
AUBIO_MSG("\n");
|
||||
AUBIO_MSG("phas: ");
|
||||
for (j=0; j< s->length; j++) {
|
||||
AUBIO_MSG(AUBIO_SMPL_FMT " ", s->phas[j]);
|
||||
}
|
||||
AUBIO_MSG("\n");
|
||||
}
|
||||
|
||||
void cvec_copy(const cvec_t *s, cvec_t *t) {
|
||||
if (s->length != t->length) {
|
||||
AUBIO_ERR("trying to copy %d elements to %d elements \n",
|
||||
s->length, t->length);
|
||||
return;
|
||||
}
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsCopy(s->phas, t->phas, (int)s->length);
|
||||
aubio_ippsCopy(s->norm, t->norm, (int)s->length);
|
||||
#elif defined(HAVE_MEMCPY_HACKS)
|
||||
memcpy(t->norm, s->norm, t->length * sizeof(smpl_t));
|
||||
memcpy(t->phas, s->phas, t->length * sizeof(smpl_t));
|
||||
#else
|
||||
uint_t j;
|
||||
for (j=0; j< t->length; j++) {
|
||||
t->norm[j] = s->norm[j];
|
||||
t->phas[j] = s->phas[j];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void cvec_norm_set_all(cvec_t *s, smpl_t val) {
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsSet(val, s->norm, (int)s->length);
|
||||
#else
|
||||
uint_t j;
|
||||
for (j=0; j< s->length; j++) {
|
||||
s->norm[j] = val;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void cvec_norm_zeros(cvec_t *s) {
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsZero(s->norm, (int)s->length);
|
||||
#elif defined(HAVE_MEMCPY_HACKS)
|
||||
memset(s->norm, 0, s->length * sizeof(smpl_t));
|
||||
#else
|
||||
cvec_norm_set_all (s, 0.);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cvec_norm_ones(cvec_t *s) {
|
||||
cvec_norm_set_all (s, 1.);
|
||||
}
|
||||
|
||||
void cvec_phas_set_all (cvec_t *s, smpl_t val) {
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsSet(val, s->phas, (int)s->length);
|
||||
#else
|
||||
uint_t j;
|
||||
for (j=0; j< s->length; j++) {
|
||||
s->phas[j] = val;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void cvec_phas_zeros(cvec_t *s) {
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsZero(s->phas, (int)s->length);
|
||||
#elif defined(HAVE_MEMCPY_HACKS)
|
||||
memset(s->phas, 0, s->length * sizeof(smpl_t));
|
||||
#else
|
||||
cvec_phas_set_all (s, 0.);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cvec_phas_ones(cvec_t *s) {
|
||||
cvec_phas_set_all (s, 1.);
|
||||
}
|
||||
|
||||
void cvec_zeros(cvec_t *s) {
|
||||
cvec_norm_zeros(s);
|
||||
cvec_phas_zeros(s);
|
||||
}
|
||||
|
||||
void cvec_logmag(cvec_t *s, smpl_t lambda) {
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsMulC(s->norm, lambda, s->norm, (int)s->length);
|
||||
aubio_ippsAddC(s->norm, 1.0, s->norm, (int)s->length);
|
||||
aubio_ippsLn(s->norm, s->norm, (int)s->length);
|
||||
#else
|
||||
uint_t j;
|
||||
for (j=0; j< s->length; j++) {
|
||||
s->norm[j] = LOG(lambda * s->norm[j] + 1);
|
||||
}
|
||||
#endif
|
||||
}
|
247
deps/aubio/src/cvec.h
vendored
Normal file
247
deps/aubio/src/cvec.h
vendored
Normal file
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_CVEC_H
|
||||
#define AUBIO_CVEC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file
|
||||
|
||||
Vector of complex-valued data, stored in polar coordinates
|
||||
|
||||
This file specifies the ::cvec_t buffer type, which is used throughout aubio
|
||||
to store complex data. Complex values are stored in terms of ::cvec_t.phas
|
||||
and norm, within 2 vectors of ::smpl_t of size (size/2+1) each.
|
||||
|
||||
\example test-cvec.c
|
||||
|
||||
*/
|
||||
|
||||
/** Vector of real-valued phase and spectrum data
|
||||
|
||||
\code
|
||||
|
||||
uint_t buffer_size = 1024;
|
||||
|
||||
// create a complex vector of 512 values
|
||||
cvec_t * input = new_cvec (buffer_size);
|
||||
|
||||
// set some values of the vector
|
||||
input->norm[23] = 2.;
|
||||
input->phas[23] = M_PI;
|
||||
// ..
|
||||
|
||||
// compute the mean of the vector
|
||||
mean = cvec_mean(input);
|
||||
|
||||
// destroy the vector
|
||||
del_cvec (input);
|
||||
|
||||
\endcode
|
||||
|
||||
*/
|
||||
typedef struct {
|
||||
uint_t length; /**< length of buffer = (requested length)/2 + 1 */
|
||||
smpl_t *norm; /**< norm array of size ::cvec_t.length */
|
||||
smpl_t *phas; /**< phase array of size ::cvec_t.length */
|
||||
} cvec_t;
|
||||
|
||||
/** cvec_t buffer creation function
|
||||
|
||||
This function creates a cvec_t structure holding two arrays of size
|
||||
[length/2+1], corresponding to the norm and phase values of the
|
||||
spectral frame. The length stored in the structure is the actual size of both
|
||||
arrays, not the length of the complex and symmetrical vector, specified as
|
||||
creation argument.
|
||||
|
||||
\param length the length of the buffer to create
|
||||
|
||||
*/
|
||||
cvec_t * new_cvec(uint_t length);
|
||||
|
||||
/** cvec_t buffer deletion function
|
||||
|
||||
\param s buffer to delete as returned by new_cvec()
|
||||
|
||||
*/
|
||||
void del_cvec(cvec_t *s);
|
||||
|
||||
/** write norm value in a complex buffer
|
||||
|
||||
This is equivalent to:
|
||||
\code
|
||||
s->norm[position] = val;
|
||||
\endcode
|
||||
|
||||
\param s vector to write to
|
||||
\param val norm value to write in s->norm[position]
|
||||
\param position sample position to write to
|
||||
|
||||
*/
|
||||
void cvec_norm_set_sample (cvec_t *s, smpl_t val, uint_t position);
|
||||
|
||||
/** write phase value in a complex buffer
|
||||
|
||||
This is equivalent to:
|
||||
\code
|
||||
s->phas[position] = val;
|
||||
\endcode
|
||||
|
||||
\param s vector to write to
|
||||
\param val phase value to write in s->phas[position]
|
||||
\param position sample position to write to
|
||||
|
||||
*/
|
||||
void cvec_phas_set_sample (cvec_t *s, smpl_t val, uint_t position);
|
||||
|
||||
/** read norm value from a complex buffer
|
||||
|
||||
This is equivalent to:
|
||||
\code
|
||||
smpl_t foo = s->norm[position];
|
||||
\endcode
|
||||
|
||||
\param s vector to read from
|
||||
\param position sample position to read from
|
||||
|
||||
*/
|
||||
smpl_t cvec_norm_get_sample (cvec_t *s, uint_t position);
|
||||
|
||||
/** read phase value from a complex buffer
|
||||
|
||||
This is equivalent to:
|
||||
\code
|
||||
smpl_t foo = s->phas[position];
|
||||
\endcode
|
||||
|
||||
\param s vector to read from
|
||||
\param position sample position to read from
|
||||
\returns the value of the sample at position
|
||||
|
||||
*/
|
||||
smpl_t cvec_phas_get_sample (cvec_t *s, uint_t position);
|
||||
|
||||
/** read norm data from a complex buffer
|
||||
|
||||
\code
|
||||
smpl_t *data = s->norm;
|
||||
\endcode
|
||||
|
||||
\param s vector to read from
|
||||
|
||||
*/
|
||||
smpl_t * cvec_norm_get_data (const cvec_t *s);
|
||||
|
||||
/** read phase data from a complex buffer
|
||||
|
||||
This is equivalent to:
|
||||
\code
|
||||
smpl_t *data = s->phas;
|
||||
\endcode
|
||||
|
||||
\param s vector to read from
|
||||
|
||||
*/
|
||||
smpl_t * cvec_phas_get_data (const cvec_t *s);
|
||||
|
||||
/** print out cvec data
|
||||
|
||||
\param s vector to print out
|
||||
|
||||
*/
|
||||
void cvec_print(const cvec_t *s);
|
||||
|
||||
/** make a copy of a vector
|
||||
|
||||
\param s source vector
|
||||
\param t vector to copy to
|
||||
|
||||
*/
|
||||
void cvec_copy(const cvec_t *s, cvec_t *t);
|
||||
|
||||
/** set all norm elements to a given value
|
||||
|
||||
\param s vector to modify
|
||||
\param val value to set elements to
|
||||
|
||||
*/
|
||||
void cvec_norm_set_all (cvec_t *s, smpl_t val);
|
||||
|
||||
/** set all norm elements to zero
|
||||
|
||||
\param s vector to modify
|
||||
|
||||
*/
|
||||
void cvec_norm_zeros(cvec_t *s);
|
||||
|
||||
/** set all norm elements to one
|
||||
|
||||
\param s vector to modify
|
||||
|
||||
*/
|
||||
void cvec_norm_ones(cvec_t *s);
|
||||
|
||||
/** set all phase elements to a given value
|
||||
|
||||
\param s vector to modify
|
||||
\param val value to set elements to
|
||||
|
||||
*/
|
||||
void cvec_phas_set_all (cvec_t *s, smpl_t val);
|
||||
|
||||
/** set all phase elements to zero
|
||||
|
||||
\param s vector to modify
|
||||
|
||||
*/
|
||||
void cvec_phas_zeros(cvec_t *s);
|
||||
|
||||
/** set all phase elements to one
|
||||
|
||||
\param s vector to modify
|
||||
|
||||
*/
|
||||
void cvec_phas_ones(cvec_t *s);
|
||||
|
||||
/** set all norm and phas elements to zero
|
||||
|
||||
\param s vector to modify
|
||||
|
||||
*/
|
||||
void cvec_zeros(cvec_t *s);
|
||||
|
||||
/** take logarithmic magnitude
|
||||
|
||||
\param s input cvec to compress
|
||||
\param lambda value to use for normalisation
|
||||
|
||||
\f$ S_k = log( \lambda * S_k + 1 ) \f$
|
||||
|
||||
*/
|
||||
void cvec_logmag(cvec_t *s, smpl_t lambda);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_CVEC_H */
|
149
deps/aubio/src/fvec.c
vendored
Normal file
149
deps/aubio/src/fvec.c
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
|
||||
fvec_t * new_fvec(uint_t length) {
|
||||
fvec_t * s;
|
||||
if ((sint_t)length <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
s = AUBIO_NEW(fvec_t);
|
||||
s->length = length;
|
||||
s->data = AUBIO_ARRAY(smpl_t, s->length);
|
||||
return s;
|
||||
}
|
||||
|
||||
void del_fvec(fvec_t *s) {
|
||||
AUBIO_FREE(s->data);
|
||||
AUBIO_FREE(s);
|
||||
}
|
||||
|
||||
void fvec_set_sample(fvec_t *s, smpl_t data, uint_t position) {
|
||||
s->data[position] = data;
|
||||
}
|
||||
|
||||
smpl_t fvec_get_sample(const fvec_t *s, uint_t position) {
|
||||
return s->data[position];
|
||||
}
|
||||
|
||||
smpl_t * fvec_get_data(const fvec_t *s) {
|
||||
return s->data;
|
||||
}
|
||||
|
||||
/* helper functions */
|
||||
|
||||
void fvec_print(const fvec_t *s) {
|
||||
uint_t j;
|
||||
for (j=0; j< s->length; j++) {
|
||||
AUBIO_MSG(AUBIO_SMPL_FMT " ", s->data[j]);
|
||||
}
|
||||
AUBIO_MSG("\n");
|
||||
}
|
||||
|
||||
void fvec_set_all (fvec_t *s, smpl_t val) {
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsSet(val, s->data, (int)s->length);
|
||||
#elif defined(HAVE_ATLAS)
|
||||
aubio_catlas_set(s->length, val, s->data, 1);
|
||||
#elif defined(HAVE_ACCELERATE)
|
||||
aubio_vDSP_vfill(&val, s->data, 1, s->length);
|
||||
#else
|
||||
uint_t j;
|
||||
for ( j = 0; j< s->length; j++ )
|
||||
{
|
||||
s->data[j] = val;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void fvec_zeros(fvec_t *s) {
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsZero(s->data, (int)s->length);
|
||||
#elif defined(HAVE_ACCELERATE)
|
||||
aubio_vDSP_vclr(s->data, 1, s->length);
|
||||
#elif defined(HAVE_MEMCPY_HACKS)
|
||||
memset(s->data, 0, s->length * sizeof(smpl_t));
|
||||
#else
|
||||
fvec_set_all(s, 0.);
|
||||
#endif
|
||||
}
|
||||
|
||||
void fvec_ones(fvec_t *s) {
|
||||
fvec_set_all (s, 1.);
|
||||
}
|
||||
|
||||
void fvec_rev(fvec_t *s) {
|
||||
uint_t j;
|
||||
for (j=0; j< FLOOR((smpl_t)s->length/2); j++) {
|
||||
ELEM_SWAP(s->data[j], s->data[s->length-1-j]);
|
||||
}
|
||||
}
|
||||
|
||||
void fvec_weight(fvec_t *s, const fvec_t *weight) {
|
||||
uint_t length = MIN(s->length, weight->length);
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsMul(s->data, weight->data, s->data, (int)length);
|
||||
#elif defined(HAVE_ACCELERATE)
|
||||
aubio_vDSP_vmul( s->data, 1, weight->data, 1, s->data, 1, length );
|
||||
#else
|
||||
uint_t j;
|
||||
for (j = 0; j < length; j++) {
|
||||
s->data[j] *= weight->data[j];
|
||||
}
|
||||
#endif /* HAVE_ACCELERATE */
|
||||
}
|
||||
|
||||
void fvec_weighted_copy(const fvec_t *in, const fvec_t *weight, fvec_t *out) {
|
||||
uint_t length = MIN(in->length, MIN(out->length, weight->length));
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsMul(in->data, weight->data, out->data, (int)length);
|
||||
#elif defined(HAVE_ACCELERATE)
|
||||
aubio_vDSP_vmul(in->data, 1, weight->data, 1, out->data, 1, length);
|
||||
#else
|
||||
uint_t j;
|
||||
for (j = 0; j < length; j++) {
|
||||
out->data[j] = in->data[j] * weight->data[j];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void fvec_copy(const fvec_t *s, fvec_t *t) {
|
||||
if (s->length != t->length) {
|
||||
AUBIO_ERR("trying to copy %d elements to %d elements \n",
|
||||
s->length, t->length);
|
||||
return;
|
||||
}
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsCopy(s->data, t->data, (int)s->length);
|
||||
#elif defined(HAVE_BLAS)
|
||||
aubio_cblas_copy(s->length, s->data, 1, t->data, 1);
|
||||
#elif defined(HAVE_ACCELERATE)
|
||||
aubio_vDSP_mmov(s->data, t->data, 1, s->length, 1, 1);
|
||||
#elif defined(HAVE_MEMCPY_HACKS)
|
||||
memcpy(t->data, s->data, t->length * sizeof(smpl_t));
|
||||
#else
|
||||
uint_t j;
|
||||
for (j = 0; j < t->length; j++) {
|
||||
t->data[j] = s->data[j];
|
||||
}
|
||||
#endif
|
||||
}
|
178
deps/aubio/src/fvec.h
vendored
Normal file
178
deps/aubio/src/fvec.h
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_FVEC_H
|
||||
#define AUBIO_FVEC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file
|
||||
|
||||
Vector of real-valued data
|
||||
|
||||
This file specifies the ::fvec_t buffer type, which is used throughout aubio
|
||||
to store vector of real-valued ::smpl_t.
|
||||
|
||||
\example test-fvec.c
|
||||
|
||||
*/
|
||||
|
||||
/** Buffer for real data
|
||||
|
||||
Vector of real-valued data
|
||||
|
||||
::fvec_t is is the structure used to store vector of real-valued data, ::smpl_t .
|
||||
|
||||
\code
|
||||
|
||||
uint_t buffer_size = 1024;
|
||||
|
||||
// create a vector of 512 values
|
||||
fvec_t * input = new_fvec (buffer_size);
|
||||
|
||||
// set some values of the vector
|
||||
input->data[23] = 2.;
|
||||
// ..
|
||||
|
||||
// compute the mean of the vector
|
||||
mean = fvec_mean(a_vector);
|
||||
|
||||
// destroy the vector
|
||||
del_fvec(a_vector);
|
||||
|
||||
\endcode
|
||||
|
||||
See `examples/` and `tests/src` directories for more examples.
|
||||
|
||||
*/
|
||||
typedef struct {
|
||||
uint_t length; /**< length of buffer */
|
||||
smpl_t *data; /**< data vector of length ::fvec_t.length */
|
||||
} fvec_t;
|
||||
|
||||
/** fvec_t buffer creation function
|
||||
|
||||
\param length the length of the buffer to create
|
||||
|
||||
*/
|
||||
fvec_t * new_fvec(uint_t length);
|
||||
|
||||
/** fvec_t buffer deletion function
|
||||
|
||||
\param s buffer to delete as returned by new_fvec()
|
||||
|
||||
*/
|
||||
void del_fvec(fvec_t *s);
|
||||
|
||||
/** read sample value in a buffer
|
||||
|
||||
\param s vector to read from
|
||||
\param position sample position to read from
|
||||
|
||||
*/
|
||||
smpl_t fvec_get_sample(const fvec_t *s, uint_t position);
|
||||
|
||||
/** write sample value in a buffer
|
||||
|
||||
\param s vector to write to
|
||||
\param data value to write in s->data[position]
|
||||
\param position sample position to write to
|
||||
|
||||
*/
|
||||
void fvec_set_sample(fvec_t *s, smpl_t data, uint_t position);
|
||||
|
||||
/** read data from a buffer
|
||||
|
||||
\param s vector to read from
|
||||
|
||||
*/
|
||||
smpl_t * fvec_get_data(const fvec_t *s);
|
||||
|
||||
/** print out fvec data
|
||||
|
||||
\param s vector to print out
|
||||
|
||||
*/
|
||||
void fvec_print(const fvec_t *s);
|
||||
|
||||
/** set all elements to a given value
|
||||
|
||||
\param s vector to modify
|
||||
\param val value to set elements to
|
||||
|
||||
*/
|
||||
void fvec_set_all (fvec_t *s, smpl_t val);
|
||||
|
||||
/** set all elements to zero
|
||||
|
||||
\param s vector to modify
|
||||
|
||||
*/
|
||||
void fvec_zeros(fvec_t *s);
|
||||
|
||||
/** set all elements to ones
|
||||
|
||||
\param s vector to modify
|
||||
|
||||
*/
|
||||
void fvec_ones(fvec_t *s);
|
||||
|
||||
/** revert order of vector elements
|
||||
|
||||
\param s vector to revert
|
||||
|
||||
*/
|
||||
void fvec_rev(fvec_t *s);
|
||||
|
||||
/** apply weight to vector
|
||||
|
||||
If the weight vector is longer than s, only the first elements are used. If
|
||||
the weight vector is shorter than s, the last elements of s are not weighted.
|
||||
|
||||
\param s vector to weight
|
||||
\param weight weighting coefficients
|
||||
|
||||
*/
|
||||
void fvec_weight(fvec_t *s, const fvec_t *weight);
|
||||
|
||||
/** make a copy of a vector
|
||||
|
||||
\param s source vector
|
||||
\param t vector to copy to
|
||||
|
||||
*/
|
||||
void fvec_copy(const fvec_t *s, fvec_t *t);
|
||||
|
||||
/** make a copy of a vector, applying weights to each element
|
||||
|
||||
\param in input vector
|
||||
\param weight weights vector
|
||||
\param out output vector
|
||||
|
||||
*/
|
||||
void fvec_weighted_copy(const fvec_t *in, const fvec_t *weight, fvec_t *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_FVEC_H */
|
80
deps/aubio/src/lvec.c
vendored
Normal file
80
deps/aubio/src/lvec.c
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "lvec.h"
|
||||
|
||||
lvec_t * new_lvec(uint_t length) {
|
||||
lvec_t * s;
|
||||
if ((sint_t)length <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
s = AUBIO_NEW(lvec_t);
|
||||
s->length = length;
|
||||
s->data = AUBIO_ARRAY(lsmp_t, s->length);
|
||||
return s;
|
||||
}
|
||||
|
||||
void del_lvec(lvec_t *s) {
|
||||
AUBIO_FREE(s->data);
|
||||
AUBIO_FREE(s);
|
||||
}
|
||||
|
||||
void lvec_set_sample(lvec_t *s, lsmp_t data, uint_t position) {
|
||||
s->data[position] = data;
|
||||
}
|
||||
|
||||
lsmp_t lvec_get_sample(lvec_t *s, uint_t position) {
|
||||
return s->data[position];
|
||||
}
|
||||
|
||||
lsmp_t * lvec_get_data(const lvec_t *s) {
|
||||
return s->data;
|
||||
}
|
||||
|
||||
/* helper functions */
|
||||
|
||||
void lvec_print(const lvec_t *s) {
|
||||
uint_t j;
|
||||
for (j=0; j< s->length; j++) {
|
||||
AUBIO_MSG(AUBIO_LSMP_FMT " ", s->data[j]);
|
||||
}
|
||||
AUBIO_MSG("\n");
|
||||
}
|
||||
|
||||
void lvec_set_all (lvec_t *s, smpl_t val) {
|
||||
uint_t j;
|
||||
for (j=0; j< s->length; j++) {
|
||||
s->data[j] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void lvec_zeros(lvec_t *s) {
|
||||
#if HAVE_MEMCPY_HACKS
|
||||
memset(s->data, 0, s->length * sizeof(lsmp_t));
|
||||
#else
|
||||
lvec_set_all (s, 0.);
|
||||
#endif
|
||||
}
|
||||
|
||||
void lvec_ones(lvec_t *s) {
|
||||
lvec_set_all (s, 1.);
|
||||
}
|
||||
|
118
deps/aubio/src/lvec.h
vendored
Normal file
118
deps/aubio/src/lvec.h
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_LVEC_H
|
||||
#define AUBIO_LVEC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file
|
||||
|
||||
Vector of real-valued data in double precision
|
||||
|
||||
This file specifies the ::lvec_t buffer type, which is used in some places in
|
||||
aubio to store a vector of ::lsmp_t.
|
||||
|
||||
Note: the lvec_t data type is required in some algorithms such as IIR filters
|
||||
(see temporal/filter.h).
|
||||
|
||||
\example test-lvec.c
|
||||
|
||||
*/
|
||||
|
||||
/** Buffer for real data in double precision */
|
||||
typedef struct {
|
||||
uint_t length; /**< length of buffer */
|
||||
lsmp_t *data; /**< data array of size [length] */
|
||||
} lvec_t;
|
||||
|
||||
/** lvec_t buffer creation function
|
||||
|
||||
\param length the length of the buffer to create
|
||||
|
||||
*/
|
||||
lvec_t * new_lvec(uint_t length);
|
||||
/** lvec_t buffer deletion function
|
||||
|
||||
\param s buffer to delete as returned by new_lvec()
|
||||
|
||||
*/
|
||||
void del_lvec(lvec_t *s);
|
||||
|
||||
/** read sample value in a buffer
|
||||
|
||||
\param s vector to read from
|
||||
\param position sample position to read from
|
||||
|
||||
*/
|
||||
lsmp_t lvec_get_sample(lvec_t *s, uint_t position);
|
||||
|
||||
/** write sample value in a buffer
|
||||
|
||||
\param s vector to write to
|
||||
\param data value to write in s->data[position]
|
||||
\param position sample position to write to
|
||||
|
||||
*/
|
||||
void lvec_set_sample(lvec_t *s, lsmp_t data, uint_t position);
|
||||
|
||||
/** read data from a buffer
|
||||
|
||||
\param s vector to read from
|
||||
|
||||
*/
|
||||
lsmp_t * lvec_get_data(const lvec_t *s);
|
||||
|
||||
/** print out lvec data
|
||||
|
||||
\param s vector to print out
|
||||
|
||||
*/
|
||||
void lvec_print(const lvec_t *s);
|
||||
|
||||
/** set all elements to a given value
|
||||
|
||||
\param s vector to modify
|
||||
\param val value to set elements to
|
||||
|
||||
*/
|
||||
void lvec_set_all(lvec_t *s, smpl_t val);
|
||||
|
||||
/** set all elements to zero
|
||||
|
||||
\param s vector to modify
|
||||
|
||||
*/
|
||||
void lvec_zeros(lvec_t *s);
|
||||
|
||||
/** set all elements to ones
|
||||
|
||||
\param s vector to modify
|
||||
|
||||
*/
|
||||
void lvec_ones(lvec_t *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_LVEC_H */
|
681
deps/aubio/src/mathutils.c
vendored
Normal file
681
deps/aubio/src/mathutils.c
vendored
Normal file
|
@ -0,0 +1,681 @@
|
|||
/*
|
||||
Copyright (C) 2003-2014 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/* see in mathutils.h for doc */
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "musicutils.h"
|
||||
|
||||
/** Window types */
|
||||
typedef enum
|
||||
{
|
||||
aubio_win_ones,
|
||||
aubio_win_rectangle,
|
||||
aubio_win_hamming,
|
||||
aubio_win_hanning,
|
||||
aubio_win_hanningz,
|
||||
aubio_win_blackman,
|
||||
aubio_win_blackman_harris,
|
||||
aubio_win_gaussian,
|
||||
aubio_win_welch,
|
||||
aubio_win_parzen,
|
||||
aubio_win_default = aubio_win_hanningz,
|
||||
} aubio_window_type;
|
||||
|
||||
fvec_t *
|
||||
new_aubio_window (char_t * window_type, uint_t length)
|
||||
{
|
||||
fvec_t * win = new_fvec (length);
|
||||
uint_t err;
|
||||
if (win == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
err = fvec_set_window (win, window_type);
|
||||
if (err != 0) {
|
||||
del_fvec(win);
|
||||
return NULL;
|
||||
}
|
||||
return win;
|
||||
}
|
||||
|
||||
uint_t fvec_set_window (fvec_t *win, char_t *window_type) {
|
||||
smpl_t * w = win->data;
|
||||
uint_t i, size = win->length;
|
||||
aubio_window_type wintype;
|
||||
if (window_type == NULL) {
|
||||
AUBIO_ERR ("window type can not be null.\n");
|
||||
return 1;
|
||||
} else if (strcmp (window_type, "ones") == 0)
|
||||
wintype = aubio_win_ones;
|
||||
else if (strcmp (window_type, "rectangle") == 0)
|
||||
wintype = aubio_win_rectangle;
|
||||
else if (strcmp (window_type, "hamming") == 0)
|
||||
wintype = aubio_win_hamming;
|
||||
else if (strcmp (window_type, "hanning") == 0)
|
||||
wintype = aubio_win_hanning;
|
||||
else if (strcmp (window_type, "hanningz") == 0)
|
||||
wintype = aubio_win_hanningz;
|
||||
else if (strcmp (window_type, "blackman") == 0)
|
||||
wintype = aubio_win_blackman;
|
||||
else if (strcmp (window_type, "blackman_harris") == 0)
|
||||
wintype = aubio_win_blackman_harris;
|
||||
else if (strcmp (window_type, "gaussian") == 0)
|
||||
wintype = aubio_win_gaussian;
|
||||
else if (strcmp (window_type, "welch") == 0)
|
||||
wintype = aubio_win_welch;
|
||||
else if (strcmp (window_type, "parzen") == 0)
|
||||
wintype = aubio_win_parzen;
|
||||
else if (strcmp (window_type, "default") == 0)
|
||||
wintype = aubio_win_default;
|
||||
else {
|
||||
AUBIO_ERR ("unknown window type `%s`.\n", window_type);
|
||||
return 1;
|
||||
}
|
||||
switch(wintype) {
|
||||
case aubio_win_ones:
|
||||
fvec_ones(win);
|
||||
break;
|
||||
case aubio_win_rectangle:
|
||||
fvec_set_all(win, .5);
|
||||
break;
|
||||
case aubio_win_hamming:
|
||||
for (i=0;i<size;i++)
|
||||
w[i] = 0.54 - 0.46 * COS(TWO_PI * i / (size));
|
||||
break;
|
||||
case aubio_win_hanning:
|
||||
for (i=0;i<size;i++)
|
||||
w[i] = 0.5 - (0.5 * COS(TWO_PI * i / (size)));
|
||||
break;
|
||||
case aubio_win_hanningz:
|
||||
for (i=0;i<size;i++)
|
||||
w[i] = 0.5 * (1.0 - COS(TWO_PI * i / (size)));
|
||||
break;
|
||||
case aubio_win_blackman:
|
||||
for (i=0;i<size;i++)
|
||||
w[i] = 0.42
|
||||
- 0.50 * COS( TWO_PI*i/(size-1.0))
|
||||
+ 0.08 * COS(2.0*TWO_PI*i/(size-1.0));
|
||||
break;
|
||||
case aubio_win_blackman_harris:
|
||||
for (i=0;i<size;i++)
|
||||
w[i] = 0.35875
|
||||
- 0.48829 * COS( TWO_PI*i/(size-1.0))
|
||||
+ 0.14128 * COS(2.0*TWO_PI*i/(size-1.0))
|
||||
- 0.01168 * COS(3.0*TWO_PI*i/(size-1.0));
|
||||
break;
|
||||
case aubio_win_gaussian:
|
||||
{
|
||||
lsmp_t a, b, c = 0.5;
|
||||
uint_t n;
|
||||
for (n = 0; n < size; n++)
|
||||
{
|
||||
a = (n-c*(size-1))/(SQR(c)*(size-1));
|
||||
b = -c*SQR(a);
|
||||
w[n] = EXP(b);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case aubio_win_welch:
|
||||
for (i=0;i<size;i++)
|
||||
w[i] = 1.0 - SQR((2.*i-size)/(size+1.0));
|
||||
break;
|
||||
case aubio_win_parzen:
|
||||
for (i=0;i<size;i++)
|
||||
w[i] = 1.0 - ABS((2.f*i-size)/(size+1.0f));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_unwrap2pi (smpl_t phase)
|
||||
{
|
||||
/* mod(phase+pi,-2pi)+pi */
|
||||
return phase + TWO_PI * (1. + FLOOR (-(phase + PI) / TWO_PI));
|
||||
}
|
||||
|
||||
smpl_t
|
||||
fvec_mean (fvec_t * s)
|
||||
{
|
||||
smpl_t tmp = 0.0;
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsMean(s->data, (int)s->length, &tmp);
|
||||
return tmp;
|
||||
#elif defined(HAVE_ACCELERATE)
|
||||
aubio_vDSP_meanv(s->data, 1, &tmp, s->length);
|
||||
return tmp;
|
||||
#else
|
||||
uint_t j;
|
||||
for (j = 0; j < s->length; j++) {
|
||||
tmp += s->data[j];
|
||||
}
|
||||
return tmp / (smpl_t)(s->length);
|
||||
#endif
|
||||
}
|
||||
|
||||
smpl_t
|
||||
fvec_sum (fvec_t * s)
|
||||
{
|
||||
smpl_t tmp = 0.0;
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
aubio_ippsSum(s->data, (int)s->length, &tmp);
|
||||
#elif defined(HAVE_ACCELERATE)
|
||||
aubio_vDSP_sve(s->data, 1, &tmp, s->length);
|
||||
#else
|
||||
uint_t j;
|
||||
for (j = 0; j < s->length; j++) {
|
||||
tmp += s->data[j];
|
||||
}
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
fvec_max (fvec_t * s)
|
||||
{
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
smpl_t tmp = 0.;
|
||||
aubio_ippsMax( s->data, (int)s->length, &tmp);
|
||||
#elif defined(HAVE_ACCELERATE)
|
||||
smpl_t tmp = 0.;
|
||||
aubio_vDSP_maxv( s->data, 1, &tmp, s->length );
|
||||
#else
|
||||
uint_t j;
|
||||
smpl_t tmp = s->data[0];
|
||||
for (j = 1; j < s->length; j++) {
|
||||
tmp = (tmp > s->data[j]) ? tmp : s->data[j];
|
||||
}
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
fvec_min (fvec_t * s)
|
||||
{
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
smpl_t tmp = 0.;
|
||||
aubio_ippsMin(s->data, (int)s->length, &tmp);
|
||||
#elif defined(HAVE_ACCELERATE)
|
||||
smpl_t tmp = 0.;
|
||||
aubio_vDSP_minv(s->data, 1, &tmp, s->length);
|
||||
#else
|
||||
uint_t j;
|
||||
smpl_t tmp = s->data[0];
|
||||
for (j = 1; j < s->length; j++) {
|
||||
tmp = (tmp < s->data[j]) ? tmp : s->data[j];
|
||||
}
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
|
||||
uint_t
|
||||
fvec_min_elem (fvec_t * s)
|
||||
{
|
||||
#ifndef HAVE_ACCELERATE
|
||||
uint_t j, pos = 0.;
|
||||
smpl_t tmp = s->data[0];
|
||||
for (j = 0; j < s->length; j++) {
|
||||
pos = (tmp < s->data[j]) ? pos : j;
|
||||
tmp = (tmp < s->data[j]) ? tmp : s->data[j];
|
||||
}
|
||||
#else
|
||||
smpl_t tmp = 0.;
|
||||
vDSP_Length pos = 0;
|
||||
aubio_vDSP_minvi(s->data, 1, &tmp, &pos, s->length);
|
||||
#endif
|
||||
return (uint_t)pos;
|
||||
}
|
||||
|
||||
uint_t
|
||||
fvec_max_elem (fvec_t * s)
|
||||
{
|
||||
#ifndef HAVE_ACCELERATE
|
||||
uint_t j, pos = 0;
|
||||
smpl_t tmp = 0.0;
|
||||
for (j = 0; j < s->length; j++) {
|
||||
pos = (tmp > s->data[j]) ? pos : j;
|
||||
tmp = (tmp > s->data[j]) ? tmp : s->data[j];
|
||||
}
|
||||
#else
|
||||
smpl_t tmp = 0.;
|
||||
vDSP_Length pos = 0;
|
||||
aubio_vDSP_maxvi(s->data, 1, &tmp, &pos, s->length);
|
||||
#endif
|
||||
return (uint_t)pos;
|
||||
}
|
||||
|
||||
void
|
||||
fvec_shift (fvec_t * s)
|
||||
{
|
||||
uint_t half = s->length / 2, start = half, j;
|
||||
// if length is odd, middle element is moved to the end
|
||||
if (2 * half < s->length) start ++;
|
||||
#ifndef HAVE_BLAS
|
||||
for (j = 0; j < half; j++) {
|
||||
ELEM_SWAP (s->data[j], s->data[j + start]);
|
||||
}
|
||||
#else
|
||||
aubio_cblas_swap(half, s->data, 1, s->data + start, 1);
|
||||
#endif
|
||||
if (start != half) {
|
||||
for (j = 0; j < half; j++) {
|
||||
ELEM_SWAP (s->data[j + start - 1], s->data[j + start]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fvec_ishift (fvec_t * s)
|
||||
{
|
||||
uint_t half = s->length / 2, start = half, j;
|
||||
// if length is odd, middle element is moved to the beginning
|
||||
if (2 * half < s->length) start ++;
|
||||
#ifndef HAVE_BLAS
|
||||
for (j = 0; j < half; j++) {
|
||||
ELEM_SWAP (s->data[j], s->data[j + start]);
|
||||
}
|
||||
#else
|
||||
aubio_cblas_swap(half, s->data, 1, s->data + start, 1);
|
||||
#endif
|
||||
if (start != half) {
|
||||
for (j = 0; j < half; j++) {
|
||||
ELEM_SWAP (s->data[half], s->data[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fvec_push(fvec_t *in, smpl_t new_elem) {
|
||||
uint_t i;
|
||||
for (i = 0; i < in->length - 1; i++) {
|
||||
in->data[i] = in->data[i + 1];
|
||||
}
|
||||
in->data[in->length - 1] = new_elem;
|
||||
}
|
||||
|
||||
void fvec_clamp(fvec_t *in, smpl_t absmax) {
|
||||
uint_t i;
|
||||
for (i = 0; i < in->length; i++) {
|
||||
if (in->data[i] > 0 && in->data[i] > ABS(absmax)) {
|
||||
in->data[i] = absmax;
|
||||
} else if (in->data[i] < 0 && in->data[i] < -ABS(absmax)) {
|
||||
in->data[i] = -absmax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_level_lin (const fvec_t * f)
|
||||
{
|
||||
smpl_t energy = 0.;
|
||||
#ifndef HAVE_BLAS
|
||||
uint_t j;
|
||||
for (j = 0; j < f->length; j++) {
|
||||
energy += SQR (f->data[j]);
|
||||
}
|
||||
#else
|
||||
energy = aubio_cblas_dot(f->length, f->data, 1, f->data, 1);
|
||||
#endif
|
||||
return energy / f->length;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
fvec_local_hfc (fvec_t * v)
|
||||
{
|
||||
smpl_t hfc = 0.;
|
||||
uint_t j;
|
||||
for (j = 0; j < v->length; j++) {
|
||||
hfc += (j + 1) * v->data[j];
|
||||
}
|
||||
return hfc;
|
||||
}
|
||||
|
||||
void
|
||||
fvec_min_removal (fvec_t * v)
|
||||
{
|
||||
smpl_t v_min = fvec_min (v);
|
||||
fvec_add (v, - v_min );
|
||||
}
|
||||
|
||||
smpl_t
|
||||
fvec_alpha_norm (fvec_t * o, smpl_t alpha)
|
||||
{
|
||||
uint_t j;
|
||||
smpl_t tmp = 0.;
|
||||
for (j = 0; j < o->length; j++) {
|
||||
tmp += POW (ABS (o->data[j]), alpha);
|
||||
}
|
||||
return POW (tmp / o->length, 1. / alpha);
|
||||
}
|
||||
|
||||
void
|
||||
fvec_alpha_normalise (fvec_t * o, smpl_t alpha)
|
||||
{
|
||||
uint_t j;
|
||||
smpl_t norm = fvec_alpha_norm (o, alpha);
|
||||
for (j = 0; j < o->length; j++) {
|
||||
o->data[j] /= norm;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fvec_add (fvec_t * o, smpl_t val)
|
||||
{
|
||||
uint_t j;
|
||||
for (j = 0; j < o->length; j++) {
|
||||
o->data[j] += val;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fvec_mul (fvec_t *o, smpl_t val)
|
||||
{
|
||||
uint_t j;
|
||||
for (j = 0; j < o->length; j++) {
|
||||
o->data[j] *= val;
|
||||
}
|
||||
}
|
||||
|
||||
void fvec_adapt_thres(fvec_t * vec, fvec_t * tmp,
|
||||
uint_t post, uint_t pre) {
|
||||
uint_t length = vec->length, j;
|
||||
for (j=0;j<length;j++) {
|
||||
vec->data[j] -= fvec_moving_thres(vec, tmp, post, pre, j);
|
||||
}
|
||||
}
|
||||
|
||||
smpl_t
|
||||
fvec_moving_thres (fvec_t * vec, fvec_t * tmpvec,
|
||||
uint_t post, uint_t pre, uint_t pos)
|
||||
{
|
||||
uint_t k;
|
||||
smpl_t *medar = (smpl_t *) tmpvec->data;
|
||||
uint_t win_length = post + pre + 1;
|
||||
uint_t length = vec->length;
|
||||
/* post part of the buffer does not exist */
|
||||
if (pos < post + 1) {
|
||||
for (k = 0; k < post + 1 - pos; k++)
|
||||
medar[k] = 0.; /* 0-padding at the beginning */
|
||||
for (k = post + 1 - pos; k < win_length; k++)
|
||||
medar[k] = vec->data[k + pos - post];
|
||||
/* the buffer is fully defined */
|
||||
} else if (pos + pre < length) {
|
||||
for (k = 0; k < win_length; k++)
|
||||
medar[k] = vec->data[k + pos - post];
|
||||
/* pre part of the buffer does not exist */
|
||||
} else {
|
||||
for (k = 0; k < length - pos + post; k++)
|
||||
medar[k] = vec->data[k + pos - post];
|
||||
for (k = length - pos + post; k < win_length; k++)
|
||||
medar[k] = 0.; /* 0-padding at the end */
|
||||
}
|
||||
return fvec_median (tmpvec);
|
||||
}
|
||||
|
||||
smpl_t fvec_median (fvec_t * input) {
|
||||
uint_t n = input->length;
|
||||
smpl_t * arr = (smpl_t *) input->data;
|
||||
uint_t low, high ;
|
||||
uint_t median;
|
||||
uint_t middle, ll, hh;
|
||||
|
||||
low = 0 ; high = n-1 ; median = (low + high) / 2;
|
||||
for (;;) {
|
||||
if (high <= low) /* One element only */
|
||||
return arr[median] ;
|
||||
|
||||
if (high == low + 1) { /* Two elements only */
|
||||
if (arr[low] > arr[high])
|
||||
ELEM_SWAP(arr[low], arr[high]) ;
|
||||
return arr[median] ;
|
||||
}
|
||||
|
||||
/* Find median of low, middle and high items; swap into position low */
|
||||
middle = (low + high) / 2;
|
||||
if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]);
|
||||
if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]);
|
||||
if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ;
|
||||
|
||||
/* Swap low item (now in position middle) into position (low+1) */
|
||||
ELEM_SWAP(arr[middle], arr[low+1]) ;
|
||||
|
||||
/* Nibble from each end towards middle, swapping items when stuck */
|
||||
ll = low + 1;
|
||||
hh = high;
|
||||
for (;;) {
|
||||
do ll++; while (arr[low] > arr[ll]) ;
|
||||
do hh--; while (arr[hh] > arr[low]) ;
|
||||
|
||||
if (hh < ll)
|
||||
break;
|
||||
|
||||
ELEM_SWAP(arr[ll], arr[hh]) ;
|
||||
}
|
||||
|
||||
/* Swap middle item (in position low) back into correct position */
|
||||
ELEM_SWAP(arr[low], arr[hh]) ;
|
||||
|
||||
/* Re-set active partition */
|
||||
if (hh <= median)
|
||||
low = ll;
|
||||
if (hh >= median)
|
||||
high = hh - 1;
|
||||
}
|
||||
}
|
||||
|
||||
smpl_t fvec_quadratic_peak_pos (const fvec_t * x, uint_t pos) {
|
||||
smpl_t s0, s1, s2; uint_t x0, x2;
|
||||
smpl_t half = .5, two = 2.;
|
||||
if (pos == 0 || pos == x->length - 1) return pos;
|
||||
x0 = (pos < 1) ? pos : pos - 1;
|
||||
x2 = (pos + 1 < x->length) ? pos + 1 : pos;
|
||||
if (x0 == pos) return (x->data[pos] <= x->data[x2]) ? pos : x2;
|
||||
if (x2 == pos) return (x->data[pos] <= x->data[x0]) ? pos : x0;
|
||||
s0 = x->data[x0];
|
||||
s1 = x->data[pos];
|
||||
s2 = x->data[x2];
|
||||
return pos + half * (s0 - s2 ) / (s0 - two * s1 + s2);
|
||||
}
|
||||
|
||||
smpl_t fvec_quadratic_peak_mag (fvec_t *x, smpl_t pos) {
|
||||
smpl_t x0, x1, x2;
|
||||
uint_t index = (uint_t)(pos - .5) + 1;
|
||||
if (pos >= x->length || pos < 0.) return 0.;
|
||||
if ((smpl_t)index == pos) return x->data[index];
|
||||
x0 = x->data[index - 1];
|
||||
x1 = x->data[index];
|
||||
x2 = x->data[index + 1];
|
||||
return x1 - .25 * (x0 - x2) * (pos - index);
|
||||
}
|
||||
|
||||
uint_t fvec_peakpick(const fvec_t * onset, uint_t pos) {
|
||||
uint_t tmp=0;
|
||||
tmp = (onset->data[pos] > onset->data[pos-1]
|
||||
&& onset->data[pos] > onset->data[pos+1]
|
||||
&& onset->data[pos] > 0.);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_quadfrac (smpl_t s0, smpl_t s1, smpl_t s2, smpl_t pf)
|
||||
{
|
||||
smpl_t tmp =
|
||||
s0 + (pf / 2.) * (pf * (s0 - 2. * s1 + s2) - 3. * s0 + 4. * s1 - s2);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_freqtomidi (smpl_t freq)
|
||||
{
|
||||
smpl_t midi;
|
||||
if (freq < 2. || freq > 100000.) return 0.; // avoid nans and infs
|
||||
/* log(freq/A-2)/log(2) */
|
||||
midi = freq / 6.875;
|
||||
midi = LOG (midi) / 0.6931471805599453;
|
||||
midi *= 12;
|
||||
midi -= 3;
|
||||
return midi;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_miditofreq (smpl_t midi)
|
||||
{
|
||||
smpl_t freq;
|
||||
if (midi > 140.) return 0.; // avoid infs
|
||||
freq = (midi + 3.) / 12.;
|
||||
freq = EXP (freq * 0.6931471805599453);
|
||||
freq *= 6.875;
|
||||
return freq;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_bintofreq (smpl_t bin, smpl_t samplerate, smpl_t fftsize)
|
||||
{
|
||||
smpl_t freq = samplerate / fftsize;
|
||||
return freq * MAX(bin, 0);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_bintomidi (smpl_t bin, smpl_t samplerate, smpl_t fftsize)
|
||||
{
|
||||
smpl_t midi = aubio_bintofreq (bin, samplerate, fftsize);
|
||||
return aubio_freqtomidi (midi);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_freqtobin (smpl_t freq, smpl_t samplerate, smpl_t fftsize)
|
||||
{
|
||||
smpl_t bin = fftsize / samplerate;
|
||||
return MAX(freq, 0) * bin;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_miditobin (smpl_t midi, smpl_t samplerate, smpl_t fftsize)
|
||||
{
|
||||
smpl_t freq = aubio_miditofreq (midi);
|
||||
return aubio_freqtobin (freq, samplerate, fftsize);
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_is_power_of_two (uint_t a)
|
||||
{
|
||||
if ((a & (a - 1)) == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_next_power_of_two (uint_t a)
|
||||
{
|
||||
uint_t i = 1;
|
||||
while (i < a) i <<= 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_power_of_two_order (uint_t a)
|
||||
{
|
||||
int order = 0;
|
||||
int temp = aubio_next_power_of_two(a);
|
||||
while (temp >>= 1) {
|
||||
++order;
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_db_spl (const fvec_t * o)
|
||||
{
|
||||
return 10. * LOG10 (aubio_level_lin (o));
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_silence_detection (const fvec_t * o, smpl_t threshold)
|
||||
{
|
||||
return (aubio_db_spl (o) < threshold);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_level_detection (const fvec_t * o, smpl_t threshold)
|
||||
{
|
||||
smpl_t db_spl = aubio_db_spl (o);
|
||||
if (db_spl < threshold) {
|
||||
return 1.;
|
||||
} else {
|
||||
return db_spl;
|
||||
}
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_zero_crossing_rate (fvec_t * input)
|
||||
{
|
||||
uint_t j;
|
||||
uint_t zcr = 0;
|
||||
for (j = 1; j < input->length; j++) {
|
||||
// previous was strictly negative
|
||||
if (input->data[j - 1] < 0.) {
|
||||
// current is positive or null
|
||||
if (input->data[j] >= 0.) {
|
||||
zcr += 1;
|
||||
}
|
||||
// previous was positive or null
|
||||
} else {
|
||||
// current is strictly negative
|
||||
if (input->data[j] < 0.) {
|
||||
zcr += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return zcr / (smpl_t) input->length;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_autocorr (const fvec_t * input, fvec_t * output)
|
||||
{
|
||||
uint_t i, j, length = input->length;
|
||||
smpl_t *data, *acf;
|
||||
smpl_t tmp = 0;
|
||||
data = input->data;
|
||||
acf = output->data;
|
||||
for (i = 0; i < length; i++) {
|
||||
tmp = 0.;
|
||||
for (j = i; j < length; j++) {
|
||||
tmp += data[j - i] * data[j];
|
||||
}
|
||||
acf[i] = tmp / (smpl_t) (length - i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aubio_cleanup (void)
|
||||
{
|
||||
#ifdef HAVE_FFTW3F
|
||||
fftwf_cleanup ();
|
||||
#else
|
||||
#ifdef HAVE_FFTW3
|
||||
fftw_cleanup ();
|
||||
#endif
|
||||
#endif
|
||||
}
|
338
deps/aubio/src/mathutils.h
vendored
Normal file
338
deps/aubio/src/mathutils.h
vendored
Normal file
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Various math functions
|
||||
|
||||
\example test-mathutils.c
|
||||
\example test-mathutils-window.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_MATHUTILS_H
|
||||
#define AUBIO_MATHUTILS_H
|
||||
|
||||
#include "fvec.h"
|
||||
#include "musicutils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** compute the mean of a vector
|
||||
|
||||
\param s vector to compute mean from
|
||||
\return the mean of `v`
|
||||
|
||||
*/
|
||||
smpl_t fvec_mean (fvec_t * s);
|
||||
|
||||
/** find the max of a vector
|
||||
|
||||
\param s vector to get the max from
|
||||
|
||||
\return the value of the minimum of v
|
||||
|
||||
*/
|
||||
smpl_t fvec_max (fvec_t * s);
|
||||
|
||||
/** find the min of a vector
|
||||
|
||||
\param s vector to get the min from
|
||||
|
||||
\return the value of the maximum of v
|
||||
|
||||
*/
|
||||
smpl_t fvec_min (fvec_t * s);
|
||||
|
||||
/** find the index of the min of a vector
|
||||
|
||||
\param s vector to get the index from
|
||||
|
||||
\return the index of the minimum element of v
|
||||
|
||||
*/
|
||||
uint_t fvec_min_elem (fvec_t * s);
|
||||
|
||||
/** find the index of the max of a vector
|
||||
|
||||
\param s vector to get the index from
|
||||
|
||||
\return the index of the maximum element of v
|
||||
|
||||
*/
|
||||
uint_t fvec_max_elem (fvec_t * s);
|
||||
|
||||
/** swap the left and right halves of a vector
|
||||
|
||||
This function swaps the left part of the signal with the right part of the
|
||||
signal. Therefore
|
||||
|
||||
\f$ a[0], a[1], ..., a[\frac{N}{2}], a[\frac{N}{2}+1], ..., a[N-1], a[N] \f$
|
||||
|
||||
becomes
|
||||
|
||||
\f$ a[\frac{N}{2}+1], ..., a[N-1], a[N], a[0], a[1], ..., a[\frac{N}{2}] \f$
|
||||
|
||||
This operation, known as 'fftshift' in the Matlab Signal Processing Toolbox,
|
||||
can be used before computing the FFT to simplify the phase relationship of the
|
||||
resulting spectrum. See Amalia de Götzen's paper referred to above.
|
||||
|
||||
*/
|
||||
void fvec_shift (fvec_t * v);
|
||||
|
||||
/** swap the left and right halves of a vector
|
||||
|
||||
This function swaps the left part of the signal with the right part of the
|
||||
signal. Therefore
|
||||
|
||||
\f$ a[0], a[1], ..., a[\frac{N}{2}], a[\frac{N}{2}+1], ..., a[N-1], a[N] \f$
|
||||
|
||||
becomes
|
||||
|
||||
\f$ a[\frac{N}{2}+1], ..., a[N-1], a[N], a[0], a[1], ..., a[\frac{N}{2}] \f$
|
||||
|
||||
This operation, known as 'ifftshift' in the Matlab Signal Processing Toolbox,
|
||||
can be used after computing the inverse FFT to simplify the phase relationship
|
||||
of the resulting spectrum. See Amalia de Götzen's paper referred to above.
|
||||
|
||||
*/
|
||||
void fvec_ishift (fvec_t * v);
|
||||
|
||||
/** push a new element to the end of a vector, erasing the first element and
|
||||
* sliding all others
|
||||
|
||||
\param in vector to push to
|
||||
\param new_elem new_element to add at the end of the vector
|
||||
|
||||
In numpy words, this is equivalent to: in = np.concatenate([in, [new_elem]])[1:]
|
||||
|
||||
*/
|
||||
void fvec_push(fvec_t *in, smpl_t new_elem);
|
||||
|
||||
/** compute the sum of all elements of a vector
|
||||
|
||||
\param v vector to compute the sum of
|
||||
|
||||
\return the sum of v
|
||||
|
||||
*/
|
||||
smpl_t fvec_sum (fvec_t * v);
|
||||
|
||||
/** compute the High Frequency Content of a vector
|
||||
|
||||
The High Frequency Content is defined as \f$ \sum_0^{N-1} (k+1) v[k] \f$.
|
||||
|
||||
\param v vector to get the energy from
|
||||
|
||||
\return the HFC of v
|
||||
|
||||
*/
|
||||
smpl_t fvec_local_hfc (fvec_t * v);
|
||||
|
||||
/** computes the p-norm of a vector
|
||||
|
||||
Computes the p-norm of a vector for \f$ p = \alpha \f$
|
||||
|
||||
\f$ L^p = ||x||_p = (|x_1|^p + |x_2|^p + ... + |x_n|^p ) ^ \frac{1}{p} \f$
|
||||
|
||||
If p = 1, the result is the Manhattan distance.
|
||||
|
||||
If p = 2, the result is the Euclidean distance.
|
||||
|
||||
As p tends towards large values, \f$ L^p \f$ tends towards the maximum of the
|
||||
input vector.
|
||||
|
||||
References:
|
||||
|
||||
- <a href="http://en.wikipedia.org/wiki/Lp_space">\f$L^p\f$ space</a> on
|
||||
Wikipedia
|
||||
|
||||
\param v vector to compute norm from
|
||||
\param p order of the computed norm
|
||||
|
||||
\return the p-norm of v
|
||||
|
||||
*/
|
||||
smpl_t fvec_alpha_norm (fvec_t * v, smpl_t p);
|
||||
|
||||
/** alpha normalisation
|
||||
|
||||
This function divides all elements of a vector by the p-norm as computed by
|
||||
fvec_alpha_norm().
|
||||
|
||||
\param v vector to compute norm from
|
||||
\param p order of the computed norm
|
||||
|
||||
*/
|
||||
void fvec_alpha_normalise (fvec_t * v, smpl_t p);
|
||||
|
||||
/** add a constant to each elements of a vector
|
||||
|
||||
\param v vector to add constant to
|
||||
\param c constant to add to v
|
||||
|
||||
*/
|
||||
void fvec_add (fvec_t * v, smpl_t c);
|
||||
|
||||
/** multiply each elements of a vector by a scalar
|
||||
|
||||
\param v vector to add constant to
|
||||
\param s constant to scale v with
|
||||
|
||||
*/
|
||||
void fvec_mul (fvec_t * v, smpl_t s);
|
||||
|
||||
/** remove the minimum value of the vector to each elements
|
||||
|
||||
\param v vector to remove minimum from
|
||||
|
||||
*/
|
||||
void fvec_min_removal (fvec_t * v);
|
||||
|
||||
/** compute moving median threshold of a vector
|
||||
|
||||
This function computes the moving median threshold value of at the given
|
||||
position of a vector, taking the median among post elements before and up to
|
||||
pre elements after pos.
|
||||
|
||||
\param v input vector
|
||||
\param tmp temporary vector of length post+1+pre
|
||||
\param post length of causal part to take before pos
|
||||
\param pre length of anti-causal part to take after pos
|
||||
\param pos index to compute threshold for
|
||||
|
||||
\return moving median threshold value
|
||||
|
||||
*/
|
||||
smpl_t fvec_moving_thres (fvec_t * v, fvec_t * tmp, uint_t post, uint_t pre,
|
||||
uint_t pos);
|
||||
|
||||
/** apply adaptive threshold to a vector
|
||||
|
||||
For each points at position p of an input vector, this function remove the
|
||||
moving median threshold computed at p.
|
||||
|
||||
\param v input vector
|
||||
\param tmp temporary vector of length post+1+pre
|
||||
\param post length of causal part to take before pos
|
||||
\param pre length of anti-causal part to take after pos
|
||||
|
||||
*/
|
||||
void fvec_adapt_thres (fvec_t * v, fvec_t * tmp, uint_t post, uint_t pre);
|
||||
|
||||
/** returns the median of a vector
|
||||
|
||||
The QuickSelect routine is based on the algorithm described in "Numerical
|
||||
recipes in C", Second Edition, Cambridge University Press, 1992, Section 8.5,
|
||||
ISBN 0-521-43108-5
|
||||
|
||||
This implementation of the QuickSelect routine is based on Nicolas
|
||||
Devillard's implementation, available at http://ndevilla.free.fr/median/median/
|
||||
and in the Public Domain.
|
||||
|
||||
\param v vector to get median from
|
||||
|
||||
\return the median of v
|
||||
|
||||
*/
|
||||
smpl_t fvec_median (fvec_t * v);
|
||||
|
||||
/** finds exact peak index by quadratic interpolation
|
||||
|
||||
See [Quadratic Interpolation of Spectral
|
||||
Peaks](https://ccrma.stanford.edu/~jos/sasp/Quadratic_Peak_Interpolation.html),
|
||||
by Julius O. Smith III
|
||||
|
||||
\f$ p_{frac} = \frac{1}{2} \frac {x[p-1] - x[p+1]} {x[p-1] - 2 x[p] + x[p+1]} \in [ -.5, .5] \f$
|
||||
|
||||
\param x vector to get the interpolated peak position from
|
||||
\param p index of the peak in vector `x`
|
||||
\return \f$ p + p_{frac} \f$ exact peak position of interpolated maximum or minimum
|
||||
|
||||
*/
|
||||
smpl_t fvec_quadratic_peak_pos (const fvec_t * x, uint_t p);
|
||||
|
||||
/** finds magnitude of peak by quadratic interpolation
|
||||
|
||||
See [Quadratic Interpolation of Spectral
|
||||
Peaks](https://ccrma.stanford.edu/~jos/sasp/Quadratic_Peak_Interpolation.html),
|
||||
by Julius O. Smith III
|
||||
|
||||
\param x vector to get the magnitude of the interpolated peak position from
|
||||
\param p index of the peak in vector `x`
|
||||
\return magnitude of interpolated peak
|
||||
|
||||
*/
|
||||
smpl_t fvec_quadratic_peak_mag (fvec_t * x, smpl_t p);
|
||||
|
||||
/** Quadratic interpolation using Lagrange polynomial.
|
||||
|
||||
Inspired from ``Comparison of interpolation algorithms in real-time sound
|
||||
processing'', Vladimir Arnost,
|
||||
|
||||
\param s0,s1,s2 are 3 consecutive samples of a curve
|
||||
\param pf is the floating point index [0;2]
|
||||
|
||||
\return \f$ s0 + (pf/2.)*((pf-3.)*s0-2.*(pf-2.)*s1+(pf-1.)*s2); \f$
|
||||
|
||||
*/
|
||||
smpl_t aubio_quadfrac (smpl_t s0, smpl_t s1, smpl_t s2, smpl_t pf);
|
||||
|
||||
/** return 1 if v[p] is a peak and positive, 0 otherwise
|
||||
|
||||
This function returns 1 if a peak is found at index p in the vector v. The
|
||||
peak is defined as follows:
|
||||
|
||||
- v[p] is positive
|
||||
- v[p-1] < v[p]
|
||||
- v[p] > v[p+1]
|
||||
|
||||
\param v input vector
|
||||
\param p position of supposed for peak
|
||||
|
||||
\return 1 if a peak is found, 0 otherwise
|
||||
|
||||
*/
|
||||
uint_t fvec_peakpick (const fvec_t * v, uint_t p);
|
||||
|
||||
/** return 1 if a is a power of 2, 0 otherwise */
|
||||
uint_t aubio_is_power_of_two(uint_t a);
|
||||
|
||||
/** return the next power of power of 2 greater than a */
|
||||
uint_t aubio_next_power_of_two(uint_t a);
|
||||
|
||||
/** return the log2 factor of the given power of 2 value a */
|
||||
uint_t aubio_power_of_two_order(uint_t a);
|
||||
|
||||
/** compute normalised autocorrelation function
|
||||
|
||||
\param input vector to compute autocorrelation from
|
||||
\param output vector to store autocorrelation function to
|
||||
|
||||
*/
|
||||
void aubio_autocorr (const fvec_t * input, fvec_t * output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_MATHUTILS_H */
|
270
deps/aubio/src/musicutils.h
vendored
Normal file
270
deps/aubio/src/musicutils.h
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* various functions useful in audio signal processing
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_MUSICUTILS_H
|
||||
#define AUBIO_MUSICUTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** create window
|
||||
|
||||
\param window_type type of the window to create
|
||||
\param size length of the window to create (see fvec_set_window())
|
||||
|
||||
*/
|
||||
fvec_t *new_aubio_window (char_t * window_type, uint_t size);
|
||||
|
||||
/** set elements of a vector to window coefficients
|
||||
|
||||
\param window exsting ::fvec_t to use
|
||||
\param window_type type of the window to create
|
||||
|
||||
List of available window types: "rectangle", "hamming", "hanning",
|
||||
"hanningz", "blackman", "blackman_harris", "gaussian", "welch", "parzen",
|
||||
"default".
|
||||
|
||||
"default" is equivalent to "hanningz".
|
||||
|
||||
References:
|
||||
|
||||
- <a href="http://en.wikipedia.org/wiki/Window_function">Window
|
||||
function</a> on Wikipedia
|
||||
- Amalia de Götzen, Nicolas Bernardini, and Daniel Arfib. Traditional (?)
|
||||
implementations of a phase vocoder: the tricks of the trade. In Proceedings of
|
||||
the International Conference on Digital Audio Effects (DAFx-00), pages 37–44,
|
||||
Uni- versity of Verona, Italy, 2000.
|
||||
(<a href="http://www.cs.princeton.edu/courses/archive/spr09/cos325/Bernardini.pdf">
|
||||
pdf</a>)
|
||||
|
||||
*/
|
||||
uint_t fvec_set_window (fvec_t * window, char_t * window_type);
|
||||
|
||||
/** compute the principal argument
|
||||
|
||||
This function maps the input phase to its corresponding value wrapped in the
|
||||
range \f$ [-\pi, \pi] \f$.
|
||||
|
||||
\param phase unwrapped phase to map to the unit circle
|
||||
|
||||
\return equivalent phase wrapped to the unit circle
|
||||
|
||||
*/
|
||||
smpl_t aubio_unwrap2pi (smpl_t phase);
|
||||
|
||||
/** convert frequency bin to midi value */
|
||||
smpl_t aubio_bintomidi (smpl_t bin, smpl_t samplerate, smpl_t fftsize);
|
||||
|
||||
/** convert midi value to frequency bin */
|
||||
smpl_t aubio_miditobin (smpl_t midi, smpl_t samplerate, smpl_t fftsize);
|
||||
|
||||
/** convert frequency bin to frequency (Hz) */
|
||||
smpl_t aubio_bintofreq (smpl_t bin, smpl_t samplerate, smpl_t fftsize);
|
||||
|
||||
/** convert frequency (Hz) to frequency bin */
|
||||
smpl_t aubio_freqtobin (smpl_t freq, smpl_t samplerate, smpl_t fftsize);
|
||||
|
||||
/** convert frequency (Hz) to mel
|
||||
|
||||
\param freq input frequency, in Hz
|
||||
|
||||
\return output mel
|
||||
|
||||
Converts a scalar from the frequency domain to the mel scale using Slaney
|
||||
Auditory Toolbox's implementation:
|
||||
|
||||
If \f$ f < 1000 \f$, \f$ m = 3 f / 200 \f$.
|
||||
|
||||
If \f$ f >= 1000 \f$, \f$ m = 1000 + 27 \frac{{ln}(f) - ln(1000))}
|
||||
{{ln}(6400) - ln(1000)}
|
||||
\f$
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
aubio_meltohz(), aubio_hztomel_htk().
|
||||
|
||||
*/
|
||||
smpl_t aubio_hztomel (smpl_t freq);
|
||||
|
||||
/** convert mel to frequency (Hz)
|
||||
|
||||
\param mel input mel
|
||||
|
||||
\return output frequency, in Hz
|
||||
|
||||
Converts a scalar from the mel scale to the frequency domain using Slaney
|
||||
Auditory Toolbox's implementation:
|
||||
|
||||
If \f$ f < 1000 \f$, \f$ f = 200 m/3 \f$.
|
||||
|
||||
If \f$ f \geq 1000 \f$, \f$ f = 1000 + \left(\frac{6400}{1000}\right)
|
||||
^{\frac{m - 1000}{27}} \f$
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
aubio_hztomel(), aubio_meltohz_htk().
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
Malcolm Slaney, *Auditory Toolbox Version 2, Technical Report #1998-010*
|
||||
https://engineering.purdue.edu/~malcolm/interval/1998-010/
|
||||
|
||||
*/
|
||||
smpl_t aubio_meltohz (smpl_t mel);
|
||||
|
||||
/** convert frequency (Hz) to mel
|
||||
|
||||
\param freq input frequency, in Hz
|
||||
|
||||
\return output mel
|
||||
|
||||
Converts a scalar from the frequency domain to the mel scale, using the
|
||||
equation defined by O'Shaughnessy, as implemented in the HTK speech
|
||||
recognition toolkit:
|
||||
|
||||
\f$ m = 1127 + ln(1 + \frac{f}{700}) \f$
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
aubio_meltohz_htk(), aubio_hztomel().
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
Douglas O'Shaughnessy (1987). *Speech communication: human and machine*.
|
||||
Addison-Wesley. p. 150. ISBN 978-0-201-16520-3.
|
||||
|
||||
HTK Speech Recognition Toolkit: http://htk.eng.cam.ac.uk/
|
||||
|
||||
*/
|
||||
smpl_t aubio_hztomel_htk (smpl_t freq);
|
||||
|
||||
/** convert mel to frequency (Hz)
|
||||
|
||||
\param mel input mel
|
||||
|
||||
\return output frequency, in Hz
|
||||
|
||||
Converts a scalar from the mel scale to the frequency domain, using the
|
||||
equation defined by O'Shaughnessy, as implemented in the HTK speech
|
||||
recognition toolkit:
|
||||
|
||||
\f$ f = 700 * {e}^\left(\frac{f}{1127} - 1\right) \f$
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
aubio_hztomel_htk(), aubio_meltohz().
|
||||
|
||||
*/
|
||||
smpl_t aubio_meltohz_htk (smpl_t mel);
|
||||
|
||||
/** convert frequency (Hz) to midi value (0-128) */
|
||||
smpl_t aubio_freqtomidi (smpl_t freq);
|
||||
|
||||
/** convert midi value (0-128) to frequency (Hz) */
|
||||
smpl_t aubio_miditofreq (smpl_t midi);
|
||||
|
||||
/** clean up cached memory at the end of program
|
||||
|
||||
This function should be used at the end of programs to purge all cached
|
||||
memory. So far it is only useful to clean FFTW's cache.
|
||||
|
||||
*/
|
||||
void aubio_cleanup (void);
|
||||
|
||||
/** zero-crossing rate (ZCR)
|
||||
|
||||
The zero-crossing rate is the number of times a signal changes sign,
|
||||
divided by the length of this signal.
|
||||
|
||||
\param v vector to compute ZCR from
|
||||
|
||||
\return zero-crossing rate of v
|
||||
|
||||
*/
|
||||
smpl_t aubio_zero_crossing_rate (fvec_t * v);
|
||||
|
||||
/** compute sound level on a linear scale
|
||||
|
||||
This gives the average of the square amplitudes.
|
||||
|
||||
\param v vector to compute level from
|
||||
|
||||
\return level of v
|
||||
|
||||
*/
|
||||
smpl_t aubio_level_lin (const fvec_t * v);
|
||||
|
||||
/** compute sound pressure level (SPL) in dB
|
||||
|
||||
This quantity is often wrongly called 'loudness'.
|
||||
|
||||
This gives ten times the log10 of the average of the square amplitudes.
|
||||
|
||||
\param v vector to compute dB SPL from
|
||||
|
||||
\return level of v in dB SPL
|
||||
|
||||
*/
|
||||
smpl_t aubio_db_spl (const fvec_t * v);
|
||||
|
||||
/** check if buffer level in dB SPL is under a given threshold
|
||||
|
||||
\param v vector to get level from
|
||||
\param threshold threshold in dB SPL
|
||||
|
||||
\return 1 if level is under the given threshold, 0 otherwise
|
||||
|
||||
*/
|
||||
uint_t aubio_silence_detection (const fvec_t * v, smpl_t threshold);
|
||||
|
||||
/** get buffer level if level >= threshold, 1. otherwise
|
||||
|
||||
\param v vector to get level from
|
||||
\param threshold threshold in dB SPL
|
||||
|
||||
\return level in dB SPL if level >= threshold, 1. otherwise
|
||||
|
||||
*/
|
||||
smpl_t aubio_level_detection (const fvec_t * v, smpl_t threshold);
|
||||
|
||||
/** clamp the values of a vector within the range [-abs(max), abs(max)]
|
||||
|
||||
\param in vector to clamp
|
||||
\param absmax maximum value over which input vector elements should be clamped
|
||||
|
||||
*/
|
||||
void fvec_clamp(fvec_t *in, smpl_t absmax);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_MUSICUTILS_H */
|
530
deps/aubio/src/pitch/pitch.c
vendored
Normal file
530
deps/aubio/src/pitch/pitch.c
vendored
Normal file
|
@ -0,0 +1,530 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "lvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "musicutils.h"
|
||||
#include "spectral/phasevoc.h"
|
||||
#include "temporal/filter.h"
|
||||
#include "temporal/c_weighting.h"
|
||||
#include "pitch/pitchmcomb.h"
|
||||
#include "pitch/pitchyin.h"
|
||||
#include "pitch/pitchfcomb.h"
|
||||
#include "pitch/pitchschmitt.h"
|
||||
#include "pitch/pitchyinfft.h"
|
||||
#include "pitch/pitchyinfast.h"
|
||||
#include "pitch/pitchspecacf.h"
|
||||
#include "pitch/pitch.h"
|
||||
|
||||
#define DEFAULT_PITCH_SILENCE -50.
|
||||
|
||||
/** pitch detection algorithms */
|
||||
typedef enum
|
||||
{
|
||||
aubio_pitcht_yin, /**< `yin`, YIN algorithm */
|
||||
aubio_pitcht_mcomb, /**< `mcomb`, Multi-comb filter */
|
||||
aubio_pitcht_schmitt, /**< `schmitt`, Schmitt trigger */
|
||||
aubio_pitcht_fcomb, /**< `fcomb`, Fast comb filter */
|
||||
aubio_pitcht_yinfft, /**< `yinfft`, Spectral YIN */
|
||||
aubio_pitcht_yinfast, /**< `yinfast`, YIN fast */
|
||||
aubio_pitcht_specacf, /**< `specacf`, Spectral autocorrelation */
|
||||
aubio_pitcht_default
|
||||
= aubio_pitcht_yinfft, /**< `default` */
|
||||
} aubio_pitch_type;
|
||||
|
||||
/** pitch detection output modes */
|
||||
typedef enum
|
||||
{
|
||||
aubio_pitchm_freq, /**< Frequency (Hz) */
|
||||
aubio_pitchm_midi, /**< MIDI note (0.,127) */
|
||||
aubio_pitchm_cent, /**< Cent */
|
||||
aubio_pitchm_bin, /**< Frequency bin (0,bufsize) */
|
||||
aubio_pitchm_default = aubio_pitchm_freq, /**< the one used when "default" is asked */
|
||||
} aubio_pitch_mode;
|
||||
|
||||
/** callback to get pitch candidate, defined below */
|
||||
typedef void (*aubio_pitch_detect_t) (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
|
||||
/** callback to convert pitch from one unit to another, defined below */
|
||||
typedef smpl_t(*aubio_pitch_convert_t) (smpl_t value, uint_t samplerate, uint_t bufsize);
|
||||
|
||||
/** callback to fetch the confidence of the algorithm */
|
||||
typedef smpl_t (*aubio_pitch_get_conf_t) (void * p);
|
||||
|
||||
/** generic pitch detection structure */
|
||||
struct _aubio_pitch_t
|
||||
{
|
||||
aubio_pitch_type type; /**< pitch detection mode */
|
||||
aubio_pitch_mode mode; /**< pitch detection output mode */
|
||||
uint_t samplerate; /**< samplerate */
|
||||
uint_t bufsize; /**< buffer size */
|
||||
void *p_object; /**< pointer to pitch object */
|
||||
aubio_filter_t *filter; /**< filter */
|
||||
fvec_t *filtered; /**< filtered input */
|
||||
aubio_pvoc_t *pv; /**< phase vocoder for mcomb */
|
||||
cvec_t *fftgrain; /**< spectral frame for mcomb */
|
||||
fvec_t *buf; /**< temporary buffer for yin */
|
||||
aubio_pitch_detect_t detect_cb; /**< callback to get the pitch candidates */
|
||||
aubio_pitch_convert_t conv_cb; /**< callback to convert it to the desired unit */
|
||||
aubio_pitch_get_conf_t conf_cb; /**< pointer to the current confidence callback */
|
||||
smpl_t silence; /**< silence threshold */
|
||||
};
|
||||
|
||||
/* callback functions for pitch detection */
|
||||
static void aubio_pitch_do_mcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_yin (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_schmitt (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_fcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_yinfft (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_yinfast (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_specacf (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
|
||||
/* internal functions for frequency conversion */
|
||||
static smpl_t freqconvbin (smpl_t f, uint_t samplerate, uint_t bufsize);
|
||||
static smpl_t freqconvmidi (smpl_t f, uint_t samplerate, uint_t bufsize);
|
||||
static smpl_t freqconvpass (smpl_t f, uint_t samplerate, uint_t bufsize);
|
||||
|
||||
/* adapter to stack ibuf new samples at the end of buf, and trim `buf` to `bufsize` */
|
||||
void aubio_pitch_slideblock (aubio_pitch_t * p, const fvec_t * ibuf);
|
||||
|
||||
|
||||
aubio_pitch_t *
|
||||
new_aubio_pitch (const char_t * pitch_mode,
|
||||
uint_t bufsize, uint_t hopsize, uint_t samplerate)
|
||||
{
|
||||
aubio_pitch_t *p = AUBIO_NEW (aubio_pitch_t);
|
||||
aubio_pitch_type pitch_type;
|
||||
if (pitch_mode == NULL) {
|
||||
AUBIO_ERR ("pitch: can not use ‘NULL‘ for pitch detection method\n");
|
||||
goto beach;
|
||||
}
|
||||
if (strcmp (pitch_mode, "mcomb") == 0)
|
||||
pitch_type = aubio_pitcht_mcomb;
|
||||
else if (strcmp (pitch_mode, "yinfast") == 0)
|
||||
pitch_type = aubio_pitcht_yinfast;
|
||||
else if (strcmp (pitch_mode, "yinfft") == 0)
|
||||
pitch_type = aubio_pitcht_yinfft;
|
||||
else if (strcmp (pitch_mode, "yin") == 0)
|
||||
pitch_type = aubio_pitcht_yin;
|
||||
else if (strcmp (pitch_mode, "schmitt") == 0)
|
||||
pitch_type = aubio_pitcht_schmitt;
|
||||
else if (strcmp (pitch_mode, "fcomb") == 0)
|
||||
pitch_type = aubio_pitcht_fcomb;
|
||||
else if (strcmp (pitch_mode, "specacf") == 0)
|
||||
pitch_type = aubio_pitcht_specacf;
|
||||
else if (strcmp (pitch_mode, "default") == 0)
|
||||
pitch_type = aubio_pitcht_default;
|
||||
else {
|
||||
AUBIO_ERR ("pitch: unknown pitch detection method ‘%s’\n", pitch_mode);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
// check parameters are valid
|
||||
if ((sint_t)hopsize < 1) {
|
||||
AUBIO_ERR("pitch: got hopsize %d, but can not be < 1\n", hopsize);
|
||||
goto beach;
|
||||
} else if ((sint_t)bufsize < 1) {
|
||||
AUBIO_ERR("pitch: got buffer_size %d, but can not be < 1\n", bufsize);
|
||||
goto beach;
|
||||
} else if (bufsize < hopsize) {
|
||||
AUBIO_ERR("pitch: hop size (%d) is larger than win size (%d)\n", hopsize, bufsize);
|
||||
goto beach;
|
||||
} else if ((sint_t)samplerate < 1) {
|
||||
AUBIO_ERR("pitch: samplerate (%d) can not be < 1\n", samplerate);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
p->samplerate = samplerate;
|
||||
p->type = pitch_type;
|
||||
aubio_pitch_set_unit (p, "default");
|
||||
p->bufsize = bufsize;
|
||||
p->silence = DEFAULT_PITCH_SILENCE;
|
||||
p->conf_cb = NULL;
|
||||
switch (p->type) {
|
||||
case aubio_pitcht_yin:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchyin (bufsize);
|
||||
if (!p->p_object) goto beach;
|
||||
p->detect_cb = aubio_pitch_do_yin;
|
||||
p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchyin_get_confidence;
|
||||
aubio_pitchyin_set_tolerance (p->p_object, 0.15);
|
||||
break;
|
||||
case aubio_pitcht_mcomb:
|
||||
p->filtered = new_fvec (hopsize);
|
||||
p->pv = new_aubio_pvoc (bufsize, hopsize);
|
||||
if (!p->pv) goto beach;
|
||||
p->fftgrain = new_cvec (bufsize);
|
||||
p->p_object = new_aubio_pitchmcomb (bufsize, hopsize);
|
||||
p->filter = new_aubio_filter_c_weighting (samplerate);
|
||||
p->detect_cb = aubio_pitch_do_mcomb;
|
||||
break;
|
||||
case aubio_pitcht_fcomb:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchfcomb (bufsize, hopsize);
|
||||
if (!p->p_object) goto beach;
|
||||
p->detect_cb = aubio_pitch_do_fcomb;
|
||||
break;
|
||||
case aubio_pitcht_schmitt:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchschmitt (bufsize);
|
||||
p->detect_cb = aubio_pitch_do_schmitt;
|
||||
break;
|
||||
case aubio_pitcht_yinfft:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchyinfft (samplerate, bufsize);
|
||||
if (!p->p_object) goto beach;
|
||||
p->detect_cb = aubio_pitch_do_yinfft;
|
||||
p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchyinfft_get_confidence;
|
||||
aubio_pitchyinfft_set_tolerance (p->p_object, 0.85);
|
||||
break;
|
||||
case aubio_pitcht_yinfast:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchyinfast (bufsize);
|
||||
if (!p->p_object) goto beach;
|
||||
p->detect_cb = aubio_pitch_do_yinfast;
|
||||
p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchyinfast_get_confidence;
|
||||
aubio_pitchyinfast_set_tolerance (p->p_object, 0.15);
|
||||
break;
|
||||
case aubio_pitcht_specacf:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchspecacf (bufsize);
|
||||
if (!p->p_object) goto beach;
|
||||
p->detect_cb = aubio_pitch_do_specacf;
|
||||
p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchspecacf_get_tolerance;
|
||||
aubio_pitchspecacf_set_tolerance (p->p_object, 0.85);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
|
||||
beach:
|
||||
if (p->filtered) del_fvec(p->filtered);
|
||||
if (p->buf) del_fvec(p->buf);
|
||||
AUBIO_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitch (aubio_pitch_t * p)
|
||||
{
|
||||
switch (p->type) {
|
||||
case aubio_pitcht_yin:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchyin (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_mcomb:
|
||||
del_fvec (p->filtered);
|
||||
del_aubio_pvoc (p->pv);
|
||||
del_cvec (p->fftgrain);
|
||||
del_aubio_filter (p->filter);
|
||||
del_aubio_pitchmcomb (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_schmitt:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchschmitt (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_fcomb:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchfcomb (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_yinfft:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchyinfft (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_yinfast:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchyinfast (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_specacf:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchspecacf (p->p_object);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
AUBIO_FREE (p);
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_slideblock (aubio_pitch_t * p, const fvec_t * ibuf)
|
||||
{
|
||||
uint_t overlap_size = p->buf->length - ibuf->length;
|
||||
#if 1 //!HAVE_MEMCPY_HACKS
|
||||
uint_t j;
|
||||
for (j = 0; j < overlap_size; j++) {
|
||||
p->buf->data[j] = p->buf->data[j + ibuf->length];
|
||||
}
|
||||
for (j = 0; j < ibuf->length; j++) {
|
||||
p->buf->data[j + overlap_size] = ibuf->data[j];
|
||||
}
|
||||
#else
|
||||
smpl_t *data = p->buf->data;
|
||||
smpl_t *newdata = ibuf->data;
|
||||
memmove(data, data + ibuf->length, overlap_size);
|
||||
memcpy(data + overlap_size, newdata, ibuf->length);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitch_set_unit (aubio_pitch_t * p, const char_t * pitch_unit)
|
||||
{
|
||||
uint_t err = AUBIO_OK;
|
||||
aubio_pitch_mode pitch_mode;
|
||||
if (strcmp (pitch_unit, "freq") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "hertz") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "Hertz") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "Hz") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "f0") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "midi") == 0)
|
||||
pitch_mode = aubio_pitchm_midi;
|
||||
else if (strcmp (pitch_unit, "cent") == 0)
|
||||
pitch_mode = aubio_pitchm_cent;
|
||||
else if (strcmp (pitch_unit, "bin") == 0)
|
||||
pitch_mode = aubio_pitchm_bin;
|
||||
else if (strcmp (pitch_unit, "default") == 0)
|
||||
pitch_mode = aubio_pitchm_default;
|
||||
else {
|
||||
AUBIO_WRN("pitch: unknown pitch detection unit ‘%s’, using default\n",
|
||||
pitch_unit);
|
||||
pitch_mode = aubio_pitchm_default;
|
||||
err = AUBIO_FAIL;
|
||||
}
|
||||
p->mode = pitch_mode;
|
||||
switch (p->mode) {
|
||||
case aubio_pitchm_freq:
|
||||
p->conv_cb = freqconvpass;
|
||||
break;
|
||||
case aubio_pitchm_midi:
|
||||
p->conv_cb = freqconvmidi;
|
||||
break;
|
||||
case aubio_pitchm_cent:
|
||||
/* bug: not implemented */
|
||||
p->conv_cb = freqconvmidi;
|
||||
break;
|
||||
case aubio_pitchm_bin:
|
||||
p->conv_cb = freqconvbin;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitch_set_tolerance (aubio_pitch_t * p, smpl_t tol)
|
||||
{
|
||||
switch (p->type) {
|
||||
case aubio_pitcht_yin:
|
||||
aubio_pitchyin_set_tolerance (p->p_object, tol);
|
||||
break;
|
||||
case aubio_pitcht_yinfft:
|
||||
aubio_pitchyinfft_set_tolerance (p->p_object, tol);
|
||||
break;
|
||||
case aubio_pitcht_yinfast:
|
||||
aubio_pitchyinfast_set_tolerance (p->p_object, tol);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return AUBIO_OK;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitch_get_tolerance (aubio_pitch_t * p)
|
||||
{
|
||||
smpl_t tolerance = 1.;
|
||||
switch (p->type) {
|
||||
case aubio_pitcht_yin:
|
||||
tolerance = aubio_pitchyin_get_tolerance (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_yinfft:
|
||||
tolerance = aubio_pitchyinfft_get_tolerance (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_yinfast:
|
||||
tolerance = aubio_pitchyinfast_get_tolerance (p->p_object);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return tolerance;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitch_set_silence (aubio_pitch_t * p, smpl_t silence)
|
||||
{
|
||||
if (silence <= 0 && silence >= -200) {
|
||||
p->silence = silence;
|
||||
return AUBIO_OK;
|
||||
} else {
|
||||
AUBIO_WRN("pitch: could not set silence to %.2f\n", silence);
|
||||
return AUBIO_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitch_get_silence (aubio_pitch_t * p)
|
||||
{
|
||||
return p->silence;
|
||||
}
|
||||
|
||||
|
||||
/* do method, calling the detection callback, then the conversion callback */
|
||||
void
|
||||
aubio_pitch_do (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
p->detect_cb (p, ibuf, obuf);
|
||||
if (aubio_silence_detection(ibuf, p->silence) == 1) {
|
||||
obuf->data[0] = 0.;
|
||||
}
|
||||
obuf->data[0] = p->conv_cb (obuf->data[0], p->samplerate, p->bufsize);
|
||||
}
|
||||
|
||||
/* do method for each algorithm */
|
||||
void
|
||||
aubio_pitch_do_mcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
aubio_filter_do_outplace (p->filter, ibuf, p->filtered);
|
||||
aubio_pvoc_do (p->pv, ibuf, p->fftgrain);
|
||||
aubio_pitchmcomb_do (p->p_object, p->fftgrain, obuf);
|
||||
obuf->data[0] = aubio_bintofreq (obuf->data[0], p->samplerate, p->bufsize);
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_do_yin (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
smpl_t pitch = 0.;
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchyin_do (p->p_object, p->buf, obuf);
|
||||
pitch = obuf->data[0];
|
||||
if (pitch > 0) {
|
||||
pitch = p->samplerate / (pitch + 0.);
|
||||
} else {
|
||||
pitch = 0.;
|
||||
}
|
||||
obuf->data[0] = pitch;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
aubio_pitch_do_yinfft (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
smpl_t pitch = 0.;
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchyinfft_do (p->p_object, p->buf, obuf);
|
||||
pitch = obuf->data[0];
|
||||
if (pitch > 0) {
|
||||
pitch = p->samplerate / (pitch + 0.);
|
||||
} else {
|
||||
pitch = 0.;
|
||||
}
|
||||
obuf->data[0] = pitch;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_do_yinfast (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
smpl_t pitch = 0.;
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchyinfast_do (p->p_object, p->buf, obuf);
|
||||
pitch = obuf->data[0];
|
||||
if (pitch > 0) {
|
||||
pitch = p->samplerate / (pitch + 0.);
|
||||
} else {
|
||||
pitch = 0.;
|
||||
}
|
||||
obuf->data[0] = pitch;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_do_specacf (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * out)
|
||||
{
|
||||
smpl_t pitch = 0., period;
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchspecacf_do (p->p_object, p->buf, out);
|
||||
//out->data[0] = aubio_bintofreq (out->data[0], p->samplerate, p->bufsize);
|
||||
period = out->data[0];
|
||||
if (period > 0) {
|
||||
pitch = p->samplerate / period;
|
||||
} else {
|
||||
pitch = 0.;
|
||||
}
|
||||
out->data[0] = pitch;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_do_fcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * out)
|
||||
{
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchfcomb_do (p->p_object, p->buf, out);
|
||||
out->data[0] = aubio_bintofreq (out->data[0], p->samplerate, p->bufsize);
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_do_schmitt (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * out)
|
||||
{
|
||||
smpl_t period, pitch = 0.;
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchschmitt_do (p->p_object, p->buf, out);
|
||||
period = out->data[0];
|
||||
if (period > 0) {
|
||||
pitch = p->samplerate / period;
|
||||
} else {
|
||||
pitch = 0.;
|
||||
}
|
||||
out->data[0] = pitch;
|
||||
}
|
||||
|
||||
/* conversion callbacks */
|
||||
smpl_t
|
||||
freqconvbin(smpl_t f, uint_t samplerate, uint_t bufsize)
|
||||
{
|
||||
return aubio_freqtobin(f, samplerate, bufsize);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
freqconvmidi (smpl_t f, uint_t samplerate UNUSED, uint_t bufsize UNUSED)
|
||||
{
|
||||
return aubio_freqtomidi (f);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
freqconvpass (smpl_t f, uint_t samplerate UNUSED, uint_t bufsize UNUSED)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
/* confidence callbacks */
|
||||
smpl_t
|
||||
aubio_pitch_get_confidence (aubio_pitch_t * p)
|
||||
{
|
||||
if (p->conf_cb) {
|
||||
return p->conf_cb(p->p_object);
|
||||
}
|
||||
return 0.;
|
||||
}
|
197
deps/aubio/src/pitch/pitch.h
vendored
Normal file
197
deps/aubio/src/pitch/pitch.h
vendored
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCH_H
|
||||
#define AUBIO_PITCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection object
|
||||
|
||||
This file creates the objects required for the computation of the selected
|
||||
pitch detection algorithm and output the results, in midi note or Hz.
|
||||
|
||||
\section pitch Pitch detection methods
|
||||
|
||||
A list of the pitch detection methods currently available follows.
|
||||
|
||||
\b \p default : use the default method
|
||||
|
||||
Currently, the default method is set to \p yinfft .
|
||||
|
||||
\b \p schmitt : Schmitt trigger
|
||||
|
||||
This pitch extraction method implements a Schmitt trigger to estimate the
|
||||
period of a signal.
|
||||
|
||||
This file was derived from the tuneit project, written by Mario Lang to
|
||||
detect the fundamental frequency of a sound.
|
||||
|
||||
See http://delysid.org/tuneit.html
|
||||
|
||||
\b \p fcomb : a fast harmonic comb filter
|
||||
|
||||
This pitch extraction method implements a fast harmonic comb filter to
|
||||
determine the fundamental frequency of a harmonic sound.
|
||||
|
||||
This file was derived from the tuneit project, written by Mario Lang to
|
||||
detect the fundamental frequency of a sound.
|
||||
|
||||
See http://delysid.org/tuneit.html
|
||||
|
||||
\b \p mcomb : multiple-comb filter
|
||||
|
||||
This fundamental frequency estimation algorithm implements spectral
|
||||
flattening, multi-comb filtering and peak histogramming.
|
||||
|
||||
This method was designed by Juan P. Bello and described in:
|
||||
|
||||
Juan-Pablo Bello. ``Towards the Automated Analysis of Simple Polyphonic
|
||||
Music''. PhD thesis, Centre for Digital Music, Queen Mary University of
|
||||
London, London, UK, 2003.
|
||||
|
||||
\b \p yin : YIN algorithm
|
||||
|
||||
This algorithm was developed by A. de Cheveigne and H. Kawahara and
|
||||
published in:
|
||||
|
||||
De Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
|
||||
see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
|
||||
\b \p yinfast : Yinfast algorithm
|
||||
|
||||
This algorithm is equivalent to the YIN algorithm, but computed in the
|
||||
spectral domain for efficiency. See also `python/demos/demo_yin_compare.py`.
|
||||
|
||||
\b \p yinfft : Yinfft algorithm
|
||||
|
||||
This algorithm was derived from the YIN algorithm. In this implementation, a
|
||||
Fourier transform is used to compute a tapered square difference function,
|
||||
which allows spectral weighting. Because the difference function is tapered,
|
||||
the selection of the period is simplified.
|
||||
|
||||
Paul Brossier, [Automatic annotation of musical audio for interactive
|
||||
systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, PhD thesis,
|
||||
Centre for Digital music, Queen Mary University of London, London, UK, 2006.
|
||||
|
||||
\example pitch/test-pitch.c
|
||||
\example examples/aubiopitch.c
|
||||
|
||||
*/
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitch_t aubio_pitch_t;
|
||||
|
||||
/** execute pitch detection on an input signal frame
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\param in input signal of size [hop_size]
|
||||
\param out output pitch candidates of size [1]
|
||||
|
||||
*/
|
||||
void aubio_pitch_do (aubio_pitch_t * o, const fvec_t * in, fvec_t * out);
|
||||
|
||||
/** change yin or yinfft tolerance threshold
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\param tol tolerance default is 0.15 for yin and 0.85 for yinfft
|
||||
|
||||
*/
|
||||
uint_t aubio_pitch_set_tolerance (aubio_pitch_t * o, smpl_t tol);
|
||||
|
||||
/** get yin or yinfft tolerance threshold
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\return tolerance (default is 0.15 for yin and 0.85 for yinfft)
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitch_get_tolerance (aubio_pitch_t * o);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
|
||||
*/
|
||||
void del_aubio_pitch (aubio_pitch_t * o);
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param method set pitch detection algorithm
|
||||
\param buf_size size of the input buffer to analyse
|
||||
\param hop_size step size between two consecutive analysis instant
|
||||
\param samplerate sampling rate of the signal
|
||||
|
||||
\return newly created ::aubio_pitch_t
|
||||
|
||||
*/
|
||||
aubio_pitch_t *new_aubio_pitch (const char_t * method,
|
||||
uint_t buf_size, uint_t hop_size, uint_t samplerate);
|
||||
|
||||
/** set the output unit of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\param mode set pitch units for output
|
||||
|
||||
mode can be one of "Hz", "midi", "cent", or "bin". Defaults to "Hz".
|
||||
|
||||
\return 0 if successfull, non-zero otherwise
|
||||
|
||||
*/
|
||||
uint_t aubio_pitch_set_unit (aubio_pitch_t * o, const char_t * mode);
|
||||
|
||||
/** set the silence threshold of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\param silence level threshold under which pitch should be ignored, in dB
|
||||
|
||||
\return 0 if successfull, non-zero otherwise
|
||||
|
||||
*/
|
||||
uint_t aubio_pitch_set_silence (aubio_pitch_t * o, smpl_t silence);
|
||||
|
||||
/** set the silence threshold of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by ::new_aubio_pitch()
|
||||
|
||||
\return level threshold under which pitch should be ignored, in dB
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitch_get_silence (aubio_pitch_t * o);
|
||||
|
||||
/** get the current confidence
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
|
||||
\return the current confidence of the pitch algorithm
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitch_get_confidence (aubio_pitch_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCH_H */
|
144
deps/aubio/src/pitch/pitchfcomb.c
vendored
Normal file
144
deps/aubio/src/pitch/pitchfcomb.c
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
Copyright (C) 2004, 2005 Mario Lang <mlang@delysid.org>
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "musicutils.h"
|
||||
#include "spectral/fft.h"
|
||||
#include "pitch/pitchfcomb.h"
|
||||
|
||||
#define MAX_PEAKS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
smpl_t bin;
|
||||
smpl_t db;
|
||||
} aubio_fpeak_t;
|
||||
|
||||
struct _aubio_pitchfcomb_t
|
||||
{
|
||||
uint_t fftSize;
|
||||
uint_t stepSize;
|
||||
uint_t rate;
|
||||
fvec_t *winput;
|
||||
fvec_t *win;
|
||||
cvec_t *fftOut;
|
||||
fvec_t *fftLastPhase;
|
||||
aubio_fft_t *fft;
|
||||
};
|
||||
|
||||
aubio_pitchfcomb_t *
|
||||
new_aubio_pitchfcomb (uint_t bufsize, uint_t hopsize)
|
||||
{
|
||||
aubio_pitchfcomb_t *p = AUBIO_NEW (aubio_pitchfcomb_t);
|
||||
p->fftSize = bufsize;
|
||||
p->stepSize = hopsize;
|
||||
p->fft = new_aubio_fft (bufsize);
|
||||
if (!p->fft) goto beach;
|
||||
p->winput = new_fvec (bufsize);
|
||||
p->fftOut = new_cvec (bufsize);
|
||||
p->fftLastPhase = new_fvec (bufsize);
|
||||
p->win = new_aubio_window ("hanning", bufsize);
|
||||
return p;
|
||||
|
||||
beach:
|
||||
AUBIO_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* input must be stepsize long */
|
||||
void
|
||||
aubio_pitchfcomb_do (aubio_pitchfcomb_t * p, const fvec_t * input, fvec_t * output)
|
||||
{
|
||||
uint_t k, l, maxharm = 0;
|
||||
smpl_t phaseDifference = TWO_PI * (smpl_t) p->stepSize / (smpl_t) p->fftSize;
|
||||
aubio_fpeak_t peaks[MAX_PEAKS];
|
||||
|
||||
for (k = 0; k < MAX_PEAKS; k++) {
|
||||
peaks[k].db = -200.;
|
||||
peaks[k].bin = 0.;
|
||||
}
|
||||
|
||||
for (k = 0; k < input->length; k++) {
|
||||
p->winput->data[k] = p->win->data[k] * input->data[k];
|
||||
}
|
||||
aubio_fft_do (p->fft, p->winput, p->fftOut);
|
||||
|
||||
for (k = 0; k <= p->fftSize / 2; k++) {
|
||||
smpl_t
|
||||
magnitude =
|
||||
20. * LOG10 (2. * p->fftOut->norm[k] / (smpl_t) p->fftSize),
|
||||
phase = p->fftOut->phas[k], tmp, bin;
|
||||
|
||||
/* compute phase difference */
|
||||
tmp = phase - p->fftLastPhase->data[k];
|
||||
p->fftLastPhase->data[k] = phase;
|
||||
|
||||
/* subtract expected phase difference */
|
||||
tmp -= (smpl_t) k *phaseDifference;
|
||||
|
||||
/* map delta phase into +/- Pi interval */
|
||||
tmp = aubio_unwrap2pi (tmp);
|
||||
|
||||
/* get deviation from bin frequency from the +/- Pi interval */
|
||||
tmp = p->fftSize / (smpl_t) p->stepSize * tmp / (TWO_PI);
|
||||
|
||||
/* compute the k-th partials' true bin */
|
||||
bin = (smpl_t) k + tmp;
|
||||
|
||||
if (bin > 0.0 && magnitude > peaks[0].db) { // && magnitude < 0) {
|
||||
memmove (peaks + 1, peaks, sizeof (aubio_fpeak_t) * (MAX_PEAKS - 1));
|
||||
peaks[0].bin = bin;
|
||||
peaks[0].db = magnitude;
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
for (l = 1; l < MAX_PEAKS && peaks[l].bin > 0.0; l++) {
|
||||
sint_t harmonic;
|
||||
for (harmonic = 5; harmonic > 1; harmonic--) {
|
||||
if (peaks[0].bin / peaks[l].bin < harmonic + .02 &&
|
||||
peaks[0].bin / peaks[l].bin > harmonic - .02) {
|
||||
if (harmonic > (sint_t) maxharm && peaks[0].db < peaks[l].db / 2) {
|
||||
maxharm = harmonic;
|
||||
k = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
output->data[0] = peaks[k].bin;
|
||||
/* quick hack to clean output a bit */
|
||||
if (peaks[k].bin > 5000.)
|
||||
output->data[0] = 0.;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchfcomb (aubio_pitchfcomb_t * p)
|
||||
{
|
||||
del_cvec (p->fftOut);
|
||||
del_fvec (p->fftLastPhase);
|
||||
del_fvec (p->win);
|
||||
del_fvec (p->winput);
|
||||
del_aubio_fft (p->fft);
|
||||
AUBIO_FREE (p);
|
||||
}
|
76
deps/aubio/src/pitch/pitchfcomb.h
vendored
Normal file
76
deps/aubio/src/pitch/pitchfcomb.h
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using a fast harmonic comb filter
|
||||
|
||||
This pitch extraction method implements a fast harmonic comb filter to
|
||||
determine the fundamental frequency of a harmonic sound.
|
||||
|
||||
This file was derived from the tuneit project, written by Mario Lang to
|
||||
detect the fundamental frequency of a sound.
|
||||
|
||||
See http://delysid.org/tuneit.html
|
||||
|
||||
\example pitch/test-pitchfcomb.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHFCOMB_H
|
||||
#define AUBIO_PITCHFCOMB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchfcomb_t aubio_pitchfcomb_t;
|
||||
|
||||
/** execute pitch detection on an input buffer
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchfcomb
|
||||
\param input input signal window (length as specified at creation time)
|
||||
\param output pitch candidates in bins
|
||||
|
||||
*/
|
||||
void aubio_pitchfcomb_do (aubio_pitchfcomb_t * p, const fvec_t * input,
|
||||
fvec_t * output);
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
\param hop_size step size between two consecutive analysis instant
|
||||
|
||||
*/
|
||||
aubio_pitchfcomb_t *new_aubio_pitchfcomb (uint_t buf_size, uint_t hop_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchfcomb
|
||||
|
||||
*/
|
||||
void del_aubio_pitchfcomb (aubio_pitchfcomb_t * p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHFCOMB_H */
|
435
deps/aubio/src/pitch/pitchmcomb.c
vendored
Normal file
435
deps/aubio/src/pitch/pitchmcomb.c
vendored
Normal file
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "pitch/pitchmcomb.h"
|
||||
|
||||
#define CAND_SWAP(a,b) { register aubio_spectralcandidate_t *t=(a);(a)=(b);(b)=t; }
|
||||
|
||||
typedef struct _aubio_spectralpeak_t aubio_spectralpeak_t;
|
||||
typedef struct _aubio_spectralcandidate_t aubio_spectralcandidate_t;
|
||||
uint_t aubio_pitchmcomb_get_root_peak (aubio_spectralpeak_t * peaks,
|
||||
uint_t length);
|
||||
uint_t aubio_pitchmcomb_quadpick (aubio_spectralpeak_t * spectral_peaks,
|
||||
const fvec_t * X);
|
||||
void aubio_pitchmcomb_spectral_pp (aubio_pitchmcomb_t * p, const fvec_t * oldmag);
|
||||
void aubio_pitchmcomb_combdet (aubio_pitchmcomb_t * p, const fvec_t * newmag);
|
||||
/* not used but useful : sort by amplitudes (or anything else)
|
||||
* sort_pitchpeak(peaks, length);
|
||||
*/
|
||||
#if 0
|
||||
/** spectral_peak comparison function (must return signed int) */
|
||||
static sint_t aubio_pitchmcomb_sort_peak_comp (const void *x, const void *y);
|
||||
/** sort spectral_peak against their mag */
|
||||
void aubio_pitchmcomb_sort_peak (aubio_spectralpeak_t * peaks, uint_t nbins);
|
||||
/** select the best candidates */
|
||||
uint_t aubio_pitch_cands (aubio_pitchmcomb_t * p, const cvec_t * fftgrain,
|
||||
smpl_t * cands);
|
||||
#endif
|
||||
|
||||
/** sort spectral_candidate against their comb ene */
|
||||
void aubio_pitchmcomb_sort_cand_ene (aubio_spectralcandidate_t ** candidates,
|
||||
uint_t nbins);
|
||||
#if 0
|
||||
/** sort spectral_candidate against their frequency */
|
||||
void aubio_pitchmcomb_sort_cand_freq (aubio_spectralcandidate_t ** candidates,
|
||||
uint_t nbins);
|
||||
#endif
|
||||
|
||||
struct _aubio_pitchmcomb_t
|
||||
{
|
||||
smpl_t threshold; /**< offset threshold [0.033 or 0.01] */
|
||||
smpl_t alpha; /**< normalisation exponent [9] */
|
||||
smpl_t cutoff; /**< low-pass filter cutoff [0.34, 1] */
|
||||
smpl_t tol; /**< tolerance [0.05] */
|
||||
// smpl_t tau; /**< frequency precision [44100/4096] */
|
||||
uint_t win_post; /**< median filter window length */
|
||||
uint_t win_pre; /**< median filter window */
|
||||
uint_t ncand; /**< maximum number of candidates (combs) */
|
||||
uint_t npartials; /**< maximum number of partials per combs */
|
||||
uint_t count; /**< picked picks */
|
||||
uint_t goodcandidate; /**< best candidate */
|
||||
uint_t spec_partition; /**< spectrum partition to consider */
|
||||
aubio_spectralpeak_t *peaks; /**< up to length win/spec_partition */
|
||||
aubio_spectralcandidate_t **candidates; /** up to five candidates */
|
||||
/* some scratch pads */
|
||||
/** \bug (unnecessary copied from fftgrain?) */
|
||||
fvec_t *newmag; /**< vec to store mag */
|
||||
fvec_t *scratch; /**< vec to store modified mag */
|
||||
fvec_t *scratch2; /**< vec to compute moving median */
|
||||
fvec_t *theta; /**< vec to store phase */
|
||||
smpl_t phasediff;
|
||||
smpl_t phasefreq;
|
||||
/** threshfn: name or handle of fn for computing adaptive threshold [median] */
|
||||
/** aubio_thresholdfn_t thresholdfn; */
|
||||
/** picker: name or handle of fn for picking event times [quadpick] */
|
||||
/** aubio_pickerfn_t pickerfn; */
|
||||
};
|
||||
|
||||
/** spectral peak object */
|
||||
struct _aubio_spectralpeak_t
|
||||
{
|
||||
uint_t bin; /**< bin [0-(length-1)] */
|
||||
smpl_t ebin; /**< estimated bin */
|
||||
smpl_t mag; /**< peak magnitude */
|
||||
};
|
||||
|
||||
/** spectral candidates array object */
|
||||
struct _aubio_spectralcandidate_t
|
||||
{
|
||||
smpl_t ebin; /**< interpolated bin */
|
||||
smpl_t *ecomb; /**< comb */
|
||||
smpl_t ene; /**< candidate energy */
|
||||
smpl_t len; /**< length */
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_do (aubio_pitchmcomb_t * p, const cvec_t * fftgrain, fvec_t * output)
|
||||
{
|
||||
uint_t j;
|
||||
smpl_t instfreq;
|
||||
fvec_t *newmag = (fvec_t *) p->newmag;
|
||||
//smpl_t hfc; //fe=instfreq(theta1,theta,ops); //theta1=theta;
|
||||
/* copy incoming grain to newmag */
|
||||
for (j = 0; j < newmag->length; j++)
|
||||
newmag->data[j] = fftgrain->norm[j];
|
||||
/* detect only if local energy > 10. */
|
||||
//if (aubio_level_lin (newmag) * newmag->length > 10.) {
|
||||
//hfc = fvec_local_hfc(newmag); //not used
|
||||
aubio_pitchmcomb_spectral_pp (p, newmag);
|
||||
aubio_pitchmcomb_combdet (p, newmag);
|
||||
//aubio_pitchmcomb_sort_cand_freq(p->candidates,p->ncand);
|
||||
//return p->candidates[p->goodcandidate]->ebin;
|
||||
j = (uint_t) FLOOR (p->candidates[p->goodcandidate]->ebin + .5);
|
||||
instfreq = aubio_unwrap2pi (fftgrain->phas[j]
|
||||
- p->theta->data[j] - j * p->phasediff);
|
||||
instfreq *= p->phasefreq;
|
||||
/* store phase for next run */
|
||||
for (j = 0; j < p->theta->length; j++) {
|
||||
p->theta->data[j] = fftgrain->phas[j];
|
||||
}
|
||||
//return p->candidates[p->goodcandidate]->ebin;
|
||||
output->data[0] =
|
||||
FLOOR (p->candidates[p->goodcandidate]->ebin + .5) + instfreq;
|
||||
/*} else {
|
||||
return -1.;
|
||||
} */
|
||||
}
|
||||
|
||||
#if 0
|
||||
uint_t
|
||||
aubio_pitch_cands (aubio_pitchmcomb_t * p, const cvec_t * fftgrain, smpl_t * cands)
|
||||
{
|
||||
uint_t j;
|
||||
uint_t k;
|
||||
fvec_t *newmag = (fvec_t *) p->newmag;
|
||||
aubio_spectralcandidate_t **scands =
|
||||
(aubio_spectralcandidate_t **) (p->candidates);
|
||||
//smpl_t hfc; //fe=instfreq(theta1,theta,ops); //theta1=theta;
|
||||
/* copy incoming grain to newmag */
|
||||
for (j = 0; j < newmag->length; j++)
|
||||
newmag->data[j] = fftgrain->norm[j];
|
||||
/* detect only if local energy > 10. */
|
||||
if (aubio_level_lin (newmag) * newmag->length > 10.) {
|
||||
/* hfc = fvec_local_hfc(newmag); do not use */
|
||||
aubio_pitchmcomb_spectral_pp (p, newmag);
|
||||
aubio_pitchmcomb_combdet (p, newmag);
|
||||
aubio_pitchmcomb_sort_cand_freq (scands, p->ncand);
|
||||
/* store ncand comb energies in cands[1:ncand] */
|
||||
for (k = 0; k < p->ncand; k++)
|
||||
cands[k] = p->candidates[k]->ene;
|
||||
/* store ncand[end] freq in cands[end] */
|
||||
cands[p->ncand] = p->candidates[p->ncand - 1]->ebin;
|
||||
return 1;
|
||||
} else {
|
||||
for (k = 0; k < p->ncand; k++)
|
||||
cands[k] = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_spectral_pp (aubio_pitchmcomb_t * p, const fvec_t * newmag)
|
||||
{
|
||||
fvec_t *mag = (fvec_t *) p->scratch;
|
||||
fvec_t *tmp = (fvec_t *) p->scratch2;
|
||||
uint_t j;
|
||||
uint_t length = mag->length;
|
||||
/* copy newmag to mag (scracth) */
|
||||
for (j = 0; j < length; j++) {
|
||||
mag->data[j] = newmag->data[j];
|
||||
}
|
||||
fvec_min_removal (mag); /* min removal */
|
||||
fvec_alpha_normalise (mag, p->alpha); /* alpha normalisation */
|
||||
/* skipped *//* low pass filtering */
|
||||
/** \bug fvec_moving_thres may write out of bounds */
|
||||
fvec_adapt_thres (mag, tmp, p->win_post, p->win_pre); /* adaptative threshold */
|
||||
fvec_add (mag, -p->threshold); /* fixed threshold */
|
||||
{
|
||||
aubio_spectralpeak_t *peaks = (aubio_spectralpeak_t *) p->peaks;
|
||||
uint_t count;
|
||||
/* return bin and ebin */
|
||||
count = aubio_pitchmcomb_quadpick (peaks, mag);
|
||||
for (j = 0; j < count; j++)
|
||||
peaks[j].mag = newmag->data[peaks[j].bin];
|
||||
/* reset non peaks */
|
||||
for (j = count; j < length; j++)
|
||||
peaks[j].mag = 0.;
|
||||
p->peaks = peaks;
|
||||
p->count = count;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_combdet (aubio_pitchmcomb_t * p, const fvec_t * newmag)
|
||||
{
|
||||
aubio_spectralpeak_t *peaks = (aubio_spectralpeak_t *) p->peaks;
|
||||
aubio_spectralcandidate_t **candidate =
|
||||
(aubio_spectralcandidate_t **) p->candidates;
|
||||
|
||||
/* parms */
|
||||
uint_t N = p->npartials; /* maximum number of partials to be considered 10 */
|
||||
uint_t M = p->ncand; /* maximum number of combs to be considered 5 */
|
||||
uint_t length = newmag->length;
|
||||
uint_t count = p->count;
|
||||
uint_t k;
|
||||
uint_t l;
|
||||
uint_t d;
|
||||
uint_t curlen = 0;
|
||||
|
||||
smpl_t delta2;
|
||||
smpl_t xx;
|
||||
uint_t position = 0;
|
||||
|
||||
uint_t root_peak = 0;
|
||||
uint_t tmpl = 0;
|
||||
smpl_t tmpene = 0.;
|
||||
|
||||
/* get the biggest peak in the spectrum */
|
||||
root_peak = aubio_pitchmcomb_get_root_peak (peaks, count);
|
||||
/* not enough partials in highest notes, could be forced */
|
||||
//if (peaks[root_peak].ebin >= aubio_miditofreq(85.)/p->tau) N=2;
|
||||
//if (peaks[root_peak].ebin >= aubio_miditofreq(90.)/p->tau) N=1;
|
||||
/* now calculate the energy of each of the 5 combs */
|
||||
for (l = 0; l < M; l++) {
|
||||
smpl_t scaler = (1. / (l + 1.));
|
||||
candidate[l]->ene = 0.; /* reset ene and len sums */
|
||||
candidate[l]->len = 0.;
|
||||
candidate[l]->ebin = scaler * peaks[root_peak].ebin;
|
||||
/* if less than N peaks available, curlen < N */
|
||||
if (candidate[l]->ebin != 0.)
|
||||
curlen = (uint_t) FLOOR (length / (candidate[l]->ebin));
|
||||
curlen = (N < curlen) ? N : curlen;
|
||||
/* fill candidate[l]->ecomb[k] with (k+1)*candidate[l]->ebin */
|
||||
for (k = 0; k < curlen; k++)
|
||||
candidate[l]->ecomb[k] = (candidate[l]->ebin) * (k + 1.);
|
||||
for (k = curlen; k < length; k++)
|
||||
candidate[l]->ecomb[k] = 0.;
|
||||
/* for each in candidate[l]->ecomb[k] */
|
||||
for (k = 0; k < curlen; k++) {
|
||||
xx = 100000.;
|
||||
/** get the candidate->ecomb the closer to peaks.ebin
|
||||
* (to cope with the inharmonicity)*/
|
||||
for (d = 0; d < count; d++) {
|
||||
delta2 = ABS (candidate[l]->ecomb[k] - peaks[d].ebin);
|
||||
if (delta2 <= xx) {
|
||||
position = d;
|
||||
xx = delta2;
|
||||
}
|
||||
}
|
||||
/* for a Q factor of 17, maintaining "constant Q filtering",
|
||||
* and sum energy and length over non null combs */
|
||||
if (17. * xx < candidate[l]->ecomb[k]) {
|
||||
candidate[l]->ecomb[k] = peaks[position].ebin;
|
||||
candidate[l]->ene += /* ecomb rounded to nearest int */
|
||||
POW (newmag->data[(uint_t) FLOOR (candidate[l]->ecomb[k] + .5)],
|
||||
0.25);
|
||||
candidate[l]->len += 1. / curlen;
|
||||
} else
|
||||
candidate[l]->ecomb[k] = 0.;
|
||||
}
|
||||
/* punishment */
|
||||
/*if (candidate[l]->len<0.6)
|
||||
candidate[l]->ene=0.; */
|
||||
/* remember best candidate energy (in polyphonic, could check for
|
||||
* tmpene*1.1 < candidate->ene to reduce jumps towards low frequencies) */
|
||||
if (tmpene < candidate[l]->ene) {
|
||||
tmpl = l;
|
||||
tmpene = candidate[l]->ene;
|
||||
}
|
||||
}
|
||||
//p->candidates=candidate;
|
||||
//p->peaks=peaks;
|
||||
p->goodcandidate = tmpl;
|
||||
}
|
||||
|
||||
/** T=quadpick(X): return indices of elements of X which are peaks and positive
|
||||
* exact peak positions are retrieved by quadratic interpolation
|
||||
*
|
||||
* \bug peak-picking too picky, sometimes counts too many peaks ?
|
||||
*/
|
||||
uint_t
|
||||
aubio_pitchmcomb_quadpick (aubio_spectralpeak_t * spectral_peaks, const fvec_t * X)
|
||||
{
|
||||
uint_t j, ispeak, count = 0;
|
||||
for (j = 1; j < X->length - 1; j++) {
|
||||
ispeak = fvec_peakpick (X, j);
|
||||
if (ispeak) {
|
||||
count += ispeak;
|
||||
spectral_peaks[count - 1].bin = j;
|
||||
spectral_peaks[count - 1].ebin = fvec_quadratic_peak_pos (X, j);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* get predominant partial */
|
||||
uint_t
|
||||
aubio_pitchmcomb_get_root_peak (aubio_spectralpeak_t * peaks, uint_t length)
|
||||
{
|
||||
uint_t i, pos = 0;
|
||||
smpl_t tmp = 0.;
|
||||
for (i = 0; i < length; i++)
|
||||
if (tmp <= peaks[i].mag) {
|
||||
pos = i;
|
||||
tmp = peaks[i].mag;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
aubio_pitchmcomb_sort_peak (aubio_spectralpeak_t * peaks, uint_t nbins)
|
||||
{
|
||||
qsort (peaks, nbins, sizeof (aubio_spectralpeak_t),
|
||||
aubio_pitchmcomb_sort_peak_comp);
|
||||
}
|
||||
|
||||
static sint_t
|
||||
aubio_pitchmcomb_sort_peak_comp (const void *x, const void *y)
|
||||
{
|
||||
return (((aubio_spectralpeak_t *) y)->mag -
|
||||
((aubio_spectralpeak_t *) x)->mag);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_sort_cand_ene (aubio_spectralcandidate_t ** candidates,
|
||||
uint_t nbins)
|
||||
{
|
||||
uint_t cur = 0;
|
||||
uint_t run = 0;
|
||||
for (cur = 0; cur < nbins; cur++) {
|
||||
for (run = cur + 1; run < nbins; run++) {
|
||||
if (candidates[run]->ene > candidates[cur]->ene)
|
||||
CAND_SWAP (candidates[run], candidates[cur]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_sort_cand_freq (aubio_spectralcandidate_t ** candidates,
|
||||
uint_t nbins)
|
||||
{
|
||||
uint_t cur = 0;
|
||||
uint_t run = 0;
|
||||
for (cur = 0; cur < nbins; cur++) {
|
||||
for (run = cur + 1; run < nbins; run++) {
|
||||
if (candidates[run]->ebin < candidates[cur]->ebin)
|
||||
CAND_SWAP (candidates[run], candidates[cur]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
aubio_pitchmcomb_t *
|
||||
new_aubio_pitchmcomb (uint_t bufsize, uint_t hopsize)
|
||||
{
|
||||
aubio_pitchmcomb_t *p = AUBIO_NEW (aubio_pitchmcomb_t);
|
||||
/* bug: should check if size / 8 > post+pre+1 */
|
||||
uint_t i, j;
|
||||
uint_t spec_size;
|
||||
p->spec_partition = 2;
|
||||
p->ncand = 5;
|
||||
p->npartials = 5;
|
||||
p->cutoff = 1.;
|
||||
p->threshold = 0.01;
|
||||
p->win_post = 8;
|
||||
p->win_pre = 7;
|
||||
// p->tau = samplerate/bufsize;
|
||||
p->alpha = 9.;
|
||||
p->goodcandidate = 0;
|
||||
p->phasefreq = bufsize / hopsize / TWO_PI;
|
||||
p->phasediff = TWO_PI * hopsize / bufsize;
|
||||
spec_size = bufsize / p->spec_partition + 1;
|
||||
//p->pickerfn = quadpick;
|
||||
//p->biquad = new_biquad(0.1600,0.3200,0.1600, -0.5949, 0.2348);
|
||||
/* allocate temp memory */
|
||||
p->newmag = new_fvec (spec_size);
|
||||
/* array for median */
|
||||
p->scratch = new_fvec (spec_size);
|
||||
/* array for phase */
|
||||
p->theta = new_fvec (spec_size);
|
||||
/* array for adaptative threshold */
|
||||
p->scratch2 = new_fvec (p->win_post + p->win_pre + 1);
|
||||
/* array of spectral peaks */
|
||||
p->peaks = AUBIO_ARRAY (aubio_spectralpeak_t, spec_size);
|
||||
for (i = 0; i < spec_size; i++) {
|
||||
p->peaks[i].bin = 0.;
|
||||
p->peaks[i].ebin = 0.;
|
||||
p->peaks[i].mag = 0.;
|
||||
}
|
||||
/* array of pointers to spectral candidates */
|
||||
p->candidates = AUBIO_ARRAY (aubio_spectralcandidate_t *, p->ncand);
|
||||
for (i = 0; i < p->ncand; i++) {
|
||||
p->candidates[i] = AUBIO_NEW (aubio_spectralcandidate_t);
|
||||
p->candidates[i]->ecomb = AUBIO_ARRAY (smpl_t, spec_size);
|
||||
for (j = 0; j < spec_size; j++) {
|
||||
p->candidates[i]->ecomb[j] = 0.;
|
||||
}
|
||||
p->candidates[i]->ene = 0.;
|
||||
p->candidates[i]->ebin = 0.;
|
||||
p->candidates[i]->len = 0.;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
del_aubio_pitchmcomb (aubio_pitchmcomb_t * p)
|
||||
{
|
||||
uint_t i;
|
||||
del_fvec (p->newmag);
|
||||
del_fvec (p->scratch);
|
||||
del_fvec (p->theta);
|
||||
del_fvec (p->scratch2);
|
||||
AUBIO_FREE (p->peaks);
|
||||
for (i = 0; i < p->ncand; i++) {
|
||||
AUBIO_FREE (p->candidates[i]->ecomb);
|
||||
AUBIO_FREE (p->candidates[i]);
|
||||
}
|
||||
AUBIO_FREE (p->candidates);
|
||||
AUBIO_FREE (p);
|
||||
}
|
77
deps/aubio/src/pitch/pitchmcomb.h
vendored
Normal file
77
deps/aubio/src/pitch/pitchmcomb.h
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using multiple-comb filter
|
||||
|
||||
This fundamental frequency estimation algorithm implements spectral
|
||||
flattening, multi-comb filtering and peak histogramming.
|
||||
|
||||
This method was designed by Juan P. Bello and described in:
|
||||
|
||||
Juan-Pablo Bello. ``Towards the Automated Analysis of Simple Polyphonic
|
||||
Music''. PhD thesis, Centre for Digital Music, Queen Mary University of
|
||||
London, London, UK, 2003.
|
||||
|
||||
\example pitch/test-pitchmcomb.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHMCOMB_H
|
||||
#define AUBIO_PITCHMCOMB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchmcomb_t aubio_pitchmcomb_t;
|
||||
|
||||
/** execute pitch detection on an input spectral frame
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchmcomb
|
||||
\param in_fftgrain input signal spectrum as computed by aubio_pvoc_do
|
||||
\param out_cands pitch candidate frequenciess, in bins
|
||||
|
||||
*/
|
||||
void aubio_pitchmcomb_do (aubio_pitchmcomb_t * p, const cvec_t * in_fftgrain,
|
||||
fvec_t * out_cands);
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
\param hop_size step size between two consecutive analysis instant
|
||||
|
||||
*/
|
||||
aubio_pitchmcomb_t *new_aubio_pitchmcomb (uint_t buf_size, uint_t hop_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchfcomb
|
||||
|
||||
*/
|
||||
void del_aubio_pitchmcomb (aubio_pitchmcomb_t * p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHMCOMB_H */
|
119
deps/aubio/src/pitch/pitchschmitt.c
vendored
Normal file
119
deps/aubio/src/pitch/pitchschmitt.c
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright (C) 2004, 2005 Mario Lang <mlang@delysid.org>
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "pitch/pitchschmitt.h"
|
||||
|
||||
smpl_t aubio_schmittS16LE (aubio_pitchschmitt_t * p, uint_t nframes,
|
||||
signed short int *indata);
|
||||
|
||||
struct _aubio_pitchschmitt_t
|
||||
{
|
||||
uint_t blockSize;
|
||||
uint_t rate;
|
||||
signed short int *schmittBuffer;
|
||||
signed short int *schmittPointer;
|
||||
signed short int *buf;
|
||||
};
|
||||
|
||||
aubio_pitchschmitt_t *
|
||||
new_aubio_pitchschmitt (uint_t size)
|
||||
{
|
||||
aubio_pitchschmitt_t *p = AUBIO_NEW (aubio_pitchschmitt_t);
|
||||
p->blockSize = size;
|
||||
p->schmittBuffer = AUBIO_ARRAY (signed short int, p->blockSize);
|
||||
p->buf = AUBIO_ARRAY (signed short int, p->blockSize);
|
||||
p->schmittPointer = p->schmittBuffer;
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchschmitt_do (aubio_pitchschmitt_t * p, const fvec_t * input,
|
||||
fvec_t * output)
|
||||
{
|
||||
uint_t j;
|
||||
for (j = 0; j < input->length; j++) {
|
||||
p->buf[j] = input->data[j] * 32768.;
|
||||
}
|
||||
output->data[0] = aubio_schmittS16LE (p, input->length, p->buf);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_schmittS16LE (aubio_pitchschmitt_t * p, uint_t nframes,
|
||||
signed short int *indata)
|
||||
{
|
||||
uint_t i, j;
|
||||
uint_t blockSize = p->blockSize;
|
||||
signed short int *schmittBuffer = p->schmittBuffer;
|
||||
signed short int *schmittPointer = p->schmittPointer;
|
||||
|
||||
smpl_t period = 0., trigfact = 0.6;
|
||||
|
||||
for (i = 0; i < nframes; i++) {
|
||||
*schmittPointer++ = indata[i];
|
||||
if (schmittPointer - schmittBuffer >= (sint_t) blockSize) {
|
||||
sint_t endpoint, startpoint, t1, t2, A1, A2, tc, schmittTriggered;
|
||||
|
||||
schmittPointer = schmittBuffer;
|
||||
|
||||
for (j = 0, A1 = 0, A2 = 0; j < blockSize; j++) {
|
||||
if (schmittBuffer[j] > 0 && A1 < schmittBuffer[j])
|
||||
A1 = schmittBuffer[j];
|
||||
if (schmittBuffer[j] < 0 && A2 < -schmittBuffer[j])
|
||||
A2 = -schmittBuffer[j];
|
||||
}
|
||||
t1 = (sint_t) (A1 * trigfact + 0.5);
|
||||
t2 = -(sint_t) (A2 * trigfact + 0.5);
|
||||
startpoint = 0;
|
||||
for (j = 1; j < blockSize && schmittBuffer[j] <= t1; j++);
|
||||
for ( ; j < blockSize - 1 && !(schmittBuffer[j] >= t2 &&
|
||||
schmittBuffer[j + 1] < t2); j++);
|
||||
startpoint = j;
|
||||
schmittTriggered = 0;
|
||||
endpoint = startpoint + 1;
|
||||
for (j = startpoint, tc = 0; j < blockSize; j++) {
|
||||
if (!schmittTriggered) {
|
||||
schmittTriggered = (schmittBuffer[j] >= t1);
|
||||
} else if (schmittBuffer[j] >= t2 && schmittBuffer[j + 1] < t2) {
|
||||
endpoint = j;
|
||||
tc++;
|
||||
schmittTriggered = 0;
|
||||
}
|
||||
}
|
||||
if ((endpoint > startpoint) && (tc > 0)) {
|
||||
period = (smpl_t) (endpoint - startpoint) / tc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p->schmittBuffer = schmittBuffer;
|
||||
p->schmittPointer = schmittPointer;
|
||||
return period;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchschmitt (aubio_pitchschmitt_t * p)
|
||||
{
|
||||
AUBIO_FREE (p->schmittBuffer);
|
||||
AUBIO_FREE (p->buf);
|
||||
AUBIO_FREE (p);
|
||||
}
|
75
deps/aubio/src/pitch/pitchschmitt.h
vendored
Normal file
75
deps/aubio/src/pitch/pitchschmitt.h
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using a Schmitt trigger
|
||||
|
||||
This pitch extraction method implements a Schmitt trigger to estimate the
|
||||
period of a signal.
|
||||
|
||||
This file was derived from the tuneit project, written by Mario Lang to
|
||||
detect the fundamental frequency of a sound.
|
||||
|
||||
See http://delysid.org/tuneit.html
|
||||
|
||||
\example pitch/test-pitchschmitt.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHSCHMITT_H
|
||||
#define AUBIO_PITCHSCHMITT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchschmitt_t aubio_pitchschmitt_t;
|
||||
|
||||
/** execute pitch detection on an input buffer
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchschmitt
|
||||
\param samples_in input signal vector (length as specified at creation time)
|
||||
\param cands_out pitch period estimates, in samples
|
||||
|
||||
*/
|
||||
void aubio_pitchschmitt_do (aubio_pitchschmitt_t * p, const fvec_t * samples_in,
|
||||
fvec_t * cands_out);
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
|
||||
*/
|
||||
aubio_pitchschmitt_t *new_aubio_pitchschmitt (uint_t buf_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchschmitt
|
||||
|
||||
*/
|
||||
void del_aubio_pitchschmitt (aubio_pitchschmitt_t * p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHSCHMITT_H */
|
116
deps/aubio/src/pitch/pitchspecacf.c
vendored
Normal file
116
deps/aubio/src/pitch/pitchspecacf.c
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Copyright (C) 2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "spectral/fft.h"
|
||||
#include "pitch/pitchspecacf.h"
|
||||
|
||||
/** pitch specacf structure */
|
||||
struct _aubio_pitchspecacf_t
|
||||
{
|
||||
fvec_t *win; /**< temporal weighting window */
|
||||
fvec_t *winput; /**< windowed spectrum */
|
||||
aubio_fft_t *fft; /**< fft object to compute*/
|
||||
fvec_t *fftout; /**< Fourier transform output */
|
||||
fvec_t *sqrmag; /**< square magnitudes */
|
||||
fvec_t *acf; /**< auto correlation function */
|
||||
smpl_t tol; /**< tolerance */
|
||||
smpl_t confidence; /**< confidence */
|
||||
};
|
||||
|
||||
aubio_pitchspecacf_t *
|
||||
new_aubio_pitchspecacf (uint_t bufsize)
|
||||
{
|
||||
aubio_pitchspecacf_t *p = AUBIO_NEW (aubio_pitchspecacf_t);
|
||||
p->fft = new_aubio_fft (bufsize);
|
||||
if (!p->fft) goto beach;
|
||||
p->win = new_aubio_window ("hanningz", bufsize);
|
||||
p->winput = new_fvec (bufsize);
|
||||
p->fftout = new_fvec (bufsize);
|
||||
p->sqrmag = new_fvec (bufsize);
|
||||
p->acf = new_fvec (bufsize / 2 + 1);
|
||||
p->tol = 1.;
|
||||
p->confidence = 0.;
|
||||
return p;
|
||||
|
||||
beach:
|
||||
AUBIO_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchspecacf_do (aubio_pitchspecacf_t * p, const fvec_t * input, fvec_t * output)
|
||||
{
|
||||
uint_t l, tau;
|
||||
fvec_t *fftout = p->fftout;
|
||||
// window the input
|
||||
for (l = 0; l < input->length; l++) {
|
||||
p->winput->data[l] = p->win->data[l] * input->data[l];
|
||||
}
|
||||
// get the real / imag parts of its fft
|
||||
aubio_fft_do_complex (p->fft, p->winput, fftout);
|
||||
for (l = 0; l < input->length / 2 + 1; l++) {
|
||||
p->sqrmag->data[l] = SQR(fftout->data[l]);
|
||||
}
|
||||
// get the real / imag parts of the fft of the squared magnitude
|
||||
aubio_fft_do_complex (p->fft, p->sqrmag, fftout);
|
||||
// copy real part to acf
|
||||
for (l = 0; l < fftout->length / 2 + 1; l++) {
|
||||
p->acf->data[l] = fftout->data[l];
|
||||
}
|
||||
// get the minimum
|
||||
tau = fvec_min_elem (p->acf);
|
||||
// get the interpolated minimum
|
||||
output->data[0] = fvec_quadratic_peak_pos (p->acf, tau) * 2.;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchspecacf (aubio_pitchspecacf_t * p)
|
||||
{
|
||||
del_fvec (p->win);
|
||||
del_fvec (p->winput);
|
||||
del_aubio_fft (p->fft);
|
||||
del_fvec (p->sqrmag);
|
||||
del_fvec (p->fftout);
|
||||
del_fvec (p->acf);
|
||||
AUBIO_FREE (p);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchspecacf_get_confidence (const aubio_pitchspecacf_t * o) {
|
||||
// no confidence for now
|
||||
return o->confidence;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitchspecacf_set_tolerance (aubio_pitchspecacf_t * p, smpl_t tol)
|
||||
{
|
||||
p->tol = tol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchspecacf_get_tolerance (const aubio_pitchspecacf_t * p)
|
||||
{
|
||||
return p->tol;
|
||||
}
|
103
deps/aubio/src/pitch/pitchspecacf.h
vendored
Normal file
103
deps/aubio/src/pitch/pitchspecacf.h
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Copyright (C) 2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using spectral auto correlation
|
||||
|
||||
This algorithm implements pitch detection by computing the autocorrelation
|
||||
function as the cosine transform of the square spectral magnitudes.
|
||||
|
||||
Anssi Klapuri. Qualitative and quantitative aspects in the design of
|
||||
periodicity esti- mation algorithms. In Proceedings of the European Signal
|
||||
Processing Conference (EUSIPCO), 2000.
|
||||
|
||||
Paul Brossier, [Automatic annotation of musical audio for interactive
|
||||
systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, Autocorrelation,
|
||||
pp. 75-77, PhD thesis, Centre for Digital music, Queen Mary University of
|
||||
London, London, UK, 2006.
|
||||
|
||||
\example pitch/test-pitchspecacf.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHSPECACF_H
|
||||
#define AUBIO_PITCHSPECACF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchspecacf_t aubio_pitchspecacf_t;
|
||||
|
||||
/** execute pitch detection on an input buffer
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchspecacf
|
||||
\param samples_in input signal vector (length as specified at creation time)
|
||||
\param cands_out pitch period candidates, in samples
|
||||
|
||||
*/
|
||||
void aubio_pitchspecacf_do (aubio_pitchspecacf_t * o, const fvec_t * samples_in, fvec_t * cands_out);
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
|
||||
*/
|
||||
aubio_pitchspecacf_t *new_aubio_pitchspecacf (uint_t buf_size);
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchspecacf()
|
||||
|
||||
*/
|
||||
void del_aubio_pitchspecacf (aubio_pitchspecacf_t * o);
|
||||
|
||||
/** get tolerance parameter for `specacf` pitch detection object
|
||||
|
||||
\param o pitch detection object
|
||||
|
||||
\return tolerance parameter for minima selection [default 1.]
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchspecacf_get_tolerance (const aubio_pitchspecacf_t * o);
|
||||
|
||||
/** set tolerance parameter for `specacf` pitch detection object
|
||||
|
||||
\param o pitch detection object
|
||||
\param tol tolerance parameter for minima selection [default 1.]
|
||||
|
||||
\return `1` on error, `0` on success
|
||||
|
||||
*/
|
||||
uint_t aubio_pitchspecacf_set_tolerance (aubio_pitchspecacf_t * o, smpl_t tol);
|
||||
|
||||
/** get currenct confidence for `specacf` pitch detection object
|
||||
|
||||
\param o pitch detection object
|
||||
\return confidence parameter
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchspecacf_get_confidence (const aubio_pitchspecacf_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHSPECACF_H */
|
189
deps/aubio/src/pitch/pitchyin.c
vendored
Normal file
189
deps/aubio/src/pitch/pitchyin.c
vendored
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/* This algorithm was developed by A. de Cheveigné and H. Kawahara and
|
||||
* published in:
|
||||
*
|
||||
* de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
* estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
*
|
||||
* see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "pitch/pitchyin.h"
|
||||
|
||||
struct _aubio_pitchyin_t
|
||||
{
|
||||
fvec_t *yin;
|
||||
smpl_t tol;
|
||||
uint_t peak_pos;
|
||||
};
|
||||
|
||||
#if 0
|
||||
/** compute difference function
|
||||
|
||||
\param input input signal
|
||||
\param yinbuf output buffer to store difference function (half shorter than input)
|
||||
|
||||
*/
|
||||
void aubio_pitchyin_diff (fvec_t * input, fvec_t * yinbuf);
|
||||
|
||||
/** in place computation of the YIN cumulative normalised function
|
||||
|
||||
\param yinbuf input signal (a square difference function), also used to store function
|
||||
|
||||
*/
|
||||
void aubio_pitchyin_getcum (fvec_t * yinbuf);
|
||||
|
||||
/** detect pitch in a YIN function
|
||||
|
||||
\param yinbuf input buffer as computed by aubio_pitchyin_getcum
|
||||
|
||||
*/
|
||||
uint_t aubio_pitchyin_getpitch (const fvec_t * yinbuf);
|
||||
#endif
|
||||
|
||||
aubio_pitchyin_t *
|
||||
new_aubio_pitchyin (uint_t bufsize)
|
||||
{
|
||||
aubio_pitchyin_t *o = AUBIO_NEW (aubio_pitchyin_t);
|
||||
o->yin = new_fvec (bufsize / 2);
|
||||
o->tol = 0.15;
|
||||
o->peak_pos = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchyin (aubio_pitchyin_t * o)
|
||||
{
|
||||
del_fvec (o->yin);
|
||||
AUBIO_FREE (o);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* outputs the difference function */
|
||||
void
|
||||
aubio_pitchyin_diff (fvec_t * input, fvec_t * yin)
|
||||
{
|
||||
uint_t j, tau;
|
||||
smpl_t tmp;
|
||||
for (tau = 0; tau < yin->length; tau++) {
|
||||
yin->data[tau] = 0.;
|
||||
}
|
||||
for (tau = 1; tau < yin->length; tau++) {
|
||||
for (j = 0; j < yin->length; j++) {
|
||||
tmp = input->data[j] - input->data[j + tau];
|
||||
yin->data[tau] += SQR (tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cumulative mean normalized difference function */
|
||||
void
|
||||
aubio_pitchyin_getcum (fvec_t * yin)
|
||||
{
|
||||
uint_t tau;
|
||||
smpl_t tmp = 0.;
|
||||
yin->data[0] = 1.;
|
||||
//AUBIO_DBG("%f\t",yin->data[0]);
|
||||
for (tau = 1; tau < yin->length; tau++) {
|
||||
tmp += yin->data[tau];
|
||||
yin->data[tau] *= tau / tmp;
|
||||
//AUBIO_DBG("%f\t",yin->data[tau]);
|
||||
}
|
||||
//AUBIO_DBG("\n");
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitchyin_getpitch (const fvec_t * yin)
|
||||
{
|
||||
uint_t tau = 1;
|
||||
do {
|
||||
if (yin->data[tau] < 0.1) {
|
||||
while (yin->data[tau + 1] < yin->data[tau]) {
|
||||
tau++;
|
||||
}
|
||||
return tau;
|
||||
}
|
||||
tau++;
|
||||
} while (tau < yin->length);
|
||||
//AUBIO_DBG("No pitch found");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* all the above in one */
|
||||
void
|
||||
aubio_pitchyin_do (aubio_pitchyin_t * o, const fvec_t * input, fvec_t * out)
|
||||
{
|
||||
const smpl_t tol = o->tol;
|
||||
fvec_t* yin = o->yin;
|
||||
const smpl_t *input_data = input->data;
|
||||
const uint_t length = yin->length;
|
||||
smpl_t *yin_data = yin->data;
|
||||
uint_t j, tau;
|
||||
sint_t period;
|
||||
smpl_t tmp, tmp2 = 0.;
|
||||
|
||||
yin_data[0] = 1.;
|
||||
for (tau = 1; tau < length; tau++) {
|
||||
yin_data[tau] = 0.;
|
||||
for (j = 0; j < length; j++) {
|
||||
tmp = input_data[j] - input_data[j + tau];
|
||||
yin_data[tau] += SQR (tmp);
|
||||
}
|
||||
tmp2 += yin_data[tau];
|
||||
if (tmp2 != 0) {
|
||||
yin->data[tau] *= tau / tmp2;
|
||||
} else {
|
||||
yin->data[tau] = 1.;
|
||||
}
|
||||
period = tau - 3;
|
||||
if (tau > 4 && (yin_data[period] < tol) &&
|
||||
(yin_data[period] < yin_data[period + 1])) {
|
||||
o->peak_pos = (uint_t)period;
|
||||
out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
|
||||
return;
|
||||
}
|
||||
}
|
||||
o->peak_pos = (uint_t)fvec_min_elem (yin);
|
||||
out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyin_get_confidence (aubio_pitchyin_t * o) {
|
||||
return 1. - o->yin->data[o->peak_pos];
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitchyin_set_tolerance (aubio_pitchyin_t * o, smpl_t tol)
|
||||
{
|
||||
o->tol = tol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyin_get_tolerance (aubio_pitchyin_t * o)
|
||||
{
|
||||
return o->tol;
|
||||
}
|
100
deps/aubio/src/pitch/pitchyin.h
vendored
Normal file
100
deps/aubio/src/pitch/pitchyin.h
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using the YIN algorithm
|
||||
|
||||
This algorithm was developed by A. de Cheveigne and H. Kawahara and
|
||||
published in:
|
||||
|
||||
De Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
|
||||
see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
http://recherche.ircam.fr/equipes/pcm/cheveign/ps/2002_JASA_YIN_proof.pdf
|
||||
|
||||
\example pitch/test-pitchyin.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHYIN_H
|
||||
#define AUBIO_PITCHYIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchyin_t aubio_pitchyin_t;
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
|
||||
*/
|
||||
aubio_pitchyin_t *new_aubio_pitchyin (uint_t buf_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyin()
|
||||
|
||||
*/
|
||||
void del_aubio_pitchyin (aubio_pitchyin_t * o);
|
||||
|
||||
/** execute pitch detection an input buffer
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyin()
|
||||
\param samples_in input signal vector (length as specified at creation time)
|
||||
\param cands_out pitch period candidates, in samples
|
||||
|
||||
*/
|
||||
void aubio_pitchyin_do (aubio_pitchyin_t * o, const fvec_t * samples_in, fvec_t * cands_out);
|
||||
|
||||
|
||||
/** set tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\param tol tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
uint_t aubio_pitchyin_set_tolerance (aubio_pitchyin_t * o, smpl_t tol);
|
||||
|
||||
/** get tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyin_get_tolerance (aubio_pitchyin_t * o);
|
||||
|
||||
/** get current confidence of YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return confidence parameter
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyin_get_confidence (aubio_pitchyin_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHYIN_H */
|
201
deps/aubio/src/pitch/pitchyinfast.c
vendored
Normal file
201
deps/aubio/src/pitch/pitchyinfast.c
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
Copyright (C) 2003-2017 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/* This algorithm was developed by A. de Cheveigné and H. Kawahara and
|
||||
* published in:
|
||||
*
|
||||
* de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
* estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
*
|
||||
* see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "cvec.h"
|
||||
#include "spectral/fft.h"
|
||||
#include "pitch/pitchyinfast.h"
|
||||
|
||||
struct _aubio_pitchyinfast_t
|
||||
{
|
||||
fvec_t *yin;
|
||||
smpl_t tol;
|
||||
uint_t peak_pos;
|
||||
fvec_t *tmpdata;
|
||||
fvec_t *sqdiff;
|
||||
fvec_t *kernel;
|
||||
fvec_t *samples_fft;
|
||||
fvec_t *kernel_fft;
|
||||
aubio_fft_t *fft;
|
||||
};
|
||||
|
||||
aubio_pitchyinfast_t *
|
||||
new_aubio_pitchyinfast (uint_t bufsize)
|
||||
{
|
||||
aubio_pitchyinfast_t *o = AUBIO_NEW (aubio_pitchyinfast_t);
|
||||
o->yin = new_fvec (bufsize / 2);
|
||||
o->tmpdata = new_fvec (bufsize);
|
||||
o->sqdiff = new_fvec (bufsize / 2);
|
||||
o->kernel = new_fvec (bufsize);
|
||||
o->samples_fft = new_fvec (bufsize);
|
||||
o->kernel_fft = new_fvec (bufsize);
|
||||
o->fft = new_aubio_fft (bufsize);
|
||||
if (!o->yin || !o->tmpdata || !o->tmpdata || !o->sqdiff
|
||||
|| !o->kernel || !o->samples_fft || !o->kernel || !o->fft)
|
||||
{
|
||||
del_aubio_pitchyinfast(o);
|
||||
return NULL;
|
||||
}
|
||||
o->tol = 0.15;
|
||||
o->peak_pos = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchyinfast (aubio_pitchyinfast_t * o)
|
||||
{
|
||||
if (o->yin)
|
||||
del_fvec (o->yin);
|
||||
if (o->tmpdata)
|
||||
del_fvec (o->tmpdata);
|
||||
if (o->sqdiff)
|
||||
del_fvec (o->sqdiff);
|
||||
if (o->kernel)
|
||||
del_fvec (o->kernel);
|
||||
if (o->samples_fft)
|
||||
del_fvec (o->samples_fft);
|
||||
if (o->kernel_fft)
|
||||
del_fvec (o->kernel_fft);
|
||||
if (o->fft)
|
||||
del_aubio_fft (o->fft);
|
||||
AUBIO_FREE (o);
|
||||
}
|
||||
|
||||
/* all the above in one */
|
||||
void
|
||||
aubio_pitchyinfast_do (aubio_pitchyinfast_t * o, const fvec_t * input, fvec_t * out)
|
||||
{
|
||||
const smpl_t tol = o->tol;
|
||||
fvec_t* yin = o->yin;
|
||||
const uint_t length = yin->length;
|
||||
uint_t B = o->tmpdata->length;
|
||||
uint_t W = o->yin->length; // B / 2
|
||||
fvec_t tmp_slice, kernel_ptr;
|
||||
uint_t tau;
|
||||
sint_t period;
|
||||
smpl_t tmp2 = 0.;
|
||||
|
||||
// compute r_t(0) + r_t+tau(0)
|
||||
{
|
||||
fvec_t *squares = o->tmpdata;
|
||||
fvec_weighted_copy(input, input, squares);
|
||||
#if 0
|
||||
for (tau = 0; tau < W; tau++) {
|
||||
tmp_slice.data = squares->data + tau;
|
||||
tmp_slice.length = W;
|
||||
o->sqdiff->data[tau] = fvec_sum(&tmp_slice);
|
||||
}
|
||||
#else
|
||||
tmp_slice.data = squares->data;
|
||||
tmp_slice.length = W;
|
||||
o->sqdiff->data[0] = fvec_sum(&tmp_slice);
|
||||
for (tau = 1; tau < W; tau++) {
|
||||
o->sqdiff->data[tau] = o->sqdiff->data[tau-1];
|
||||
o->sqdiff->data[tau] -= squares->data[tau-1];
|
||||
o->sqdiff->data[tau] += squares->data[W+tau-1];
|
||||
}
|
||||
#endif
|
||||
fvec_add(o->sqdiff, o->sqdiff->data[0]);
|
||||
}
|
||||
// compute r_t(tau) = -2.*ifft(fft(samples)*fft(samples[W-1::-1]))
|
||||
{
|
||||
fvec_t *compmul = o->tmpdata;
|
||||
fvec_t *rt_of_tau = o->samples_fft;
|
||||
aubio_fft_do_complex(o->fft, input, o->samples_fft);
|
||||
// build kernel, take a copy of first half of samples
|
||||
tmp_slice.data = input->data;
|
||||
tmp_slice.length = W;
|
||||
kernel_ptr.data = o->kernel->data + 1;
|
||||
kernel_ptr.length = W;
|
||||
fvec_copy(&tmp_slice, &kernel_ptr);
|
||||
// reverse them
|
||||
fvec_rev(&kernel_ptr);
|
||||
// compute fft(kernel)
|
||||
aubio_fft_do_complex(o->fft, o->kernel, o->kernel_fft);
|
||||
// compute complex product
|
||||
compmul->data[0] = o->kernel_fft->data[0] * o->samples_fft->data[0];
|
||||
for (tau = 1; tau < W; tau++) {
|
||||
compmul->data[tau] = o->kernel_fft->data[tau] * o->samples_fft->data[tau];
|
||||
compmul->data[tau] -= o->kernel_fft->data[B-tau] * o->samples_fft->data[B-tau];
|
||||
}
|
||||
compmul->data[W] = o->kernel_fft->data[W] * o->samples_fft->data[W];
|
||||
for (tau = 1; tau < W; tau++) {
|
||||
compmul->data[B-tau] = o->kernel_fft->data[B-tau] * o->samples_fft->data[tau];
|
||||
compmul->data[B-tau] += o->kernel_fft->data[tau] * o->samples_fft->data[B-tau];
|
||||
}
|
||||
// compute inverse fft
|
||||
aubio_fft_rdo_complex(o->fft, compmul, rt_of_tau);
|
||||
// compute square difference r_t(tau) = sqdiff - 2 * r_t_tau[W-1:-1]
|
||||
for (tau = 0; tau < W; tau++) {
|
||||
yin->data[tau] = o->sqdiff->data[tau] - 2. * rt_of_tau->data[tau+W];
|
||||
}
|
||||
}
|
||||
|
||||
// now build yin and look for first minimum
|
||||
fvec_zeros(out);
|
||||
yin->data[0] = 1.;
|
||||
for (tau = 1; tau < length; tau++) {
|
||||
tmp2 += yin->data[tau];
|
||||
if (tmp2 != 0) {
|
||||
yin->data[tau] *= tau / tmp2;
|
||||
} else {
|
||||
yin->data[tau] = 1.;
|
||||
}
|
||||
period = tau - 3;
|
||||
if (tau > 4 && (yin->data[period] < tol) &&
|
||||
(yin->data[period] < yin->data[period + 1])) {
|
||||
o->peak_pos = (uint_t)period;
|
||||
out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// use global minimum
|
||||
o->peak_pos = (uint_t)fvec_min_elem (yin);
|
||||
out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyinfast_get_confidence (aubio_pitchyinfast_t * o) {
|
||||
return 1. - o->yin->data[o->peak_pos];
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitchyinfast_set_tolerance (aubio_pitchyinfast_t * o, smpl_t tol)
|
||||
{
|
||||
o->tol = tol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyinfast_get_tolerance (aubio_pitchyinfast_t * o)
|
||||
{
|
||||
return o->tol;
|
||||
}
|
102
deps/aubio/src/pitch/pitchyinfast.h
vendored
Normal file
102
deps/aubio/src/pitch/pitchyinfast.h
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright (C) 2003-2017 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using YIN algorithm (fast implementation)
|
||||
|
||||
This algorithm was developed by A. de Cheveigne and H. Kawahara and
|
||||
published in:
|
||||
|
||||
De Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
|
||||
This implementation compute the autocorrelation function using time domain
|
||||
convolution computed in the spectral domain.
|
||||
|
||||
see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
http://recherche.ircam.fr/equipes/pcm/cheveign/ps/2002_JASA_YIN_proof.pdf
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHYINFAST_H
|
||||
#define AUBIO_PITCHYINFAST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchyinfast_t aubio_pitchyinfast_t;
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
|
||||
*/
|
||||
aubio_pitchyinfast_t *new_aubio_pitchyinfast (uint_t buf_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyin()
|
||||
|
||||
*/
|
||||
void del_aubio_pitchyinfast (aubio_pitchyinfast_t * o);
|
||||
|
||||
/** execute pitch detection an input buffer
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyin()
|
||||
\param samples_in input signal vector (length as specified at creation time)
|
||||
\param cands_out pitch period candidates, in samples
|
||||
|
||||
*/
|
||||
void aubio_pitchyinfast_do (aubio_pitchyinfast_t * o, const fvec_t * samples_in, fvec_t * cands_out);
|
||||
|
||||
|
||||
/** set tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\param tol tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
uint_t aubio_pitchyinfast_set_tolerance (aubio_pitchyinfast_t * o, smpl_t tol);
|
||||
|
||||
/** get tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyinfast_get_tolerance (aubio_pitchyinfast_t * o);
|
||||
|
||||
/** get current confidence of YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return confidence parameter
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyinfast_get_confidence (aubio_pitchyinfast_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHYINFAST_H */
|
||||
|
208
deps/aubio/src/pitch/pitchyinfft.c
vendored
Normal file
208
deps/aubio/src/pitch/pitchyinfft.c
vendored
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "spectral/fft.h"
|
||||
#include "pitch/pitchyinfft.h"
|
||||
|
||||
/** pitch yinfft structure */
|
||||
struct _aubio_pitchyinfft_t
|
||||
{
|
||||
fvec_t *win; /**< temporal weighting window */
|
||||
fvec_t *winput; /**< windowed spectrum */
|
||||
fvec_t *sqrmag; /**< square difference function */
|
||||
fvec_t *weight; /**< spectral weighting window (psychoacoustic model) */
|
||||
fvec_t *fftout; /**< Fourier transform output */
|
||||
aubio_fft_t *fft; /**< fft object to compute square difference function */
|
||||
fvec_t *yinfft; /**< Yin function */
|
||||
smpl_t tol; /**< Yin tolerance */
|
||||
uint_t peak_pos; /**< currently selected peak pos*/
|
||||
uint_t short_period; /** shortest period under which to check for octave error */
|
||||
};
|
||||
|
||||
static const smpl_t freqs[] = {
|
||||
0., 20., 25., 31.5, 40., 50., 63., 80., 100., 125.,
|
||||
160., 200., 250., 315., 400., 500., 630., 800., 1000., 1250.,
|
||||
1600., 2000., 2500., 3150., 4000., 5000., 6300., 8000., 9000., 10000.,
|
||||
12500., 15000., 20000., 25100., -1.
|
||||
};
|
||||
|
||||
static const smpl_t weight[] = {
|
||||
-75.8, -70.1, -60.8, -52.1, -44.2, -37.5, -31.3, -25.6, -20.9, -16.5,
|
||||
-12.6, -9.60, -7.00, -4.70, -3.00, -1.80, -0.80, -0.20, -0.00, 0.50,
|
||||
1.60, 3.20, 5.40, 7.80, 8.10, 5.30, -2.40, -11.1, -12.8, -12.2,
|
||||
-7.40, -17.8, -17.8, -17.8
|
||||
};
|
||||
|
||||
aubio_pitchyinfft_t *
|
||||
new_aubio_pitchyinfft (uint_t samplerate, uint_t bufsize)
|
||||
{
|
||||
uint_t i = 0, j = 1;
|
||||
smpl_t freq = 0, a0 = 0, a1 = 0, f0 = 0, f1 = 0;
|
||||
aubio_pitchyinfft_t *p = AUBIO_NEW (aubio_pitchyinfft_t);
|
||||
p->winput = new_fvec (bufsize);
|
||||
p->fft = new_aubio_fft (bufsize);
|
||||
if (!p->fft) goto beach;
|
||||
p->fftout = new_fvec (bufsize);
|
||||
p->sqrmag = new_fvec (bufsize);
|
||||
p->yinfft = new_fvec (bufsize / 2 + 1);
|
||||
p->tol = 0.85;
|
||||
p->peak_pos = 0;
|
||||
p->win = new_aubio_window ("hanningz", bufsize);
|
||||
p->weight = new_fvec (bufsize / 2 + 1);
|
||||
for (i = 0; i < p->weight->length; i++) {
|
||||
freq = (smpl_t) i / (smpl_t) bufsize *(smpl_t) samplerate;
|
||||
while (freq > freqs[j] && freqs[j] > 0) {
|
||||
//AUBIO_DBG("freq %3.5f > %3.5f \tsamplerate %d (Hz) \t"
|
||||
// "(weight length %d, bufsize %d) %d %d\n", freq, freqs[j],
|
||||
// samplerate, p->weight->length, bufsize, i, j);
|
||||
j += 1;
|
||||
}
|
||||
a0 = weight[j - 1];
|
||||
f0 = freqs[j - 1];
|
||||
a1 = weight[j];
|
||||
f1 = freqs[j];
|
||||
if (f0 == f1) { // just in case
|
||||
p->weight->data[i] = a0;
|
||||
} else if (f0 == 0) { // y = ax+b
|
||||
p->weight->data[i] = (a1 - a0) / f1 * freq + a0;
|
||||
} else {
|
||||
p->weight->data[i] = (a1 - a0) / (f1 - f0) * freq +
|
||||
(a0 - (a1 - a0) / (f1 / f0 - 1.));
|
||||
}
|
||||
while (freq > freqs[j]) {
|
||||
j += 1;
|
||||
}
|
||||
//AUBIO_DBG("%f\n",p->weight->data[i]);
|
||||
p->weight->data[i] = DB2LIN (p->weight->data[i]);
|
||||
//p->weight->data[i] = SQRT(DB2LIN(p->weight->data[i]));
|
||||
}
|
||||
// check for octave errors above 1300 Hz
|
||||
p->short_period = (uint_t)ROUND(samplerate / 1300.);
|
||||
return p;
|
||||
|
||||
beach:
|
||||
if (p->winput) del_fvec(p->winput);
|
||||
AUBIO_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, const fvec_t * input, fvec_t * output)
|
||||
{
|
||||
uint_t tau, l;
|
||||
uint_t length = p->fftout->length;
|
||||
uint_t halfperiod;
|
||||
fvec_t *fftout = p->fftout;
|
||||
fvec_t *yin = p->yinfft;
|
||||
smpl_t tmp = 0., sum = 0.;
|
||||
// window the input
|
||||
fvec_weighted_copy(input, p->win, p->winput);
|
||||
// get the real / imag parts of its fft
|
||||
aubio_fft_do_complex (p->fft, p->winput, fftout);
|
||||
// get the squared magnitude spectrum, applying some weight
|
||||
p->sqrmag->data[0] = SQR(fftout->data[0]);
|
||||
p->sqrmag->data[0] *= p->weight->data[0];
|
||||
for (l = 1; l < length / 2; l++) {
|
||||
p->sqrmag->data[l] = SQR(fftout->data[l]) + SQR(fftout->data[length - l]);
|
||||
p->sqrmag->data[l] *= p->weight->data[l];
|
||||
p->sqrmag->data[length - l] = p->sqrmag->data[l];
|
||||
}
|
||||
p->sqrmag->data[length / 2] = SQR(fftout->data[length / 2]);
|
||||
p->sqrmag->data[length / 2] *= p->weight->data[length / 2];
|
||||
// get sum of weighted squared mags
|
||||
for (l = 0; l < length / 2 + 1; l++) {
|
||||
sum += p->sqrmag->data[l];
|
||||
}
|
||||
sum *= 2.;
|
||||
// get the real / imag parts of the fft of the squared magnitude
|
||||
aubio_fft_do_complex (p->fft, p->sqrmag, fftout);
|
||||
yin->data[0] = 1.;
|
||||
for (tau = 1; tau < yin->length; tau++) {
|
||||
// compute the square differences
|
||||
yin->data[tau] = sum - fftout->data[tau];
|
||||
// and the cumulative mean normalized difference function
|
||||
tmp += yin->data[tau];
|
||||
if (tmp != 0) {
|
||||
yin->data[tau] *= tau / tmp;
|
||||
} else {
|
||||
yin->data[tau] = 1.;
|
||||
}
|
||||
}
|
||||
// find best candidates
|
||||
tau = fvec_min_elem (yin);
|
||||
if (yin->data[tau] < p->tol) {
|
||||
// no interpolation, directly return the period as an integer
|
||||
//output->data[0] = tau;
|
||||
//return;
|
||||
|
||||
// 3 point quadratic interpolation
|
||||
//return fvec_quadratic_peak_pos (yin,tau,1);
|
||||
/* additional check for (unlikely) octave doubling in higher frequencies */
|
||||
if (tau > p->short_period) {
|
||||
output->data[0] = fvec_quadratic_peak_pos (yin, tau);
|
||||
} else {
|
||||
/* should compare the minimum value of each interpolated peaks */
|
||||
halfperiod = FLOOR (tau / 2 + .5);
|
||||
if (yin->data[halfperiod] < p->tol)
|
||||
p->peak_pos = halfperiod;
|
||||
else
|
||||
p->peak_pos = tau;
|
||||
output->data[0] = fvec_quadratic_peak_pos (yin, p->peak_pos);
|
||||
}
|
||||
} else {
|
||||
p->peak_pos = 0;
|
||||
output->data[0] = 0.;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchyinfft (aubio_pitchyinfft_t * p)
|
||||
{
|
||||
del_fvec (p->win);
|
||||
del_aubio_fft (p->fft);
|
||||
del_fvec (p->yinfft);
|
||||
del_fvec (p->sqrmag);
|
||||
del_fvec (p->fftout);
|
||||
del_fvec (p->winput);
|
||||
del_fvec (p->weight);
|
||||
AUBIO_FREE (p);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyinfft_get_confidence (aubio_pitchyinfft_t * o) {
|
||||
return 1. - o->yinfft->data[o->peak_pos];
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * p, smpl_t tol)
|
||||
{
|
||||
p->tol = tol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * p)
|
||||
{
|
||||
return p->tol;
|
||||
}
|
99
deps/aubio/src/pitch/pitchyinfft.h
vendored
Normal file
99
deps/aubio/src/pitch/pitchyinfft.h
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using a spectral implementation of the YIN algorithm
|
||||
|
||||
This algorithm was derived from the YIN algorithm. In this implementation, a
|
||||
Fourier transform is used to compute a tapered square difference function,
|
||||
which allows spectral weighting. Because the difference function is tapered,
|
||||
the selection of the period is simplified.
|
||||
|
||||
Paul Brossier, [Automatic annotation of musical audio for interactive
|
||||
systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, PhD thesis,
|
||||
Centre for Digital music, Queen Mary University of London, London, UK, 2006.
|
||||
|
||||
\example pitch/test-pitchyinfft.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHYINFFT_H
|
||||
#define AUBIO_PITCHYINFFT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchyinfft_t aubio_pitchyinfft_t;
|
||||
|
||||
/** execute pitch detection on an input buffer
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyinfft
|
||||
\param samples_in input signal vector (length as specified at creation time)
|
||||
\param cands_out pitch period candidates, in samples
|
||||
|
||||
*/
|
||||
void aubio_pitchyinfft_do (aubio_pitchyinfft_t * o, const fvec_t * samples_in, fvec_t * cands_out);
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param samplerate samplerate of the input signal
|
||||
\param buf_size size of the input buffer to analyse
|
||||
|
||||
*/
|
||||
aubio_pitchyinfft_t *new_aubio_pitchyinfft (uint_t samplerate, uint_t buf_size);
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyinfft()
|
||||
|
||||
*/
|
||||
void del_aubio_pitchyinfft (aubio_pitchyinfft_t * o);
|
||||
|
||||
/** get tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
|
||||
\return tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * o);
|
||||
|
||||
/** set tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\param tol tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
uint_t aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * o, smpl_t tol);
|
||||
|
||||
/** get current confidence of YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return confidence parameter
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyinfft_get_confidence (aubio_pitchyinfft_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHYINFFT_H */
|
582
deps/aubio/src/spectral/fft.c
vendored
Normal file
582
deps/aubio/src/spectral/fft.c
vendored
Normal file
|
@ -0,0 +1,582 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "spectral/fft.h"
|
||||
|
||||
#ifdef HAVE_FFTW3 // using FFTW3
|
||||
/* note that <complex.h> is not included here but only in aubio_priv.h, so that
|
||||
* c++ projects can still use their own complex definition. */
|
||||
#include <fftw3.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef HAVE_COMPLEX_H
|
||||
#ifdef HAVE_FFTW3F
|
||||
/** fft data type with complex.h and fftw3f */
|
||||
#define FFTW_TYPE fftwf_complex
|
||||
#else
|
||||
/** fft data type with complex.h and fftw3 */
|
||||
#define FFTW_TYPE fftw_complex
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_FFTW3F
|
||||
/** fft data type without complex.h and with fftw3f */
|
||||
#define FFTW_TYPE float
|
||||
#else
|
||||
/** fft data type without complex.h and with fftw */
|
||||
#define FFTW_TYPE double
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** fft data type */
|
||||
typedef FFTW_TYPE fft_data_t;
|
||||
|
||||
#ifdef HAVE_FFTW3F
|
||||
#define fftw_malloc fftwf_malloc
|
||||
#define fftw_free fftwf_free
|
||||
#define fftw_execute fftwf_execute
|
||||
#define fftw_plan_dft_r2c_1d fftwf_plan_dft_r2c_1d
|
||||
#define fftw_plan_dft_c2r_1d fftwf_plan_dft_c2r_1d
|
||||
#define fftw_plan_r2r_1d fftwf_plan_r2r_1d
|
||||
#define fftw_plan fftwf_plan
|
||||
#define fftw_destroy_plan fftwf_destroy_plan
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FFTW3F
|
||||
#if HAVE_AUBIO_DOUBLE
|
||||
#error "Using aubio in double precision with fftw3 in single precision"
|
||||
#endif /* HAVE_AUBIO_DOUBLE */
|
||||
#define real_t float
|
||||
#elif defined (HAVE_FFTW3) /* HAVE_FFTW3F */
|
||||
#if !HAVE_AUBIO_DOUBLE
|
||||
#error "Using aubio in single precision with fftw3 in double precision"
|
||||
#endif /* HAVE_AUBIO_DOUBLE */
|
||||
#define real_t double
|
||||
#endif /* HAVE_FFTW3F */
|
||||
|
||||
#ifndef __MOD_DEVICES__
|
||||
// a global mutex for FFTW thread safety
|
||||
pthread_mutex_t aubio_fftw_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
#elif defined HAVE_ACCELERATE // using ACCELERATE
|
||||
// https://developer.apple.com/library/mac/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html
|
||||
#include <Accelerate/Accelerate.h>
|
||||
|
||||
#if !HAVE_AUBIO_DOUBLE
|
||||
#define aubio_vDSP_ctoz vDSP_ctoz
|
||||
#define aubio_vDSP_fft_zrip vDSP_fft_zrip
|
||||
#define aubio_vDSP_ztoc vDSP_ztoc
|
||||
#define aubio_vDSP_zvmags vDSP_zvmags
|
||||
#define aubio_vDSP_zvphas vDSP_zvphas
|
||||
#define aubio_vDSP_vsadd vDSP_vsadd
|
||||
#define aubio_vDSP_vsmul vDSP_vsmul
|
||||
#define aubio_DSPComplex DSPComplex
|
||||
#define aubio_DSPSplitComplex DSPSplitComplex
|
||||
#define aubio_vDSP_DFT_Setup vDSP_DFT_Setup
|
||||
#define aubio_vDSP_DFT_zrop_CreateSetup vDSP_DFT_zrop_CreateSetup
|
||||
#define aubio_vDSP_DFT_Execute vDSP_DFT_Execute
|
||||
#define aubio_vDSP_DFT_DestroySetup vDSP_DFT_DestroySetup
|
||||
#define aubio_vvsqrt vvsqrtf
|
||||
#else
|
||||
#define aubio_vDSP_ctoz vDSP_ctozD
|
||||
#define aubio_vDSP_fft_zrip vDSP_fft_zripD
|
||||
#define aubio_vDSP_ztoc vDSP_ztocD
|
||||
#define aubio_vDSP_zvmags vDSP_zvmagsD
|
||||
#define aubio_vDSP_zvphas vDSP_zvphasD
|
||||
#define aubio_vDSP_vsadd vDSP_vsaddD
|
||||
#define aubio_vDSP_vsmul vDSP_vsmulD
|
||||
#define aubio_DSPComplex DSPDoubleComplex
|
||||
#define aubio_DSPSplitComplex DSPDoubleSplitComplex
|
||||
#define aubio_vDSP_DFT_Setup vDSP_DFT_SetupD
|
||||
#define aubio_vDSP_DFT_zrop_CreateSetup vDSP_DFT_zrop_CreateSetupD
|
||||
#define aubio_vDSP_DFT_Execute vDSP_DFT_ExecuteD
|
||||
#define aubio_vDSP_DFT_DestroySetup vDSP_DFT_DestroySetupD
|
||||
#define aubio_vvsqrt vvsqrt
|
||||
#endif /* HAVE_AUBIO_DOUBLE */
|
||||
|
||||
#elif defined HAVE_INTEL_IPP // using INTEL IPP
|
||||
|
||||
#if !HAVE_AUBIO_DOUBLE
|
||||
#define aubio_IppFloat Ipp32f
|
||||
#define aubio_IppComplex Ipp32fc
|
||||
#define aubio_FFTSpec FFTSpec_R_32f
|
||||
#define aubio_ippsMalloc_complex ippsMalloc_32fc
|
||||
#define aubio_ippsFFTInit_R ippsFFTInit_R_32f
|
||||
#define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_32f
|
||||
#define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_32f
|
||||
#define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_32f
|
||||
#define aubio_ippsAtan2 ippsAtan2_32f_A21
|
||||
#else /* HAVE_AUBIO_DOUBLE */
|
||||
#define aubio_IppFloat Ipp64f
|
||||
#define aubio_IppComplex Ipp64fc
|
||||
#define aubio_FFTSpec FFTSpec_R_64f
|
||||
#define aubio_ippsMalloc_complex ippsMalloc_64fc
|
||||
#define aubio_ippsFFTInit_R ippsFFTInit_R_64f
|
||||
#define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_64f
|
||||
#define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_64f
|
||||
#define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_64f
|
||||
#define aubio_ippsAtan2 ippsAtan2_64f_A50
|
||||
#endif
|
||||
|
||||
|
||||
#else // using OOURA
|
||||
// let's use ooura instead
|
||||
extern void aubio_ooura_rdft(int, int, smpl_t *, int *, smpl_t *);
|
||||
|
||||
#endif
|
||||
|
||||
struct _aubio_fft_t {
|
||||
uint_t winsize;
|
||||
uint_t fft_size;
|
||||
|
||||
#ifdef HAVE_FFTW3 // using FFTW3
|
||||
real_t *in, *out;
|
||||
fftw_plan pfw, pbw;
|
||||
fft_data_t * specdata; /* complex spectral data */
|
||||
|
||||
#elif defined HAVE_ACCELERATE // using ACCELERATE
|
||||
aubio_vDSP_DFT_Setup fftSetupFwd;
|
||||
aubio_vDSP_DFT_Setup fftSetupBwd;
|
||||
aubio_DSPSplitComplex spec;
|
||||
smpl_t *in, *out;
|
||||
|
||||
#elif defined HAVE_INTEL_IPP // using Intel IPP
|
||||
smpl_t *in, *out;
|
||||
Ipp8u* memSpec;
|
||||
Ipp8u* memInit;
|
||||
Ipp8u* memBuffer;
|
||||
struct aubio_FFTSpec* fftSpec;
|
||||
aubio_IppComplex* complexOut;
|
||||
#else // using OOURA
|
||||
smpl_t *in, *out;
|
||||
smpl_t *w;
|
||||
int *ip;
|
||||
#endif /* using OOURA */
|
||||
|
||||
fvec_t * compspec;
|
||||
};
|
||||
|
||||
aubio_fft_t * new_aubio_fft (uint_t winsize) {
|
||||
aubio_fft_t * s = AUBIO_NEW(aubio_fft_t);
|
||||
if ((sint_t)winsize < 2) {
|
||||
AUBIO_ERR("fft: got winsize %d, but can not be < 2\n", winsize);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FFTW3
|
||||
uint_t i;
|
||||
s->winsize = winsize;
|
||||
/* allocate memory */
|
||||
s->in = AUBIO_ARRAY(real_t,winsize);
|
||||
s->out = AUBIO_ARRAY(real_t,winsize);
|
||||
s->compspec = new_fvec(winsize);
|
||||
/* create plans */
|
||||
#ifndef __MOD_DEVICES__
|
||||
pthread_mutex_lock(&aubio_fftw_mutex);
|
||||
#endif
|
||||
#ifdef HAVE_COMPLEX_H
|
||||
s->fft_size = winsize/2 + 1;
|
||||
s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size);
|
||||
s->pfw = fftw_plan_dft_r2c_1d(winsize, s->in, s->specdata, FFTW_ESTIMATE);
|
||||
s->pbw = fftw_plan_dft_c2r_1d(winsize, s->specdata, s->out, FFTW_ESTIMATE);
|
||||
#else
|
||||
s->fft_size = winsize;
|
||||
s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size);
|
||||
s->pfw = fftw_plan_r2r_1d(winsize, s->in, s->specdata, FFTW_R2HC, FFTW_ESTIMATE);
|
||||
s->pbw = fftw_plan_r2r_1d(winsize, s->specdata, s->out, FFTW_HC2R, FFTW_ESTIMATE);
|
||||
#endif
|
||||
#ifndef __MOD_DEVICES__
|
||||
pthread_mutex_unlock(&aubio_fftw_mutex);
|
||||
#endif
|
||||
for (i = 0; i < s->winsize; i++) {
|
||||
s->in[i] = 0.;
|
||||
s->out[i] = 0.;
|
||||
}
|
||||
for (i = 0; i < s->fft_size; i++) {
|
||||
s->specdata[i] = 0.;
|
||||
}
|
||||
|
||||
#elif defined HAVE_ACCELERATE // using ACCELERATE
|
||||
{
|
||||
uint_t radix = winsize;
|
||||
uint_t order = 0;
|
||||
while ((radix / 2) * 2 == radix) {
|
||||
radix /= 2;
|
||||
order++;
|
||||
}
|
||||
if (order < 4 || (radix != 1 && radix != 3 && radix != 5 && radix != 15)) {
|
||||
AUBIO_ERR("fft: vDSP/Accelerate supports FFT with sizes = "
|
||||
"f * 2 ** n, where n > 4 and f in [1, 3, 5, 15], but requested %d. "
|
||||
"Use the closest power of two, or try recompiling aubio with "
|
||||
"--enable-fftw3.\n", winsize);
|
||||
goto beach;
|
||||
}
|
||||
}
|
||||
s->winsize = winsize;
|
||||
s->fft_size = winsize;
|
||||
s->compspec = new_fvec(winsize);
|
||||
s->in = AUBIO_ARRAY(smpl_t, s->fft_size);
|
||||
s->out = AUBIO_ARRAY(smpl_t, s->fft_size);
|
||||
s->spec.realp = AUBIO_ARRAY(smpl_t, s->fft_size/2);
|
||||
s->spec.imagp = AUBIO_ARRAY(smpl_t, s->fft_size/2);
|
||||
s->fftSetupFwd = aubio_vDSP_DFT_zrop_CreateSetup(NULL,
|
||||
s->fft_size, vDSP_DFT_FORWARD);
|
||||
s->fftSetupBwd = aubio_vDSP_DFT_zrop_CreateSetup(s->fftSetupFwd,
|
||||
s->fft_size, vDSP_DFT_INVERSE);
|
||||
|
||||
#elif defined HAVE_INTEL_IPP // using Intel IPP
|
||||
const IppHintAlgorithm qualityHint = ippAlgHintAccurate; // OR ippAlgHintFast;
|
||||
const int flags = IPP_FFT_NODIV_BY_ANY; // we're scaling manually afterwards
|
||||
int order = aubio_power_of_two_order(winsize);
|
||||
int sizeSpec, sizeInit, sizeBuffer;
|
||||
IppStatus status;
|
||||
|
||||
if (winsize <= 4 || aubio_is_power_of_two(winsize) != 1)
|
||||
{
|
||||
AUBIO_ERR("intel IPP fft: can only create with sizes > 4 and power of two, requested %d,"
|
||||
" try recompiling aubio with --enable-fftw3\n", winsize);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
status = aubio_ippsFFTGetSize_R(order, flags, qualityHint,
|
||||
&sizeSpec, &sizeInit, &sizeBuffer);
|
||||
if (status != ippStsNoErr) {
|
||||
AUBIO_ERR("fft: failed to initialize fft. IPP error: %d\n", status);
|
||||
goto beach;
|
||||
}
|
||||
s->fft_size = s->winsize = winsize;
|
||||
s->compspec = new_fvec(winsize);
|
||||
s->in = AUBIO_ARRAY(smpl_t, s->winsize);
|
||||
s->out = AUBIO_ARRAY(smpl_t, s->winsize);
|
||||
s->memSpec = ippsMalloc_8u(sizeSpec);
|
||||
s->memBuffer = ippsMalloc_8u(sizeBuffer);
|
||||
if (sizeInit > 0 ) {
|
||||
s->memInit = ippsMalloc_8u(sizeInit);
|
||||
}
|
||||
s->complexOut = aubio_ippsMalloc_complex(s->fft_size / 2 + 1);
|
||||
status = aubio_ippsFFTInit_R(
|
||||
&s->fftSpec, order, flags, qualityHint, s->memSpec, s->memInit);
|
||||
if (status != ippStsNoErr) {
|
||||
AUBIO_ERR("fft: failed to initialize. IPP error: %d\n", status);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
#else // using OOURA
|
||||
if (aubio_is_power_of_two(winsize) != 1) {
|
||||
AUBIO_ERR("fft: can only create with sizes power of two, requested %d,"
|
||||
" try recompiling aubio with --enable-fftw3\n", winsize);
|
||||
goto beach;
|
||||
}
|
||||
s->winsize = winsize;
|
||||
s->fft_size = winsize / 2 + 1;
|
||||
s->compspec = new_fvec(winsize);
|
||||
s->in = AUBIO_ARRAY(smpl_t, s->winsize);
|
||||
s->out = AUBIO_ARRAY(smpl_t, s->winsize);
|
||||
s->ip = AUBIO_ARRAY(int , s->fft_size);
|
||||
s->w = AUBIO_ARRAY(smpl_t, s->fft_size);
|
||||
s->ip[0] = 0;
|
||||
#endif /* using OOURA */
|
||||
|
||||
return s;
|
||||
|
||||
beach:
|
||||
AUBIO_FREE(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void del_aubio_fft(aubio_fft_t * s) {
|
||||
/* destroy data */
|
||||
#ifdef HAVE_FFTW3 // using FFTW3
|
||||
#ifndef __MOD_DEVICES__
|
||||
pthread_mutex_lock(&aubio_fftw_mutex);
|
||||
#endif
|
||||
fftw_destroy_plan(s->pfw);
|
||||
fftw_destroy_plan(s->pbw);
|
||||
fftw_free(s->specdata);
|
||||
#ifndef __MOD_DEVICES__
|
||||
pthread_mutex_unlock(&aubio_fftw_mutex);
|
||||
#endif
|
||||
|
||||
#elif defined HAVE_ACCELERATE // using ACCELERATE
|
||||
AUBIO_FREE(s->spec.realp);
|
||||
AUBIO_FREE(s->spec.imagp);
|
||||
aubio_vDSP_DFT_DestroySetup(s->fftSetupBwd);
|
||||
aubio_vDSP_DFT_DestroySetup(s->fftSetupFwd);
|
||||
|
||||
#elif defined HAVE_INTEL_IPP // using Intel IPP
|
||||
ippFree(s->memSpec);
|
||||
ippFree(s->memInit);
|
||||
ippFree(s->memBuffer);
|
||||
ippFree(s->complexOut);
|
||||
|
||||
#else // using OOURA
|
||||
AUBIO_FREE(s->w);
|
||||
AUBIO_FREE(s->ip);
|
||||
#endif
|
||||
|
||||
del_fvec(s->compspec);
|
||||
AUBIO_FREE(s->in);
|
||||
AUBIO_FREE(s->out);
|
||||
AUBIO_FREE(s);
|
||||
}
|
||||
|
||||
void aubio_fft_do(aubio_fft_t * s, const fvec_t * input, cvec_t * spectrum) {
|
||||
aubio_fft_do_complex(s, input, s->compspec);
|
||||
aubio_fft_get_spectrum(s->compspec, spectrum);
|
||||
}
|
||||
|
||||
void aubio_fft_rdo(aubio_fft_t * s, const cvec_t * spectrum, fvec_t * output) {
|
||||
aubio_fft_get_realimag(spectrum, s->compspec);
|
||||
aubio_fft_rdo_complex(s, s->compspec, output);
|
||||
}
|
||||
|
||||
void aubio_fft_do_complex(aubio_fft_t * s, const fvec_t * input, fvec_t * compspec) {
|
||||
uint_t i;
|
||||
#ifndef HAVE_MEMCPY_HACKS
|
||||
for (i=0; i < s->winsize; i++) {
|
||||
s->in[i] = input->data[i];
|
||||
}
|
||||
#else
|
||||
memcpy(s->in, input->data, s->winsize * sizeof(smpl_t));
|
||||
#endif /* HAVE_MEMCPY_HACKS */
|
||||
|
||||
#ifdef HAVE_FFTW3 // using FFTW3
|
||||
fftw_execute(s->pfw);
|
||||
#ifdef HAVE_COMPLEX_H
|
||||
compspec->data[0] = REAL(s->specdata[0]);
|
||||
for (i = 1; i < s->fft_size -1 ; i++) {
|
||||
compspec->data[i] = REAL(s->specdata[i]);
|
||||
compspec->data[compspec->length - i] = IMAG(s->specdata[i]);
|
||||
}
|
||||
compspec->data[s->fft_size-1] = REAL(s->specdata[s->fft_size-1]);
|
||||
#else /* HAVE_COMPLEX_H */
|
||||
for (i = 0; i < s->fft_size; i++) {
|
||||
compspec->data[i] = s->specdata[i];
|
||||
}
|
||||
#endif /* HAVE_COMPLEX_H */
|
||||
|
||||
#elif defined HAVE_ACCELERATE // using ACCELERATE
|
||||
// convert real data to even/odd format used in vDSP
|
||||
aubio_vDSP_ctoz((aubio_DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
|
||||
// compute the FFT
|
||||
aubio_vDSP_DFT_Execute(s->fftSetupFwd, s->spec.realp, s->spec.imagp,
|
||||
s->spec.realp, s->spec.imagp);
|
||||
// convert from vDSP complex split to [ r0, r1, ..., rN, iN-1, .., i2, i1]
|
||||
compspec->data[0] = s->spec.realp[0];
|
||||
compspec->data[s->fft_size / 2] = s->spec.imagp[0];
|
||||
for (i = 1; i < s->fft_size / 2; i++) {
|
||||
compspec->data[i] = s->spec.realp[i];
|
||||
compspec->data[s->fft_size - i] = s->spec.imagp[i];
|
||||
}
|
||||
// apply scaling
|
||||
smpl_t scale = 1./2.;
|
||||
aubio_vDSP_vsmul(compspec->data, 1, &scale, compspec->data, 1, s->fft_size);
|
||||
|
||||
#elif defined HAVE_INTEL_IPP // using Intel IPP
|
||||
|
||||
// apply fft
|
||||
aubio_ippsFFTFwd_RToCCS(s->in, (aubio_IppFloat*)s->complexOut, s->fftSpec, s->memBuffer);
|
||||
// convert complex buffer to [ r0, r1, ..., rN, iN-1, .., i2, i1]
|
||||
compspec->data[0] = s->complexOut[0].re;
|
||||
compspec->data[s->fft_size / 2] = s->complexOut[s->fft_size / 2].re;
|
||||
for (i = 1; i < s->fft_size / 2; i++) {
|
||||
compspec->data[i] = s->complexOut[i].re;
|
||||
compspec->data[s->fft_size - i] = s->complexOut[i].im;
|
||||
}
|
||||
|
||||
#else // using OOURA
|
||||
aubio_ooura_rdft(s->winsize, 1, s->in, s->ip, s->w);
|
||||
compspec->data[0] = s->in[0];
|
||||
compspec->data[s->winsize / 2] = s->in[1];
|
||||
for (i = 1; i < s->fft_size - 1; i++) {
|
||||
compspec->data[i] = s->in[2 * i];
|
||||
compspec->data[s->winsize - i] = - s->in[2 * i + 1];
|
||||
}
|
||||
#endif /* using OOURA */
|
||||
}
|
||||
|
||||
void aubio_fft_rdo_complex(aubio_fft_t * s, const fvec_t * compspec, fvec_t * output) {
|
||||
uint_t i;
|
||||
#ifdef HAVE_FFTW3
|
||||
const smpl_t renorm = 1./(smpl_t)s->winsize;
|
||||
#ifdef HAVE_COMPLEX_H
|
||||
s->specdata[0] = compspec->data[0];
|
||||
for (i=1; i < s->fft_size - 1; i++) {
|
||||
s->specdata[i] = compspec->data[i] +
|
||||
I * compspec->data[compspec->length - i];
|
||||
}
|
||||
s->specdata[s->fft_size - 1] = compspec->data[s->fft_size - 1];
|
||||
#else
|
||||
for (i=0; i < s->fft_size; i++) {
|
||||
s->specdata[i] = compspec->data[i];
|
||||
}
|
||||
#endif
|
||||
fftw_execute(s->pbw);
|
||||
for (i = 0; i < output->length; i++) {
|
||||
output->data[i] = s->out[i]*renorm;
|
||||
}
|
||||
|
||||
#elif defined HAVE_ACCELERATE // using ACCELERATE
|
||||
// convert from real imag [ r0, r1, ..., rN, iN-1, .., i2, i1]
|
||||
// to vDSP packed format [ r0, rN, r1, i1, ..., rN-1, iN-1 ]
|
||||
s->out[0] = compspec->data[0];
|
||||
s->out[1] = compspec->data[s->winsize / 2];
|
||||
for (i = 1; i < s->fft_size / 2; i++) {
|
||||
s->out[2 * i] = compspec->data[i];
|
||||
s->out[2 * i + 1] = compspec->data[s->winsize - i];
|
||||
}
|
||||
// convert to split complex format used in vDSP
|
||||
aubio_vDSP_ctoz((aubio_DSPComplex*)s->out, 2, &s->spec, 1, s->fft_size/2);
|
||||
// compute the FFT
|
||||
aubio_vDSP_DFT_Execute(s->fftSetupBwd, s->spec.realp, s->spec.imagp,
|
||||
s->spec.realp, s->spec.imagp);
|
||||
// convert result to real output
|
||||
aubio_vDSP_ztoc(&s->spec, 1, (aubio_DSPComplex*)output->data, 2, s->fft_size/2);
|
||||
// apply scaling
|
||||
smpl_t scale = 1.0 / s->winsize;
|
||||
aubio_vDSP_vsmul(output->data, 1, &scale, output->data, 1, s->fft_size);
|
||||
|
||||
#elif defined HAVE_INTEL_IPP // using Intel IPP
|
||||
|
||||
// convert from real imag [ r0, 0, ..., rN, iN-1, .., i2, i1, iN-1] to complex format
|
||||
s->complexOut[0].re = compspec->data[0];
|
||||
s->complexOut[0].im = 0;
|
||||
s->complexOut[s->fft_size / 2].re = compspec->data[s->fft_size / 2];
|
||||
s->complexOut[s->fft_size / 2].im = 0.0;
|
||||
for (i = 1; i < s->fft_size / 2; i++) {
|
||||
s->complexOut[i].re = compspec->data[i];
|
||||
s->complexOut[i].im = compspec->data[s->fft_size - i];
|
||||
}
|
||||
// apply fft
|
||||
aubio_ippsFFTInv_CCSToR((const aubio_IppFloat *)s->complexOut, output->data, s->fftSpec, s->memBuffer);
|
||||
// apply scaling
|
||||
aubio_ippsMulC(output->data, 1.0 / s->winsize, output->data, s->fft_size);
|
||||
|
||||
#else // using OOURA
|
||||
smpl_t scale = 2.0 / s->winsize;
|
||||
s->out[0] = compspec->data[0];
|
||||
s->out[1] = compspec->data[s->winsize / 2];
|
||||
for (i = 1; i < s->fft_size - 1; i++) {
|
||||
s->out[2 * i] = compspec->data[i];
|
||||
s->out[2 * i + 1] = - compspec->data[s->winsize - i];
|
||||
}
|
||||
aubio_ooura_rdft(s->winsize, -1, s->out, s->ip, s->w);
|
||||
for (i=0; i < s->winsize; i++) {
|
||||
output->data[i] = s->out[i] * scale;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void aubio_fft_get_spectrum(const fvec_t * compspec, cvec_t * spectrum) {
|
||||
aubio_fft_get_phas(compspec, spectrum);
|
||||
aubio_fft_get_norm(compspec, spectrum);
|
||||
}
|
||||
|
||||
void aubio_fft_get_realimag(const cvec_t * spectrum, fvec_t * compspec) {
|
||||
aubio_fft_get_imag(spectrum, compspec);
|
||||
aubio_fft_get_real(spectrum, compspec);
|
||||
}
|
||||
|
||||
void aubio_fft_get_phas(const fvec_t * compspec, cvec_t * spectrum) {
|
||||
uint_t i;
|
||||
if (compspec->data[0] < 0) {
|
||||
spectrum->phas[0] = PI;
|
||||
} else {
|
||||
spectrum->phas[0] = 0.;
|
||||
}
|
||||
#if defined(HAVE_INTEL_IPP)
|
||||
// convert from real imag [ r0, r1, ..., rN, iN-1, ..., i2, i1, i0]
|
||||
// to [ r0, r1, ..., rN, i0, i1, i2, ..., iN-1]
|
||||
for (i = 1; i < spectrum->length / 2; i++) {
|
||||
ELEM_SWAP(compspec->data[compspec->length - i],
|
||||
compspec->data[spectrum->length + i - 1]);
|
||||
}
|
||||
aubio_ippsAtan2(compspec->data + spectrum->length,
|
||||
compspec->data + 1, spectrum->phas + 1, spectrum->length - 1);
|
||||
// revert the imaginary part back again
|
||||
for (i = 1; i < spectrum->length / 2; i++) {
|
||||
ELEM_SWAP(compspec->data[spectrum->length + i - 1],
|
||||
compspec->data[compspec->length - i]);
|
||||
}
|
||||
#else
|
||||
for (i=1; i < spectrum->length - 1; i++) {
|
||||
spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i],
|
||||
compspec->data[i]);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_FFTW3
|
||||
// for even length only, make sure last element is 0 or PI
|
||||
if (2 * (compspec->length / 2) == compspec->length) {
|
||||
#endif
|
||||
if (compspec->data[compspec->length/2] < 0) {
|
||||
spectrum->phas[spectrum->length - 1] = PI;
|
||||
} else {
|
||||
spectrum->phas[spectrum->length - 1] = 0.;
|
||||
}
|
||||
#ifdef HAVE_FFTW3
|
||||
} else {
|
||||
i = spectrum->length - 1;
|
||||
spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i],
|
||||
compspec->data[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void aubio_fft_get_norm(const fvec_t * compspec, cvec_t * spectrum) {
|
||||
uint_t i = 0;
|
||||
spectrum->norm[0] = ABS(compspec->data[0]);
|
||||
for (i=1; i < spectrum->length - 1; i++) {
|
||||
spectrum->norm[i] = SQRT(SQR(compspec->data[i])
|
||||
+ SQR(compspec->data[compspec->length - i]) );
|
||||
}
|
||||
#ifdef HAVE_FFTW3
|
||||
// for even length, make sure last element is > 0
|
||||
if (2 * (compspec->length / 2) == compspec->length) {
|
||||
#endif
|
||||
spectrum->norm[spectrum->length-1] =
|
||||
ABS(compspec->data[compspec->length/2]);
|
||||
#ifdef HAVE_FFTW3
|
||||
} else {
|
||||
i = spectrum->length - 1;
|
||||
spectrum->norm[i] = SQRT(SQR(compspec->data[i])
|
||||
+ SQR(compspec->data[compspec->length - i]) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void aubio_fft_get_imag(const cvec_t * spectrum, fvec_t * compspec) {
|
||||
uint_t i;
|
||||
for (i = 1; i < ( compspec->length + 1 ) / 2 /*- 1 + 1*/; i++) {
|
||||
compspec->data[compspec->length - i] =
|
||||
spectrum->norm[i]*SIN(spectrum->phas[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void aubio_fft_get_real(const cvec_t * spectrum, fvec_t * compspec) {
|
||||
uint_t i;
|
||||
for (i = 0; i < compspec->length / 2 + 1; i++) {
|
||||
compspec->data[i] =
|
||||
spectrum->norm[i]*COS(spectrum->phas[i]);
|
||||
}
|
||||
}
|
144
deps/aubio/src/spectral/fft.h
vendored
Normal file
144
deps/aubio/src/spectral/fft.h
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Fast Fourier Transform
|
||||
|
||||
Depending on how aubio was compiled, FFT are computed using one of:
|
||||
- [Ooura](http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html)
|
||||
- [FFTW3](http://www.fftw.org)
|
||||
- [vDSP](https://developer.apple.com/library/mac/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html)
|
||||
|
||||
\example spectral/test-fft.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_FFT_H
|
||||
#define AUBIO_FFT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** FFT object
|
||||
|
||||
This object computes forward and backward FFTs.
|
||||
|
||||
*/
|
||||
typedef struct _aubio_fft_t aubio_fft_t;
|
||||
|
||||
/** create new FFT computation object
|
||||
|
||||
\param size length of the FFT
|
||||
|
||||
*/
|
||||
aubio_fft_t * new_aubio_fft (uint_t size);
|
||||
/** delete FFT object
|
||||
|
||||
\param s fft object as returned by new_aubio_fft
|
||||
|
||||
*/
|
||||
void del_aubio_fft(aubio_fft_t * s);
|
||||
|
||||
/** compute forward FFT
|
||||
|
||||
\param s fft object as returned by new_aubio_fft
|
||||
\param input input signal
|
||||
\param spectrum output spectrum
|
||||
|
||||
*/
|
||||
void aubio_fft_do (aubio_fft_t *s, const fvec_t * input, cvec_t * spectrum);
|
||||
/** compute backward (inverse) FFT
|
||||
|
||||
\param s fft object as returned by new_aubio_fft
|
||||
\param spectrum input spectrum
|
||||
\param output output signal
|
||||
|
||||
*/
|
||||
void aubio_fft_rdo (aubio_fft_t *s, const cvec_t * spectrum, fvec_t * output);
|
||||
|
||||
/** compute forward FFT
|
||||
|
||||
\param s fft object as returned by new_aubio_fft
|
||||
\param input real input signal
|
||||
\param compspec complex output fft real/imag
|
||||
|
||||
*/
|
||||
void aubio_fft_do_complex (aubio_fft_t *s, const fvec_t * input, fvec_t * compspec);
|
||||
/** compute backward (inverse) FFT from real/imag
|
||||
|
||||
\param s fft object as returned by new_aubio_fft
|
||||
\param compspec real/imag input fft array
|
||||
\param output real output array
|
||||
|
||||
*/
|
||||
void aubio_fft_rdo_complex (aubio_fft_t *s, const fvec_t * compspec, fvec_t * output);
|
||||
|
||||
/** convert real/imag spectrum to norm/phas spectrum
|
||||
|
||||
\param compspec real/imag input fft array
|
||||
\param spectrum cvec norm/phas output array
|
||||
|
||||
*/
|
||||
void aubio_fft_get_spectrum(const fvec_t * compspec, cvec_t * spectrum);
|
||||
/** convert real/imag spectrum to norm/phas spectrum
|
||||
|
||||
\param compspec real/imag input fft array
|
||||
\param spectrum cvec norm/phas output array
|
||||
|
||||
*/
|
||||
void aubio_fft_get_realimag(const cvec_t * spectrum, fvec_t * compspec);
|
||||
|
||||
/** compute phas spectrum from real/imag parts
|
||||
|
||||
\param compspec real/imag input fft array
|
||||
\param spectrum cvec norm/phas output array
|
||||
|
||||
*/
|
||||
void aubio_fft_get_phas(const fvec_t * compspec, cvec_t * spectrum);
|
||||
/** compute imaginary part from the norm/phas cvec
|
||||
|
||||
\param spectrum norm/phas input array
|
||||
\param compspec real/imag output fft array
|
||||
|
||||
*/
|
||||
void aubio_fft_get_imag(const cvec_t * spectrum, fvec_t * compspec);
|
||||
|
||||
/** compute norm component from real/imag parts
|
||||
|
||||
\param compspec real/imag input fft array
|
||||
\param spectrum cvec norm/phas output array
|
||||
|
||||
*/
|
||||
void aubio_fft_get_norm(const fvec_t * compspec, cvec_t * spectrum);
|
||||
/** compute real part from norm/phas components
|
||||
|
||||
\param spectrum norm/phas input array
|
||||
\param compspec real/imag output fft array
|
||||
|
||||
*/
|
||||
void aubio_fft_get_real(const cvec_t * spectrum, fvec_t * compspec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_FFT_H */
|
224
deps/aubio/src/spectral/phasevoc.c
vendored
Normal file
224
deps/aubio/src/spectral/phasevoc.c
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
Copyright (C) 2003-2014 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "spectral/fft.h"
|
||||
#include "spectral/phasevoc.h"
|
||||
|
||||
/** phasevocoder internal object */
|
||||
struct _aubio_pvoc_t {
|
||||
uint_t win_s; /** grain length */
|
||||
uint_t hop_s; /** overlap step */
|
||||
aubio_fft_t * fft; /** fft object */
|
||||
fvec_t * data; /** current input grain, [win_s] frames */
|
||||
fvec_t * dataold; /** memory of past grain, [win_s-hop_s] frames */
|
||||
fvec_t * synth; /** current output grain, [win_s] frames */
|
||||
fvec_t * synthold; /** memory of past grain, [win_s-hop_s] frames */
|
||||
fvec_t * w; /** grain window [win_s] */
|
||||
uint_t start; /** where to start additive synthesis */
|
||||
uint_t end; /** where to end it */
|
||||
smpl_t scale; /** scaling factor for synthesis */
|
||||
uint_t end_datasize; /** size of memory to end */
|
||||
uint_t hop_datasize; /** size of memory to hop_s */
|
||||
};
|
||||
|
||||
|
||||
/** returns data and dataold slided by hop_s */
|
||||
static void aubio_pvoc_swapbuffers(aubio_pvoc_t *pv, const fvec_t *new);
|
||||
|
||||
/** do additive synthesis from 'old' and 'cur' */
|
||||
static void aubio_pvoc_addsynth(aubio_pvoc_t *pv, fvec_t * synthnew);
|
||||
|
||||
void aubio_pvoc_do(aubio_pvoc_t *pv, const fvec_t * datanew, cvec_t *fftgrain) {
|
||||
/* slide */
|
||||
aubio_pvoc_swapbuffers(pv, datanew);
|
||||
/* windowing */
|
||||
fvec_weight(pv->data, pv->w);
|
||||
/* shift */
|
||||
fvec_shift(pv->data);
|
||||
/* calculate fft */
|
||||
aubio_fft_do (pv->fft,pv->data,fftgrain);
|
||||
}
|
||||
|
||||
void aubio_pvoc_rdo(aubio_pvoc_t *pv,cvec_t * fftgrain, fvec_t * synthnew) {
|
||||
/* calculate rfft */
|
||||
aubio_fft_rdo(pv->fft,fftgrain,pv->synth);
|
||||
/* unshift */
|
||||
fvec_ishift(pv->synth);
|
||||
/* windowing */
|
||||
// if overlap = 50%, do not apply window (identity)
|
||||
if (pv->hop_s * 2 < pv->win_s) {
|
||||
fvec_weight(pv->synth, pv->w);
|
||||
}
|
||||
/* additive synthesis */
|
||||
aubio_pvoc_addsynth(pv, synthnew);
|
||||
}
|
||||
|
||||
aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s) {
|
||||
aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t);
|
||||
|
||||
/* if (win_s < 2*hop_s) {
|
||||
AUBIO_WRN("Hop size bigger than half the window size!\n");
|
||||
} */
|
||||
|
||||
if ((sint_t)hop_s < 1) {
|
||||
AUBIO_ERR("pvoc: got hop_size %d, but can not be < 1\n", hop_s);
|
||||
goto beach;
|
||||
} else if ((sint_t)win_s < 2) {
|
||||
AUBIO_ERR("pvoc: got buffer_size %d, but can not be < 2\n", win_s);
|
||||
goto beach;
|
||||
} else if (win_s < hop_s) {
|
||||
AUBIO_ERR("pvoc: hop size (%d) is larger than win size (%d)\n", hop_s, win_s);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
pv->fft = new_aubio_fft (win_s);
|
||||
if (pv->fft == NULL) {
|
||||
goto beach;
|
||||
}
|
||||
|
||||
/* remember old */
|
||||
pv->data = new_fvec (win_s);
|
||||
pv->synth = new_fvec (win_s);
|
||||
|
||||
/* new input output */
|
||||
if (win_s > hop_s) {
|
||||
pv->dataold = new_fvec (win_s-hop_s);
|
||||
pv->synthold = new_fvec (win_s-hop_s);
|
||||
} else {
|
||||
pv->dataold = new_fvec (1);
|
||||
pv->synthold = new_fvec (1);
|
||||
}
|
||||
pv->w = new_aubio_window ("hanningz", win_s);
|
||||
|
||||
pv->hop_s = hop_s;
|
||||
pv->win_s = win_s;
|
||||
|
||||
/* more than 50% overlap, overlap anyway */
|
||||
if (win_s < 2 * hop_s) pv->start = 0;
|
||||
/* less than 50% overlap, reset latest grain trail */
|
||||
else pv->start = win_s - hop_s - hop_s;
|
||||
|
||||
if (win_s > hop_s) pv->end = win_s - hop_s;
|
||||
else pv->end = 0;
|
||||
|
||||
pv->end_datasize = pv->end * sizeof(smpl_t);
|
||||
pv->hop_datasize = pv->hop_s * sizeof(smpl_t);
|
||||
|
||||
// for reconstruction with 75% overlap
|
||||
if (win_s == hop_s * 4) {
|
||||
pv->scale = 2./3.;
|
||||
} else if (win_s == hop_s * 8) {
|
||||
pv->scale = 1./3.;
|
||||
} else if (win_s == hop_s * 2) {
|
||||
pv->scale = 1.;
|
||||
} else {
|
||||
pv->scale = .5;
|
||||
}
|
||||
|
||||
return pv;
|
||||
|
||||
beach:
|
||||
AUBIO_FREE (pv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint_t aubio_pvoc_set_window(aubio_pvoc_t *pv, const char_t *window) {
|
||||
return fvec_set_window(pv->w, (char_t*)window);
|
||||
}
|
||||
|
||||
void del_aubio_pvoc(aubio_pvoc_t *pv) {
|
||||
del_fvec(pv->data);
|
||||
del_fvec(pv->synth);
|
||||
del_fvec(pv->dataold);
|
||||
del_fvec(pv->synthold);
|
||||
del_fvec(pv->w);
|
||||
del_aubio_fft(pv->fft);
|
||||
AUBIO_FREE(pv);
|
||||
}
|
||||
|
||||
static void aubio_pvoc_swapbuffers(aubio_pvoc_t *pv, const fvec_t *new)
|
||||
{
|
||||
/* some convenience pointers */
|
||||
smpl_t * data = pv->data->data;
|
||||
smpl_t * dataold = pv->dataold->data;
|
||||
smpl_t * datanew = new->data;
|
||||
#ifndef HAVE_MEMCPY_HACKS
|
||||
uint_t i;
|
||||
for (i = 0; i < pv->end; i++)
|
||||
data[i] = dataold[i];
|
||||
for (i = 0; i < pv->hop_s; i++)
|
||||
data[pv->end + i] = datanew[i];
|
||||
for (i = 0; i < pv->end; i++)
|
||||
dataold[i] = data[i + pv->hop_s];
|
||||
#else
|
||||
memcpy(data, dataold, pv->end_datasize);
|
||||
data += pv->end;
|
||||
memcpy(data, datanew, pv->hop_datasize);
|
||||
data -= pv->end;
|
||||
data += pv->hop_s;
|
||||
memcpy(dataold, data, pv->end_datasize);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void aubio_pvoc_addsynth(aubio_pvoc_t *pv, fvec_t *synth_new)
|
||||
{
|
||||
uint_t i;
|
||||
/* some convenience pointers */
|
||||
smpl_t * synth = pv->synth->data;
|
||||
smpl_t * synthold = pv->synthold->data;
|
||||
smpl_t * synthnew = synth_new->data;
|
||||
|
||||
/* put new result in synthnew */
|
||||
for (i = 0; i < pv->hop_s; i++)
|
||||
synthnew[i] = synth[i] * pv->scale;
|
||||
|
||||
/* no overlap, nothing else to do */
|
||||
if (pv->end == 0) return;
|
||||
|
||||
/* add new synth to old one */
|
||||
for (i = 0; i < pv->hop_s; i++)
|
||||
synthnew[i] += synthold[i];
|
||||
|
||||
/* shift synthold */
|
||||
for (i = 0; i < pv->start; i++)
|
||||
synthold[i] = synthold[i + pv->hop_s];
|
||||
|
||||
/* erase last frame in synthold */
|
||||
for (i = pv->start; i < pv->end; i++)
|
||||
synthold[i] = 0.;
|
||||
|
||||
/* additive synth */
|
||||
for (i = 0; i < pv->end; i++)
|
||||
synthold[i] += synth[i + pv->hop_s] * pv->scale;
|
||||
}
|
||||
|
||||
uint_t aubio_pvoc_get_win(aubio_pvoc_t* pv)
|
||||
{
|
||||
return pv->win_s;
|
||||
}
|
||||
|
||||
uint_t aubio_pvoc_get_hop(aubio_pvoc_t* pv)
|
||||
{
|
||||
return pv->hop_s;
|
||||
}
|
113
deps/aubio/src/spectral/phasevoc.h
vendored
Normal file
113
deps/aubio/src/spectral/phasevoc.h
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Phase vocoder object
|
||||
|
||||
This object implements a phase vocoder. The spectral frames are computed
|
||||
using a HanningZ window and a swapped version of the signal to simplify the
|
||||
phase relationships across frames. The window sizes and overlap are specified
|
||||
at creation time.
|
||||
|
||||
\example spectral/test-phasevoc.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PHASEVOC_H
|
||||
#define AUBIO_PHASEVOC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** phasevocoder object */
|
||||
typedef struct _aubio_pvoc_t aubio_pvoc_t;
|
||||
|
||||
/** create phase vocoder object
|
||||
|
||||
\param win_s size of analysis buffer (and length the FFT transform)
|
||||
\param hop_s step size between two consecutive analysis
|
||||
|
||||
*/
|
||||
aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s);
|
||||
/** delete phase vocoder object
|
||||
|
||||
\param pv phase vocoder object as returned by new_aubio_pvoc
|
||||
|
||||
*/
|
||||
void del_aubio_pvoc(aubio_pvoc_t *pv);
|
||||
|
||||
/** compute spectral frame
|
||||
|
||||
This function accepts an input vector of size [hop_s]. The
|
||||
analysis buffer is rotated and filled with the new data. After windowing of
|
||||
this signal window, the Fourier transform is computed and returned in
|
||||
fftgrain as two vectors, magnitude and phase.
|
||||
|
||||
\param pv phase vocoder object as returned by new_aubio_pvoc
|
||||
\param in new input signal (hop_s long)
|
||||
\param fftgrain output spectral frame
|
||||
|
||||
*/
|
||||
void aubio_pvoc_do(aubio_pvoc_t *pv, const fvec_t *in, cvec_t * fftgrain);
|
||||
/** compute signal from spectral frame
|
||||
|
||||
This function takes an input spectral frame fftgrain of size
|
||||
[buf_s] and computes its inverse Fourier transform. Overlap-add
|
||||
synthesis is then computed using the previously synthetised frames, and the
|
||||
output stored in out.
|
||||
|
||||
\param pv phase vocoder object as returned by new_aubio_pvoc
|
||||
\param fftgrain input spectral frame
|
||||
\param out output signal (hop_s long)
|
||||
|
||||
*/
|
||||
void aubio_pvoc_rdo(aubio_pvoc_t *pv, cvec_t * fftgrain, fvec_t *out);
|
||||
|
||||
/** get window size
|
||||
|
||||
\param pv phase vocoder to get the window size from
|
||||
|
||||
*/
|
||||
uint_t aubio_pvoc_get_win(aubio_pvoc_t* pv);
|
||||
|
||||
/** get hop size
|
||||
|
||||
\param pv phase vocoder to get the hop size from
|
||||
|
||||
*/
|
||||
uint_t aubio_pvoc_get_hop(aubio_pvoc_t* pv);
|
||||
|
||||
/** set window type
|
||||
|
||||
\param pv phase vocoder to set the window type
|
||||
\param window_type a string representing a window
|
||||
|
||||
\return 0 if successful, non-zero otherwise
|
||||
|
||||
*/
|
||||
uint_t aubio_pvoc_set_window(aubio_pvoc_t *pv, const char_t *window_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PHASEVOC_H */
|
262
deps/aubio/src/temporal/a_weighting.c
vendored
Normal file
262
deps/aubio/src/temporal/a_weighting.c
vendored
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "types.h"
|
||||
#include "fvec.h"
|
||||
#include "lvec.h"
|
||||
#include "temporal/filter.h"
|
||||
#include "temporal/a_weighting.h"
|
||||
|
||||
uint_t
|
||||
aubio_filter_set_a_weighting (aubio_filter_t * f, uint_t samplerate)
|
||||
{
|
||||
uint_t order; lsmp_t *a, *b; lvec_t *as, *bs;
|
||||
|
||||
if ((sint_t)samplerate <= 0) {
|
||||
AUBIO_ERROR("aubio_filter: failed setting A-weighting with samplerate %d\n", samplerate);
|
||||
return AUBIO_FAIL;
|
||||
}
|
||||
if (f == NULL) {
|
||||
AUBIO_ERROR("aubio_filter: failed setting A-weighting with filter NULL\n");
|
||||
return AUBIO_FAIL;
|
||||
}
|
||||
|
||||
order = aubio_filter_get_order (f);
|
||||
if (order != 7) {
|
||||
AUBIO_ERROR ("aubio_filter: order of A-weighting filter must be 7, not %d\n", order);
|
||||
return 1;
|
||||
}
|
||||
|
||||
aubio_filter_set_samplerate (f, samplerate);
|
||||
bs = aubio_filter_get_feedforward (f);
|
||||
as = aubio_filter_get_feedback (f);
|
||||
b = bs->data, a = as->data;
|
||||
|
||||
/* select coefficients according to sampling frequency */
|
||||
switch (samplerate) {
|
||||
|
||||
case 8000:
|
||||
b[0] = 6.306209468238731519207362907764036208391189575195312500e-01;
|
||||
b[1] = -1.261241893647746525886077506584115326404571533203125000e+00;
|
||||
b[2] = -6.306209468238730408984338282607495784759521484375000000e-01;
|
||||
b[3] = 2.522483787295493051772155013168230652809143066406250000e+00;
|
||||
b[4] = -6.306209468238730408984338282607495784759521484375000000e-01;
|
||||
b[5] = -1.261241893647746525886077506584115326404571533203125000e+00;
|
||||
b[6] = 6.306209468238731519207362907764036208391189575195312500e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -2.128467193009123015201566886389628052711486816406250000e+00;
|
||||
a[2] = 2.948668980101234460278192273108288645744323730468750000e-01;
|
||||
a[3] = 1.824183830735050637628091863007284700870513916015625000e+00;
|
||||
a[4] = -8.056628943119792385374466903158463537693023681640625000e-01;
|
||||
a[5] = -3.947497982842933517133587884018197655677795410156250000e-01;
|
||||
a[6] = 2.098548546080332977137317129745497368276119232177734375e-01;
|
||||
break;
|
||||
|
||||
case 11025:
|
||||
b[0] = 6.014684165832374640459079273568931967020034790039062500e-01;
|
||||
b[1] = -1.202936833166475150136420779745094478130340576171875000e+00;
|
||||
b[2] = -6.014684165832373530236054648412391543388366699218750000e-01;
|
||||
b[3] = 2.405873666332950300272841559490188956260681152343750000e+00;
|
||||
b[4] = -6.014684165832373530236054648412391543388366699218750000e-01;
|
||||
b[5] = -1.202936833166475150136420779745094478130340576171875000e+00;
|
||||
b[6] = 6.014684165832374640459079273568931967020034790039062500e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -2.463578747722854345170162559952586889266967773437500000e+00;
|
||||
a[2] = 1.096799662705210121060872552334330976009368896484375000e+00;
|
||||
a[3] = 1.381222210556041218865175324026495218276977539062500000e+00;
|
||||
a[4] = -1.013875696476876031582037285261321812868118286132812500e+00;
|
||||
a[5] = -1.839132734476921215982514468123554252088069915771484375e-01;
|
||||
a[6] = 1.833526393172056623281918064094497822225093841552734375e-01;
|
||||
break;
|
||||
|
||||
case 16000:
|
||||
b[0] = 5.314898298235570806014038680586963891983032226562500000e-01;
|
||||
b[1] = -1.062979659647114161202807736117392778396606445312500000e+00;
|
||||
b[2] = -5.314898298235570806014038680586963891983032226562500000e-01;
|
||||
b[3] = 2.125959319294228322405615472234785556793212890625000000e+00;
|
||||
b[4] = -5.314898298235570806014038680586963891983032226562500000e-01;
|
||||
b[5] = -1.062979659647114161202807736117392778396606445312500000e+00;
|
||||
b[6] = 5.314898298235570806014038680586963891983032226562500000e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -2.867832572992162987191022693878039717674255371093750000e+00;
|
||||
a[2] = 2.221144410202312347024644623161293566226959228515625000e+00;
|
||||
a[3] = 4.552683347886614662058946123579517006874084472656250000e-01;
|
||||
a[4] = -9.833868636162828025248927588108927011489868164062500000e-01;
|
||||
a[5] = 5.592994142413361402521587706360151059925556182861328125e-02;
|
||||
a[6] = 1.188781038285612462468421313133148942142724990844726562e-01;
|
||||
break;
|
||||
|
||||
case 22050:
|
||||
b[0] = 4.492998504299193784916610638902056962251663208007812500e-01;
|
||||
b[1] = -8.985997008598388680056245902960654348134994506835937500e-01;
|
||||
b[2] = -4.492998504299192674693586013745516538619995117187500000e-01;
|
||||
b[3] = 1.797199401719677958055854105623438954353332519531250000e+00;
|
||||
b[4] = -4.492998504299192674693586013745516538619995117187500000e-01;
|
||||
b[5] = -8.985997008598388680056245902960654348134994506835937500e-01;
|
||||
b[6] = 4.492998504299193784916610638902056962251663208007812500e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -3.229078805225074955131958631682209670543670654296875000e+00;
|
||||
a[2] = 3.354494881236033787530459449044428765773773193359375000e+00;
|
||||
a[3] = -7.317843680657351024265722116979304701089859008789062500e-01;
|
||||
a[4] = -6.271627581807257545420952737913466989994049072265625000e-01;
|
||||
a[5] = 1.772142005020879151899748649157118052244186401367187500e-01;
|
||||
a[6] = 5.631716697383508385410522123493137769401073455810546875e-02;
|
||||
break;
|
||||
|
||||
case 24000:
|
||||
b[0] = 4.256263892891054001488271296693710610270500183105468750e-01;
|
||||
b[1] = -8.512527785782106892753517968230880796909332275390625000e-01;
|
||||
b[2] = -4.256263892891054556599783609271980822086334228515625000e-01;
|
||||
b[3] = 1.702505557156421378550703593646176159381866455078125000e+00;
|
||||
b[4] = -4.256263892891054556599783609271980822086334228515625000e-01;
|
||||
b[5] = -8.512527785782106892753517968230880796909332275390625000e-01;
|
||||
b[6] = 4.256263892891054001488271296693710610270500183105468750e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -3.325996004241962733516402295208536088466644287109375000e+00;
|
||||
a[2] = 3.677161079286316969216841243905946612358093261718750000e+00;
|
||||
a[3] = -1.106476076828482035807610373012721538543701171875000000e+00;
|
||||
a[4] = -4.726706734908718843257702246773988008499145507812500000e-01;
|
||||
a[5] = 1.861941760230954034938122276798821985721588134765625000e-01;
|
||||
a[6] = 4.178771337829546850262119050967157818377017974853515625e-02;
|
||||
break;
|
||||
|
||||
case 32000:
|
||||
b[0] = 3.434583386824304196416335344110848382115364074707031250e-01;
|
||||
b[1] = -6.869166773648609503055695313378237187862396240234375000e-01;
|
||||
b[2] = -3.434583386824303641304823031532578170299530029296875000e-01;
|
||||
b[3] = 1.373833354729721900611139062675647437572479248046875000e+00;
|
||||
b[4] = -3.434583386824303641304823031532578170299530029296875000e-01;
|
||||
b[5] = -6.869166773648609503055695313378237187862396240234375000e-01;
|
||||
b[6] = 3.434583386824304196416335344110848382115364074707031250e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -3.656446043233668063976438133977353572845458984375000000e+00;
|
||||
a[2] = 4.831468450652579349480220116674900054931640625000000000e+00;
|
||||
a[3] = -2.557597496581567764195597192156128585338592529296875000e+00;
|
||||
a[4] = 2.533680394205302666144064005493419244885444641113281250e-01;
|
||||
a[5] = 1.224430322452567110325105659285327419638633728027343750e-01;
|
||||
a[6] = 6.764072168342137418572956875095769646577537059783935547e-03;
|
||||
break;
|
||||
|
||||
case 44100:
|
||||
b[0] = 2.557411252042575133813784304948057979345321655273437500e-01;
|
||||
b[1] = -5.114822504085150267627568609896115958690643310546875000e-01;
|
||||
b[2] = -2.557411252042575133813784304948057979345321655273437500e-01;
|
||||
b[3] = 1.022964500817030053525513721979223191738128662109375000e+00;
|
||||
b[4] = -2.557411252042575133813784304948057979345321655273437500e-01;
|
||||
b[5] = -5.114822504085150267627568609896115958690643310546875000e-01;
|
||||
b[6] = 2.557411252042575133813784304948057979345321655273437500e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -4.019576181115832369528106937650591135025024414062500000e+00;
|
||||
a[2] = 6.189406442920693862674852425698190927505493164062500000e+00;
|
||||
a[3] = -4.453198903544116404873420833609998226165771484375000000e+00;
|
||||
a[4] = 1.420842949621876627475103305187076330184936523437500000e+00;
|
||||
a[5] = -1.418254738303044160119270600262098014354705810546875000e-01;
|
||||
a[6] = 4.351177233495117681327801761881346465088427066802978516e-03;
|
||||
break;
|
||||
|
||||
case 48000:
|
||||
b[0] = 2.343017922995132285013397677175817079842090606689453125e-01;
|
||||
b[1] = -4.686035845990265125138307666929904371500015258789062500e-01;
|
||||
b[2] = -2.343017922995132007457641520886681973934173583984375000e-01;
|
||||
b[3] = 9.372071691980530250276615333859808743000030517578125000e-01;
|
||||
b[4] = -2.343017922995132007457641520886681973934173583984375000e-01;
|
||||
b[5] = -4.686035845990265125138307666929904371500015258789062500e-01;
|
||||
b[6] = 2.343017922995132285013397677175817079842090606689453125e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -4.113043408775872045168853219365701079368591308593750000e+00;
|
||||
a[2] = 6.553121752655050258340452273841947317123413085937500000e+00;
|
||||
a[3] = -4.990849294163385074796224216697737574577331542968750000e+00;
|
||||
a[4] = 1.785737302937575599059982778271660208702087402343750000e+00;
|
||||
a[5] = -2.461905953194876706113802811159985139966011047363281250e-01;
|
||||
a[6] = 1.122425003323123879339640041052916785702109336853027344e-02;
|
||||
break;
|
||||
|
||||
case 88200:
|
||||
b[0] = 1.118876366882113199130444058937428053468465805053710938e-01;
|
||||
b[1] = -2.237752733764226120705131961585721001029014587402343750e-01;
|
||||
b[2] = -1.118876366882113337908322137081995606422424316406250000e-01;
|
||||
b[3] = 4.475505467528452241410263923171442002058029174804687500e-01;
|
||||
b[4] = -1.118876366882113337908322137081995606422424316406250000e-01;
|
||||
b[5] = -2.237752733764226120705131961585721001029014587402343750e-01;
|
||||
b[6] = 1.118876366882113199130444058937428053468465805053710938e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -4.726938565651158441482948546763509511947631835937500000e+00;
|
||||
a[2] = 9.076897983832765248735086061060428619384765625000000000e+00;
|
||||
a[3] = -9.014855113464800950850985827855765819549560546875000000e+00;
|
||||
a[4] = 4.852772261031594425162438710685819387435913085937500000e+00;
|
||||
a[5] = -1.333877820398965186043938047077972441911697387695312500e+00;
|
||||
a[6] = 1.460012549591642450064199465487035922706127166748046875e-01;
|
||||
break;
|
||||
|
||||
case 96000:
|
||||
b[0] = 9.951898975972744976203898659150581806898117065429687500e-02;
|
||||
b[1] = -1.990379795194548995240779731830116361379623413085937500e-01;
|
||||
b[2] = -9.951898975972744976203898659150581806898117065429687500e-02;
|
||||
b[3] = 3.980759590389097990481559463660232722759246826171875000e-01;
|
||||
b[4] = -9.951898975972744976203898659150581806898117065429687500e-02;
|
||||
b[5] = -1.990379795194548995240779731830116361379623413085937500e-01;
|
||||
b[6] = 9.951898975972744976203898659150581806898117065429687500e-02;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -4.802203044225376693532325589330866932868957519531250000e+00;
|
||||
a[2] = 9.401807218627226347962277941405773162841796875000000000e+00;
|
||||
a[3] = -9.566143943569164420637207513209432363510131835937500000e+00;
|
||||
a[4] = 5.309775930392619081032989925006404519081115722656250000e+00;
|
||||
a[5] = -1.517333360452622237346531619550660252571105957031250000e+00;
|
||||
a[6] = 1.740971994228911745583587844521389342844486236572265625e-01;
|
||||
break;
|
||||
|
||||
case 192000:
|
||||
b[0] = 3.433213424548713782469278044118254911154508590698242188e-02;
|
||||
b[1] = -6.866426849097426177159775306790834292769432067871093750e-02;
|
||||
b[2] = -3.433213424548714476358668434841092675924301147460937500e-02;
|
||||
b[3] = 1.373285369819485235431955061358166858553886413574218750e-01;
|
||||
b[4] = -3.433213424548714476358668434841092675924301147460937500e-02;
|
||||
b[5] = -6.866426849097426177159775306790834292769432067871093750e-02;
|
||||
b[6] = 3.433213424548713782469278044118254911154508590698242188e-02;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -5.305923689674640009172890131594613194465637207031250000e+00;
|
||||
a[2] = 1.165952437466175695135461864992976188659667968750000000e+01;
|
||||
a[3] = -1.357560092700591525272102444432675838470458984375000000e+01;
|
||||
a[4] = 8.828906932824192921316353022120893001556396484375000000e+00;
|
||||
a[5] = -3.039490120988216581565666274400427937507629394531250000e+00;
|
||||
a[6] = 4.325834301870381537469256727490574121475219726562500000e-01;
|
||||
break;
|
||||
|
||||
default:
|
||||
AUBIO_ERROR ("sampling rate of A-weighting filter is %d, should be one of\
|
||||
8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, 192000.\n", samplerate);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
aubio_filter_t *
|
||||
new_aubio_filter_a_weighting (uint_t samplerate)
|
||||
{
|
||||
aubio_filter_t *f = new_aubio_filter (7);
|
||||
if (aubio_filter_set_a_weighting(f,samplerate) != AUBIO_OK) {
|
||||
del_aubio_filter(f);
|
||||
return NULL;
|
||||
}
|
||||
return f;
|
||||
}
|
88
deps/aubio/src/temporal/a_weighting.h
vendored
Normal file
88
deps/aubio/src/temporal/a_weighting.h
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_FILTER_A_DESIGN_H
|
||||
#define AUBIO_FILTER_A_DESIGN_H
|
||||
|
||||
/** \file
|
||||
|
||||
A-weighting filter coefficients
|
||||
|
||||
This file creates an A-weighting digital filter, which reduces low and high
|
||||
frequencies and enhance the middle ones to reflect the ability of the human
|
||||
hearing.
|
||||
|
||||
The implementation is based on the following standard:
|
||||
|
||||
- IEC/CD 1672: Electroacoustics-Sound Level Meters, IEC, Geneva, Nov. 1996,
|
||||
for A- and C-weighting filters.
|
||||
|
||||
See also:
|
||||
|
||||
- <a href="http://en.wikipedia.org/wiki/A-weighting">A-Weighting on
|
||||
Wikipedia</a>
|
||||
- <a href="http://en.wikipedia.org/wiki/Weighting_filter">Weighting filter on
|
||||
Wikipedia</a>
|
||||
- <a href="http://www.mathworks.com/matlabcentral/fileexchange/69">Christophe
|
||||
Couvreur's 'octave' toolbox</a>
|
||||
|
||||
The coefficients in this file have been computed using Christophe Couvreur's
|
||||
scripts in octave 3.0 (debian package 1:3.0.5-6+b2 with octave-signal
|
||||
1.0.9-1+b1 on i386), with <pre> [b, a] = adsign(1/Fs) </pre> for various
|
||||
sampling frequencies (8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
|
||||
88200, 96000, and 192000 Hz).
|
||||
|
||||
The sampling frequency should normally be higher than 20kHz, but most common
|
||||
file sampling rates have been included for completeness.
|
||||
|
||||
\example temporal/test-a_weighting.c
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** create new A-design filter
|
||||
|
||||
\param samplerate sampling frequency of the signal to filter. Should be one of
|
||||
8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and
|
||||
192000 Hz
|
||||
|
||||
\return a new filter object
|
||||
|
||||
*/
|
||||
aubio_filter_t *new_aubio_filter_a_weighting (uint_t samplerate);
|
||||
|
||||
/** set feedback and feedforward coefficients of a A-weighting filter
|
||||
|
||||
\param f filter object to get coefficients from
|
||||
\param samplerate sampling frequency of the signal to filter. Should be one of
|
||||
8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and
|
||||
192000 Hz
|
||||
|
||||
*/
|
||||
uint_t aubio_filter_set_a_weighting (aubio_filter_t * f, uint_t samplerate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_FILTER_A_DESIGN_H */
|
54
deps/aubio/src/temporal/biquad.c
vendored
Normal file
54
deps/aubio/src/temporal/biquad.c
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "lvec.h"
|
||||
#include "temporal/filter.h"
|
||||
#include "temporal/biquad.h"
|
||||
|
||||
uint_t
|
||||
aubio_filter_set_biquad (aubio_filter_t * f, lsmp_t b0, lsmp_t b1, lsmp_t b2,
|
||||
lsmp_t a1, lsmp_t a2)
|
||||
{
|
||||
uint_t order = aubio_filter_get_order (f);
|
||||
lvec_t *bs = aubio_filter_get_feedforward (f);
|
||||
lvec_t *as = aubio_filter_get_feedback (f);
|
||||
|
||||
if (order != 3) {
|
||||
AUBIO_ERROR ("order of biquad filter must be 3, not %d\n", order);
|
||||
return AUBIO_FAIL;
|
||||
}
|
||||
bs->data[0] = b0;
|
||||
bs->data[1] = b1;
|
||||
bs->data[2] = b2;
|
||||
as->data[0] = 1.;
|
||||
as->data[1] = a1;
|
||||
as->data[2] = a2;
|
||||
return AUBIO_OK;
|
||||
}
|
||||
|
||||
aubio_filter_t *
|
||||
new_aubio_filter_biquad (lsmp_t b0, lsmp_t b1, lsmp_t b2, lsmp_t a1, lsmp_t a2)
|
||||
{
|
||||
aubio_filter_t *f = new_aubio_filter (3);
|
||||
aubio_filter_set_biquad (f, b0, b1, b2, a1, a2);
|
||||
return f;
|
||||
}
|
75
deps/aubio/src/temporal/biquad.h
vendored
Normal file
75
deps/aubio/src/temporal/biquad.h
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_FILTER_BIQUAD_H
|
||||
#define AUBIO_FILTER_BIQUAD_H
|
||||
|
||||
/** \file
|
||||
|
||||
Second order Infinite Impulse Response filter
|
||||
|
||||
This file implements a normalised biquad filter (second order IIR):
|
||||
|
||||
\f$ y[n] = b_0 x[n] + b_1 x[n-1] + b_2 x[n-2] - a_1 y[n-1] - a_2 y[n-2] \f$
|
||||
|
||||
The filtfilt version runs the filter twice, forward and backward, to
|
||||
compensate the phase shifting of the forward operation.
|
||||
|
||||
See also <a href="http://en.wikipedia.org/wiki/Digital_biquad_filter">Digital
|
||||
biquad filter</a> on wikipedia.
|
||||
|
||||
\example temporal/test-biquad.c
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** set coefficients of a biquad filter
|
||||
|
||||
\param f filter object as returned by new_aubio_filter()
|
||||
\param b0 forward filter coefficient
|
||||
\param b1 forward filter coefficient
|
||||
\param b2 forward filter coefficient
|
||||
\param a1 feedback filter coefficient
|
||||
\param a2 feedback filter coefficient
|
||||
|
||||
*/
|
||||
uint_t aubio_filter_set_biquad (aubio_filter_t * f, lsmp_t b0, lsmp_t b1,
|
||||
lsmp_t b2, lsmp_t a1, lsmp_t a2);
|
||||
|
||||
/** create biquad filter with `b0`, `b1`, `b2`, `a1`, `a2` coeffs
|
||||
|
||||
\param b0 forward filter coefficient
|
||||
\param b1 forward filter coefficient
|
||||
\param b2 forward filter coefficient
|
||||
\param a1 feedback filter coefficient
|
||||
\param a2 feedback filter coefficient
|
||||
|
||||
*/
|
||||
aubio_filter_t *new_aubio_filter_biquad (lsmp_t b0, lsmp_t b1, lsmp_t b2,
|
||||
lsmp_t a1, lsmp_t a2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_FILTER_BIQUAD_H */
|
217
deps/aubio/src/temporal/c_weighting.c
vendored
Normal file
217
deps/aubio/src/temporal/c_weighting.c
vendored
Normal file
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "types.h"
|
||||
#include "fvec.h"
|
||||
#include "lvec.h"
|
||||
#include "temporal/filter.h"
|
||||
#include "temporal/c_weighting.h"
|
||||
|
||||
uint_t
|
||||
aubio_filter_set_c_weighting (aubio_filter_t * f, uint_t samplerate)
|
||||
{
|
||||
uint_t order; lsmp_t *a, *b; lvec_t *as, *bs;
|
||||
|
||||
if ((sint_t)samplerate <= 0) {
|
||||
AUBIO_ERROR("aubio_filter: failed setting C-weighting with samplerate %d\n", samplerate);
|
||||
return AUBIO_FAIL;
|
||||
}
|
||||
if (f == NULL) {
|
||||
AUBIO_ERROR("aubio_filter: failed setting C-weighting with filter NULL\n");
|
||||
return AUBIO_FAIL;
|
||||
}
|
||||
|
||||
order = aubio_filter_get_order (f);
|
||||
if ( order != 5 ) {
|
||||
AUBIO_ERROR ("aubio_filter: order of C-weighting filter must be 5, not %d\n", order);
|
||||
return 1;
|
||||
}
|
||||
|
||||
aubio_filter_set_samplerate (f, samplerate);
|
||||
bs = aubio_filter_get_feedforward (f);
|
||||
as = aubio_filter_get_feedback (f);
|
||||
b = bs->data, a = as->data;
|
||||
|
||||
/* select coefficients according to sampling frequency */
|
||||
switch (samplerate) {
|
||||
|
||||
case 8000:
|
||||
b[0] = 6.782173932405135552414776611840352416038513183593750000e-01;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -1.356434786481027110482955322368070483207702636718750000e+00;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 6.782173932405135552414776611840352416038513183593750000e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -6.589092811505605773447769024642184376716613769531250000e-01;
|
||||
a[2] = -1.179445664897062595599663836765103042125701904296875000e+00;
|
||||
a[3] = 4.243329729632123736848825501510873436927795410156250000e-01;
|
||||
a[4] = 4.147270002091348328754349950031610205769538879394531250e-01;
|
||||
break;
|
||||
|
||||
case 11025:
|
||||
b[0] = 6.002357155402652244546857218665536493062973022460937500e-01;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -1.200471431080530448909371443733107298612594604492187500e+00;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 6.002357155402652244546857218665536493062973022460937500e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -8.705602141280316397242700077185872942209243774414062500e-01;
|
||||
a[2] = -9.037199507150940336330791069485712796449661254882812500e-01;
|
||||
a[3] = 4.758433040929530011275971901341108605265617370605468750e-01;
|
||||
a[4] = 2.987653956523212417373258631414500996470451354980468750e-01;
|
||||
break;
|
||||
|
||||
case 16000:
|
||||
b[0] = 4.971057193673903418229542694461997598409652709960937500e-01;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -9.942114387347806836459085388923995196819305419921875000e-01;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 4.971057193673903418229542694461997598409652709960937500e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -1.162322939286873690889478893950581550598144531250000000e+00;
|
||||
a[2] = -4.771961355734982701548574368644040077924728393554687500e-01;
|
||||
a[3] = 4.736145114694704227886745684372726827859878540039062500e-01;
|
||||
a[4] = 1.660337524309875301131711466950946487486362457275390625e-01;
|
||||
break;
|
||||
|
||||
case 22050:
|
||||
b[0] = 4.033381299002754549754001800465630367398262023925781250e-01;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -8.066762598005509099508003600931260734796524047851562500e-01;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 4.033381299002754549754001800465630367398262023925781250e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -1.449545371157945350404361306573264300823211669921875000e+00;
|
||||
a[2] = -1.030104190885922088583015465701464563608169555664062500e-02;
|
||||
a[3] = 3.881857047554073680828423675848171114921569824218750000e-01;
|
||||
a[4] = 7.171589940116777917022972133054281584918498992919921875e-02;
|
||||
break;
|
||||
|
||||
case 24000:
|
||||
b[0] = 3.786678621924967069745093795063439756631851196289062500e-01;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -7.573357243849934139490187590126879513263702392578125000e-01;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 3.786678621924967069745093795063439756631851196289062500e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -1.529945307555420797029910318087786436080932617187500000e+00;
|
||||
a[2] = 1.283553182116208835061854642844991758465766906738281250e-01;
|
||||
a[3] = 3.494608072385725350272878131363540887832641601562500000e-01;
|
||||
a[4] = 5.217291949300089520802359288609295617789030075073242188e-02;
|
||||
break;
|
||||
|
||||
case 32000:
|
||||
b[0] = 2.977986488230693340462096330156782642006874084472656250e-01;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -5.955972976461386680924192660313565284013748168945312500e-01;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 2.977986488230693340462096330156782642006874084472656250e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -1.812455387128179218336754274787381291389465332031250000e+00;
|
||||
a[2] = 6.425013281155662614452239722595550119876861572265625000e-01;
|
||||
a[3] = 1.619857574578579817448087396769551560282707214355468750e-01;
|
||||
a[4] = 7.987649713547682189807019881300220731645822525024414062e-03;
|
||||
break;
|
||||
|
||||
case 44100:
|
||||
b[0] = 2.170085619492190254220531642204150557518005371093750000e-01;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -4.340171238984380508441063284408301115036010742187500000e-01;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 2.170085619492190254220531642204150557518005371093750000e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -2.134674963687040794013682898366823792457580566406250000e+00;
|
||||
a[2] = 1.279333533236062692139967111870646476745605468750000000e+00;
|
||||
a[3] = -1.495598460893957093453821016737492755055427551269531250e-01;
|
||||
a[4] = 4.908700174624683852664386307651511742733418941497802734e-03;
|
||||
break;
|
||||
|
||||
case 48000:
|
||||
b[0] = 1.978871200263932761398422144338837824761867523193359375e-01;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -3.957742400527865522796844288677675649523735046386718750e-01;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 1.978871200263932761398422144338837824761867523193359375e-01;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -2.219172914052801814932536217384040355682373046875000000e+00;
|
||||
a[2] = 1.455135878947171557129536267893854528665542602539062500e+00;
|
||||
a[3] = -2.484960738877830532800317087094299495220184326171875000e-01;
|
||||
a[4] = 1.253882314727246607977129144728678511455655097961425781e-02;
|
||||
break;
|
||||
|
||||
case 88200:
|
||||
b[0] = 9.221909851156021020734954163344809785485267639160156250e-02;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -1.844381970231204204146990832668961957097053527832031250e-01;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 9.221909851156021020734954163344809785485267639160156250e-02;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -2.785795902923448696952846148633398115634918212890625000e+00;
|
||||
a[2] = 2.727736758747444145711824603495188057422637939453125000e+00;
|
||||
a[3] = -1.097007502819661528548067508381791412830352783203125000e+00;
|
||||
a[4] = 1.550674356752141103132913713125162757933139801025390625e-01;
|
||||
break;
|
||||
|
||||
case 96000:
|
||||
b[0] = 8.182864044979756834585771230194950476288795471191406250e-02;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -1.636572808995951366917154246038990095257759094238281250e-01;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 8.182864044979756834585771230194950476288795471191406250e-02;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -2.856378516857566829401093855267390608787536621093750000e+00;
|
||||
a[2] = 2.897640237559524045707348705036565661430358886718750000e+00;
|
||||
a[3] = -1.225265958339703198376469117647502571344375610351562500e+00;
|
||||
a[4] = 1.840048283551226071530493300087982788681983947753906250e-01;
|
||||
break;
|
||||
|
||||
case 192000:
|
||||
b[0] = 2.784755468532278815940728122768632601946592330932617188e-02;
|
||||
b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[2] = -5.569510937064557631881456245537265203893184661865234375e-02;
|
||||
b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
|
||||
b[4] = 2.784755468532278815940728122768632601946592330932617188e-02;
|
||||
a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
|
||||
a[1] = -3.333298856144166322224009491037577390670776367187500000e+00;
|
||||
a[2] = 4.111467536240339448738723149290308356285095214843750000e+00;
|
||||
a[3] = -2.222889041651291641699117462849244475364685058593750000e+00;
|
||||
a[4] = 4.447204118126878991112960193277103826403617858886718750e-01;
|
||||
break;
|
||||
|
||||
default:
|
||||
AUBIO_ERROR ( "sampling rate of C-weighting filter is %d, should be one of\
|
||||
8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, 192000.\n",
|
||||
samplerate );
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
aubio_filter_t * new_aubio_filter_c_weighting (uint_t samplerate) {
|
||||
aubio_filter_t * f = new_aubio_filter(5);
|
||||
if (aubio_filter_set_c_weighting(f,samplerate) != AUBIO_OK) {
|
||||
del_aubio_filter(f);
|
||||
return NULL;
|
||||
}
|
||||
return f;
|
||||
}
|
88
deps/aubio/src/temporal/c_weighting.h
vendored
Normal file
88
deps/aubio/src/temporal/c_weighting.h
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_FILTER_C_DESIGN_H
|
||||
#define AUBIO_FILTER_C_DESIGN_H
|
||||
|
||||
/** \file
|
||||
|
||||
C-weighting filter coefficients
|
||||
|
||||
This file creates a C-weighting digital filter, which reduces low and high
|
||||
frequencies and enhance the middle ones to reflect the ability of the human
|
||||
hearing.
|
||||
|
||||
The implementation is based on the following standard:
|
||||
|
||||
- IEC/CD 1672: Electroacoustics-Sound Level Meters, IEC, Geneva, Nov. 1996,
|
||||
for A- and C-weighting filters.
|
||||
|
||||
See also:
|
||||
|
||||
- <a href="http://en.wikipedia.org/wiki/A-weighting">A-Weighting on
|
||||
Wikipedia</a>
|
||||
- <a href="http://en.wikipedia.org/wiki/Weighting_filter">Weighting filter on
|
||||
Wikipedia</a>
|
||||
- <a href="http://www.mathworks.com/matlabcentral/fileexchange/69">Christophe
|
||||
Couvreur's 'octave' toolbox</a>
|
||||
|
||||
The coefficients in this file have been computed using Christophe Couvreur's
|
||||
scripts in octave 3.0 (debian package 1:3.0.5-6+b2 with octave-signal
|
||||
1.0.9-1+b1 on i386), with <pre> [b, a] = cdsign(1/Fs) </pre> for various
|
||||
sampling frequencies (8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
|
||||
88200, 96000, and 192000 Hz).
|
||||
|
||||
The sampling frequency should normally be higher than 20kHz, but most common
|
||||
file sampling rates have been included for completeness.
|
||||
|
||||
\example temporal/test-c_weighting.c
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** create new C-design filter
|
||||
|
||||
\param samplerate sampling frequency of the signal to filter. Should be one of
|
||||
8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and
|
||||
192000 Hz
|
||||
|
||||
\return a new filter object
|
||||
|
||||
*/
|
||||
aubio_filter_t *new_aubio_filter_c_weighting (uint_t samplerate);
|
||||
|
||||
/** set feedback and feedforward coefficients of a C-weighting filter
|
||||
|
||||
\param f filter object to get coefficients from
|
||||
\param samplerate sampling frequency of the signal to filter. Should be one of
|
||||
8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and
|
||||
192000 Hz
|
||||
|
||||
*/
|
||||
uint_t aubio_filter_set_c_weighting (aubio_filter_t * f, uint_t samplerate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_FILTER_C_DESIGN_H */
|
163
deps/aubio/src/temporal/filter.c
vendored
Normal file
163
deps/aubio/src/temporal/filter.c
vendored
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* Requires lsmp_t to be long or double. float will NOT give reliable
|
||||
* results */
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "lvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "temporal/filter.h"
|
||||
|
||||
struct _aubio_filter_t
|
||||
{
|
||||
uint_t order;
|
||||
uint_t samplerate;
|
||||
lvec_t *a;
|
||||
lvec_t *b;
|
||||
lvec_t *y;
|
||||
lvec_t *x;
|
||||
};
|
||||
|
||||
void
|
||||
aubio_filter_do_outplace (aubio_filter_t * f, const fvec_t * in, fvec_t * out)
|
||||
{
|
||||
fvec_copy (in, out);
|
||||
aubio_filter_do (f, out);
|
||||
}
|
||||
|
||||
void
|
||||
aubio_filter_do (aubio_filter_t * f, fvec_t * in)
|
||||
{
|
||||
uint_t j, l, order = f->order;
|
||||
lsmp_t *x = f->x->data;
|
||||
lsmp_t *y = f->y->data;
|
||||
lsmp_t *a = f->a->data;
|
||||
lsmp_t *b = f->b->data;
|
||||
|
||||
for (j = 0; j < in->length; j++) {
|
||||
/* new input */
|
||||
x[0] = KILL_DENORMAL (in->data[j]);
|
||||
y[0] = b[0] * x[0];
|
||||
for (l = 1; l < order; l++) {
|
||||
y[0] += b[l] * x[l];
|
||||
y[0] -= a[l] * y[l];
|
||||
}
|
||||
/* new output */
|
||||
in->data[j] = y[0];
|
||||
/* store for next sample */
|
||||
for (l = order - 1; l > 0; l--) {
|
||||
x[l] = x[l - 1];
|
||||
y[l] = y[l - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The rough way: reset memory of filter between each run to avoid end effects. */
|
||||
void
|
||||
aubio_filter_do_filtfilt (aubio_filter_t * f, fvec_t * in, fvec_t * tmp)
|
||||
{
|
||||
uint_t j;
|
||||
uint_t length = in->length;
|
||||
/* apply filtering */
|
||||
aubio_filter_do (f, in);
|
||||
aubio_filter_do_reset (f);
|
||||
/* mirror */
|
||||
for (j = 0; j < length; j++)
|
||||
tmp->data[length - j - 1] = in->data[j];
|
||||
/* apply filtering on mirrored */
|
||||
aubio_filter_do (f, tmp);
|
||||
aubio_filter_do_reset (f);
|
||||
/* invert back */
|
||||
for (j = 0; j < length; j++)
|
||||
in->data[j] = tmp->data[length - j - 1];
|
||||
}
|
||||
|
||||
lvec_t *
|
||||
aubio_filter_get_feedback (const aubio_filter_t * f)
|
||||
{
|
||||
return f->a;
|
||||
}
|
||||
|
||||
lvec_t *
|
||||
aubio_filter_get_feedforward (const aubio_filter_t * f)
|
||||
{
|
||||
return f->b;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_filter_get_order (const aubio_filter_t * f)
|
||||
{
|
||||
return f->order;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_filter_get_samplerate (const aubio_filter_t * f)
|
||||
{
|
||||
return f->samplerate;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_filter_set_samplerate (aubio_filter_t * f, uint_t samplerate)
|
||||
{
|
||||
f->samplerate = samplerate;
|
||||
return AUBIO_OK;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_filter_do_reset (aubio_filter_t * f)
|
||||
{
|
||||
lvec_zeros (f->x);
|
||||
lvec_zeros (f->y);
|
||||
}
|
||||
|
||||
aubio_filter_t *
|
||||
new_aubio_filter (uint_t order)
|
||||
{
|
||||
aubio_filter_t *f = AUBIO_NEW (aubio_filter_t);
|
||||
if ((sint_t)order < 1) {
|
||||
AUBIO_FREE(f);
|
||||
return NULL;
|
||||
}
|
||||
f->x = new_lvec (order);
|
||||
f->y = new_lvec (order);
|
||||
f->a = new_lvec (order);
|
||||
f->b = new_lvec (order);
|
||||
/* by default, samplerate is not set */
|
||||
f->samplerate = 0;
|
||||
f->order = order;
|
||||
/* set default to identity */
|
||||
f->a->data[0] = 1.;
|
||||
f->b->data[0] = 1.;
|
||||
return f;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_filter (aubio_filter_t * f)
|
||||
{
|
||||
del_lvec (f->a);
|
||||
del_lvec (f->b);
|
||||
del_lvec (f->x);
|
||||
del_lvec (f->y);
|
||||
AUBIO_FREE (f);
|
||||
return;
|
||||
}
|
176
deps/aubio/src/temporal/filter.h
vendored
Normal file
176
deps/aubio/src/temporal/filter.h
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_FILTER_H
|
||||
#define AUBIO_FILTER_H
|
||||
|
||||
/** \file
|
||||
|
||||
Digital filter
|
||||
|
||||
This object stores a digital filter of order \f$n\f$.
|
||||
It contains the following data:
|
||||
- \f$ n*1 b_i \f$ feedforward coefficients
|
||||
- \f$ n*1 a_i \f$ feedback coefficients
|
||||
- \f$ n*c x_i \f$ input signal
|
||||
- \f$ n*c y_i \f$ output signal
|
||||
|
||||
For convenience, the samplerate of the input signal is also stored in the
|
||||
object.
|
||||
|
||||
Feedforward and feedback parameters can be modified using
|
||||
aubio_filter_get_feedback() and aubio_filter_get_feedforward().
|
||||
|
||||
The function aubio_filter_do_outplace() computes the following output signal
|
||||
\f$ y[n] \f$ from the input signal \f$ x[n] \f$:
|
||||
|
||||
\f{eqnarray*}{
|
||||
y[n] = b_0 x[n] & + & b_1 x[n-1] + b_2 x[n-2] + ... + b_P x[n-P] \\
|
||||
& - & a_1 y[n-1] - a_2 y[n-2] - ... - a_P y[n-P] \\
|
||||
\f}
|
||||
|
||||
The function aubio_filter_do() executes the same computation but modifies
|
||||
directly the input signal (in-place).
|
||||
|
||||
The function aubio_filter_do_filtfilt() version runs the filter twice, first
|
||||
forward then backward, to compensate with the phase shifting of the forward
|
||||
operation.
|
||||
|
||||
Some convenience functions are provided:
|
||||
- new_aubio_filter_a_weighting() and aubio_filter_set_a_weighting(),
|
||||
- new_aubio_filter_c_weighting() and aubio_filter_set_c_weighting().
|
||||
- new_aubio_filter_biquad() and aubio_filter_set_biquad().
|
||||
|
||||
\example temporal/test-filter.c
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Digital filter
|
||||
|
||||
*/
|
||||
typedef struct _aubio_filter_t aubio_filter_t;
|
||||
|
||||
/** filter input vector (in-place)
|
||||
|
||||
\param f filter object as returned by new_aubio_filter()
|
||||
\param in input vector to filter
|
||||
|
||||
*/
|
||||
void aubio_filter_do (aubio_filter_t * f, fvec_t * in);
|
||||
|
||||
/** filter input vector (out-of-place)
|
||||
|
||||
\param f filter object as returned by new_aubio_filter()
|
||||
\param in input vector to filter
|
||||
\param out output vector to store filtered input
|
||||
|
||||
*/
|
||||
void aubio_filter_do_outplace (aubio_filter_t * f, const fvec_t * in, fvec_t * out);
|
||||
|
||||
/** filter input vector forward and backward
|
||||
|
||||
\param f ::aubio_filter_t object as returned by new_aubio_filter()
|
||||
\param in ::fvec_t input vector to filter
|
||||
\param tmp memory space to use for computation
|
||||
|
||||
*/
|
||||
void aubio_filter_do_filtfilt (aubio_filter_t * f, fvec_t * in, fvec_t * tmp);
|
||||
|
||||
/** returns a pointer to feedback coefficients \f$ a_i \f$
|
||||
|
||||
\param f filter object to get parameters from
|
||||
|
||||
\return a pointer to the \f$ a_0 ... a_i ... a_P \f$ coefficients
|
||||
|
||||
*/
|
||||
lvec_t *aubio_filter_get_feedback (const aubio_filter_t * f);
|
||||
|
||||
/** returns a pointer to feedforward coefficients \f$ b_i \f$
|
||||
|
||||
\param f filter object to get coefficients from
|
||||
|
||||
\return a pointer to the \f$ b_0 ... b_i ... b_P \f$ coefficients
|
||||
|
||||
*/
|
||||
lvec_t *aubio_filter_get_feedforward (const aubio_filter_t * f);
|
||||
|
||||
/** get order of the filter
|
||||
|
||||
\param f filter to get order from
|
||||
|
||||
\return the order of the filter
|
||||
|
||||
*/
|
||||
uint_t aubio_filter_get_order (const aubio_filter_t * f);
|
||||
|
||||
/** get sampling rate of the filter
|
||||
|
||||
\param f filter to get sampling rate from
|
||||
|
||||
\return the sampling rate of the filter, in Hz
|
||||
|
||||
*/
|
||||
uint_t aubio_filter_get_samplerate (const aubio_filter_t * f);
|
||||
|
||||
/** get sampling rate of the filter
|
||||
|
||||
\param f filter to get sampling rate from
|
||||
\param samplerate sample rate to set the filter to
|
||||
|
||||
\return the sampling rate of the filter, in Hz
|
||||
|
||||
*/
|
||||
uint_t aubio_filter_set_samplerate (aubio_filter_t * f, uint_t samplerate);
|
||||
|
||||
/** reset filter memory
|
||||
|
||||
\param f filter object as returned by new_aubio_filter()
|
||||
|
||||
*/
|
||||
void aubio_filter_do_reset (aubio_filter_t * f);
|
||||
|
||||
/** create new filter object
|
||||
|
||||
This function creates a new ::aubio_filter_t object, given the order of the
|
||||
filter.
|
||||
|
||||
\param order order of the filter (number of coefficients)
|
||||
|
||||
\return the newly created filter object
|
||||
|
||||
*/
|
||||
aubio_filter_t *new_aubio_filter (uint_t order);
|
||||
|
||||
/** delete a filter object
|
||||
|
||||
\param f filter object to delete
|
||||
|
||||
*/
|
||||
void del_aubio_filter (aubio_filter_t * f);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_FILTER_H */
|
100
deps/aubio/src/temporal/resampler.c
vendored
Normal file
100
deps/aubio/src/temporal/resampler.c
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "temporal/resampler.h"
|
||||
|
||||
#ifdef HAVE_SAMPLERATE
|
||||
|
||||
#if HAVE_AUBIO_DOUBLE
|
||||
#error "Should not use libsamplerate with aubio in double precision"
|
||||
#endif
|
||||
|
||||
#include <samplerate.h> /* from libsamplerate */
|
||||
|
||||
struct _aubio_resampler_t
|
||||
{
|
||||
SRC_DATA *proc;
|
||||
SRC_STATE *stat;
|
||||
smpl_t ratio;
|
||||
uint_t type;
|
||||
};
|
||||
|
||||
aubio_resampler_t *
|
||||
new_aubio_resampler (smpl_t ratio, uint_t type)
|
||||
{
|
||||
aubio_resampler_t *s = AUBIO_NEW (aubio_resampler_t);
|
||||
int error = 0;
|
||||
s->stat = src_new (type, 1, &error); /* only one channel */
|
||||
if (error) {
|
||||
AUBIO_ERR ("Failed creating resampler: %s\n", src_strerror (error));
|
||||
del_aubio_resampler(s);
|
||||
return NULL;
|
||||
}
|
||||
s->proc = AUBIO_NEW (SRC_DATA);
|
||||
s->ratio = ratio;
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_resampler (aubio_resampler_t * s)
|
||||
{
|
||||
if (s->stat) src_delete (s->stat);
|
||||
AUBIO_FREE (s->proc);
|
||||
AUBIO_FREE (s);
|
||||
}
|
||||
|
||||
void
|
||||
aubio_resampler_do (aubio_resampler_t * s, const fvec_t * input, fvec_t * output)
|
||||
{
|
||||
s->proc->input_frames = input->length;
|
||||
s->proc->output_frames = output->length;
|
||||
s->proc->src_ratio = (double) s->ratio;
|
||||
/* make SRC_PROC data point to input outputs */
|
||||
s->proc->data_in = (float *) input->data;
|
||||
s->proc->data_out = (float *) output->data;
|
||||
/* do resampling */
|
||||
src_process (s->stat, s->proc);
|
||||
}
|
||||
|
||||
#else
|
||||
struct _aubio_resampler_t
|
||||
{
|
||||
void *dummy;
|
||||
};
|
||||
|
||||
aubio_resampler_t *
|
||||
new_aubio_resampler (smpl_t ratio UNUSED, uint_t type UNUSED)
|
||||
{
|
||||
AUBIO_ERR ("aubio was not compiled with libsamplerate\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_resampler (aubio_resampler_t * s UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
aubio_resampler_do (aubio_resampler_t * s UNUSED, const fvec_t * input UNUSED, fvec_t * output UNUSED)
|
||||
{
|
||||
}
|
||||
#endif /* HAVE_SAMPLERATE */
|
65
deps/aubio/src/temporal/resampler.h
vendored
Normal file
65
deps/aubio/src/temporal/resampler.h
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_RESAMPLER_H
|
||||
#define AUBIO_RESAMPLER_H
|
||||
|
||||
/** \file
|
||||
|
||||
Resampling object
|
||||
|
||||
This object resamples an input vector into an output vector using
|
||||
libsamplerate. See http://www.mega-nerd.com/SRC/
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** resampler object */
|
||||
typedef struct _aubio_resampler_t aubio_resampler_t;
|
||||
|
||||
/** create resampler object
|
||||
|
||||
\param ratio output_sample_rate / input_sample_rate
|
||||
\param type libsamplerate resampling type, see http://www.mega-nerd.com/SRC/api_misc.html#Converters
|
||||
|
||||
*/
|
||||
aubio_resampler_t *new_aubio_resampler (smpl_t ratio, uint_t type);
|
||||
|
||||
/** delete resampler object */
|
||||
void del_aubio_resampler (aubio_resampler_t * s);
|
||||
|
||||
/** resample input in output
|
||||
|
||||
\param s resampler object
|
||||
\param input input buffer of size N
|
||||
\param output output buffer of size N*ratio
|
||||
|
||||
*/
|
||||
void aubio_resampler_do (aubio_resampler_t * s, const fvec_t * input,
|
||||
fvec_t * output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_RESAMPLER_H */
|
70
deps/aubio/src/types.h
vendored
Normal file
70
deps/aubio/src/types.h
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_TYPES_H
|
||||
#define AUBIO_TYPES_H
|
||||
|
||||
/** \file
|
||||
|
||||
Definition of data types used in aubio
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_AUBIO_DOUBLE
|
||||
/** defined to 1 if aubio is compiled in double precision */
|
||||
#define HAVE_AUBIO_DOUBLE 0
|
||||
#endif
|
||||
|
||||
/** short sample format (32 or 64 bits) */
|
||||
#if !HAVE_AUBIO_DOUBLE
|
||||
typedef float smpl_t;
|
||||
/** print format for sample in single precision */
|
||||
#define AUBIO_SMPL_FMT "%f"
|
||||
#else
|
||||
typedef double smpl_t;
|
||||
/** print format for double in single precision */
|
||||
#define AUBIO_SMPL_FMT "%lf"
|
||||
#endif
|
||||
/** long sample format (64 bits or more) */
|
||||
#if !HAVE_AUBIO_DOUBLE
|
||||
typedef double lsmp_t;
|
||||
/** print format for sample in double precision */
|
||||
#define AUBIO_LSMP_FMT "%lf"
|
||||
#else
|
||||
typedef long double lsmp_t;
|
||||
/** print format for double in double precision */
|
||||
#define AUBIO_LSMP_FMT "%Lf"
|
||||
#endif
|
||||
/** unsigned integer */
|
||||
typedef unsigned int uint_t;
|
||||
/** signed integer */
|
||||
typedef int sint_t;
|
||||
/** character */
|
||||
typedef char char_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_TYPES_H */
|
92
deps/aubio/src/utils/log.c
vendored
Normal file
92
deps/aubio/src/utils/log.c
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
Copyright (C) 2016 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "log.h"
|
||||
|
||||
/** array of pointers to logging functions, one per level */
|
||||
static aubio_log_function_t aubio_log_function[AUBIO_LOG_LAST_LEVEL];
|
||||
/** array of pointers to closure passed to logging functions, one per level */
|
||||
static void* aubio_log_user_data[AUBIO_LOG_LAST_LEVEL];
|
||||
/** buffer for logging messages */
|
||||
static char aubio_log_buffer[512];
|
||||
|
||||
/** private function used by default by logging functions */
|
||||
void
|
||||
aubio_default_log(sint_t level, const char_t *message, void * data UNUSED)
|
||||
{
|
||||
FILE *out;
|
||||
out = stdout;
|
||||
if (level == AUBIO_LOG_ERR || level == AUBIO_LOG_DBG || level == AUBIO_LOG_WRN) {
|
||||
out = stderr;
|
||||
}
|
||||
fprintf(out, "%s", message);
|
||||
//fflush(out);
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_log(sint_t level, const char_t *fmt, ...)
|
||||
{
|
||||
aubio_log_function_t fun = NULL;
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(aubio_log_buffer, sizeof(aubio_log_buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if ((level >= 0) && (level < AUBIO_LOG_LAST_LEVEL)) {
|
||||
fun = aubio_log_function[level];
|
||||
if (fun != NULL) {
|
||||
(*fun)(level, aubio_log_buffer, aubio_log_user_data[level]);
|
||||
} else {
|
||||
aubio_default_log(level, aubio_log_buffer, NULL);
|
||||
}
|
||||
}
|
||||
return AUBIO_FAIL;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_log_reset(void)
|
||||
{
|
||||
uint_t i = 0;
|
||||
for (i = 0; i < AUBIO_LOG_LAST_LEVEL; i++) {
|
||||
aubio_log_set_level_function(i, aubio_default_log, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
aubio_log_function_t
|
||||
aubio_log_set_level_function(sint_t level, aubio_log_function_t fun, void * data)
|
||||
{
|
||||
aubio_log_function_t old = NULL;
|
||||
if ((level >= 0) && (level < AUBIO_LOG_LAST_LEVEL)) {
|
||||
old = aubio_log_function[level];
|
||||
aubio_log_function[level] = fun;
|
||||
aubio_log_user_data[level] = data;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_log_set_function(aubio_log_function_t fun, void * data) {
|
||||
uint_t i = 0;
|
||||
for (i = 0; i < AUBIO_LOG_LAST_LEVEL; i++) {
|
||||
aubio_log_set_level_function(i, fun, data);
|
||||
}
|
||||
}
|
99
deps/aubio/src/utils/log.h
vendored
Normal file
99
deps/aubio/src/utils/log.h
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Copyright (C) 2016 Paul Brossier <piem@aubio.org>
|
||||
|
||||
This file is part of aubio.
|
||||
|
||||
aubio 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
aubio 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with aubio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_LOG_H
|
||||
#define AUBIO_LOG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file
|
||||
|
||||
Logging features
|
||||
|
||||
This file specifies ::aubio_log_set_function and
|
||||
::aubio_log_set_level_function, which let you define one or several custom
|
||||
logging functions to redirect warnings and errors from aubio to your
|
||||
application. The custom function should have the prototype defined in
|
||||
::aubio_log_function_t.
|
||||
|
||||
After a call to ::aubio_log_set_level_function, ::aubio_log_reset can be used
|
||||
to reset each logging functions to the default ones.
|
||||
|
||||
\example utils/test-log.c
|
||||
|
||||
*/
|
||||
|
||||
/** list of logging levels */
|
||||
enum aubio_log_level {
|
||||
AUBIO_LOG_ERR, /**< critical errors */
|
||||
AUBIO_LOG_INF, /**< infos */
|
||||
AUBIO_LOG_MSG, /**< general messages */
|
||||
AUBIO_LOG_DBG, /**< debug messages */
|
||||
AUBIO_LOG_WRN, /**< warnings */
|
||||
AUBIO_LOG_LAST_LEVEL, /**< number of valid levels */
|
||||
};
|
||||
|
||||
/** Logging function prototype, to be passed to ::aubio_log_set_function
|
||||
|
||||
\param level log level
|
||||
\param message text to log
|
||||
\param data optional closure used by the callback
|
||||
|
||||
See @ref utils/test-log.c for an example of logging function.
|
||||
|
||||
*/
|
||||
typedef void (*aubio_log_function_t)(sint_t level, const char_t *message, void
|
||||
*data);
|
||||
|
||||
/** Set logging function for all levels
|
||||
|
||||
\param fun the function to be used to log, of type ::aubio_log_function_t
|
||||
\param data optional closure to be passed to the function (can be NULL if
|
||||
nothing to pass)
|
||||
|
||||
*/
|
||||
void aubio_log_set_function(aubio_log_function_t fun, void* data);
|
||||
|
||||
/** Set logging function for a given level
|
||||
|
||||
\param level the level for which to set the logging function
|
||||
\param fun the function to be used to log, of type ::aubio_log_function_t
|
||||
\param data optional closure to be passed to the function (can be NULL if
|
||||
nothing to pass)
|
||||
|
||||
*/
|
||||
aubio_log_function_t aubio_log_set_level_function(sint_t level,
|
||||
aubio_log_function_t fun, void* data);
|
||||
|
||||
/** Reset all logging functions to the default one
|
||||
|
||||
After calling this function, the default logging function will be used to
|
||||
print error, warning, normal, and debug messages to `stdout` or `stderr`.
|
||||
|
||||
*/
|
||||
void aubio_log_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_LOG_H */
|
Loading…
Add table
Add a link
Reference in a new issue