diff options
author | Jamie Bullock <jamie@jamiebullock.com> | 2013-01-07 16:27:15 +0000 |
---|---|---|
committer | Jamie Bullock <jamie@jamiebullock.com> | 2013-01-07 16:39:29 +0000 |
commit | 144e7f8668166ee1779ad304cc5ac94d8e525529 (patch) | |
tree | 089b2bbbcf15ee8bdde390a4d270e4812e7e2228 | |
parent | 0f46938156dedf13032bdb1fc914a63d46bae558 (diff) | |
download | LibXtract-144e7f8668166ee1779ad304cc5ac94d8e525529.tar.gz LibXtract-144e7f8668166ee1779ad304cc5ac94d8e525529.tar.bz2 LibXtract-144e7f8668166ee1779ad304cc5ac94d8e525529.zip |
added Ooura implementation to repository
-rwxr-xr-x | autogen.sh | 2 | ||||
-rw-r--r-- | configure.ac | 59 | ||||
-rw-r--r-- | doc/documentation.doxygen.in | 2 | ||||
-rw-r--r-- | examples/simpletest/simpletest.c | 4 | ||||
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/delta.c | 41 | ||||
-rw-r--r-- | src/descriptors.c | 2356 | ||||
-rw-r--r-- | src/fftsg.c | 3492 | ||||
-rw-r--r-- | src/fftsg.h | 21 | ||||
-rw-r--r-- | src/fini.c | 11 | ||||
-rw-r--r-- | src/helper.c | 18 | ||||
-rw-r--r-- | src/init.c | 281 | ||||
-rw-r--r-- | src/libxtract.c | 7 | ||||
-rw-r--r-- | src/scalar.c | 572 | ||||
-rw-r--r-- | src/vector.c | 467 | ||||
-rw-r--r-- | src/window.c | 101 | ||||
-rw-r--r-- | src/xtract_globals_private.h | 24 | ||||
-rw-r--r-- | swig/java/Makefile.am | 3 | ||||
-rw-r--r-- | swig/java/SWIG.java | 16 | ||||
-rw-r--r-- | xtract/xtract_helper.h | 5 |
20 files changed, 5552 insertions, 1938 deletions
@@ -12,7 +12,7 @@ case `uname -s` in ;; Darwin) LIBTOOLIZE=glibtoolize - ACLOCALARGS='-I /usr/share/aclocal -I m4' + ACLOCALARGS='-I m4' ;; *) echo error: unrecognized OS exit 1 diff --git a/configure.ac b/configure.ac index fe3ae64..be8e0b5 100644 --- a/configure.ac +++ b/configure.ac @@ -2,9 +2,9 @@ AC_PREREQ(2.13) # Increment for major API changes, release status changes m4_define(libxtract_major_version, 0) # Increment for feature additions and enhancements -m4_define(libxtract_minor_version, 6) +m4_define(libxtract_minor_version, 7) # Increment for fixes -m4_define(libxtract_fix_version, 6) +m4_define(libxtract_fix_version, 0) # Development status m4_define(libIntegra_dev_status, [beta]) @@ -14,7 +14,6 @@ PACKAGE=libxtract AC_INIT([libxtract], [libxtract_version], [libxtract-devel@lists.sourceforge.net]) AC_DEFINE(LIBXTRACT_VERSION, libxtract_version, [LibXtract Version]) -dnl AM_INIT_AUTOMAKE($PACKAGE, $LIBXTRACT_VERSION) AM_INIT_AUTOMAKE(1.6) AM_CONFIG_HEADER(config.h) AC_CONFIG_MACRO_DIR([m4]) @@ -30,14 +29,6 @@ AC_CHECK_HEADERS([math.h, stdlib.h, stdio.h]) AC_CHECK_PROG([DOXYGEN], [doxygen], [doc], []) AC_SUBST(DOXYGEN) -AC_ARG_ENABLE(fft, - [ --enable-fft Turn fft-based fft processing on], - [case "${enableval}" in - yes) fft=true ;; - no) fft=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-fft) ;; - esac],[fft=false]) - AC_ARG_ENABLE(pd_example, [ --enable-pd_example Compile the Pure Data external example], [case "${enableval}" in @@ -81,25 +72,6 @@ AC_ARG_WITH(pd_dir, echo ]) -AC_ARG_WITH(fftw3_dir, - [ --with-fftw3-dir=path fftw3 header path (default=/usr/local/include) ], - [ - CFLAGS="$CFLAGS -I$withval" - echo - echo "fftw3 dir is $withval" - echo - ]) - -dnl Set FFT optimisation level -AC_ARG_WITH(fft_optimisation, - [ --with-fft_optimisation=level set fft optimistaion level (default=1)], - [ - FFT_OPTIMISATION="$withval" - echo - echo "fft optimisation level is $withval" - echo - ]) - dnl set a specific java compiler AC_ARG_WITH(javac, [ --with-javac=compiler set a specific java compiler (determined automatically if not set) ], @@ -199,28 +171,6 @@ if [[ "$swig" = "true" ]] ; then AC_DEFINE([BUILD_SWIG], [1], [Build the swig bindings]) fi -dnl Are we building with fftw? -if [[ "$fft" = "true" ]] ; then - LDFLAGS="$LDFLAGS -lfftw3f" - AC_DEFINE([BUILD_FFT], [1], [Build the fft functions]) - if test "$FFT_OPTIMISATION" = "" - then - AC_DEFINE([XTRACT_FFT_OPTIMISATION_LEVEL], [1], [fft optimisation 1]) - else - # AC_SUBST(OPTIMISATION_LEVEL, "$FFT_OPTIMISATION") - AC_DEFINE_UNQUOTED(XTRACT_FFT_OPTIMISATION_LEVEL, ${FFT_OPTIMISATION}) - fi - AC_CHECK_HEADER(fftw3.h, [have_fftw3_hdr=yes ], [ - have_pd_hdr=no - echo - echo "no fftw3.h header found. try with option --with-fftw3-dir=/path/to/fftw3/header" - echo - exit - ]) -fi - -AM_CONDITIONAL(BUILD_FFT, test "x${fft}" = 'xtrue') - dnl Check for architecture endian-ness #AC_C_BIGENDIAN(bigendian=true, bigendian=false, bigendian=undefined) #if [[ "$is_bigendian" = "false" ]] ; then @@ -317,11 +267,6 @@ echo "Summary:" echo dnl echo you are using the ${host} architecture -if test "$fft" = "true"; then - echo "fft: yes (using fftw3f)" -else - echo "fft: no (not using fftw3, no fft functions)" -fi if test "$simpletest" = "true"; then echo "simpletest example: yes" else diff --git a/doc/documentation.doxygen.in b/doc/documentation.doxygen.in index 89dfa5a..6e4d48c 100644 --- a/doc/documentation.doxygen.in +++ b/doc/documentation.doxygen.in @@ -1055,7 +1055,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = XTRACT_FFT +PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/examples/simpletest/simpletest.c b/examples/simpletest/simpletest.c index a5380be..f4acd95 100644 --- a/examples/simpletest/simpletest.c +++ b/examples/simpletest/simpletest.c @@ -53,8 +53,8 @@ int main(void) /* get the spectrum */ argf[0] = SAMPLERATE / (float)BLOCKSIZE; argf[1] = XTRACT_MAGNITUDE_SPECTRUM; - argf[2] = 0.f; - argf[3] = 0.f; + argf[2] = 0.f; /* No DC component */ + argf[3] = 0.f; /* No Normalisation */ xtract_init_fft(BLOCKSIZE, XTRACT_SPECTRUM); xtract[XTRACT_SPECTRUM]((void *)&input, BLOCKSIZE, &argf[0], (void *)&spectrum[0]); diff --git a/src/Makefile.am b/src/Makefile.am index 7092ff6..d768d2d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,13 +1,7 @@ MAINTAINERCLEANFILES = Makefile.in SOURCES = libxtract.c descriptors.c scalar.c vector.c delta.c init.c\ - window.c fini.c helper.c - -if BUILD_FFT -FFT_DEFINE = -DXTRACT_FFT -else -FFT_DEFINE = -endif + window.c fini.c helper.c fftsg.c lib_LTLIBRARIES = libxtract.la libxtract_la_CFLAGS = $(FFT_DEFINE) diff --git a/src/delta.c b/src/delta.c index b1effd0..9620294 100644 --- a/src/delta.c +++ b/src/delta.c @@ -1,5 +1,5 @@ /* libxtract feature extraction library - * + * * Copyright (C) 2006 Jamie Bullock * * This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ @@ -24,14 +24,16 @@ #include "xtract/libxtract.h" -int xtract_flux(const float *data, const int N, const void *argv , float *result){ +int xtract_flux(const float *data, const int N, const void *argv , float *result) +{ /* FIX: don't be lazy -- take the lnorm of the difference vector! */ return xtract_lnorm(data, N, argv, result); } -int xtract_lnorm(const float *data, const int N, const void *argv , float *result){ +int xtract_lnorm(const float *data, const int N, const void *argv , float *result) +{ int n, type; @@ -45,18 +47,20 @@ int xtract_lnorm(const float *data, const int N, const void *argv , float *resul *result = 0.f; - switch(type){ + switch(type) + { - case XTRACT_POSITIVE_SLOPE: - for(n = 0; n < N; n++){ - if(data[n] > 0) - *result += powf(data[n], order); - } - break; - default: - for(n = 0; n < N; n++) + case XTRACT_POSITIVE_SLOPE: + for(n = 0; n < N; n++) + { + if(data[n] > 0) *result += powf(data[n], order); - break; + } + break; + default: + for(n = 0; n < N; n++) + *result += powf(data[n], order); + break; } @@ -66,19 +70,22 @@ int xtract_lnorm(const float *data, const int N, const void *argv , float *resul } -int xtract_attack_time(const float *data, const int N, const void *argv , float *result){ +int xtract_attack_time(const float *data, const int N, const void *argv , float *result) +{ return XTRACT_FEATURE_NOT_IMPLEMENTED; } -int xtract_decay_time(const float *data, const int N, const void *argv, float *result){ +int xtract_decay_time(const float *data, const int N, const void *argv, float *result) +{ return XTRACT_FEATURE_NOT_IMPLEMENTED; } -int xtract_difference_vector(const float *data, const int N, const void *argv, float *result){ +int xtract_difference_vector(const float *data, const int N, const void *argv, float *result) +{ const float *frame1, *frame2; diff --git a/src/descriptors.c b/src/descriptors.c index 892a899..1072d42 100644 --- a/src/descriptors.c +++ b/src/descriptors.c @@ -1,5 +1,5 @@ /* libxtract feature extraction library - * + * * Copyright (C) 2006 Jamie Bullock * * This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ @@ -24,13 +24,14 @@ #include <string.h> #define XTRACT -xtract_function_descriptor_t *xtract_make_descriptors(void){ +xtract_function_descriptor_t *xtract_make_descriptors(void) +{ int f , F; - char *name, *p_name, *desc, *p_desc, *author; + char *name, *p_name, *desc, *p_desc, *author; float *argv_min, *argv_max, *argv_def, *result_min, *result_max; int *argc, *year, *argv_donor; - xtract_vector_t *data_format, *result_format; + xtract_vector_t *data_format, *result_format; xtract_unit_t *data_unit, *argv_unit, *result_unit; xtract_bool_t *is_scalar, *is_delta; xtract_function_descriptor_t *fd, *d; @@ -42,7 +43,8 @@ xtract_function_descriptor_t *xtract_make_descriptors(void){ /* FIX - this file probably needs a rewrite for readability */ - while(f--){ + while(f--) + { d = &fd[f]; d->id = f; @@ -54,396 +56,400 @@ xtract_function_descriptor_t *xtract_make_descriptors(void){ argv_def = &d->argv.def[0]; argv_unit = &d->argv.unit[0]; - switch (f) { + switch (f) + { /* argc = 1 */ - case XTRACT_VARIANCE: - case XTRACT_SPECTRAL_VARIANCE: - case XTRACT_STANDARD_DEVIATION: - case XTRACT_DIFFERENCE_VECTOR: - case XTRACT_AVERAGE_DEVIATION: - case XTRACT_SPECTRAL_STANDARD_DEVIATION: + case XTRACT_VARIANCE: + case XTRACT_SPECTRAL_VARIANCE: + case XTRACT_STANDARD_DEVIATION: + case XTRACT_DIFFERENCE_VECTOR: + case XTRACT_AVERAGE_DEVIATION: + case XTRACT_SPECTRAL_STANDARD_DEVIATION: /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ - case XTRACT_LOWEST_VALUE: - case XTRACT_TONALITY: - case XTRACT_MFCC: - case XTRACT_LPC: - case XTRACT_LPCC: - *argv_min = XTRACT_ANY; - *argv_max = XTRACT_ANY; - *argv_def = XTRACT_ANY; - *argv_unit = XTRACT_DBFS; - break; - case XTRACT_SPECTRAL_INHARMONICITY: - *argv_min = 0.f; - *argv_max = XTRACT_SR_UPPER_LIMIT / 2; - *argv_def = XTRACT_FUNDAMENTAL_DEFAULT; - *argv_unit = XTRACT_HERTZ; - break; - case XTRACT_F0: - case XTRACT_FAILSAFE_F0: - *argv_min = XTRACT_SR_LOWER_LIMIT; - *argv_max = XTRACT_SR_UPPER_LIMIT; - *argv_def = XTRACT_SR_DEFAULT; - *argv_unit = XTRACT_HERTZ; - break; - case XTRACT_FLATNESS_DB: - *argv_min = 0; - *argv_max = 1.0; - *argv_def = XTRACT_ANY; - *argv_unit = XTRACT_DBFS; - break; + case XTRACT_LOWEST_VALUE: + case XTRACT_TONALITY: + case XTRACT_MFCC: + case XTRACT_LPC: + case XTRACT_LPCC: + *argv_min = XTRACT_ANY; + *argv_max = XTRACT_ANY; + *argv_def = XTRACT_ANY; + *argv_unit = XTRACT_DBFS; + break; + case XTRACT_SPECTRAL_INHARMONICITY: + *argv_min = 0.f; + *argv_max = XTRACT_SR_UPPER_LIMIT / 2; + *argv_def = XTRACT_FUNDAMENTAL_DEFAULT; + *argv_unit = XTRACT_HERTZ; + break; + case XTRACT_F0: + case XTRACT_FAILSAFE_F0: + *argv_min = XTRACT_SR_LOWER_LIMIT; + *argv_max = XTRACT_SR_UPPER_LIMIT; + *argv_def = XTRACT_SR_DEFAULT; + *argv_unit = XTRACT_HERTZ; + break; + case XTRACT_FLATNESS_DB: + *argv_min = 0; + *argv_max = 1.0; + *argv_def = XTRACT_ANY; + *argv_unit = XTRACT_DBFS; + break; /* argc = 2 */; - case XTRACT_ROLLOFF: - *argv_min = XTRACT_FFT_BANDS_MIN; - *argv_max = XTRACT_FFT_BANDS_MAX; - *argv_def = XTRACT_SPEC_BW_DEF ; - *argv_unit = XTRACT_HERTZ; - *(argv_min + 1) = 0.f; - *(argv_max + 1) = 100.f; - *(argv_def + 1) = 95.f; - *(argv_unit + 1) = XTRACT_PERCENT; - break; - case XTRACT_PEAK_SPECTRUM: - *argv_min = XTRACT_SR_LOWER_LIMIT / 2; - *argv_max = XTRACT_SR_UPPER_LIMIT / 2; - *argv_def = XTRACT_SR_DEFAULT / 2; - *argv_unit = XTRACT_HERTZ; - *(argv_min + 1) = 0.f; - *(argv_max + 1) = 100.f ; - *(argv_def + 1) = 10.f ; - *(argv_unit + 1) = XTRACT_PERCENT; - break; - case XTRACT_HARMONIC_SPECTRUM: - *argv_min = 0.f; - *argv_max = XTRACT_SR_UPPER_LIMIT / 2; - *argv_def = XTRACT_FUNDAMENTAL_DEFAULT; - *argv_unit = XTRACT_HERTZ; - *(argv_min + 1) = 0.f; - *(argv_max + 1) = 1.f ; - *(argv_def + 1) = .1f ; - *(argv_unit + 1) = XTRACT_NONE; - break; - case XTRACT_NOISINESS: - case XTRACT_SKEWNESS: - case XTRACT_KURTOSIS: - case XTRACT_SPECTRAL_SKEWNESS: - case XTRACT_SPECTRAL_KURTOSIS: - case XTRACT_CREST: - *argv_min = XTRACT_NONE; - *argv_max = XTRACT_NONE; - *argv_def = XTRACT_NONE; - *argv_unit = XTRACT_NONE; - *(argv_min + 1) = XTRACT_NONE; - *(argv_max + 1) = XTRACT_NONE; - *(argv_def + 1) = XTRACT_NONE; - *(argv_unit + 1) = XTRACT_NONE; - break; + case XTRACT_ROLLOFF: + *argv_min = XTRACT_FFT_BANDS_MIN; + *argv_max = XTRACT_FFT_BANDS_MAX; + *argv_def = XTRACT_SPEC_BW_DEF ; + *argv_unit = XTRACT_HERTZ; + *(argv_min + 1) = 0.f; + *(argv_max + 1) = 100.f; + *(argv_def + 1) = 95.f; + *(argv_unit + 1) = XTRACT_PERCENT; + break; + case XTRACT_PEAK_SPECTRUM: + *argv_min = XTRACT_SR_LOWER_LIMIT / 2; + *argv_max = XTRACT_SR_UPPER_LIMIT / 2; + *argv_def = XTRACT_SR_DEFAULT / 2; + *argv_unit = XTRACT_HERTZ; + *(argv_min + 1) = 0.f; + *(argv_max + 1) = 100.f ; + *(argv_def + 1) = 10.f ; + *(argv_unit + 1) = XTRACT_PERCENT; + break; + case XTRACT_HARMONIC_SPECTRUM: + *argv_min = 0.f; + *argv_max = XTRACT_SR_UPPER_LIMIT / 2; + *argv_def = XTRACT_FUNDAMENTAL_DEFAULT; + *argv_unit = XTRACT_HERTZ; + *(argv_min + 1) = 0.f; + *(argv_max + 1) = 1.f ; + *(argv_def + 1) = .1f ; + *(argv_unit + 1) = XTRACT_NONE; + break; + case XTRACT_NOISINESS: + case XTRACT_SKEWNESS: + case XTRACT_KURTOSIS: + case XTRACT_SPECTRAL_SKEWNESS: + case XTRACT_SPECTRAL_KURTOSIS: + case XTRACT_CREST: + *argv_min = XTRACT_NONE; + *argv_max = XTRACT_NONE; + *argv_def = XTRACT_NONE; + *argv_unit = XTRACT_NONE; + *(argv_min + 1) = XTRACT_NONE; + *(argv_max + 1) = XTRACT_NONE; + *(argv_def + 1) = XTRACT_NONE; + *(argv_unit + 1) = XTRACT_NONE; + break; /* argc = 4 */ - case XTRACT_SPECTRUM: - *argv_min = XTRACT_SR_LOWER_LIMIT / XTRACT_FFT_BANDS_MIN; - *argv_max = XTRACT_SR_UPPER_LIMIT / XTRACT_FFT_BANDS_MAX; - *argv_def = XTRACT_SR_DEFAULT / XTRACT_FFT_BANDS_DEF; - *argv_unit = XTRACT_HERTZ; - *(argv_min + 1) = 0; - *(argv_max + 1) = 3 ; - *(argv_def + 1) = 0; - *(argv_unit + 1) = XTRACT_NONE; - *(argv_min + 2) = 0; - *(argv_max + 2) = 1; - *(argv_def + 2) = 0; - *(argv_unit + 2) = XTRACT_NONE; - *(argv_min + 3) = 0; - *(argv_max + 3) = 1; - *(argv_def + 3) = 0; - *(argv_unit + 3) = XTRACT_NONE; - break; - case XTRACT_SUBBANDS: - *argv_min = XTRACT_ANY; - *argv_max = XTRACT_ANY; - *argv_def = XTRACT_MEAN; - *argv_unit = XTRACT_NONE; - *(argv_min + 1) = 1; - *(argv_max + 1) = 16384; - *(argv_def + 1) = 4; - *(argv_unit + 1) = XTRACT_NONE; - *(argv_min + 2) = 0; - *(argv_max + 2) = 32; - *(argv_def + 2) = 0; - *(argv_unit + 2) = XTRACT_NONE; - *(argv_min + 3) = 0; - *(argv_max + 3) = XTRACT_ANY; - *(argv_def + 3) = 0; - *(argv_unit + 3) = XTRACT_BINS; - break; - case XTRACT_BARK_COEFFICIENTS: - /* BARK_COEFFICIENTS is special because argc = BARK_BANDS */ - case XTRACT_WINDOWED: - /* WINDOWED is special because argc = window size = N */ - default: - *argv_min = XTRACT_NONE; - *argv_max = XTRACT_NONE; - *argv_def = XTRACT_NONE; - *argv_unit = XTRACT_NONE; - break; + case XTRACT_SPECTRUM: + *argv_min = XTRACT_SR_LOWER_LIMIT / XTRACT_FFT_BANDS_MIN; + *argv_max = XTRACT_SR_UPPER_LIMIT / XTRACT_FFT_BANDS_MAX; + *argv_def = XTRACT_SR_DEFAULT / XTRACT_FFT_BANDS_DEF; + *argv_unit = XTRACT_HERTZ; + *(argv_min + 1) = 0; + *(argv_max + 1) = 3 ; + *(argv_def + 1) = 0; + *(argv_unit + 1) = XTRACT_NONE; + *(argv_min + 2) = 0; + *(argv_max + 2) = 1; + *(argv_def + 2) = 0; + *(argv_unit + 2) = XTRACT_NONE; + *(argv_min + 3) = 0; + *(argv_max + 3) = 1; + *(argv_def + 3) = 0; + *(argv_unit + 3) = XTRACT_NONE; + break; + case XTRACT_SUBBANDS: + *argv_min = XTRACT_ANY; + *argv_max = XTRACT_ANY; + *argv_def = XTRACT_MEAN; + *argv_unit = XTRACT_NONE; + *(argv_min + 1) = 1; + *(argv_max + 1) = 16384; + *(argv_def + 1) = 4; + *(argv_unit + 1) = XTRACT_NONE; + *(argv_min + 2) = 0; + *(argv_max + 2) = 32; + *(argv_def + 2) = 0; + *(argv_unit + 2) = XTRACT_NONE; + *(argv_min + 3) = 0; + *(argv_max + 3) = XTRACT_ANY; + *(argv_def + 3) = 0; + *(argv_unit + 3) = XTRACT_BINS; + break; + case XTRACT_BARK_COEFFICIENTS: + /* BARK_COEFFICIENTS is special because argc = BARK_BANDS */ + case XTRACT_WINDOWED: + /* WINDOWED is special because argc = window size = N */ + default: + *argv_min = XTRACT_NONE; + *argv_max = XTRACT_NONE; + *argv_def = XTRACT_NONE; + *argv_unit = XTRACT_NONE; + break; } argv_donor = &d->argv.donor[0]; - switch (f) { + switch (f) + { /* argc = 1 */ - case XTRACT_VARIANCE: - *argv_donor = XTRACT_MEAN; - break; - case XTRACT_SPECTRAL_VARIANCE: - *argv_donor = XTRACT_SPECTRAL_MEAN; - break; - case XTRACT_STANDARD_DEVIATION: - *argv_donor = XTRACT_VARIANCE; - break; - case XTRACT_AVERAGE_DEVIATION: - *argv_donor = XTRACT_MEAN; - break; - case XTRACT_SPECTRAL_STANDARD_DEVIATION: - *argv_donor = XTRACT_SPECTRAL_VARIANCE; - break; + case XTRACT_VARIANCE: + *argv_donor = XTRACT_MEAN; + break; + case XTRACT_SPECTRAL_VARIANCE: + *argv_donor = XTRACT_SPECTRAL_MEAN; + break; + case XTRACT_STANDARD_DEVIATION: + *argv_donor = XTRACT_VARIANCE; + break; + case XTRACT_AVERAGE_DEVIATION: + *argv_donor = XTRACT_MEAN; + break; + case XTRACT_SPECTRAL_STANDARD_DEVIATION: + *argv_donor = XTRACT_SPECTRAL_VARIANCE; + break; /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: *argv_donor = XTRACT_SPECTRAL_MEAN; break; */ - case XTRACT_SPECTRAL_INHARMONICITY: - *argv_donor = XTRACT_FAILSAFE_F0; - break; - case XTRACT_FLATNESS_DB: - *argv_donor = XTRACT_FLATNESS; - break; - case XTRACT_TONALITY: - *argv_donor = XTRACT_FLATNESS_DB; - break; - case XTRACT_LOWEST_VALUE: - case XTRACT_F0: - case XTRACT_FAILSAFE_F0: - *argv_donor = XTRACT_ANY; - break; - case XTRACT_MFCC: - *argv_donor = XTRACT_INIT_MFCC; - break; - /* argc = 2 */; - case XTRACT_ROLLOFF: - case XTRACT_PEAK_SPECTRUM: - case XTRACT_FLUX: - case XTRACT_LNORM: - *argv_donor = XTRACT_ANY; - *(argv_donor + 1) = XTRACT_ANY; - break; - case XTRACT_SKEWNESS: - case XTRACT_KURTOSIS: - *argv_donor = XTRACT_MEAN; - *(argv_donor + 1) = XTRACT_STANDARD_DEVIATION; - break; - case XTRACT_SPECTRAL_SKEWNESS: - case XTRACT_SPECTRAL_KURTOSIS: - *argv_donor = XTRACT_SPECTRAL_MEAN; - *(argv_donor + 1) = XTRACT_SPECTRAL_STANDARD_DEVIATION; - break; - case XTRACT_HARMONIC_SPECTRUM: - *argv_donor = XTRACT_FAILSAFE_F0; - *(argv_donor + 1) = XTRACT_ANY; - break; - case XTRACT_NOISINESS: - *argv_donor = XTRACT_SUM; - *(argv_donor + 1) = XTRACT_SUM; - break; - case XTRACT_CREST: - *argv_donor = XTRACT_HIGHEST_VALUE; - *(argv_donor + 1) = XTRACT_MEAN; - break; - /* argc = 4 */ - case XTRACT_SPECTRUM: - *argv_donor = XTRACT_ANY; - *(argv_donor + 1) = XTRACT_ANY; - *(argv_donor + 2) = XTRACT_ANY; - *(argv_donor + 3) = XTRACT_ANY; - break; - case XTRACT_SUBBANDS: - *argv_donor = XTRACT_ANY; - *(argv_donor + 1) = XTRACT_ANY; - *(argv_donor + 2) = XTRACT_ANY; - *(argv_donor + 3) = XTRACT_ANY; - break; + case XTRACT_SPECTRAL_INHARMONICITY: + *argv_donor = XTRACT_FAILSAFE_F0; + break; + case XTRACT_FLATNESS_DB: + *argv_donor = XTRACT_FLATNESS; + break; + case XTRACT_TONALITY: + *argv_donor = XTRACT_FLATNESS_DB; + break; + case XTRACT_LOWEST_VALUE: + case XTRACT_F0: + case XTRACT_FAILSAFE_F0: + *argv_donor = XTRACT_ANY; + break; + case XTRACT_MFCC: + *argv_donor = XTRACT_INIT_MFCC; + break; + /* argc = 2 */; + case XTRACT_ROLLOFF: + case XTRACT_PEAK_SPECTRUM: + case XTRACT_FLUX: + case XTRACT_LNORM: + *argv_donor = XTRACT_ANY; + *(argv_donor + 1) = XTRACT_ANY; + break; + case XTRACT_SKEWNESS: + case XTRACT_KURTOSIS: + *argv_donor = XTRACT_MEAN; + *(argv_donor + 1) = XTRACT_STANDARD_DEVIATION; + break; + case XTRACT_SPECTRAL_SKEWNESS: + case XTRACT_SPECTRAL_KURTOSIS: + *argv_donor = XTRACT_SPECTRAL_MEAN; + *(argv_donor + 1) = XTRACT_SPECTRAL_STANDARD_DEVIATION; + break; + case XTRACT_HARMONIC_SPECTRUM: + *argv_donor = XTRACT_FAILSAFE_F0; + *(argv_donor + 1) = XTRACT_ANY; + break; + case XTRACT_NOISINESS: + *argv_donor = XTRACT_SUM; + *(argv_donor + 1) = XTRACT_SUM; + break; + case XTRACT_CREST: + *argv_donor = XTRACT_HIGHEST_VALUE; + *(argv_donor + 1) = XTRACT_MEAN; + break; + /* argc = 4 */ + case XTRACT_SPECTRUM: + *argv_donor = XTRACT_ANY; + *(argv_donor + 1) = XTRACT_ANY; + *(argv_donor + 2) = XTRACT_ANY; + *(argv_donor + 3) = XTRACT_ANY; + break; + case XTRACT_SUBBANDS: + *argv_donor = XTRACT_ANY; + *(argv_donor + 1) = XTRACT_ANY; + *(argv_donor + 2) = XTRACT_ANY; + *(argv_donor + 3) = XTRACT_ANY; + break; /* BARK_BANDS */ - case XTRACT_BARK_COEFFICIENTS: - *argv_donor = XTRACT_INIT_BARK; - break; - case XTRACT_WINDOWED: - *argv_donor = XTRACT_INIT_WINDOWED; - break; - default: - *argv_donor = XTRACT_ANY; - break; + case XTRACT_BARK_COEFFICIENTS: + *argv_donor = XTRACT_INIT_BARK; + break; + case XTRACT_WINDOWED: + *argv_donor = XTRACT_INIT_WINDOWED; + break; + default: + *argv_donor = XTRACT_ANY; + break; } data_format = &d->data.format; - switch(f){ + switch(f) + { - case XTRACT_MEAN: - case XTRACT_VARIANCE: - case XTRACT_STANDARD_DEVIATION: - case XTRACT_AVERAGE_DEVIATION: - case XTRACT_SKEWNESS: - case XTRACT_KURTOSIS: - case XTRACT_LOWEST_VALUE: - case XTRACT_HIGHEST_VALUE: - case XTRACT_SUM: - case XTRACT_WINDOWED: - *data_format = XTRACT_ARBITRARY_SERIES; - break; - case XTRACT_SPECTRAL_MEAN: - case XTRACT_SPECTRAL_VARIANCE: - case XTRACT_SPECTRAL_STANDARD_DEVIATION: + case XTRACT_MEAN: + case XTRACT_VARIANCE: + case XTRACT_STANDARD_DEVIATION: + case XTRACT_AVERAGE_DEVIATION: + case XTRACT_SKEWNESS: + case XTRACT_KURTOSIS: + case XTRACT_LOWEST_VALUE: + case XTRACT_HIGHEST_VALUE: + case XTRACT_SUM: + case XTRACT_WINDOWED: + *data_format = XTRACT_ARBITRARY_SERIES; + break; + case XTRACT_SPECTRAL_MEAN: + case XTRACT_SPECTRAL_VARIANCE: + case XTRACT_SPECTRAL_STANDARD_DEVIATION: /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ - case XTRACT_SPECTRAL_SKEWNESS: - case XTRACT_SPECTRAL_KURTOSIS: - case XTRACT_SPECTRAL_CENTROID: - case XTRACT_SPECTRAL_SLOPE: - *data_format = XTRACT_SPECTRAL; - break; - case XTRACT_ROLLOFF: - case XTRACT_NOISINESS: - case XTRACT_BARK_COEFFICIENTS: - case XTRACT_CREST: - case XTRACT_IRREGULARITY_K: - case XTRACT_IRREGULARITY_J: - case XTRACT_SMOOTHNESS: - case XTRACT_FLATNESS: - case XTRACT_SPREAD: - case XTRACT_POWER: - case XTRACT_HPS: - case XTRACT_PEAK_SPECTRUM: - case XTRACT_SUBBANDS: - case XTRACT_MFCC: - *data_format = XTRACT_SPECTRAL_MAGNITUDES; - break; - case XTRACT_LPC: - *data_format = XTRACT_AUTOCORRELATION_COEFFS; - break; - case XTRACT_LPCC: - *data_format = XTRACT_LPC_COEFFS; - break; - case XTRACT_SPECTRAL_INHARMONICITY: - case XTRACT_HARMONIC_SPECTRUM: - *data_format = XTRACT_SPECTRAL_PEAKS; - break; - case XTRACT_NONZERO_COUNT: - *data_format = XTRACT_SPECTRAL_PEAKS_MAGNITUDES; - break; - case XTRACT_F0: - case XTRACT_FAILSAFE_F0: - case XTRACT_SPECTRUM: - case XTRACT_AUTOCORRELATION: - case XTRACT_AUTOCORRELATION_FFT: - case XTRACT_DCT: - case XTRACT_AMDF: - case XTRACT_ASDF: - case XTRACT_ZCR: - case XTRACT_RMS_AMPLITUDE: - case XTRACT_FLUX: - case XTRACT_LNORM: - *data_format = XTRACT_AUDIO_SAMPLES; - break; - case XTRACT_TONALITY: - case XTRACT_FLATNESS_DB: - *data_format = XTRACT_NO_DATA; - break; - case XTRACT_TRISTIMULUS_1: - case XTRACT_TRISTIMULUS_2: - case XTRACT_TRISTIMULUS_3: - case XTRACT_ODD_EVEN_RATIO: - *data_format = XTRACT_SPECTRAL_HARMONICS_MAGNITUDES; - break; - case XTRACT_LOUDNESS: - case XTRACT_SHARPNESS: - *data_format = XTRACT_BARK_COEFFS; - break; - case XTRACT_DIFFERENCE_VECTOR: - *data_format = XTRACT_SUBFRAMES; - break; - case XTRACT_ATTACK_TIME: - case XTRACT_DECAY_TIME: - default: - *data_format = XTRACT_NO_DATA; - break; + case XTRACT_SPECTRAL_SKEWNESS: + case XTRACT_SPECTRAL_KURTOSIS: + case XTRACT_SPECTRAL_CENTROID: + case XTRACT_SPECTRAL_SLOPE: + *data_format = XTRACT_SPECTRAL; + break; + case XTRACT_ROLLOFF: + case XTRACT_NOISINESS: + case XTRACT_BARK_COEFFICIENTS: + case XTRACT_CREST: + case XTRACT_IRREGULARITY_K: + case XTRACT_IRREGULARITY_J: + case XTRACT_SMOOTHNESS: + case XTRACT_FLATNESS: + case XTRACT_SPREAD: + case XTRACT_POWER: + case XTRACT_HPS: + case XTRACT_PEAK_SPECTRUM: + case XTRACT_SUBBANDS: + case XTRACT_MFCC: + *data_format = XTRACT_SPECTRAL_MAGNITUDES; + break; + case XTRACT_LPC: + *data_format = XTRACT_AUTOCORRELATION_COEFFS; + break; + case XTRACT_LPCC: + *data_format = XTRACT_LPC_COEFFS; + break; + case XTRACT_SPECTRAL_INHARMONICITY: + case XTRACT_HARMONIC_SPECTRUM: + *data_format = XTRACT_SPECTRAL_PEAKS; + break; + case XTRACT_NONZERO_COUNT: + *data_format = XTRACT_SPECTRAL_PEAKS_MAGNITUDES; + break; + case XTRACT_F0: + case XTRACT_FAILSAFE_F0: + case XTRACT_SPECTRUM: + case XTRACT_AUTOCORRELATION: + case XTRACT_AUTOCORRELATION_FFT: + case XTRACT_DCT: + case XTRACT_AMDF: + case XTRACT_ASDF: + case XTRACT_ZCR: + case XTRACT_RMS_AMPLITUDE: + case XTRACT_FLUX: + case XTRACT_LNORM: + *data_format = XTRACT_AUDIO_SAMPLES; + break; + case XTRACT_TONALITY: + case XTRACT_FLATNESS_DB: + *data_format = XTRACT_NO_DATA; + break; + case XTRACT_TRISTIMULUS_1: + case XTRACT_TRISTIMULUS_2: + case XTRACT_TRISTIMULUS_3: + case XTRACT_ODD_EVEN_RATIO: + *data_format = XTRACT_SPECTRAL_HARMONICS_MAGNITUDES; + break; + case XTRACT_LOUDNESS: + case XTRACT_SHARPNESS: + *data_format = XTRACT_BARK_COEFFS; + break; + case XTRACT_DIFFERENCE_VECTOR: + *data_format = XTRACT_SUBFRAMES; + break; + case XTRACT_ATTACK_TIME: + case XTRACT_DECAY_TIME: + default: + *data_format = XTRACT_NO_DATA; + break; } data_unit = &d->data.unit; - switch(f){ + switch(f) + { - case XTRACT_MEAN: - case XTRACT_VARIANCE: - case XTRACT_STANDARD_DEVIATION: - case XTRACT_AVERAGE_DEVIATION: - case XTRACT_SKEWNESS: - case XTRACT_KURTOSIS: - case XTRACT_LOWEST_VALUE: - case XTRACT_HIGHEST_VALUE: - case XTRACT_SUM: - case XTRACT_ZCR: - case XTRACT_PEAK_SPECTRUM: - case XTRACT_TRISTIMULUS_1: - case XTRACT_TRISTIMULUS_2: - case XTRACT_TRISTIMULUS_3: - case XTRACT_DCT: - case XTRACT_AMDF: - case XTRACT_ASDF: - case XTRACT_IRREGULARITY_K: - case XTRACT_IRREGULARITY_J: - case XTRACT_ATTACK_TIME: - case XTRACT_DECAY_TIME: - case XTRACT_DIFFERENCE_VECTOR: - case XTRACT_FLUX: - case XTRACT_LNORM: - case XTRACT_F0: - case XTRACT_FAILSAFE_F0: - case XTRACT_MFCC: - case XTRACT_AUTOCORRELATION: - case XTRACT_AUTOCORRELATION_FFT: - case XTRACT_ROLLOFF: - case XTRACT_NOISINESS: - case XTRACT_CREST: - case XTRACT_FLATNESS: - case XTRACT_FLATNESS_DB: - case XTRACT_POWER: - case XTRACT_BARK_COEFFICIENTS: - case XTRACT_RMS_AMPLITUDE: - case XTRACT_SMOOTHNESS: - case XTRACT_SPREAD: - case XTRACT_SHARPNESS: - case XTRACT_HPS: - case XTRACT_SPECTRUM: - case XTRACT_TONALITY: - case XTRACT_LOUDNESS: - case XTRACT_NONZERO_COUNT: - case XTRACT_LPC: - case XTRACT_LPCC: - case XTRACT_WINDOWED: - case XTRACT_SUBBANDS: - *data_unit = XTRACT_ANY; - break; - case XTRACT_SPECTRAL_MEAN: - case XTRACT_SPECTRAL_VARIANCE: - case XTRACT_SPECTRAL_STANDARD_DEVIATION: + case XTRACT_MEAN: + case XTRACT_VARIANCE: + case XTRACT_STANDARD_DEVIATION: + case XTRACT_AVERAGE_DEVIATION: + case XTRACT_SKEWNESS: + case XTRACT_KURTOSIS: + case XTRACT_LOWEST_VALUE: + case XTRACT_HIGHEST_VALUE: + case XTRACT_SUM: + case XTRACT_ZCR: + case XTRACT_PEAK_SPECTRUM: + case XTRACT_TRISTIMULUS_1: + case XTRACT_TRISTIMULUS_2: + case XTRACT_TRISTIMULUS_3: + case XTRACT_DCT: + case XTRACT_AMDF: + case XTRACT_ASDF: + case XTRACT_IRREGULARITY_K: + case XTRACT_IRREGULARITY_J: + case XTRACT_ATTACK_TIME: + case XTRACT_DECAY_TIME: + case XTRACT_DIFFERENCE_VECTOR: + case XTRACT_FLUX: + case XTRACT_LNORM: + case XTRACT_F0: + case XTRACT_FAILSAFE_F0: + case XTRACT_MFCC: + case XTRACT_AUTOCORRELATION: + case XTRACT_AUTOCORRELATION_FFT: + case XTRACT_ROLLOFF: + case XTRACT_NOISINESS: + case XTRACT_CREST: + case XTRACT_FLATNESS: + case XTRACT_FLATNESS_DB: + case XTRACT_POWER: + case XTRACT_BARK_COEFFICIENTS: + case XTRACT_RMS_AMPLITUDE: + case XTRACT_SMOOTHNESS: + case XTRACT_SPREAD: + case XTRACT_SHARPNESS: + case XTRACT_HPS: + case XTRACT_SPECTRUM: + case XTRACT_TONALITY: + case XTRACT_LOUDNESS: + case XTRACT_NONZERO_COUNT: + case XTRACT_LPC: + case XTRACT_LPCC: + case XTRACT_WINDOWED: + case XTRACT_SUBBANDS: + *data_unit = XTRACT_ANY; + break; + case XTRACT_SPECTRAL_MEAN: + case XTRACT_SPECTRAL_VARIANCE: + case XTRACT_SPECTRAL_STANDARD_DEVIATION: /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ - case XTRACT_SPECTRAL_SKEWNESS: - case XTRACT_SPECTRAL_KURTOSIS: - case XTRACT_SPECTRAL_CENTROID: - case XTRACT_SPECTRAL_SLOPE: - case XTRACT_HARMONIC_SPECTRUM: - case XTRACT_SPECTRAL_INHARMONICITY: - *data_unit = XTRACT_ANY_AMPLITUDE_HERTZ; - break; - case XTRACT_ODD_EVEN_RATIO: - *data_unit = XTRACT_HERTZ; - break; + case XTRACT_SPECTRAL_SKEWNESS: + case XTRACT_SPECTRAL_KURTOSIS: + case XTRACT_SPECTRAL_CENTROID: + case XTRACT_SPECTRAL_SLOPE: + case XTRACT_HARMONIC_SPECTRUM: + case XTRACT_SPECTRAL_INHARMONICITY: + *data_unit = XTRACT_ANY_AMPLITUDE_HERTZ; + break; + case XTRACT_ODD_EVEN_RATIO: + *data_unit = XTRACT_HERTZ; + break; } name = d->algo.name; @@ -456,864 +462,872 @@ xtract_function_descriptor_t *xtract_make_descriptors(void){ strcpy(author, ""); *year = 0; - switch(f){ - case XTRACT_MEAN: - strcpy(name, "mean"); - strcpy(p_name, "Mean"); - strcpy(desc, "Extract the mean of an input vector"); - strcpy(p_desc, "Extract the mean of a range of values"); - strcpy(author, ""); - break; - case XTRACT_VARIANCE: - strcpy(name, "variance"); - strcpy(p_name, "Variance"); - strcpy(desc, "Extract the variance of an input vector"); - strcpy(p_desc, "Extract the variance of a range of values"); - strcpy(author, ""); - break; - case XTRACT_STANDARD_DEVIATION: - strcpy(name, "standard_deviation"); - strcpy(p_name, "Standard Deviation"); - strcpy(desc, - "Extract the standard deviation of an input vector"); - strcpy(p_desc, - "Extract the standard deviation of a range of values"); - strcpy(author, ""); - break; - case XTRACT_AVERAGE_DEVIATION: - strcpy(name, "average_deviation"); - strcpy(p_name, "Average Deviation"); - strcpy(desc, - "Extract the average deviation of an input vector"); - strcpy(p_desc, - "Extract the average deviation of a range of values"); - strcpy(author, ""); - break; - case XTRACT_SKEWNESS: - strcpy(name, "skewness"); - strcpy(p_name, "Skewness"); - strcpy(desc, - "Extract the skewness of an input vector"); - strcpy(p_desc, - "Extract the skewness of a range of values"); - strcpy(author, ""); - break; - case XTRACT_KURTOSIS: - strcpy(name, "kurtosis"); - strcpy(p_name, "Kurtosis"); - strcpy(desc, - "Extract the kurtosis of an input vector"); - strcpy(p_desc, - "Extract the kurtosis of a range of values"); - strcpy(author, ""); - break; - case XTRACT_SPECTRAL_MEAN: - strcpy(name, "spectral_mean"); - strcpy(p_name, "Spectral Mean"); - strcpy(desc, "Extract the mean of an input spectrum"); - strcpy(p_desc, "Extract the mean of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_SPECTRAL_VARIANCE: - strcpy(name, "spectral_variance"); - strcpy(p_name, "Spectral Variance"); - strcpy(desc, "Extract the variance of an input spectrum"); - strcpy(p_desc, "Extract the variance of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_SPECTRAL_STANDARD_DEVIATION: - strcpy(name, "spectral_standard_deviation"); - strcpy(p_name, "Spectral Standard Deviation"); - strcpy(desc, - "Extract the standard deviation of an input spectrum"); - strcpy(p_desc, - "Extract the standard deviation of an audio spectrum"); - strcpy(author, ""); - break; + switch(f) + { + case XTRACT_MEAN: + strcpy(name, "mean"); + strcpy(p_name, "Mean"); + strcpy(desc, "Extract the mean of an input vector"); + strcpy(p_desc, "Extract the mean of a range of values"); + strcpy(author, ""); + break; + case XTRACT_VARIANCE: + strcpy(name, "variance"); + strcpy(p_name, "Variance"); + strcpy(desc, "Extract the variance of an input vector"); + strcpy(p_desc, "Extract the variance of a range of values"); + strcpy(author, ""); + break; + case XTRACT_STANDARD_DEVIATION: + strcpy(name, "standard_deviation"); + strcpy(p_name, "Standard Deviation"); + strcpy(desc, + "Extract the standard deviation of an input vector"); + strcpy(p_desc, + "Extract the standard deviation of a range of values"); + strcpy(author, ""); + break; + case XTRACT_AVERAGE_DEVIATION: + strcpy(name, "average_deviation"); + strcpy(p_name, "Average Deviation"); + strcpy(desc, + "Extract the average deviation of an input vector"); + strcpy(p_desc, + "Extract the average deviation of a range of values"); + strcpy(author, ""); + break; + case XTRACT_SKEWNESS: + strcpy(name, "skewness"); + strcpy(p_name, "Skewness"); + strcpy(desc, + "Extract the skewness of an input vector"); + strcpy(p_desc, + "Extract the skewness of a range of values"); + strcpy(author, ""); + break; + case XTRACT_KURTOSIS: + strcpy(name, "kurtosis"); + strcpy(p_name, "Kurtosis"); + strcpy(desc, + "Extract the kurtosis of an input vector"); + strcpy(p_desc, + "Extract the kurtosis of a range of values"); + strcpy(author, ""); + break; + case XTRACT_SPECTRAL_MEAN: + strcpy(name, "spectral_mean"); + strcpy(p_name, "Spectral Mean"); + strcpy(desc, "Extract the mean of an input spectrum"); + strcpy(p_desc, "Extract the mean of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_SPECTRAL_VARIANCE: + strcpy(name, "spectral_variance"); + strcpy(p_name, "Spectral Variance"); + strcpy(desc, "Extract the variance of an input spectrum"); + strcpy(p_desc, "Extract the variance of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_SPECTRAL_STANDARD_DEVIATION: + strcpy(name, "spectral_standard_deviation"); + strcpy(p_name, "Spectral Standard Deviation"); + strcpy(desc, + "Extract the standard deviation of an input spectrum"); + strcpy(p_desc, + "Extract the standard deviation of an audio spectrum"); + strcpy(author, ""); + break; /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: strcpy(name, "spectral_average_deviation"); strcpy(p_name, "Spectral Average Deviation"); - strcpy(desc, + strcpy(desc, "Extract the average deviation of an input spectrum"); - strcpy(p_desc, + strcpy(p_desc, "Extract the average deviation of an audio spectrum"); strcpy(author, ""); break; */ - case XTRACT_ROLLOFF: - strcpy(name, "rolloff"); - strcpy(p_name, "Spectral Rolloff"); - strcpy(desc, - "Extract the rolloff point of a spectrum"); - strcpy(p_desc, - "Extract the rolloff point of an audio spectrum"); - strcpy(author, "Bee Suan Ong"); - *year = 2005; - break; - case XTRACT_SPECTRAL_INHARMONICITY: - strcpy(name, "spectral_inharmonicity"); - strcpy(p_name, "Inharmonicity"); - strcpy(desc, "Extract the inharmonicity of a spectrum"); - strcpy(p_desc, - "Extract the inharmonicity of an audio spectrum"); - break; - case XTRACT_SPECTRUM: - strcpy(name, "spectrum"); - strcpy(p_name, "Spectrum"); - strcpy(desc, - "Extract the spectrum of an input vector"); - strcpy(p_desc, - "Extract the spectrum of an audio signal"); - strcpy(author, ""); - break; - case XTRACT_ODD_EVEN_RATIO: - strcpy(name, "odd_even_ratio"); - strcpy(p_name, "Odd/even Harmonic Ratio"); - strcpy(desc, - "Extract the odd-to-even harmonic ratio of a spectrum"); - strcpy(p_desc, - "Extract the odd-to-even harmonic ratio of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_LOWEST_VALUE: - strcpy(name, "lowest_value"); - strcpy(p_name, "Lowest Value"); - strcpy(desc, "Extract the lowest value from an input vector"); - strcpy(p_desc, "Extract the lowest value from a given range"); - strcpy(author, ""); - break; - case XTRACT_F0: - strcpy(name, "f0"); - strcpy(p_name, "Fundamental Frequency"); - strcpy(desc, "Extract the fundamental frequency of a signal"); - strcpy(p_desc, - "Extract the fundamental frequency of an audio signal"); - strcpy(author, "Jamie Bullock"); - break; - case XTRACT_FAILSAFE_F0: - strcpy(name, "failsafe_f0"); - strcpy(p_name, "Fundamental Frequency (failsafe)"); - strcpy(desc, "Extract the fundamental frequency of a signal (failsafe)"); - strcpy(p_desc, - "Extract the fundamental frequency of an audio signal (failsafe)"); - strcpy(author, "Jamie Bullock"); - break; - case XTRACT_TONALITY: - strcpy(name, "tonality"); - strcpy(p_name, "Tonality"); - strcpy(desc, "Extract the tonality of a spectrum"); - strcpy(p_desc, "Extract the tonality an audio spectrum"); - strcpy(author, "J. D. Johnston"); - *year = 1988; - break; - case XTRACT_SPECTRAL_SKEWNESS: - strcpy(name, "spectral_skewness"); - strcpy(p_name, "Spectral Skewness"); - strcpy(desc, "Extract the skewness of an input spectrum"); - strcpy(p_desc, "Extract the skewness of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_SPECTRAL_KURTOSIS: - strcpy(name, "spectral_kurtosis"); - strcpy(p_name, "Spectral Kurtosis"); - strcpy(desc, "Extract the kurtosis of an input spectrum"); - strcpy(p_desc, "Extract the kurtosis of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_PEAK_SPECTRUM: - strcpy(name, "peak_spectrum"); - strcpy(p_name, "Peak Spectrum"); - strcpy(desc, "Extract the spectral peaks from of a spectrum"); - strcpy(p_desc, - "Extract the spectral peaks from an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_HARMONIC_SPECTRUM: - strcpy(name, "harmonic_spectrum"); - strcpy(p_name, "Harmonic Spectrum"); - strcpy(desc, "Extract the harmonics from a spectrum"); - strcpy(p_desc, "Extract the harmonics from an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_NOISINESS: - strcpy(name, "noisiness"); - strcpy(p_name, "Noisiness"); - strcpy(desc, "Extract the noisiness of a spectrum"); - strcpy(p_desc, "Extract the noisiness of an audio spectrum"); - strcpy(author, "Tae Hong Park"); - *year = 2000; - break; - case XTRACT_CREST: - strcpy(name, "crest"); - strcpy(p_name, "Spectral Crest Measure"); - strcpy(desc, - "Extract the spectral crest measure of a spectrum"); - strcpy(p_desc, - "Extract the spectral crest measure of an audio spectrum"); - strcpy(author, "Peeters"); - *year = 2003; - break; - case XTRACT_MFCC: - strcpy(name, "mfcc"); - strcpy(p_name, "Mel-Frequency Cepstral Coefficients"); - strcpy(desc, "Extract MFCC from a spectrum"); - strcpy(p_desc, "Extract MFCC from an audio spectrum"); - strcpy(author, "Rabiner"); - break; - case XTRACT_LPC: - strcpy(name, "lpc"); - strcpy(p_name, "Linear predictive coding coefficients"); - strcpy(desc, "Extract LPC from autocorrelation coefficients"); - strcpy(p_desc, - "Extract LPC from autocorrelation coefficients"); - strcpy(author, - "Rabiner and Juang as implemented by Jutta Degener"); - *year = 1994; - break; - case XTRACT_LPCC: - strcpy(name, "lpcc"); - strcpy(p_name, "Linear predictive coding cepstral coefficients"); - strcpy(desc, "Extract LPC cepstrum from LPC coefficients"); - strcpy(p_desc, - "Extract LPC cepstrum from LPC coefficients"); - strcpy(author, "Rabiner and Juang"); - *year = 1993; - break; - case XTRACT_SUBBANDS: - strcpy(name, "subbands"); - strcpy(p_name, "Sub band coefficients"); - strcpy(desc, "Extract subband coefficients from spectral magnitudes"); - strcpy(p_desc, - "Extract subband coefficients from spectral magnitudes"); - strcpy(author, ""); - break; - case XTRACT_BARK_COEFFICIENTS: - strcpy(name, "bark_coefficients"); - strcpy(p_name, "Bark Coefficients"); - strcpy(desc, "Extract bark coefficients from a spectrum"); - strcpy(p_desc, - "Extract bark coefficients from an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_SPECTRAL_CENTROID: - strcpy(name, "spectral_centroid"); - strcpy(p_name, "Spectral Centroid"); - strcpy(desc, "Extract the spectral centroid of a spectrum"); - strcpy(p_desc, - "Extract the spectral centroid of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_IRREGULARITY_K: - strcpy(name, "irregularity_k"); - strcpy(p_name, "Irregularity I"); - strcpy(desc, "Extract the irregularity (type I) of a spectrum"); - strcpy(p_desc, - "Extract the irregularity (type I) of an audio spectrum"); - strcpy(author, "Krimphoff"); - *year = 1994; - break; - case XTRACT_IRREGULARITY_J: - strcpy(name, "irregularity_j"); - strcpy(p_name, "Irregularity II"); - strcpy(desc, "Extract the irregularity (type II) of a spectrum"); - strcpy(p_desc, - "Extract the irregularity (type II) of an audio spectrum"); - strcpy(author, "Jensen"); - *year = 1999; - break; - case XTRACT_TRISTIMULUS_1: - strcpy(name, "tristimulus_1"); - strcpy(p_name, "Tristimulus I"); - strcpy(desc, "Extract the tristimulus (type I) of a spectrum"); - strcpy(p_desc, - "Extract the tristimulus (type I) of an audio spectrum"); - strcpy(author, "Pollard and Jansson"); - *year = 1982; - break; - case XTRACT_TRISTIMULUS_2: - strcpy(name, "tristimulus_2"); - strcpy(p_name, "Tristimulus II"); - strcpy(desc, "Extract the tristimulus (type II) of a spectrum"); - strcpy(p_desc, - "Extract the tristimulus (type II) of an audio spectrum"); - strcpy(author, "Pollard and Jansson"); - *year = 1982; - break; - case XTRACT_TRISTIMULUS_3: - strcpy(name, "tristimulus_3"); - strcpy(p_name, "Tristimulus III"); - strcpy(desc, - "Extract the tristimulus (type III) of a spectrum"); - strcpy(p_desc, - "Extract the tristimulus (type III) of an audio spectrum"); - strcpy(author, "Pollard and Jansson"); - *year = 1982; - break; - case XTRACT_SMOOTHNESS: - strcpy(name, "smoothness"); - strcpy(p_name, "Spectral Smoothness"); - strcpy(desc, "Extract the spectral smoothness of a spectrum"); - strcpy(p_desc, - "Extract the spectral smoothness of an audio spectrum"); - strcpy(author, "McAdams"); - *year = 1999; - break; - case XTRACT_FLATNESS: - strcpy(name, "flatness"); - strcpy(p_name, "Spectral Flatness"); - strcpy(desc, "Extract the spectral flatness of a spectrum"); - strcpy(p_desc, - "Extract the spectral flatness of an audio spectrum"); - strcpy(author, "Tristan Jehan"); - *year = 2005; - break; - case XTRACT_FLATNESS_DB: - strcpy(name, "flatness_db"); - strcpy(p_name, "Log Spectral Flatness"); - strcpy(desc, "Extract the log spectral flatness of a spectrum"); - strcpy(p_desc, - "Extract the log spectral flatness of an audio spectrum"); - strcpy(author, "Peeters"); - *year = 2003; - break; - case XTRACT_SPREAD: - strcpy(name, "spread"); - strcpy(p_name, "Spectral Spread"); - strcpy(desc, "Extract the spectral spread of a spectrum"); - strcpy(p_desc, - "Extract the spectral spread of an audio spectrum"); - strcpy(author, "Norman Casagrande"); - *year = 2005; - break; - case XTRACT_ZCR: - strcpy(name, "zcr"); - strcpy(p_name, "Zero Crossing Rate"); - strcpy(desc, "Extract the zero crossing rate of a vector"); - strcpy(p_desc, - "Extract the zero crossing rate of an audio signal"); - strcpy(author, ""); - break; - case XTRACT_LOUDNESS: - strcpy(name, "loudness"); - strcpy(p_name, "Loudness"); - strcpy(desc, - "Extract the loudness of a signal from its spectrum"); - strcpy(p_desc, - "Extract the loudness of an audio signal from its spectrum"); - strcpy(author, "Moore, Glasberg et al"); - *year = 2005; - break; - case XTRACT_HIGHEST_VALUE: - strcpy(name, "highest_value"); - strcpy(p_name, "Highest Value"); - strcpy(desc, "Extract the highest value from an input vector"); - strcpy(p_desc, "Extract the highest value from a given range"); - strcpy(author, ""); - break; - case XTRACT_SUM: - strcpy(name, "sum"); - strcpy(p_name, "Sum of Values"); - strcpy(desc, - "Extract the sum of the values in an input vector"); - strcpy(p_desc, - "Extract the sum of the values in a given range"); - strcpy(author, ""); - break; - case XTRACT_RMS_AMPLITUDE: - strcpy(name, "rms_amplitude"); - strcpy(p_name, "RMS Amplitude"); - strcpy(desc, "Extract the RMS amplitude of a signal"); - strcpy(p_desc, "Extract the RMS amplitude of an audio signal"); - strcpy(author, ""); - break; - case XTRACT_POWER: - strcpy(name, "power"); - strcpy(p_name, "Spectral Power"); - strcpy(desc, "Extract the spectral power of a spectrum"); - strcpy(p_desc, - "Extract the spectral power of an audio spectrum"); - strcpy(author, "Bee Suan Ong"); - *year = 2005; - break; - case XTRACT_SHARPNESS: - strcpy(name, "sharpness"); - strcpy(p_name, "Spectral Sharpness"); - strcpy(desc, "Extract the spectral sharpness of a spectrum"); - strcpy(p_desc, - "Extract the spectral sharpness of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_SPECTRAL_SLOPE: - strcpy(name, "spectral_slope"); - strcpy(p_name, "Spectral Slope"); - strcpy(desc, "Extract the spectral slope of a spectrum"); - strcpy(p_desc, - "Extract the spectral slope of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_HPS: - strcpy(name, "hps"); - strcpy(p_name, "Harmonic Product Spectrum"); - strcpy(desc, - "Extract the harmonic product spectrum of a spectrum"); - strcpy(p_desc, - "Extract the harmonic product spectrum of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_FLUX: - strcpy(name, "flux"); - strcpy(p_name, "Spectral Flux"); - strcpy(desc, "Extract the spectral flux of a spectrum"); - strcpy(p_desc, - "Extract the spectral flux of an audio spectrum"); - strcpy(author, ""); - break; - case XTRACT_LNORM: - strcpy(name, "lnorm"); - strcpy(p_name, "L-norm"); - strcpy(desc, "Extract the L-norm of a vector"); - strcpy(p_desc, "Extract the L-norm of a vector"); - strcpy(author, ""); - break; - case XTRACT_ATTACK_TIME: - strcpy(name, "attack_time"); - strcpy(p_name, "Attack Time"); - strcpy(desc, "Extract the attack time of a signal"); - strcpy(p_desc, "Extract the attack time of an audio signal"); - strcpy(author, ""); - break; - case XTRACT_DECAY_TIME: - strcpy(name, "decay_time"); - strcpy(p_name, "Decay Time"); - strcpy(desc, "Extract the decay time of a signal"); - strcpy(p_desc, "Extract the decay time of an audio signal"); - strcpy(author, ""); - break; - case XTRACT_DIFFERENCE_VECTOR: - strcpy(name, "difference_vector"); - strcpy(p_name, "Difference vector"); - strcpy(desc, "Extract the difference between two vectors"); - strcpy(p_desc, "Extract the difference between two vectors"); - strcpy(author, ""); - break; - case XTRACT_AUTOCORRELATION_FFT: - strcpy(name, "autocorrelation_fft"); - strcpy(p_name, "Autocorrelation (FFT method)"); - strcpy(desc, "Extract the autocorrelation of a signal (fft method)"); - strcpy(p_desc, "Extract the autocorrelation of an audio signal (fft method)"); - strcpy(author, ""); - break; - case XTRACT_DCT: - strcpy(name, "dct"); - strcpy(p_name, "Discrete Cosine Transform"); - strcpy(desc, "Extract the DCT of a signal"); - strcpy(p_desc, "Extract the DCT of an audio signal"); - strcpy(author, ""); - break; - case XTRACT_AUTOCORRELATION: - strcpy(name, "autocorrelation"); - strcpy(p_name, "Autocorrelation"); - strcpy(desc, "Extract the autocorrelation of a signal"); - strcpy(p_desc, - "Extract the autocorrelation of an audio signal"); - strcpy(author, ""); - break; - case XTRACT_AMDF: - strcpy(name, "amdf"); - strcpy(p_name, "Average Magnitude Difference Function"); - strcpy(desc, "Extract the AMDF of a signal"); - strcpy(p_desc, "Extract the AMDF of an audio signal"); - strcpy(author, ""); - break; - case XTRACT_ASDF: - strcpy(name, "asdf"); - strcpy(p_name, "Average Squared Difference Function"); - strcpy(desc, "Extract the ASDF of a signal"); - strcpy(p_desc, "Extract the ASDF of an audio signal"); - strcpy(author, ""); - break; - case XTRACT_NONZERO_COUNT: - strcpy(name, "nonzero_count"); - strcpy(p_name, "Non-zero count"); - strcpy(desc, - "Extract the number of non-zero elements in the input vector"); - strcpy(p_desc, - "Extract the number of non-zero elements in an input spectrum"); - strcpy(author, ""); - break; - case XTRACT_WINDOWED: - strcpy(name, "windowed"); - strcpy(p_name, "Windowed frame"); - strcpy(desc, "Apply a window function to a frame of data"); - strcpy(p_desc, "Apply a window function to a frame of data"); - strcpy(author, ""); - break; - default: - strcpy(name, ""); - strcpy(p_name, ""); - strcpy(desc, ""); - strcpy(p_desc, ""); - strcpy(author, ""); - break; + case XTRACT_ROLLOFF: + strcpy(name, "rolloff"); + strcpy(p_name, "Spectral Rolloff"); + strcpy(desc, + "Extract the rolloff point of a spectrum"); + strcpy(p_desc, + "Extract the rolloff point of an audio spectrum"); + strcpy(author, "Bee Suan Ong"); + *year = 2005; + break; + case XTRACT_SPECTRAL_INHARMONICITY: + strcpy(name, "spectral_inharmonicity"); + strcpy(p_name, "Inharmonicity"); + strcpy(desc, "Extract the inharmonicity of a spectrum"); + strcpy(p_desc, + "Extract the inharmonicity of an audio spectrum"); + break; + case XTRACT_SPECTRUM: + strcpy(name, "spectrum"); + strcpy(p_name, "Spectrum"); + strcpy(desc, + "Extract the spectrum of an input vector"); + strcpy(p_desc, + "Extract the spectrum of an audio signal"); + strcpy(author, ""); + break; + case XTRACT_ODD_EVEN_RATIO: + strcpy(name, "odd_even_ratio"); + strcpy(p_name, "Odd/even Harmonic Ratio"); + strcpy(desc, + "Extract the odd-to-even harmonic ratio of a spectrum"); + strcpy(p_desc, + "Extract the odd-to-even harmonic ratio of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_LOWEST_VALUE: + strcpy(name, "lowest_value"); + strcpy(p_name, "Lowest Value"); + strcpy(desc, "Extract the lowest value from an input vector"); + strcpy(p_desc, "Extract the lowest value from a given range"); + strcpy(author, ""); + break; + case XTRACT_F0: + strcpy(name, "f0"); + strcpy(p_name, "Fundamental Frequency"); + strcpy(desc, "Extract the fundamental frequency of a signal"); + strcpy(p_desc, + "Extract the fundamental frequency of an audio signal"); + strcpy(author, "Jamie Bullock"); + break; + case XTRACT_FAILSAFE_F0: + strcpy(name, "failsafe_f0"); + strcpy(p_name, "Fundamental Frequency (failsafe)"); + strcpy(desc, "Extract the fundamental frequency of a signal (failsafe)"); + strcpy(p_desc, + "Extract the fundamental frequency of an audio signal (failsafe)"); + strcpy(author, "Jamie Bullock"); + break; + case XTRACT_TONALITY: + strcpy(name, "tonality"); + strcpy(p_name, "Tonality"); + strcpy(desc, "Extract the tonality of a spectrum"); + strcpy(p_desc, "Extract the tonality an audio spectrum"); + strcpy(author, "J. D. Johnston"); + *year = 1988; + break; + case XTRACT_SPECTRAL_SKEWNESS: + strcpy(name, "spectral_skewness"); + strcpy(p_name, "Spectral Skewness"); + strcpy(desc, "Extract the skewness of an input spectrum"); + strcpy(p_desc, "Extract the skewness of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_SPECTRAL_KURTOSIS: + strcpy(name, "spectral_kurtosis"); + strcpy(p_name, "Spectral Kurtosis"); + strcpy(desc, "Extract the kurtosis of an input spectrum"); + strcpy(p_desc, "Extract the kurtosis of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_PEAK_SPECTRUM: + strcpy(name, "peak_spectrum"); + strcpy(p_name, "Peak Spectrum"); + strcpy(desc, "Extract the spectral peaks from of a spectrum"); + strcpy(p_desc, + "Extract the spectral peaks from an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_HARMONIC_SPECTRUM: + strcpy(name, "harmonic_spectrum"); + strcpy(p_name, "Harmonic Spectrum"); + strcpy(desc, "Extract the harmonics from a spectrum"); + strcpy(p_desc, "Extract the harmonics from an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_NOISINESS: + strcpy(name, "noisiness"); + strcpy(p_name, "Noisiness"); + strcpy(desc, "Extract the noisiness of a spectrum"); + strcpy(p_desc, "Extract the noisiness of an audio spectrum"); + strcpy(author, "Tae Hong Park"); + *year = 2000; + break; + case XTRACT_CREST: + strcpy(name, "crest"); + strcpy(p_name, "Spectral Crest Measure"); + strcpy(desc, + "Extract the spectral crest measure of a spectrum"); + strcpy(p_desc, + "Extract the spectral crest measure of an audio spectrum"); + strcpy(author, "Peeters"); + *year = 2003; + break; + case XTRACT_MFCC: + strcpy(name, "mfcc"); + strcpy(p_name, "Mel-Frequency Cepstral Coefficients"); + strcpy(desc, "Extract MFCC from a spectrum"); + strcpy(p_desc, "Extract MFCC from an audio spectrum"); + strcpy(author, "Rabiner"); + break; + case XTRACT_LPC: + strcpy(name, "lpc"); + strcpy(p_name, "Linear predictive coding coefficients"); + strcpy(desc, "Extract LPC from autocorrelation coefficients"); + strcpy(p_desc, + "Extract LPC from autocorrelation coefficients"); + strcpy(author, + "Rabiner and Juang as implemented by Jutta Degener"); + *year = 1994; + break; + case XTRACT_LPCC: + strcpy(name, "lpcc"); + strcpy(p_name, "Linear predictive coding cepstral coefficients"); + strcpy(desc, "Extract LPC cepstrum from LPC coefficients"); + strcpy(p_desc, + "Extract LPC cepstrum from LPC coefficients"); + strcpy(author, "Rabiner and Juang"); + *year = 1993; + break; + case XTRACT_SUBBANDS: + strcpy(name, "subbands"); + strcpy(p_name, "Sub band coefficients"); + strcpy(desc, "Extract subband coefficients from spectral magnitudes"); + strcpy(p_desc, + "Extract subband coefficients from spectral magnitudes"); + strcpy(author, ""); + break; + case XTRACT_BARK_COEFFICIENTS: + strcpy(name, "bark_coefficients"); + strcpy(p_name, "Bark Coefficients"); + strcpy(desc, "Extract bark coefficients from a spectrum"); + strcpy(p_desc, + "Extract bark coefficients from an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_SPECTRAL_CENTROID: + strcpy(name, "spectral_centroid"); + strcpy(p_name, "Spectral Centroid"); + strcpy(desc, "Extract the spectral centroid of a spectrum"); + strcpy(p_desc, + "Extract the spectral centroid of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_IRREGULARITY_K: + strcpy(name, "irregularity_k"); + strcpy(p_name, "Irregularity I"); + strcpy(desc, "Extract the irregularity (type I) of a spectrum"); + strcpy(p_desc, + "Extract the irregularity (type I) of an audio spectrum"); + strcpy(author, "Krimphoff"); + *year = 1994; + break; + case XTRACT_IRREGULARITY_J: + strcpy(name, "irregularity_j"); + strcpy(p_name, "Irregularity II"); + strcpy(desc, "Extract the irregularity (type II) of a spectrum"); + strcpy(p_desc, + "Extract the irregularity (type II) of an audio spectrum"); + strcpy(author, "Jensen"); + *year = 1999; + break; + case XTRACT_TRISTIMULUS_1: + strcpy(name, "tristimulus_1"); + strcpy(p_name, "Tristimulus I"); + strcpy(desc, "Extract the tristimulus (type I) of a spectrum"); + strcpy(p_desc, + "Extract the tristimulus (type I) of an audio spectrum"); + strcpy(author, "Pollard and Jansson"); + *year = 1982; + break; + case XTRACT_TRISTIMULUS_2: + strcpy(name, "tristimulus_2"); + strcpy(p_name, "Tristimulus II"); + strcpy(desc, "Extract the tristimulus (type II) of a spectrum"); + strcpy(p_desc, + "Extract the tristimulus (type II) of an audio spectrum"); + strcpy(author, "Pollard and Jansson"); + *year = 1982; + break; + case XTRACT_TRISTIMULUS_3: + strcpy(name, "tristimulus_3"); + strcpy(p_name, "Tristimulus III"); + strcpy(desc, + "Extract the tristimulus (type III) of a spectrum"); + strcpy(p_desc, + "Extract the tristimulus (type III) of an audio spectrum"); + strcpy(author, "Pollard and Jansson"); + *year = 1982; + break; + case XTRACT_SMOOTHNESS: + strcpy(name, "smoothness"); + strcpy(p_name, "Spectral Smoothness"); + strcpy(desc, "Extract the spectral smoothness of a spectrum"); + strcpy(p_desc, + "Extract the spectral smoothness of an audio spectrum"); + strcpy(author, "McAdams"); + *year = 1999; + break; + case XTRACT_FLATNESS: + strcpy(name, "flatness"); + strcpy(p_name, "Spectral Flatness"); + strcpy(desc, "Extract the spectral flatness of a spectrum"); + strcpy(p_desc, + "Extract the spectral flatness of an audio spectrum"); + strcpy(author, "Tristan Jehan"); + *year = 2005; + break; + case XTRACT_FLATNESS_DB: + strcpy(name, "flatness_db"); + strcpy(p_name, "Log Spectral Flatness"); + strcpy(desc, "Extract the log spectral flatness of a spectrum"); + strcpy(p_desc, + "Extract the log spectral flatness of an audio spectrum"); + strcpy(author, "Peeters"); + *year = 2003; + break; + case XTRACT_SPREAD: + strcpy(name, "spread"); + strcpy(p_name, "Spectral Spread"); + strcpy(desc, "Extract the spectral spread of a spectrum"); + strcpy(p_desc, + "Extract the spectral spread of an audio spectrum"); + strcpy(author, "Norman Casagrande"); + *year = 2005; + break; + case XTRACT_ZCR: + strcpy(name, "zcr"); + strcpy(p_name, "Zero Crossing Rate"); + strcpy(desc, "Extract the zero crossing rate of a vector"); + strcpy(p_desc, + "Extract the zero crossing rate of an audio signal"); + strcpy(author, ""); + break; + case XTRACT_LOUDNESS: + strcpy(name, "loudness"); + strcpy(p_name, "Loudness"); + strcpy(desc, + "Extract the loudness of a signal from its spectrum"); + strcpy(p_desc, + "Extract the loudness of an audio signal from its spectrum"); + strcpy(author, "Moore, Glasberg et al"); + *year = 2005; + break; + case XTRACT_HIGHEST_VALUE: + strcpy(name, "highest_value"); + strcpy(p_name, "Highest Value"); + strcpy(desc, "Extract the highest value from an input vector"); + strcpy(p_desc, "Extract the highest value from a given range"); + strcpy(author, ""); + break; + case XTRACT_SUM: + strcpy(name, "sum"); + strcpy(p_name, "Sum of Values"); + strcpy(desc, + "Extract the sum of the values in an input vector"); + strcpy(p_desc, + "Extract the sum of the values in a given range"); + strcpy(author, ""); + break; + case XTRACT_RMS_AMPLITUDE: + strcpy(name, "rms_amplitude"); + strcpy(p_name, "RMS Amplitude"); + strcpy(desc, "Extract the RMS amplitude of a signal"); + strcpy(p_desc, "Extract the RMS amplitude of an audio signal"); + strcpy(author, ""); + break; + case XTRACT_POWER: + strcpy(name, "power"); + strcpy(p_name, "Spectral Power"); + strcpy(desc, "Extract the spectral power of a spectrum"); + strcpy(p_desc, + "Extract the spectral power of an audio spectrum"); + strcpy(author, "Bee Suan Ong"); + *year = 2005; + break; + case XTRACT_SHARPNESS: + strcpy(name, "sharpness"); + strcpy(p_name, "Spectral Sharpness"); + strcpy(desc, "Extract the spectral sharpness of a spectrum"); + strcpy(p_desc, + "Extract the spectral sharpness of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_SPECTRAL_SLOPE: + strcpy(name, "spectral_slope"); + strcpy(p_name, "Spectral Slope"); + strcpy(desc, "Extract the spectral slope of a spectrum"); + strcpy(p_desc, + "Extract the spectral slope of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_HPS: + strcpy(name, "hps"); + strcpy(p_name, "Harmonic Product Spectrum"); + strcpy(desc, + "Extract the harmonic product spectrum of a spectrum"); + strcpy(p_desc, + "Extract the harmonic product spectrum of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_FLUX: + strcpy(name, "flux"); + strcpy(p_name, "Spectral Flux"); + strcpy(desc, "Extract the spectral flux of a spectrum"); + strcpy(p_desc, + "Extract the spectral flux of an audio spectrum"); + strcpy(author, ""); + break; + case XTRACT_LNORM: + strcpy(name, "lnorm"); + strcpy(p_name, "L-norm"); + strcpy(desc, "Extract the L-norm of a vector"); + strcpy(p_desc, "Extract the L-norm of a vector"); + strcpy(author, ""); + break; + case XTRACT_ATTACK_TIME: + strcpy(name, "attack_time"); + strcpy(p_name, "Attack Time"); + strcpy(desc, "Extract the attack time of a signal"); + strcpy(p_desc, "Extract the attack time of an audio signal"); + strcpy(author, ""); + break; + case XTRACT_DECAY_TIME: + strcpy(name, "decay_time"); + strcpy(p_name, "Decay Time"); + strcpy(desc, "Extract the decay time of a signal"); + strcpy(p_desc, "Extract the decay time of an audio signal"); + strcpy(author, ""); + break; + case XTRACT_DIFFERENCE_VECTOR: + strcpy(name, "difference_vector"); + strcpy(p_name, "Difference vector"); + strcpy(desc, "Extract the difference between two vectors"); + strcpy(p_desc, "Extract the difference between two vectors"); + strcpy(author, ""); + break; + case XTRACT_AUTOCORRELATION_FFT: + strcpy(name, "autocorrelation_fft"); + strcpy(p_name, "Autocorrelation (FFT method)"); + strcpy(desc, "Extract the autocorrelation of a signal (fft method)"); + strcpy(p_desc, "Extract the autocorrelation of an audio signal (fft method)"); + strcpy(author, ""); + break; + case XTRACT_DCT: + strcpy(name, "dct"); + strcpy(p_name, "Discrete Cosine Transform"); + strcpy(desc, "Extract the DCT of a signal"); + strcpy(p_desc, "Extract the DCT of an audio signal"); + strcpy(author, ""); + break; + case XTRACT_AUTOCORRELATION: + strcpy(name, "autocorrelation"); + strcpy(p_name, "Autocorrelation"); + strcpy(desc, "Extract the autocorrelation of a signal"); + strcpy(p_desc, + "Extract the autocorrelation of an audio signal"); + strcpy(author, ""); + break; + case XTRACT_AMDF: + strcpy(name, "amdf"); + strcpy(p_name, "Average Magnitude Difference Function"); + strcpy(desc, "Extract the AMDF of a signal"); + strcpy(p_desc, "Extract the AMDF of an audio signal"); + strcpy(author, ""); + break; + case XTRACT_ASDF: + strcpy(name, "asdf"); + strcpy(p_name, "Average Squared Difference Function"); + strcpy(desc, "Extract the ASDF of a signal"); + strcpy(p_desc, "Extract the ASDF of an audio signal"); + strcpy(author, ""); + break; + case XTRACT_NONZERO_COUNT: + strcpy(name, "nonzero_count"); + strcpy(p_name, "Non-zero count"); + strcpy(desc, + "Extract the number of non-zero elements in the input vector"); + strcpy(p_desc, + "Extract the number of non-zero elements in an input spectrum"); + strcpy(author, ""); + break; + case XTRACT_WINDOWED: + strcpy(name, "windowed"); + strcpy(p_name, "Windowed frame"); + strcpy(desc, "Apply a window function to a frame of data"); + strcpy(p_desc, "Apply a window function to a frame of data"); + strcpy(author, ""); + break; + default: + strcpy(name, ""); + strcpy(p_name, ""); + strcpy(desc, ""); + strcpy(p_desc, ""); + strcpy(author, ""); + break; } - switch(f){ + switch(f) + { - case XTRACT_VARIANCE: - case XTRACT_STANDARD_DEVIATION: - case XTRACT_AVERAGE_DEVIATION: - case XTRACT_SPECTRAL_VARIANCE: - case XTRACT_SPECTRAL_STANDARD_DEVIATION: + case XTRACT_VARIANCE: + case XTRACT_STANDARD_DEVIATION: + case XTRACT_AVERAGE_DEVIATION: + case XTRACT_SPECTRAL_VARIANCE: + case XTRACT_SPECTRAL_STANDARD_DEVIATION: /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ - case XTRACT_SPECTRAL_INHARMONICITY: - case XTRACT_LOWEST_VALUE: - case XTRACT_F0: - case XTRACT_FAILSAFE_F0: - case XTRACT_FLATNESS_DB: - case XTRACT_TONALITY: - *argc = 1; - *argv_type = XTRACT_FLOAT; - break; - case XTRACT_SKEWNESS: - case XTRACT_KURTOSIS: - case XTRACT_SPECTRAL_SKEWNESS: - case XTRACT_SPECTRAL_KURTOSIS: - case XTRACT_PEAK_SPECTRUM: - case XTRACT_HARMONIC_SPECTRUM: - case XTRACT_NOISINESS: - case XTRACT_CREST: - case XTRACT_ROLLOFF: - case XTRACT_FLUX: - case XTRACT_LNORM: - *argc = 2; - *argv_type = XTRACT_FLOAT; - break; - case XTRACT_SPECTRUM: - *argc = 4; - *argv_type = XTRACT_FLOAT; - break; - case XTRACT_SUBBANDS: - *argc = 4; - *argv_type = XTRACT_INT; - break; - case XTRACT_MFCC: - *argc = 1; - *argv_type = XTRACT_MEL_FILTER; - break; - case XTRACT_LPCC: - *argc = 1; - *argv_type = XTRACT_INT; - break; - case XTRACT_BARK_COEFFICIENTS: - *argc = XTRACT_BARK_BANDS; - *argv_type = XTRACT_INT; - break; - case XTRACT_WINDOWED: - *argc = XTRACT_WINDOW_SIZE; - *argv_type = XTRACT_FLOAT; - break; - case XTRACT_MEAN: - case XTRACT_SPECTRAL_MEAN: - case XTRACT_SPECTRAL_CENTROID: - case XTRACT_IRREGULARITY_K: - case XTRACT_IRREGULARITY_J: - case XTRACT_TRISTIMULUS_1: - case XTRACT_TRISTIMULUS_2: - case XTRACT_TRISTIMULUS_3: - case XTRACT_SMOOTHNESS: - case XTRACT_FLATNESS: - case XTRACT_SPREAD: - case XTRACT_ZCR: - case XTRACT_LOUDNESS: - case XTRACT_HIGHEST_VALUE: - case XTRACT_SUM: - case XTRACT_RMS_AMPLITUDE: - case XTRACT_POWER: - case XTRACT_SHARPNESS: - case XTRACT_SPECTRAL_SLOPE: - case XTRACT_HPS: - case XTRACT_ATTACK_TIME: - case XTRACT_DECAY_TIME: - case XTRACT_DIFFERENCE_VECTOR: - case XTRACT_AUTOCORRELATION_FFT: - case XTRACT_DCT: - case XTRACT_AUTOCORRELATION: - case XTRACT_AMDF: - case XTRACT_ASDF: - case XTRACT_NONZERO_COUNT: - case XTRACT_ODD_EVEN_RATIO: - case XTRACT_LPC: - default: - *argc = 0; - break; + case XTRACT_SPECTRAL_INHARMONICITY: + case XTRACT_LOWEST_VALUE: + case XTRACT_F0: + case XTRACT_FAILSAFE_F0: + case XTRACT_FLATNESS_DB: + case XTRACT_TONALITY: + *argc = 1; + *argv_type = XTRACT_FLOAT; + break; + case XTRACT_SKEWNESS: + case XTRACT_KURTOSIS: + case XTRACT_SPECTRAL_SKEWNESS: + case XTRACT_SPECTRAL_KURTOSIS: + case XTRACT_PEAK_SPECTRUM: + case XTRACT_HARMONIC_SPECTRUM: + case XTRACT_NOISINESS: + case XTRACT_CREST: + case XTRACT_ROLLOFF: + case XTRACT_FLUX: + case XTRACT_LNORM: + *argc = 2; + *argv_type = XTRACT_FLOAT; + break; + case XTRACT_SPECTRUM: + *argc = 4; + *argv_type = XTRACT_FLOAT; + break; + case XTRACT_SUBBANDS: + *argc = 4; + *argv_type = XTRACT_INT; + break; + case XTRACT_MFCC: + *argc = 1; + *argv_type = XTRACT_MEL_FILTER; + break; + case XTRACT_LPCC: + *argc = 1; + *argv_type = XTRACT_INT; + break; + case XTRACT_BARK_COEFFICIENTS: + *argc = XTRACT_BARK_BANDS; + *argv_type = XTRACT_INT; + break; + case XTRACT_WINDOWED: + *argc = XTRACT_WINDOW_SIZE; + *argv_type = XTRACT_FLOAT; + break; + case XTRACT_MEAN: + case XTRACT_SPECTRAL_MEAN: + case XTRACT_SPECTRAL_CENTROID: + case XTRACT_IRREGULARITY_K: + case XTRACT_IRREGULARITY_J: + case XTRACT_TRISTIMULUS_1: + case XTRACT_TRISTIMULUS_2: + case XTRACT_TRISTIMULUS_3: + case XTRACT_SMOOTHNESS: + case XTRACT_FLATNESS: + case XTRACT_SPREAD: + case XTRACT_ZCR: + case XTRACT_LOUDNESS: + case XTRACT_HIGHEST_VALUE: + case XTRACT_SUM: + case XTRACT_RMS_AMPLITUDE: + case XTRACT_POWER: + case XTRACT_SHARPNESS: + case XTRACT_SPECTRAL_SLOPE: + case XTRACT_HPS: + case XTRACT_ATTACK_TIME: + case XTRACT_DECAY_TIME: + case XTRACT_DIFFERENCE_VECTOR: + case XTRACT_AUTOCORRELATION_FFT: + case XTRACT_DCT: + case XTRACT_AUTOCORRELATION: + case XTRACT_AMDF: + case XTRACT_ASDF: + case XTRACT_NONZERO_COUNT: + case XTRACT_ODD_EVEN_RATIO: + case XTRACT_LPC: + default: + *argc = 0; + break; } is_scalar = &d->is_scalar; - switch(f){ + switch(f) + { + case XTRACT_MEAN: + case XTRACT_VARIANCE: + case XTRACT_STANDARD_DEVIATION: + case XTRACT_AVERAGE_DEVIATION: + case XTRACT_SKEWNESS: + case XTRACT_KURTOSIS: + case XTRACT_SPECTRAL_MEAN: + case XTRACT_SPECTRAL_VARIANCE: + case XTRACT_SPECTRAL_STANDARD_DEVIATION: + /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ + case XTRACT_SPECTRAL_SKEWNESS: + case XTRACT_SPECTRAL_KURTOSIS: + case XTRACT_SPECTRAL_CENTROID: + case XTRACT_IRREGULARITY_K: + case XTRACT_IRREGULARITY_J: + case XTRACT_TRISTIMULUS_1: + case XTRACT_TRISTIMULUS_2: + case XTRACT_TRISTIMULUS_3: + case XTRACT_SMOOTHNESS: + case XTRACT_SPREAD: + case XTRACT_ZCR: + case XTRACT_ROLLOFF: + case XTRACT_LOUDNESS: + case XTRACT_FLATNESS: + case XTRACT_FLATNESS_DB: + case XTRACT_TONALITY: + case XTRACT_CREST: + case XTRACT_NOISINESS: + case XTRACT_RMS_AMPLITUDE: + case XTRACT_SPECTRAL_INHARMONICITY: + case XTRACT_POWER: + case XTRACT_ODD_EVEN_RATIO: + case XTRACT_SHARPNESS: + case XTRACT_SPECTRAL_SLOPE: + case XTRACT_LOWEST_VALUE: + case XTRACT_HIGHEST_VALUE: + case XTRACT_SUM: + case XTRACT_HPS: + case XTRACT_F0: + case XTRACT_FAILSAFE_F0: + case XTRACT_FLUX: + case XTRACT_LNORM: + case XTRACT_NONZERO_COUNT: + *is_scalar = XTRACT_TRUE; + break; + case XTRACT_AUTOCORRELATION: + case XTRACT_AMDF: + case XTRACT_ASDF: + case XTRACT_BARK_COEFFICIENTS: + case XTRACT_PEAK_SPECTRUM: + case XTRACT_SPECTRUM: + case XTRACT_SUBBANDS: + case XTRACT_AUTOCORRELATION_FFT: + case XTRACT_MFCC: + case XTRACT_LPC: + case XTRACT_LPCC: + case XTRACT_DCT: + case XTRACT_HARMONIC_SPECTRUM: + case XTRACT_DIFFERENCE_VECTOR: + case XTRACT_WINDOWED: + *is_scalar = XTRACT_FALSE; + break; + default: + *is_scalar = XTRACT_TRUE; + break; + + } + + is_delta = &d->is_delta; + + switch(f) + { + case XTRACT_FLUX: + case XTRACT_LNORM: + case XTRACT_DIFFERENCE_VECTOR: + *is_delta = XTRACT_TRUE; + break; + case XTRACT_MEAN: + case XTRACT_VARIANCE: + case XTRACT_STANDARD_DEVIATION: + case XTRACT_AVERAGE_DEVIATION: + case XTRACT_SKEWNESS: + case XTRACT_KURTOSIS: + case XTRACT_SPECTRAL_MEAN: + case XTRACT_SPECTRAL_VARIANCE: + case XTRACT_SPECTRAL_STANDARD_DEVIATION: + /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ + case XTRACT_SPECTRAL_SKEWNESS: + case XTRACT_SPECTRAL_KURTOSIS: + case XTRACT_SPECTRAL_CENTROID: + case XTRACT_IRREGULARITY_K: + case XTRACT_IRREGULARITY_J: + case XTRACT_TRISTIMULUS_1: + case XTRACT_TRISTIMULUS_2: + case XTRACT_TRISTIMULUS_3: + case XTRACT_SMOOTHNESS: + case XTRACT_SPREAD: + case XTRACT_ZCR: + case XTRACT_ROLLOFF: + case XTRACT_LOUDNESS: + case XTRACT_FLATNESS: + case XTRACT_FLATNESS_DB: + case XTRACT_TONALITY: + case XTRACT_CREST: + case XTRACT_NOISINESS: + case XTRACT_RMS_AMPLITUDE: + case XTRACT_SPECTRAL_INHARMONICITY: + case XTRACT_POWER: + case XTRACT_ODD_EVEN_RATIO: + case XTRACT_SHARPNESS: + case XTRACT_SPECTRAL_SLOPE: + case XTRACT_LOWEST_VALUE: + case XTRACT_HIGHEST_VALUE: + case XTRACT_SUM: + case XTRACT_HPS: + case XTRACT_F0: + case XTRACT_FAILSAFE_F0: + case XTRACT_NONZERO_COUNT: + case XTRACT_AUTOCORRELATION: + case XTRACT_AMDF: + case XTRACT_ASDF: + case XTRACT_BARK_COEFFICIENTS: + case XTRACT_PEAK_SPECTRUM: + case XTRACT_SPECTRUM: + case XTRACT_SUBBANDS: + case XTRACT_AUTOCORRELATION_FFT: + case XTRACT_MFCC: + case XTRACT_LPC: + case XTRACT_LPCC: + case XTRACT_DCT: + case XTRACT_HARMONIC_SPECTRUM: + case XTRACT_WINDOWED: + default: + *is_delta = XTRACT_FALSE; + break; + } + + if(*is_scalar) + { + + result_unit = &d->result.scalar.unit; + result_min = &d->result.scalar.min; + result_max = &d->result.scalar.max; + + switch(f) + { case XTRACT_MEAN: case XTRACT_VARIANCE: case XTRACT_STANDARD_DEVIATION: case XTRACT_AVERAGE_DEVIATION: case XTRACT_SKEWNESS: case XTRACT_KURTOSIS: - case XTRACT_SPECTRAL_MEAN: - case XTRACT_SPECTRAL_VARIANCE: - case XTRACT_SPECTRAL_STANDARD_DEVIATION: - /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ - case XTRACT_SPECTRAL_SKEWNESS: - case XTRACT_SPECTRAL_KURTOSIS: - case XTRACT_SPECTRAL_CENTROID: - case XTRACT_IRREGULARITY_K: - case XTRACT_IRREGULARITY_J: - case XTRACT_TRISTIMULUS_1: - case XTRACT_TRISTIMULUS_2: - case XTRACT_TRISTIMULUS_3: - case XTRACT_SMOOTHNESS: - case XTRACT_SPREAD: - case XTRACT_ZCR: - case XTRACT_ROLLOFF: - case XTRACT_LOUDNESS: - case XTRACT_FLATNESS: - case XTRACT_FLATNESS_DB: - case XTRACT_TONALITY: - case XTRACT_CREST: - case XTRACT_NOISINESS: case XTRACT_RMS_AMPLITUDE: - case XTRACT_SPECTRAL_INHARMONICITY: - case XTRACT_POWER: - case XTRACT_ODD_EVEN_RATIO: - case XTRACT_SHARPNESS: - case XTRACT_SPECTRAL_SLOPE: case XTRACT_LOWEST_VALUE: case XTRACT_HIGHEST_VALUE: case XTRACT_SUM: - case XTRACT_HPS: - case XTRACT_F0: - case XTRACT_FAILSAFE_F0: case XTRACT_FLUX: case XTRACT_LNORM: case XTRACT_NONZERO_COUNT: - *is_scalar = XTRACT_TRUE; - break; - case XTRACT_AUTOCORRELATION: - case XTRACT_AMDF: - case XTRACT_ASDF: - case XTRACT_BARK_COEFFICIENTS: - case XTRACT_PEAK_SPECTRUM: - case XTRACT_SPECTRUM: - case XTRACT_SUBBANDS: - case XTRACT_AUTOCORRELATION_FFT: - case XTRACT_MFCC: - case XTRACT_LPC: - case XTRACT_LPCC: - case XTRACT_DCT: - case XTRACT_HARMONIC_SPECTRUM: - case XTRACT_DIFFERENCE_VECTOR: case XTRACT_WINDOWED: - *is_scalar = XTRACT_FALSE; - break; - default: - *is_scalar = XTRACT_TRUE; - break; - - } - - is_delta = &d->is_delta; - - switch(f){ - case XTRACT_FLUX: - case XTRACT_LNORM: - case XTRACT_DIFFERENCE_VECTOR: - *is_delta = XTRACT_TRUE; + *result_unit = XTRACT_ANY; + *result_min = XTRACT_ANY; + *result_max = XTRACT_ANY; break; - case XTRACT_MEAN: - case XTRACT_VARIANCE: - case XTRACT_STANDARD_DEVIATION: - case XTRACT_AVERAGE_DEVIATION: - case XTRACT_SKEWNESS: - case XTRACT_KURTOSIS: - case XTRACT_SPECTRAL_MEAN: - case XTRACT_SPECTRAL_VARIANCE: - case XTRACT_SPECTRAL_STANDARD_DEVIATION: - /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ case XTRACT_SPECTRAL_SKEWNESS: case XTRACT_SPECTRAL_KURTOSIS: - case XTRACT_SPECTRAL_CENTROID: case XTRACT_IRREGULARITY_K: case XTRACT_IRREGULARITY_J: case XTRACT_TRISTIMULUS_1: case XTRACT_TRISTIMULUS_2: case XTRACT_TRISTIMULUS_3: + case XTRACT_NOISINESS: case XTRACT_SMOOTHNESS: + *result_unit = XTRACT_NONE; + *result_min = XTRACT_ANY; /* FIX: need to check these */ + *result_max = XTRACT_ANY; + break; + case XTRACT_SPECTRAL_MEAN: + case XTRACT_SPECTRAL_VARIANCE: + case XTRACT_SPECTRAL_STANDARD_DEVIATION: + /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ + case XTRACT_SPECTRAL_CENTROID: case XTRACT_SPREAD: - case XTRACT_ZCR: + case XTRACT_F0: + case XTRACT_FAILSAFE_F0: + case XTRACT_HPS: case XTRACT_ROLLOFF: + *result_unit = XTRACT_HERTZ; + *result_min = 0.f; + *result_max = XTRACT_SR_UPPER_LIMIT / 2; + break; + case XTRACT_ZCR: + *result_unit = XTRACT_HERTZ; + *result_min = 0.f; + *result_max = XTRACT_ANY; + break; + case XTRACT_ODD_EVEN_RATIO: + *result_unit = XTRACT_NONE; + *result_min = 0.f; + *result_max = 1.f; + break; + case XTRACT_FLATNESS_DB: + *result_unit = XTRACT_DBFS; + *result_min = XTRACT_ANY; /* FIX: check this */ + *result_max = XTRACT_ANY; + break; case XTRACT_LOUDNESS: case XTRACT_FLATNESS: - case XTRACT_FLATNESS_DB: case XTRACT_TONALITY: case XTRACT_CREST: - case XTRACT_NOISINESS: - case XTRACT_RMS_AMPLITUDE: case XTRACT_SPECTRAL_INHARMONICITY: case XTRACT_POWER: - case XTRACT_ODD_EVEN_RATIO: case XTRACT_SHARPNESS: case XTRACT_SPECTRAL_SLOPE: - case XTRACT_LOWEST_VALUE: - case XTRACT_HIGHEST_VALUE: - case XTRACT_SUM: - case XTRACT_HPS: - case XTRACT_F0: - case XTRACT_FAILSAFE_F0: - case XTRACT_NONZERO_COUNT: - case XTRACT_AUTOCORRELATION: - case XTRACT_AMDF: - case XTRACT_ASDF: - case XTRACT_BARK_COEFFICIENTS: - case XTRACT_PEAK_SPECTRUM: - case XTRACT_SPECTRUM: - case XTRACT_SUBBANDS: - case XTRACT_AUTOCORRELATION_FFT: - case XTRACT_MFCC: case XTRACT_LPC: case XTRACT_LPCC: - case XTRACT_DCT: - case XTRACT_HARMONIC_SPECTRUM: - case XTRACT_WINDOWED: default: - *is_delta = XTRACT_FALSE; + *result_unit = XTRACT_UNKNOWN; + *result_min = XTRACT_UNKNOWN; + *result_max = XTRACT_UNKNOWN; break; - } - - if(*is_scalar){ - - result_unit = &d->result.scalar.unit; - result_min = &d->result.scalar.min; - result_max = &d->result.scalar.max; - - switch(f){ - case XTRACT_MEAN: - case XTRACT_VARIANCE: - case XTRACT_STANDARD_DEVIATION: - case XTRACT_AVERAGE_DEVIATION: - case XTRACT_SKEWNESS: - case XTRACT_KURTOSIS: - case XTRACT_RMS_AMPLITUDE: - case XTRACT_LOWEST_VALUE: - case XTRACT_HIGHEST_VALUE: - case XTRACT_SUM: - case XTRACT_FLUX: - case XTRACT_LNORM: - case XTRACT_NONZERO_COUNT: - case XTRACT_WINDOWED: - *result_unit = XTRACT_ANY; - *result_min = XTRACT_ANY; - *result_max = XTRACT_ANY; - break; - case XTRACT_SPECTRAL_SKEWNESS: - case XTRACT_SPECTRAL_KURTOSIS: - case XTRACT_IRREGULARITY_K: - case XTRACT_IRREGULARITY_J: - case XTRACT_TRISTIMULUS_1: - case XTRACT_TRISTIMULUS_2: - case XTRACT_TRISTIMULUS_3: - case XTRACT_NOISINESS: - case XTRACT_SMOOTHNESS: - *result_unit = XTRACT_NONE; - *result_min = XTRACT_ANY; /* FIX: need to check these */ - *result_max = XTRACT_ANY; - break; - case XTRACT_SPECTRAL_MEAN: - case XTRACT_SPECTRAL_VARIANCE: - case XTRACT_SPECTRAL_STANDARD_DEVIATION: - /* case XTRACT_SPECTRAL_AVERAGE_DEVIATION: */ - case XTRACT_SPECTRAL_CENTROID: - case XTRACT_SPREAD: - case XTRACT_F0: - case XTRACT_FAILSAFE_F0: - case XTRACT_HPS: - case XTRACT_ROLLOFF: - *result_unit = XTRACT_HERTZ; - *result_min = 0.f; - *result_max = XTRACT_SR_UPPER_LIMIT / 2; - break; - case XTRACT_ZCR: - *result_unit = XTRACT_HERTZ; - *result_min = 0.f; - *result_max = XTRACT_ANY; - break; - case XTRACT_ODD_EVEN_RATIO: - *result_unit = XTRACT_NONE; - *result_min = 0.f; - *result_max = 1.f; - break; - case XTRACT_FLATNESS_DB: - *result_unit = XTRACT_DBFS; - *result_min = XTRACT_ANY; /* FIX: check this */ - *result_max = XTRACT_ANY; - break; - case XTRACT_LOUDNESS: - case XTRACT_FLATNESS: - case XTRACT_TONALITY: - case XTRACT_CREST: - case XTRACT_SPECTRAL_INHARMONICITY: - case XTRACT_POWER: - case XTRACT_SHARPNESS: - case XTRACT_SPECTRAL_SLOPE: - case XTRACT_LPC: - case XTRACT_LPCC: - default: - *result_unit = XTRACT_UNKNOWN; - *result_min = XTRACT_UNKNOWN; - *result_max = XTRACT_UNKNOWN; - break; } } - else { + else + { result_min = NULL; result_max = NULL; result_unit = &d->result.vector.unit; result_format = &d->result.vector.format; - switch(f) { - case XTRACT_AUTOCORRELATION: - case XTRACT_AMDF: - case XTRACT_ASDF: - case XTRACT_DCT: - case XTRACT_SUBBANDS: - case XTRACT_WINDOWED: - *result_format = XTRACT_ARBITRARY_SERIES; - *result_unit = XTRACT_ANY; - break; - case XTRACT_BARK_COEFFICIENTS: - *result_format = XTRACT_BARK_COEFFS; - *result_unit = XTRACT_UNKNOWN; /* FIX: check */ - break; - case XTRACT_PEAK_SPECTRUM: - case XTRACT_SPECTRUM: - case XTRACT_HARMONIC_SPECTRUM: - *result_format = XTRACT_SPECTRAL; - *result_unit = XTRACT_ANY_AMPLITUDE_HERTZ; - break; - case XTRACT_AUTOCORRELATION_FFT: - break; - case XTRACT_MFCC: - *result_format = XTRACT_MEL_COEFFS; - *result_unit = XTRACT_UNKNOWN; /* FIX: check */ - break; - case XTRACT_LPC: - *result_format = XTRACT_LPC_COEFFS; - *result_unit = XTRACT_UNKNOWN; - break; - case XTRACT_LPCC: - *result_format = XTRACT_LPCC_COEFFS; - *result_unit = XTRACT_UNKNOWN; - break; - default: - break; + switch(f) + { + case XTRACT_AUTOCORRELATION: + case XTRACT_AMDF: + case XTRACT_ASDF: + case XTRACT_DCT: + case XTRACT_SUBBANDS: + case XTRACT_WINDOWED: + *result_format = XTRACT_ARBITRARY_SERIES; + *result_unit = XTRACT_ANY; + break; + case XTRACT_BARK_COEFFICIENTS: + *result_format = XTRACT_BARK_COEFFS; + *result_unit = XTRACT_UNKNOWN; /* FIX: check */ + break; + case XTRACT_PEAK_SPECTRUM: + case XTRACT_SPECTRUM: + case XTRACT_HARMONIC_SPECTRUM: + *result_format = XTRACT_SPECTRAL; + *result_unit = XTRACT_ANY_AMPLITUDE_HERTZ; + break; + case XTRACT_AUTOCORRELATION_FFT: + break; + case XTRACT_MFCC: + *result_format = XTRACT_MEL_COEFFS; + *result_unit = XTRACT_UNKNOWN; /* FIX: check */ + break; + case XTRACT_LPC: + *result_format = XTRACT_LPC_COEFFS; + *result_unit = XTRACT_UNKNOWN; + break; + case XTRACT_LPCC: + *result_format = XTRACT_LPCC_COEFFS; + *result_unit = XTRACT_UNKNOWN; + break; + default: + break; } } } @@ -1321,9 +1335,11 @@ xtract_function_descriptor_t *xtract_make_descriptors(void){ return fd; } -int xtract_free_descriptors(xtract_function_descriptor_t *fd){ +int xtract_free_descriptors(xtract_function_descriptor_t *fd) +{ - if (fd != NULL) { + if (fd != NULL) + { free(fd); } diff --git a/src/fftsg.c b/src/fftsg.c new file mode 100644 index 0000000..0f3092b --- /dev/null +++ b/src/fftsg.c @@ -0,0 +1,3492 @@ +/* +Fast Fourier/Cosine/Sine Transform + dimension :one + data length :power of 2 + decimation :frequency + radix :split-radix + data :inplace + table :use +functions + cdft: Complex Discrete Fourier Transform + rdft: Real Discrete Fourier Transform + ddct: Discrete Cosine Transform + ddst: Discrete Sine Transform + dfct: Cosine Transform of RDFT (Real Symmetric DFT) + dfst: Sine Transform of RDFT (Real Anti-symmetric DFT) +function prototypes + void cdft(int, int, double *, int *, double *); + void rdft(int, int, double *, int *, double *); + void ddct(int, int, double *, int *, double *); + void ddst(int, int, double *, int *, double *); + void dfct(int, double *, double *, int *, double *); + void dfst(int, double *, double *, int *, double *); +macro definitions + USE_CDFT_PTHREADS : default=not defined + CDFT_THREADS_BEGIN_N : must be >= 512, default=8192 + CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536 + USE_CDFT_WINTHREADS : default=not defined + CDFT_THREADS_BEGIN_N : must be >= 512, default=32768 + CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288 + + +-------- Complex DFT (Discrete Fourier Transform) -------- + [definition] + <case1> + X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n + <case2> + X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n + (notes: sum_j=0^n-1 is a summation from j=0 to n-1) + [usage] + <case1> + ip[0] = 0; // first time only + cdft(2*n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + cdft(2*n, -1, a, ip, w); + [parameters] + 2*n :data length (int) + n >= 1, n = power of 2 + a[0...2*n-1] :input/output data (double *) + input data + a[2*j] = Re(x[j]), + a[2*j+1] = Im(x[j]), 0<=j<n + output data + a[2*k] = Re(X[k]), + a[2*k+1] = Im(X[k]), 0<=k<n + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n) + strictly, + length of ip >= + 2+(1<<(int)(log(n+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n/2-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + cdft(2*n, -1, a, ip, w); + is + cdft(2*n, 1, a, ip, w); + for (j = 0; j <= 2 * n - 1; j++) { + a[j] *= 1.0 / n; + } + . + + +-------- Real DFT / Inverse of Real DFT -------- + [definition] + <case1> RDFT + R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2 + I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2 + <case2> IRDFT (excluding scale) + a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + + sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + + sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n + [usage] + <case1> + ip[0] = 0; // first time only + rdft(n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + rdft(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + <case1> + output data + a[2*k] = R[k], 0<=k<n/2 + a[2*k+1] = I[k], 0<k<n/2 + a[1] = R[n/2] + <case2> + input data + a[2*j] = R[j], 0<=j<n/2 + a[2*j+1] = I[j], 0<j<n/2 + a[1] = R[n/2] + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n/2-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + rdft(n, 1, a, ip, w); + is + rdft(n, -1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- DCT (Discrete Cosine Transform) / Inverse of DCT -------- + [definition] + <case1> IDCT (excluding scale) + C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n + <case2> DCT + C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n + [usage] + <case1> + ip[0] = 0; // first time only + ddct(n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + ddct(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + output data + a[k] = C[k], 0<=k<n + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/4-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddct(n, -1, a, ip, w); + is + a[0] *= 0.5; + ddct(n, 1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- DST (Discrete Sine Transform) / Inverse of DST -------- + [definition] + <case1> IDST (excluding scale) + S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n + <case2> DST + S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n + [usage] + <case1> + ip[0] = 0; // first time only + ddst(n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + ddst(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + <case1> + input data + a[j] = A[j], 0<j<n + a[0] = A[n] + output data + a[k] = S[k], 0<=k<n + <case2> + output data + a[k] = S[k], 0<k<n + a[0] = S[n] + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/4-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddst(n, -1, a, ip, w); + is + a[0] *= 0.5; + ddst(n, 1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- Cosine Transform of RDFT (Real Symmetric DFT) -------- + [definition] + C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n + [usage] + ip[0] = 0; // first time only + dfct(n, a, t, ip, w); + [parameters] + n :data length - 1 (int) + n >= 2, n = power of 2 + a[0...n] :input/output data (double *) + output data + a[k] = C[k], 0<=k<=n + t[0...n/2] :work area (double *) + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/4) + strictly, + length of ip >= + 2+(1<<(int)(log(n/4+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/8-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + a[0] *= 0.5; + a[n] *= 0.5; + dfct(n, a, t, ip, w); + is + a[0] *= 0.5; + a[n] *= 0.5; + dfct(n, a, t, ip, w); + for (j = 0; j <= n; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- Sine Transform of RDFT (Real Anti-symmetric DFT) -------- + [definition] + S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n + [usage] + ip[0] = 0; // first time only + dfst(n, a, t, ip, w); + [parameters] + n :data length + 1 (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + output data + a[k] = S[k], 0<k<n + (a[0] is used for work area) + t[0...n/2-1] :work area (double *) + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/4) + strictly, + length of ip >= + 2+(1<<(int)(log(n/4+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/8-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + dfst(n, a, t, ip, w); + is + dfst(n, a, t, ip, w); + for (j = 1; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +Appendix : + The cos/sin table is recalculated when the larger table required. + w[] and ip[] are compatible with all routines. +*/ + + +void cdft(int n, int isgn, double *a, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void cftbsub(int n, double *a, int *ip, int nw, double *w); + int nw; + + nw = ip[0]; + if (n > (nw << 2)) + { + nw = n >> 2; + makewt(nw, ip, w); + } + if (isgn >= 0) + { + cftfsub(n, a, ip, nw, w); + } + else + { + cftbsub(n, a, ip, nw, w); + } +} + + +void rdft(int n, int isgn, double *a, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void cftbsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void rftbsub(int n, double *a, int nc, double *c); + int nw, nc; + double xi; + + nw = ip[0]; + if (n > (nw << 2)) + { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > (nc << 2)) + { + nc = n >> 2; + makect(nc, ip, w + nw); + } + if (isgn >= 0) + { + if (n > 4) + { + cftfsub(n, a, ip, nw, w); + rftfsub(n, a, nc, w + nw); + } + else if (n == 4) + { + cftfsub(n, a, ip, nw, w); + } + xi = a[0] - a[1]; + a[0] += a[1]; + a[1] = xi; + } + else + { + a[1] = 0.5 * (a[0] - a[1]); + a[0] -= a[1]; + if (n > 4) + { + rftbsub(n, a, nc, w + nw); + cftbsub(n, a, ip, nw, w); + } + else if (n == 4) + { + cftbsub(n, a, ip, nw, w); + } + } +} + + +void ddct(int n, int isgn, double *a, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void cftbsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void rftbsub(int n, double *a, int nc, double *c); + void dctsub(int n, double *a, int nc, double *c); + int j, nw, nc; + double xr; + + nw = ip[0]; + if (n > (nw << 2)) + { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > nc) + { + nc = n; + makect(nc, ip, w + nw); + } + if (isgn < 0) + { + xr = a[n - 1]; + for (j = n - 2; j >= 2; j -= 2) + { + a[j + 1] = a[j] - a[j - 1]; + a[j] += a[j - 1]; + } + a[1] = a[0] - xr; + a[0] += xr; + if (n > 4) + { + rftbsub(n, a, nc, w + nw); + cftbsub(n, a, ip, nw, w); + } + else if (n == 4) + { + cftbsub(n, a, ip, nw, w); + } + } + dctsub(n, a, nc, w + nw); + if (isgn >= 0) + { + if (n > 4) + { + cftfsub(n, a, ip, nw, w); + rftfsub(n, a, nc, w + nw); + } + else if (n == 4) + { + cftfsub(n, a, ip, nw, w); + } + xr = a[0] - a[1]; + a[0] += a[1]; + for (j = 2; j < n; j += 2) + { + a[j - 1] = a[j] - a[j + 1]; + a[j] += a[j + 1]; + } + a[n - 1] = xr; + } +} + + +void ddst(int n, int isgn, double *a, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void cftbsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void rftbsub(int n, double *a, int nc, double *c); + void dstsub(int n, double *a, int nc, double *c); + int j, nw, nc; + double xr; + + nw = ip[0]; + if (n > (nw << 2)) + { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > nc) + { + nc = n; + makect(nc, ip, w + nw); + } + if (isgn < 0) + { + xr = a[n - 1]; + for (j = n - 2; j >= 2; j -= 2) + { + a[j + 1] = -a[j] - a[j - 1]; + a[j] -= a[j - 1]; + } + a[1] = a[0] + xr; + a[0] -= xr; + if (n > 4) + { + rftbsub(n, a, nc, w + nw); + cftbsub(n, a, ip, nw, w); + } + else if (n == 4) + { + cftbsub(n, a, ip, nw, w); + } + } + dstsub(n, a, nc, w + nw); + if (isgn >= 0) + { + if (n > 4) + { + cftfsub(n, a, ip, nw, w); + rftfsub(n, a, nc, w + nw); + } + else if (n == 4) + { + cftfsub(n, a, ip, nw, w); + } + xr = a[0] - a[1]; + a[0] += a[1]; + for (j = 2; j < n; j += 2) + { + a[j - 1] = -a[j] - a[j + 1]; + a[j] -= a[j + 1]; + } + a[n - 1] = -xr; + } +} + + +void dfct(int n, double *a, double *t, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void dctsub(int n, double *a, int nc, double *c); + int j, k, l, m, mh, nw, nc; + double xr, xi, yr, yi; + + nw = ip[0]; + if (n > (nw << 3)) + { + nw = n >> 3; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > (nc << 1)) + { + nc = n >> 1; + makect(nc, ip, w + nw); + } + m = n >> 1; + yi = a[m]; + xi = a[0] + a[n]; + a[0] -= a[n]; + t[0] = xi - yi; + t[m] = xi + yi; + if (n > 2) + { + mh = m >> 1; + for (j = 1; j < mh; j++) + { + k = m - j; + xr = a[j] - a[n - j]; + xi = a[j] + a[n - j]; + yr = a[k] - a[n - k]; + yi = a[k] + a[n - k]; + a[j] = xr; + a[k] = yr; + t[j] = xi - yi; + t[k] = xi + yi; + } + t[mh] = a[mh] + a[n - mh]; + a[mh] -= a[n - mh]; + dctsub(m, a, nc, w + nw); + if (m > 4) + { + cftfsub(m, a, ip, nw, w); + rftfsub(m, a, nc, w + nw); + } + else if (m == 4) + { + cftfsub(m, a, ip, nw, w); + } + a[n - 1] = a[0] - a[1]; + a[1] = a[0] + a[1]; + for (j = m - 2; j >= 2; j -= 2) + { + a[2 * j + 1] = a[j] + a[j + 1]; + a[2 * j - 1] = a[j] - a[j + 1]; + } + l = 2; + m = mh; + while (m >= 2) + { + dctsub(m, t, nc, w + nw); + if (m > 4) + { + cftfsub(m, t, ip, nw, w); + rftfsub(m, t, nc, w + nw); + } + else if (m == 4) + { + cftfsub(m, t, ip, nw, w); + } + a[n - l] = t[0] - t[1]; + a[l] = t[0] + t[1]; + k = 0; + for (j = 2; j < m; j += 2) + { + k += l << 2; + a[k - l] = t[j] - t[j + 1]; + a[k + l] = t[j] + t[j + 1]; + } + l <<= 1; + mh = m >> 1; + for (j = 0; j < mh; j++) + { + k = m - j; + t[j] = t[m + k] - t[m + j]; + t[k] = t[m + k] + t[m + j]; + } + t[mh] = t[m + mh]; + m = mh; + } + a[l] = t[0]; + a[n] = t[2] - t[1]; + a[0] = t[2] + t[1]; + } + else + { + a[1] = a[0]; + a[2] = t[0]; + a[0] = t[1]; + } +} + + +void dfst(int n, double *a, double *t, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void dstsub(int n, double *a, int nc, double *c); + int j, k, l, m, mh, nw, nc; + double xr, xi, yr, yi; + + nw = ip[0]; + if (n > (nw << 3)) + { + nw = n >> 3; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > (nc << 1)) + { + nc = n >> 1; + makect(nc, ip, w + nw); + } + if (n > 2) + { + m = n >> 1; + mh = m >> 1; + for (j = 1; j < mh; j++) + { + k = m - j; + xr = a[j] + a[n - j]; + xi = a[j] - a[n - j]; + yr = a[k] + a[n - k]; + yi = a[k] - a[n - k]; + a[j] = xr; + a[k] = yr; + t[j] = xi + yi; + t[k] = xi - yi; + } + t[0] = a[mh] - a[n - mh]; + a[mh] += a[n - mh]; + a[0] = a[m]; + dstsub(m, a, nc, w + nw); + if (m > 4) + { + cftfsub(m, a, ip, nw, w); + rftfsub(m, a, nc, w + nw); + } + else if (m == 4) + { + cftfsub(m, a, ip, nw, w); + } + a[n - 1] = a[1] - a[0]; + a[1] = a[0] + a[1]; + for (j = m - 2; j >= 2; j -= 2) + { + a[2 * j + 1] = a[j] - a[j + 1]; + a[2 * j - 1] = -a[j] - a[j + 1]; + } + l = 2; + m = mh; + while (m >= 2) + { + dstsub(m, t, nc, w + nw); + if (m > 4) + { + cftfsub(m, t, ip, nw, w); + rftfsub(m, t, nc, w + nw); + } + else if (m == 4) + { + cftfsub(m, t, ip, nw, w); + } + a[n - l] = t[1] - t[0]; + a[l] = t[0] + t[1]; + k = 0; + for (j = 2; j < m; j += 2) + { + k += l << 2; + a[k - l] = -t[j] - t[j + 1]; + a[k + l] = t[j] - t[j + 1]; + } + l <<= 1; + mh = m >> 1; + for (j = 1; j < mh; j++) + { + k = m - j; + t[j] = t[m + k] + t[m + j]; + t[k] = t[m + k] - t[m + j]; + } + t[0] = t[m + mh]; + m = mh; + } + a[l] = t[0]; + } + a[0] = 0; +} + + +/* -------- initializing routines -------- */ + + +#include <math.h> + +void makewt(int nw, int *ip, double *w) +{ + void makeipt(int nw, int *ip); + int j, nwh, nw0, nw1; + double delta, wn4r, wk1r, wk1i, wk3r, wk3i; + + ip[0] = nw; + ip[1] = 1; + if (nw > 2) + { + nwh = nw >> 1; + delta = atan(1.0) / nwh; + wn4r = cos(delta * nwh); + w[0] = 1; + w[1] = wn4r; + if (nwh == 4) + { + w[2] = cos(delta * 2); + w[3] = sin(delta * 2); + } + else if (nwh > 4) + { + makeipt(nw, ip); + w[2] = 0.5 / cos(delta * 2); + w[3] = 0.5 / cos(delta * 6); + for (j = 4; j < nwh; j += 4) + { + w[j] = cos(delta * j); + w[j + 1] = sin(delta * j); + w[j + 2] = cos(3 * delta * j); + w[j + 3] = -sin(3 * delta * j); + } + } + nw0 = 0; + while (nwh > 2) + { + nw1 = nw0 + nwh; + nwh >>= 1; + w[nw1] = 1; + w[nw1 + 1] = wn4r; + if (nwh == 4) + { + wk1r = w[nw0 + 4]; + wk1i = w[nw0 + 5]; + w[nw1 + 2] = wk1r; + w[nw1 + 3] = wk1i; + } + else if (nwh > 4) + { + wk1r = w[nw0 + 4]; + wk3r = w[nw0 + 6]; + w[nw1 + 2] = 0.5 / wk1r; + w[nw1 + 3] = 0.5 / wk3r; + for (j = 4; j < nwh; j += 4) + { + wk1r = w[nw0 + 2 * j]; + wk1i = w[nw0 + 2 * j + 1]; + wk3r = w[nw0 + 2 * j + 2]; + wk3i = w[nw0 + 2 * j + 3]; + w[nw1 + j] = wk1r; + w[nw1 + j + 1] = wk1i; + w[nw1 + j + 2] = wk3r; + w[nw1 + j + 3] = wk3i; + } + } + nw0 = nw1; + } + } +} + + +void makeipt(int nw, int *ip) +{ + int j, l, m, m2, p, q; + + ip[2] = 0; + ip[3] = 16; + m = 2; + for (l = nw; l > 32; l >>= 2) + { + m2 = m << 1; + q = m2 << 3; + for (j = m; j < m2; j++) + { + p = ip[j] << 2; + ip[m + j] = p; + ip[m2 + j] = p + q; + } + m = m2; + } +} + + +void makect(int nc, int *ip, double *c) +{ + int j, nch; + double delta; + + ip[1] = nc; + if (nc > 1) + { + nch = nc >> 1; + delta = atan(1.0) / nch; + c[0] = cos(delta * nch); + c[nch] = 0.5 * c[0]; + for (j = 1; j < nch; j++) + { + c[j] = 0.5 * cos(delta * j); + c[nc - j] = 0.5 * sin(delta * j); + } + } +} + + +/* -------- child routines -------- */ + + +#ifdef USE_CDFT_PTHREADS +#define USE_CDFT_THREADS +#ifndef CDFT_THREADS_BEGIN_N +#define CDFT_THREADS_BEGIN_N 8192 +#endif +#ifndef CDFT_4THREADS_BEGIN_N +#define CDFT_4THREADS_BEGIN_N 65536 +#endif +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#define cdft_thread_t pthread_t +#define cdft_thread_create(thp,func,argp) { \ + if (pthread_create(thp, NULL, func, (void *) argp) != 0) { \ + fprintf(stderr, "cdft thread error\n"); \ + exit(1); \ + } \ +} +#define cdft_thread_wait(th) { \ + if (pthread_join(th, NULL) != 0) { \ + fprintf(stderr, "cdft thread error\n"); \ + exit(1); \ + } \ +} +#endif /* USE_CDFT_PTHREADS */ + + +#ifdef USE_CDFT_WINTHREADS +#define USE_CDFT_THREADS +#ifndef CDFT_THREADS_BEGIN_N +#define CDFT_THREADS_BEGIN_N 32768 +#endif +#ifndef CDFT_4THREADS_BEGIN_N +#define CDFT_4THREADS_BEGIN_N 524288 +#endif +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#define cdft_thread_t HANDLE +#define cdft_thread_create(thp,func,argp) { \ + DWORD thid; \ + *(thp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, (LPVOID) argp, 0, &thid); \ + if (*(thp) == 0) { \ + fprintf(stderr, "cdft thread error\n"); \ + exit(1); \ + } \ +} +#define cdft_thread_wait(th) { \ + WaitForSingleObject(th, INFINITE); \ + CloseHandle(th); \ +} +#endif /* USE_CDFT_WINTHREADS */ + + +void cftfsub(int n, double *a, int *ip, int nw, double *w) +{ + void bitrv2(int n, int *ip, double *a); + void bitrv216(double *a); + void bitrv208(double *a); + void cftf1st(int n, double *a, double *w); + void cftrec4(int n, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftfx41(int n, double *a, int nw, double *w); + void cftf161(double *a, double *w); + void cftf081(double *a, double *w); + void cftf040(double *a); + void cftx020(double *a); +#ifdef USE_CDFT_THREADS + void cftrec4_th(int n, double *a, int nw, double *w); +#endif /* USE_CDFT_THREADS */ + + if (n > 8) + { + if (n > 32) + { + cftf1st(n, a, &w[nw - (n >> 2)]); +#ifdef USE_CDFT_THREADS + if (n > CDFT_THREADS_BEGIN_N) + { + cftrec4_th(n, a, nw, w); + } + else +#endif /* USE_CDFT_THREADS */ + if (n > 512) + { + cftrec4(n, a, nw, w); + } + else if (n > 128) + { + cftleaf(n, 1, a, nw, w); + } + else + { + cftfx41(n, a, nw, w); + } + bitrv2(n, ip, a); + } + else if (n == 32) + { + cftf161(a, &w[nw - 8]); + bitrv216(a); + } + else + { + cftf081(a, w); + bitrv208(a); + } + } + else if (n == 8) + { + cftf040(a); + } + else if (n == 4) + { + cftx020(a); + } +} + + +void cftbsub(int n, double *a, int *ip, int nw, double *w) +{ + void bitrv2conj(int n, int *ip, double *a); + void bitrv216neg(double *a); + void bitrv208neg(double *a); + void cftb1st(int n, double *a, double *w); + void cftrec4(int n, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftfx41(int n, double *a, int nw, double *w); + void cftf161(double *a, double *w); + void cftf081(double *a, double *w); + void cftb040(double *a); + void cftx020(double *a); +#ifdef USE_CDFT_THREADS + void cftrec4_th(int n, double *a, int nw, double *w); +#endif /* USE_CDFT_THREADS */ + + if (n > 8) + { + if (n > 32) + { + cftb1st(n, a, &w[nw - (n >> 2)]); +#ifdef USE_CDFT_THREADS + if (n > CDFT_THREADS_BEGIN_N) + { + cftrec4_th(n, a, nw, w); + } + else +#endif /* USE_CDFT_THREADS */ + if (n > 512) + { + cftrec4(n, a, nw, w); + } + else if (n > 128) + { + cftleaf(n, 1, a, nw, w); + } + else + { + cftfx41(n, a, nw, w); + } + bitrv2conj(n, ip, a); + } + else if (n == 32) + { + cftf161(a, &w[nw - 8]); + bitrv216neg(a); + } + else + { + cftf081(a, w); + bitrv208neg(a); + } + } + else if (n == 8) + { + cftb040(a); + } + else if (n == 4) + { + cftx020(a); + } +} + + +void bitrv2(int n, int *ip, double *a) +{ + int j, j1, k, k1, l, m, nh, nm; + double xr, xi, yr, yi; + + m = 1; + for (l = n >> 2; l > 8; l >>= 2) + { + m <<= 1; + } + nh = n >> 1; + nm = 4 * m; + if (l == 8) + { + for (k = 0; k < m; k++) + { + for (j = 0; j < k; j++) + { + j1 = 4 * j + 2 * ip[m + k]; + k1 = 4 * k + 2 * ip[m + j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + 2 * ip[m + k]; + j1 = k1 + 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= 2; + k1 -= nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh + 2; + k1 += nh + 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh - nm; + k1 += 2 * nm - 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + else + { + for (k = 0; k < m; k++) + { + for (j = 0; j < k; j++) + { + j1 = 4 * j + ip[m + k]; + k1 = 4 * k + ip[m + j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + ip[m + k]; + j1 = k1 + 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } +} + + +void bitrv2conj(int n, int *ip, double *a) +{ + int j, j1, k, k1, l, m, nh, nm; + double xr, xi, yr, yi; + + m = 1; + for (l = n >> 2; l > 8; l >>= 2) + { + m <<= 1; + } + nh = n >> 1; + nm = 4 * m; + if (l == 8) + { + for (k = 0; k < m; k++) + { + for (j = 0; j < k; j++) + { + j1 = 4 * j + 2 * ip[m + k]; + k1 = 4 * k + 2 * ip[m + j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + 2 * ip[m + k]; + j1 = k1 + 2; + k1 += nh; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= 2; + k1 -= nh; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh + 2; + k1 += nh + 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh - nm; + k1 += 2 * nm - 2; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + } + } + else + { + for (k = 0; k < m; k++) + { + for (j = 0; j < k; j++) + { + j1 = 4 * j + ip[m + k]; + k1 = 4 * k + ip[m + j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + ip[m + k]; + j1 = k1 + 2; + k1 += nh; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + j1 += nm; + k1 += nm; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + } + } +} + + +void bitrv216(double *a) +{ + double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, + x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, + x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i; + + x1r = a[2]; + x1i = a[3]; + x2r = a[4]; + x2i = a[5]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x5r = a[10]; + x5i = a[11]; + x7r = a[14]; + x7i = a[15]; + x8r = a[16]; + x8i = a[17]; + x10r = a[20]; + x10i = a[21]; + x11r = a[22]; + x11i = a[23]; + x12r = a[24]; + x12i = a[25]; + x13r = a[26]; + x13i = a[27]; + x14r = a[28]; + x14i = a[29]; + a[2] = x8r; + a[3] = x8i; + a[4] = x4r; + a[5] = x4i; + a[6] = x12r; + a[7] = x12i; + a[8] = x2r; + a[9] = x2i; + a[10] = x10r; + a[11] = x10i; + a[14] = x14r; + a[15] = x14i; + a[16] = x1r; + a[17] = x1i; + a[20] = x5r; + a[21] = x5i; + a[22] = x13r; + a[23] = x13i; + a[24] = x3r; + a[25] = x3i; + a[26] = x11r; + a[27] = x11i; + a[28] = x7r; + a[29] = x7i; +} + + +void bitrv216neg(double *a) +{ + double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, + x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, + x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, + x13r, x13i, x14r, x14i, x15r, x15i; + + x1r = a[2]; + x1i = a[3]; + x2r = a[4]; + x2i = a[5]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x5r = a[10]; + x5i = a[11]; + x6r = a[12]; + x6i = a[13]; + x7r = a[14]; + x7i = a[15]; + x8r = a[16]; + x8i = a[17]; + x9r = a[18]; + x9i = a[19]; + x10r = a[20]; + x10i = a[21]; + x11r = a[22]; + x11i = a[23]; + x12r = a[24]; + x12i = a[25]; + x13r = a[26]; + x13i = a[27]; + x14r = a[28]; + x14i = a[29]; + x15r = a[30]; + x15i = a[31]; + a[2] = x15r; + a[3] = x15i; + a[4] = x7r; + a[5] = x7i; + a[6] = x11r; + a[7] = x11i; + a[8] = x3r; + a[9] = x3i; + a[10] = x13r; + a[11] = x13i; + a[12] = x5r; + a[13] = x5i; + a[14] = x9r; + a[15] = x9i; + a[16] = x1r; + a[17] = x1i; + a[18] = x14r; + a[19] = x14i; + a[20] = x6r; + a[21] = x6i; + a[22] = x10r; + a[23] = x10i; + a[24] = x2r; + a[25] = x2i; + a[26] = x12r; + a[27] = x12i; + a[28] = x4r; + a[29] = x4i; + a[30] = x8r; + a[31] = x8i; +} + + +void bitrv208(double *a) +{ + double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i; + + x1r = a[2]; + x1i = a[3]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x6r = a[12]; + x6i = a[13]; + a[2] = x4r; + a[3] = x4i; + a[6] = x6r; + a[7] = x6i; + a[8] = x1r; + a[9] = x1i; + a[12] = x3r; + a[13] = x3i; +} + + +void bitrv208neg(double *a) +{ + double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, + x5r, x5i, x6r, x6i, x7r, x7i; + + x1r = a[2]; + x1i = a[3]; + x2r = a[4]; + x2i = a[5]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x5r = a[10]; + x5i = a[11]; + x6r = a[12]; + x6i = a[13]; + x7r = a[14]; + x7i = a[15]; + a[2] = x7r; + a[3] = x7i; + a[4] = x3r; + a[5] = x3i; + a[6] = x5r; + a[7] = x5i; + a[8] = x1r; + a[9] = x1i; + a[10] = x6r; + a[11] = x6i; + a[12] = x2r; + a[13] = x2i; + a[14] = x4r; + a[15] = x4i; +} + + +void cftf1st(int n, double *a, double *w) +{ + int j, j0, j1, j2, j3, k, m, mh; + double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, + wd1r, wd1i, wd3r, wd3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; + + mh = n >> 3; + m = 2 * mh; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] + a[j2]; + x0i = a[1] + a[j2 + 1]; + x1r = a[0] - a[j2]; + x1i = a[1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j2] = x1r - x3i; + a[j2 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + wn4r = w[1]; + csc1 = w[2]; + csc3 = w[3]; + wd1r = 1; + wd1i = 0; + wd3r = 1; + wd3i = 0; + k = 0; + for (j = 2; j < mh - 2; j += 4) + { + k += 4; + wk1r = csc1 * (wd1r + w[k]); + wk1i = csc1 * (wd1i + w[k + 1]); + wk3r = csc3 * (wd3r + w[k + 2]); + wk3i = csc3 * (wd3i + w[k + 3]); + wd1r = w[k]; + wd1i = w[k + 1]; + wd3r = w[k + 2]; + wd3i = w[k + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] + a[j2]; + x0i = a[j + 1] + a[j2 + 1]; + x1r = a[j] - a[j2]; + x1i = a[j + 1] - a[j2 + 1]; + y0r = a[j + 2] + a[j2 + 2]; + y0i = a[j + 3] + a[j2 + 3]; + y1r = a[j + 2] - a[j2 + 2]; + y1i = a[j + 3] - a[j2 + 3]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 + 2] + a[j3 + 2]; + y2i = a[j1 + 3] + a[j3 + 3]; + y3r = a[j1 + 2] - a[j3 + 2]; + y3i = a[j1 + 3] - a[j3 + 3]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j + 2] = y0r + y2r; + a[j + 3] = y0i + y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j1 + 2] = y0r - y2r; + a[j1 + 3] = y0i - y2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1r * x0r - wk1i * x0i; + a[j2 + 1] = wk1r * x0i + wk1i * x0r; + x0r = y1r - y3i; + x0i = y1i + y3r; + a[j2 + 2] = wd1r * x0r - wd1i * x0i; + a[j2 + 3] = wd1r * x0i + wd1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r + wk3i * x0i; + a[j3 + 1] = wk3r * x0i - wk3i * x0r; + x0r = y1r + y3i; + x0i = y1i - y3r; + a[j3 + 2] = wd3r * x0r + wd3i * x0i; + a[j3 + 3] = wd3r * x0i - wd3i * x0r; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + y0r = a[j0 - 2] + a[j2 - 2]; + y0i = a[j0 - 1] + a[j2 - 1]; + y1r = a[j0 - 2] - a[j2 - 2]; + y1i = a[j0 - 1] - a[j2 - 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 - 2] + a[j3 - 2]; + y2i = a[j1 - 1] + a[j3 - 1]; + y3r = a[j1 - 2] - a[j3 - 2]; + y3i = a[j1 - 1] - a[j3 - 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j0 - 2] = y0r + y2r; + a[j0 - 1] = y0i + y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j1 - 2] = y0r - y2r; + a[j1 - 1] = y0i - y2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1i * x0r - wk1r * x0i; + a[j2 + 1] = wk1i * x0i + wk1r * x0r; + x0r = y1r - y3i; + x0i = y1i + y3r; + a[j2 - 2] = wd1i * x0r - wd1r * x0i; + a[j2 - 1] = wd1i * x0i + wd1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3i * x0r + wk3r * x0i; + a[j3 + 1] = wk3i * x0i - wk3r * x0r; + x0r = y1r + y3i; + x0i = y1i - y3r; + a[j3 - 2] = wd3i * x0r + wd3r * x0i; + a[j3 - 1] = wd3i * x0i - wd3r * x0r; + } + wk1r = csc1 * (wd1r + wn4r); + wk1i = csc1 * (wd1i + wn4r); + wk3r = csc3 * (wd3r - wn4r); + wk3i = csc3 * (wd3i - wn4r); + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0 - 2] + a[j2 - 2]; + x0i = a[j0 - 1] + a[j2 - 1]; + x1r = a[j0 - 2] - a[j2 - 2]; + x1i = a[j0 - 1] - a[j2 - 1]; + x2r = a[j1 - 2] + a[j3 - 2]; + x2i = a[j1 - 1] + a[j3 - 1]; + x3r = a[j1 - 2] - a[j3 - 2]; + x3i = a[j1 - 1] - a[j3 - 1]; + a[j0 - 2] = x0r + x2r; + a[j0 - 1] = x0i + x2i; + a[j1 - 2] = x0r - x2r; + a[j1 - 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2 - 2] = wk1r * x0r - wk1i * x0i; + a[j2 - 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3 - 2] = wk3r * x0r + wk3i * x0i; + a[j3 - 1] = wk3r * x0i - wk3i * x0r; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = -wn4r * (x0r + x0i); + a[j3 + 1] = -wn4r * (x0i - x0r); + x0r = a[j0 + 2] + a[j2 + 2]; + x0i = a[j0 + 3] + a[j2 + 3]; + x1r = a[j0 + 2] - a[j2 + 2]; + x1i = a[j0 + 3] - a[j2 + 3]; + x2r = a[j1 + 2] + a[j3 + 2]; + x2i = a[j1 + 3] + a[j3 + 3]; + x3r = a[j1 + 2] - a[j3 + 2]; + x3i = a[j1 + 3] - a[j3 + 3]; + a[j0 + 2] = x0r + x2r; + a[j0 + 3] = x0i + x2i; + a[j1 + 2] = x0r - x2r; + a[j1 + 3] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2 + 2] = wk1i * x0r - wk1r * x0i; + a[j2 + 3] = wk1i * x0i + wk1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3 + 2] = wk3i * x0r + wk3r * x0i; + a[j3 + 3] = wk3i * x0i - wk3r * x0r; +} + + +void cftb1st(int n, double *a, double *w) +{ + int j, j0, j1, j2, j3, k, m, mh; + double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, + wd1r, wd1i, wd3r, wd3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; + + mh = n >> 3; + m = 2 * mh; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] + a[j2]; + x0i = -a[1] - a[j2 + 1]; + x1r = a[0] - a[j2]; + x1i = -a[1] + a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[0] = x0r + x2r; + a[1] = x0i - x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + a[j2] = x1r + x3i; + a[j2 + 1] = x1i + x3r; + a[j3] = x1r - x3i; + a[j3 + 1] = x1i - x3r; + wn4r = w[1]; + csc1 = w[2]; + csc3 = w[3]; + wd1r = 1; + wd1i = 0; + wd3r = 1; + wd3i = 0; + k = 0; + for (j = 2; j < mh - 2; j += 4) + { + k += 4; + wk1r = csc1 * (wd1r + w[k]); + wk1i = csc1 * (wd1i + w[k + 1]); + wk3r = csc3 * (wd3r + w[k + 2]); + wk3i = csc3 * (wd3i + w[k + 3]); + wd1r = w[k]; + wd1i = w[k + 1]; + wd3r = w[k + 2]; + wd3i = w[k + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] + a[j2]; + x0i = -a[j + 1] - a[j2 + 1]; + x1r = a[j] - a[j2]; + x1i = -a[j + 1] + a[j2 + 1]; + y0r = a[j + 2] + a[j2 + 2]; + y0i = -a[j + 3] - a[j2 + 3]; + y1r = a[j + 2] - a[j2 + 2]; + y1i = -a[j + 3] + a[j2 + 3]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 + 2] + a[j3 + 2]; + y2i = a[j1 + 3] + a[j3 + 3]; + y3r = a[j1 + 2] - a[j3 + 2]; + y3i = a[j1 + 3] - a[j3 + 3]; + a[j] = x0r + x2r; + a[j + 1] = x0i - x2i; + a[j + 2] = y0r + y2r; + a[j + 3] = y0i - y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + a[j1 + 2] = y0r - y2r; + a[j1 + 3] = y0i + y2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2] = wk1r * x0r - wk1i * x0i; + a[j2 + 1] = wk1r * x0i + wk1i * x0r; + x0r = y1r + y3i; + x0i = y1i + y3r; + a[j2 + 2] = wd1r * x0r - wd1i * x0i; + a[j2 + 3] = wd1r * x0i + wd1i * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r + wk3i * x0i; + a[j3 + 1] = wk3r * x0i - wk3i * x0r; + x0r = y1r - y3i; + x0i = y1i - y3r; + a[j3 + 2] = wd3r * x0r + wd3i * x0i; + a[j3 + 3] = wd3r * x0i - wd3i * x0r; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = -a[j0 + 1] - a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = -a[j0 + 1] + a[j2 + 1]; + y0r = a[j0 - 2] + a[j2 - 2]; + y0i = -a[j0 - 1] - a[j2 - 1]; + y1r = a[j0 - 2] - a[j2 - 2]; + y1i = -a[j0 - 1] + a[j2 - 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 - 2] + a[j3 - 2]; + y2i = a[j1 - 1] + a[j3 - 1]; + y3r = a[j1 - 2] - a[j3 - 2]; + y3i = a[j1 - 1] - a[j3 - 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i - x2i; + a[j0 - 2] = y0r + y2r; + a[j0 - 1] = y0i - y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + a[j1 - 2] = y0r - y2r; + a[j1 - 1] = y0i + y2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2] = wk1i * x0r - wk1r * x0i; + a[j2 + 1] = wk1i * x0i + wk1r * x0r; + x0r = y1r + y3i; + x0i = y1i + y3r; + a[j2 - 2] = wd1i * x0r - wd1r * x0i; + a[j2 - 1] = wd1i * x0i + wd1r * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3] = wk3i * x0r + wk3r * x0i; + a[j3 + 1] = wk3i * x0i - wk3r * x0r; + x0r = y1r - y3i; + x0i = y1i - y3r; + a[j3 - 2] = wd3i * x0r + wd3r * x0i; + a[j3 - 1] = wd3i * x0i - wd3r * x0r; + } + wk1r = csc1 * (wd1r + wn4r); + wk1i = csc1 * (wd1i + wn4r); + wk3r = csc3 * (wd3r - wn4r); + wk3i = csc3 * (wd3i - wn4r); + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0 - 2] + a[j2 - 2]; + x0i = -a[j0 - 1] - a[j2 - 1]; + x1r = a[j0 - 2] - a[j2 - 2]; + x1i = -a[j0 - 1] + a[j2 - 1]; + x2r = a[j1 - 2] + a[j3 - 2]; + x2i = a[j1 - 1] + a[j3 - 1]; + x3r = a[j1 - 2] - a[j3 - 2]; + x3i = a[j1 - 1] - a[j3 - 1]; + a[j0 - 2] = x0r + x2r; + a[j0 - 1] = x0i - x2i; + a[j1 - 2] = x0r - x2r; + a[j1 - 1] = x0i + x2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2 - 2] = wk1r * x0r - wk1i * x0i; + a[j2 - 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3 - 2] = wk3r * x0r + wk3i * x0i; + a[j3 - 1] = wk3r * x0i - wk3i * x0r; + x0r = a[j0] + a[j2]; + x0i = -a[j0 + 1] - a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = -a[j0 + 1] + a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i - x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3] = -wn4r * (x0r + x0i); + a[j3 + 1] = -wn4r * (x0i - x0r); + x0r = a[j0 + 2] + a[j2 + 2]; + x0i = -a[j0 + 3] - a[j2 + 3]; + x1r = a[j0 + 2] - a[j2 + 2]; + x1i = -a[j0 + 3] + a[j2 + 3]; + x2r = a[j1 + 2] + a[j3 + 2]; + x2i = a[j1 + 3] + a[j3 + 3]; + x3r = a[j1 + 2] - a[j3 + 2]; + x3i = a[j1 + 3] - a[j3 + 3]; + a[j0 + 2] = x0r + x2r; + a[j0 + 3] = x0i - x2i; + a[j1 + 2] = x0r - x2r; + a[j1 + 3] = x0i + x2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2 + 2] = wk1i * x0r - wk1r * x0i; + a[j2 + 3] = wk1i * x0i + wk1r * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3 + 2] = wk3i * x0r + wk3r * x0i; + a[j3 + 3] = wk3i * x0i - wk3r * x0r; +} + + +#ifdef USE_CDFT_THREADS +struct cdft_arg_st +{ + int n0; + int n; + double *a; + int nw; + double *w; +}; +typedef struct cdft_arg_st cdft_arg_t; + + +void cftrec4_th(int n, double *a, int nw, double *w) +{ + void *cftrec1_th(void *p); + void *cftrec2_th(void *p); + int i, idiv4, m, nthread; + cdft_thread_t th[4]; + cdft_arg_t ag[4]; + + nthread = 2; + idiv4 = 0; + m = n >> 1; + if (n > CDFT_4THREADS_BEGIN_N) + { + nthread = 4; + idiv4 = 1; + m >>= 1; + } + for (i = 0; i < nthread; i++) + { + ag[i].n0 = n; + ag[i].n = m; + ag[i].a = &a[i * m]; + ag[i].nw = nw; + ag[i].w = w; + if (i != idiv4) + { + cdft_thread_create(&th[i], cftrec1_th, &ag[i]); + } + else + { + cdft_thread_create(&th[i], cftrec2_th, &ag[i]); + } + } + for (i = 0; i < nthread; i++) + { + cdft_thread_wait(th[i]); + } +} + + +void *cftrec1_th(void *p) +{ + int cfttree(int n, int j, int k, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftmdl1(int n, double *a, double *w); + int isplt, j, k, m, n, n0, nw; + double *a, *w; + + n0 = ((cdft_arg_t *) p)->n0; + n = ((cdft_arg_t *) p)->n; + a = ((cdft_arg_t *) p)->a; + nw = ((cdft_arg_t *) p)->nw; + w = ((cdft_arg_t *) p)->w; + m = n0; + while (m > 512) + { + m >>= 2; + cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]); + } + cftleaf(m, 1, &a[n - m], nw, w); + k = 0; + for (j = n - m; j > 0; j -= m) + { + k++; + isplt = cfttree(m, j, k, a, nw, w); + cftleaf(m, isplt, &a[j - m], nw, w); + } + return (void *) 0; +} + + +void *cftrec2_th(void *p) +{ + int cfttree(int n, int j, int k, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftmdl2(int n, double *a, double *w); + int isplt, j, k, m, n, n0, nw; + double *a, *w; + + n0 = ((cdft_arg_t *) p)->n0; + n = ((cdft_arg_t *) p)->n; + a = ((cdft_arg_t *) p)->a; + nw = ((cdft_arg_t *) p)->nw; + w = ((cdft_arg_t *) p)->w; + k = 1; + m = n0; + while (m > 512) + { + m >>= 2; + k <<= 2; + cftmdl2(m, &a[n - m], &w[nw - m]); + } + cftleaf(m, 0, &a[n - m], nw, w); + k >>= 1; + for (j = n - m; j > 0; j -= m) + { + k++; + isplt = cfttree(m, j, k, a, nw, w); + cftleaf(m, isplt, &a[j - m], nw, w); + } + return (void *) 0; +} +#endif /* USE_CDFT_THREADS */ + + +void cftrec4(int n, double *a, int nw, double *w) +{ + int cfttree(int n, int j, int k, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftmdl1(int n, double *a, double *w); + int isplt, j, k, m; + + m = n; + while (m > 512) + { + m >>= 2; + cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]); + } + cftleaf(m, 1, &a[n - m], nw, w); + k = 0; + for (j = n - m; j > 0; j -= m) + { + k++; + isplt = cfttree(m, j, k, a, nw, w); + cftleaf(m, isplt, &a[j - m], nw, w); + } +} + + +int cfttree(int n, int j, int k, double *a, int nw, double *w) +{ + void cftmdl1(int n, double *a, double *w); + void cftmdl2(int n, double *a, double *w); + int i, isplt, m; + + if ((k & 3) != 0) + { + isplt = k & 1; + if (isplt != 0) + { + cftmdl1(n, &a[j - n], &w[nw - (n >> 1)]); + } + else + { + cftmdl2(n, &a[j - n], &w[nw - n]); + } + } + else + { + m = n; + for (i = k; (i & 3) == 0; i >>= 2) + { + m <<= 2; + } + isplt = i & 1; + if (isplt != 0) + { + while (m > 128) + { + cftmdl1(m, &a[j - m], &w[nw - (m >> 1)]); + m >>= 2; + } + } + else + { + while (m > 128) + { + cftmdl2(m, &a[j - m], &w[nw - m]); + m >>= 2; + } + } + } + return isplt; +} + + +void cftleaf(int n, int isplt, double *a, int nw, double *w) +{ + void cftmdl1(int n, double *a, double *w); + void cftmdl2(int n, double *a, double *w); + void cftf161(double *a, double *w); + void cftf162(double *a, double *w); + void cftf081(double *a, double *w); + void cftf082(double *a, double *w); + + if (n == 512) + { + cftmdl1(128, a, &w[nw - 64]); + cftf161(a, &w[nw - 8]); + cftf162(&a[32], &w[nw - 32]); + cftf161(&a[64], &w[nw - 8]); + cftf161(&a[96], &w[nw - 8]); + cftmdl2(128, &a[128], &w[nw - 128]); + cftf161(&a[128], &w[nw - 8]); + cftf162(&a[160], &w[nw - 32]); + cftf161(&a[192], &w[nw - 8]); + cftf162(&a[224], &w[nw - 32]); + cftmdl1(128, &a[256], &w[nw - 64]); + cftf161(&a[256], &w[nw - 8]); + cftf162(&a[288], &w[nw - 32]); + cftf161(&a[320], &w[nw - 8]); + cftf161(&a[352], &w[nw - 8]); + if (isplt != 0) + { + cftmdl1(128, &a[384], &w[nw - 64]); + cftf161(&a[480], &w[nw - 8]); + } + else + { + cftmdl2(128, &a[384], &w[nw - 128]); + cftf162(&a[480], &w[nw - 32]); + } + cftf161(&a[384], &w[nw - 8]); + cftf162(&a[416], &w[nw - 32]); + cftf161(&a[448], &w[nw - 8]); + } + else + { + cftmdl1(64, a, &w[nw - 32]); + cftf081(a, &w[nw - 8]); + cftf082(&a[16], &w[nw - 8]); + cftf081(&a[32], &w[nw - 8]); + cftf081(&a[48], &w[nw - 8]); + cftmdl2(64, &a[64], &w[nw - 64]); + cftf081(&a[64], &w[nw - 8]); + cftf082(&a[80], &w[nw - 8]); + cftf081(&a[96], &w[nw - 8]); + cftf082(&a[112], &w[nw - 8]); + cftmdl1(64, &a[128], &w[nw - 32]); + cftf081(&a[128], &w[nw - 8]); + cftf082(&a[144], &w[nw - 8]); + cftf081(&a[160], &w[nw - 8]); + cftf081(&a[176], &w[nw - 8]); + if (isplt != 0) + { + cftmdl1(64, &a[192], &w[nw - 32]); + cftf081(&a[240], &w[nw - 8]); + } + else + { + cftmdl2(64, &a[192], &w[nw - 64]); + cftf082(&a[240], &w[nw - 8]); + } + cftf081(&a[192], &w[nw - 8]); + cftf082(&a[208], &w[nw - 8]); + cftf081(&a[224], &w[nw - 8]); + } +} + + +void cftmdl1(int n, double *a, double *w) +{ + int j, j0, j1, j2, j3, k, m, mh; + double wn4r, wk1r, wk1i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + mh = n >> 3; + m = 2 * mh; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] + a[j2]; + x0i = a[1] + a[j2 + 1]; + x1r = a[0] - a[j2]; + x1i = a[1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j2] = x1r - x3i; + a[j2 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + wn4r = w[1]; + k = 0; + for (j = 2; j < mh; j += 2) + { + k += 4; + wk1r = w[k]; + wk1i = w[k + 1]; + wk3r = w[k + 2]; + wk3i = w[k + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] + a[j2]; + x0i = a[j + 1] + a[j2 + 1]; + x1r = a[j] - a[j2]; + x1i = a[j + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1r * x0r - wk1i * x0i; + a[j2 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r + wk3i * x0i; + a[j3 + 1] = wk3r * x0i - wk3i * x0r; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1i * x0r - wk1r * x0i; + a[j2 + 1] = wk1i * x0i + wk1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3i * x0r + wk3r * x0i; + a[j3 + 1] = wk3i * x0i - wk3r * x0r; + } + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = -wn4r * (x0r + x0i); + a[j3 + 1] = -wn4r * (x0i - x0r); +} + + +void cftmdl2(int n, double *a, double *w) +{ + int j, j0, j1, j2, j3, k, kr, m, mh; + double wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i; + + mh = n >> 3; + m = 2 * mh; + wn4r = w[1]; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] - a[j2 + 1]; + x0i = a[1] + a[j2]; + x1r = a[0] + a[j2 + 1]; + x1i = a[1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wn4r * (x2r - x2i); + y0i = wn4r * (x2i + x2r); + a[0] = x0r + y0r; + a[1] = x0i + y0i; + a[j1] = x0r - y0r; + a[j1 + 1] = x0i - y0i; + y0r = wn4r * (x3r - x3i); + y0i = wn4r * (x3i + x3r); + a[j2] = x1r - y0i; + a[j2 + 1] = x1i + y0r; + a[j3] = x1r + y0i; + a[j3 + 1] = x1i - y0r; + k = 0; + kr = 2 * m; + for (j = 2; j < mh; j += 2) + { + k += 4; + wk1r = w[k]; + wk1i = w[k + 1]; + wk3r = w[k + 2]; + wk3i = w[k + 3]; + kr -= 4; + wd1i = w[kr]; + wd1r = w[kr + 1]; + wd3i = w[kr + 2]; + wd3r = w[kr + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] - a[j2 + 1]; + x0i = a[j + 1] + a[j2]; + x1r = a[j] + a[j2 + 1]; + x1i = a[j + 1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wk1r * x0r - wk1i * x0i; + y0i = wk1r * x0i + wk1i * x0r; + y2r = wd1r * x2r - wd1i * x2i; + y2i = wd1r * x2i + wd1i * x2r; + a[j] = y0r + y2r; + a[j + 1] = y0i + y2i; + a[j1] = y0r - y2r; + a[j1 + 1] = y0i - y2i; + y0r = wk3r * x1r + wk3i * x1i; + y0i = wk3r * x1i - wk3i * x1r; + y2r = wd3r * x3r + wd3i * x3i; + y2i = wd3r * x3i - wd3i * x3r; + a[j2] = y0r + y2r; + a[j2 + 1] = y0i + y2i; + a[j3] = y0r - y2r; + a[j3 + 1] = y0i - y2i; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] - a[j2 + 1]; + x0i = a[j0 + 1] + a[j2]; + x1r = a[j0] + a[j2 + 1]; + x1i = a[j0 + 1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wd1i * x0r - wd1r * x0i; + y0i = wd1i * x0i + wd1r * x0r; + y2r = wk1i * x2r - wk1r * x2i; + y2i = wk1i * x2i + wk1r * x2r; + a[j0] = y0r + y2r; + a[j0 + 1] = y0i + y2i; + a[j1] = y0r - y2r; + a[j1 + 1] = y0i - y2i; + y0r = wd3i * x1r + wd3r * x1i; + y0i = wd3i * x1i - wd3r * x1r; + y2r = wk3i * x3r + wk3r * x3i; + y2i = wk3i * x3i - wk3r * x3r; + a[j2] = y0r + y2r; + a[j2 + 1] = y0i + y2i; + a[j3] = y0r - y2r; + a[j3 + 1] = y0i - y2i; + } + wk1r = w[m]; + wk1i = w[m + 1]; + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] - a[j2 + 1]; + x0i = a[j0 + 1] + a[j2]; + x1r = a[j0] + a[j2 + 1]; + x1i = a[j0 + 1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wk1r * x0r - wk1i * x0i; + y0i = wk1r * x0i + wk1i * x0r; + y2r = wk1i * x2r - wk1r * x2i; + y2i = wk1i * x2i + wk1r * x2r; + a[j0] = y0r + y2r; + a[j0 + 1] = y0i + y2i; + a[j1] = y0r - y2r; + a[j1 + 1] = y0i - y2i; + y0r = wk1i * x1r - wk1r * x1i; + y0i = wk1i * x1i + wk1r * x1r; + y2r = wk1r * x3r - wk1i * x3i; + y2i = wk1r * x3i + wk1i * x3r; + a[j2] = y0r - y2r; + a[j2 + 1] = y0i - y2i; + a[j3] = y0r + y2r; + a[j3 + 1] = y0i + y2i; +} + + +void cftfx41(int n, double *a, int nw, double *w) +{ + void cftf161(double *a, double *w); + void cftf162(double *a, double *w); + void cftf081(double *a, double *w); + void cftf082(double *a, double *w); + + if (n == 128) + { + cftf161(a, &w[nw - 8]); + cftf162(&a[32], &w[nw - 32]); + cftf161(&a[64], &w[nw - 8]); + cftf161(&a[96], &w[nw - 8]); + } + else + { + cftf081(a, &w[nw - 8]); + cftf082(&a[16], &w[nw - 8]); + cftf081(&a[32], &w[nw - 8]); + cftf081(&a[48], &w[nw - 8]); + } +} + + +void cftf161(double *a, double *w) +{ + double wn4r, wk1r, wk1i, + x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, + y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, + y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; + + wn4r = w[1]; + wk1r = w[2]; + wk1i = w[3]; + x0r = a[0] + a[16]; + x0i = a[1] + a[17]; + x1r = a[0] - a[16]; + x1i = a[1] - a[17]; + x2r = a[8] + a[24]; + x2i = a[9] + a[25]; + x3r = a[8] - a[24]; + x3i = a[9] - a[25]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y4r = x0r - x2r; + y4i = x0i - x2i; + y8r = x1r - x3i; + y8i = x1i + x3r; + y12r = x1r + x3i; + y12i = x1i - x3r; + x0r = a[2] + a[18]; + x0i = a[3] + a[19]; + x1r = a[2] - a[18]; + x1i = a[3] - a[19]; + x2r = a[10] + a[26]; + x2i = a[11] + a[27]; + x3r = a[10] - a[26]; + x3i = a[11] - a[27]; + y1r = x0r + x2r; + y1i = x0i + x2i; + y5r = x0r - x2r; + y5i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + y9r = wk1r * x0r - wk1i * x0i; + y9i = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + y13r = wk1i * x0r - wk1r * x0i; + y13i = wk1i * x0i + wk1r * x0r; + x0r = a[4] + a[20]; + x0i = a[5] + a[21]; + x1r = a[4] - a[20]; + x1i = a[5] - a[21]; + x2r = a[12] + a[28]; + x2i = a[13] + a[29]; + x3r = a[12] - a[28]; + x3i = a[13] - a[29]; + y2r = x0r + x2r; + y2i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + y10r = wn4r * (x0r - x0i); + y10i = wn4r * (x0i + x0r); + x0r = x1r + x3i; + x0i = x1i - x3r; + y14r = wn4r * (x0r + x0i); + y14i = wn4r * (x0i - x0r); + x0r = a[6] + a[22]; + x0i = a[7] + a[23]; + x1r = a[6] - a[22]; + x1i = a[7] - a[23]; + x2r = a[14] + a[30]; + x2i = a[15] + a[31]; + x3r = a[14] - a[30]; + x3i = a[15] - a[31]; + y3r = x0r + x2r; + y3i = x0i + x2i; + y7r = x0r - x2r; + y7i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + y11r = wk1i * x0r - wk1r * x0i; + y11i = wk1i * x0i + wk1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + y15r = wk1r * x0r - wk1i * x0i; + y15i = wk1r * x0i + wk1i * x0r; + x0r = y12r - y14r; + x0i = y12i - y14i; + x1r = y12r + y14r; + x1i = y12i + y14i; + x2r = y13r - y15r; + x2i = y13i - y15i; + x3r = y13r + y15r; + x3i = y13i + y15i; + a[24] = x0r + x2r; + a[25] = x0i + x2i; + a[26] = x0r - x2r; + a[27] = x0i - x2i; + a[28] = x1r - x3i; + a[29] = x1i + x3r; + a[30] = x1r + x3i; + a[31] = x1i - x3r; + x0r = y8r + y10r; + x0i = y8i + y10i; + x1r = y8r - y10r; + x1i = y8i - y10i; + x2r = y9r + y11r; + x2i = y9i + y11i; + x3r = y9r - y11r; + x3i = y9i - y11i; + a[16] = x0r + x2r; + a[17] = x0i + x2i; + a[18] = x0r - x2r; + a[19] = x0i - x2i; + a[20] = x1r - x3i; + a[21] = x1i + x3r; + a[22] = x1r + x3i; + a[23] = x1i - x3r; + x0r = y5r - y7i; + x0i = y5i + y7r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + x0r = y5r + y7i; + x0i = y5i - y7r; + x3r = wn4r * (x0r - x0i); + x3i = wn4r * (x0i + x0r); + x0r = y4r - y6i; + x0i = y4i + y6r; + x1r = y4r + y6i; + x1i = y4i - y6r; + a[8] = x0r + x2r; + a[9] = x0i + x2i; + a[10] = x0r - x2r; + a[11] = x0i - x2i; + a[12] = x1r - x3i; + a[13] = x1i + x3r; + a[14] = x1r + x3i; + a[15] = x1i - x3r; + x0r = y0r + y2r; + x0i = y0i + y2i; + x1r = y0r - y2r; + x1i = y0i - y2i; + x2r = y1r + y3r; + x2i = y1i + y3i; + x3r = y1r - y3r; + x3i = y1i - y3i; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[2] = x0r - x2r; + a[3] = x0i - x2i; + a[4] = x1r - x3i; + a[5] = x1i + x3r; + a[6] = x1r + x3i; + a[7] = x1i - x3r; +} + + +void cftf162(double *a, double *w) +{ + double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, + x0r, x0i, x1r, x1i, x2r, x2i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, + y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, + y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; + + wn4r = w[1]; + wk1r = w[4]; + wk1i = w[5]; + wk3r = w[6]; + wk3i = -w[7]; + wk2r = w[8]; + wk2i = w[9]; + x1r = a[0] - a[17]; + x1i = a[1] + a[16]; + x0r = a[8] - a[25]; + x0i = a[9] + a[24]; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + y0r = x1r + x2r; + y0i = x1i + x2i; + y4r = x1r - x2r; + y4i = x1i - x2i; + x1r = a[0] + a[17]; + x1i = a[1] - a[16]; + x0r = a[8] + a[25]; + x0i = a[9] - a[24]; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + y8r = x1r - x2i; + y8i = x1i + x2r; + y12r = x1r + x2i; + y12i = x1i - x2r; + x0r = a[2] - a[19]; + x0i = a[3] + a[18]; + x1r = wk1r * x0r - wk1i * x0i; + x1i = wk1r * x0i + wk1i * x0r; + x0r = a[10] - a[27]; + x0i = a[11] + a[26]; + x2r = wk3i * x0r - wk3r * x0i; + x2i = wk3i * x0i + wk3r * x0r; + y1r = x1r + x2r; + y1i = x1i + x2i; + y5r = x1r - x2r; + y5i = x1i - x2i; + x0r = a[2] + a[19]; + x0i = a[3] - a[18]; + x1r = wk3r * x0r - wk3i * x0i; + x1i = wk3r * x0i + wk3i * x0r; + x0r = a[10] + a[27]; + x0i = a[11] - a[26]; + x2r = wk1r * x0r + wk1i * x0i; + x2i = wk1r * x0i - wk1i * x0r; + y9r = x1r - x2r; + y9i = x1i - x2i; + y13r = x1r + x2r; + y13i = x1i + x2i; + x0r = a[4] - a[21]; + x0i = a[5] + a[20]; + x1r = wk2r * x0r - wk2i * x0i; + x1i = wk2r * x0i + wk2i * x0r; + x0r = a[12] - a[29]; + x0i = a[13] + a[28]; + x2r = wk2i * x0r - wk2r * x0i; + x2i = wk2i * x0i + wk2r * x0r; + y2r = x1r + x2r; + y2i = x1i + x2i; + y6r = x1r - x2r; + y6i = x1i - x2i; + x0r = a[4] + a[21]; + x0i = a[5] - a[20]; + x1r = wk2i * x0r - wk2r * x0i; + x1i = wk2i * x0i + wk2r * x0r; + x0r = a[12] + a[29]; + x0i = a[13] - a[28]; + x2r = wk2r * x0r - wk2i * x0i; + x2i = wk2r * x0i + wk2i * x0r; + y10r = x1r - x2r; + y10i = x1i - x2i; + y14r = x1r + x2r; + y14i = x1i + x2i; + x0r = a[6] - a[23]; + x0i = a[7] + a[22]; + x1r = wk3r * x0r - wk3i * x0i; + x1i = wk3r * x0i + wk3i * x0r; + x0r = a[14] - a[31]; + x0i = a[15] + a[30]; + x2r = wk1i * x0r - wk1r * x0i; + x2i = wk1i * x0i + wk1r * x0r; + y3r = x1r + x2r; + y3i = x1i + x2i; + y7r = x1r - x2r; + y7i = x1i - x2i; + x0r = a[6] + a[23]; + x0i = a[7] - a[22]; + x1r = wk1i * x0r + wk1r * x0i; + x1i = wk1i * x0i - wk1r * x0r; + x0r = a[14] + a[31]; + x0i = a[15] - a[30]; + x2r = wk3i * x0r - wk3r * x0i; + x2i = wk3i * x0i + wk3r * x0r; + y11r = x1r + x2r; + y11i = x1i + x2i; + y15r = x1r - x2r; + y15i = x1i - x2i; + x1r = y0r + y2r; + x1i = y0i + y2i; + x2r = y1r + y3r; + x2i = y1i + y3i; + a[0] = x1r + x2r; + a[1] = x1i + x2i; + a[2] = x1r - x2r; + a[3] = x1i - x2i; + x1r = y0r - y2r; + x1i = y0i - y2i; + x2r = y1r - y3r; + x2i = y1i - y3i; + a[4] = x1r - x2i; + a[5] = x1i + x2r; + a[6] = x1r + x2i; + a[7] = x1i - x2r; + x1r = y4r - y6i; + x1i = y4i + y6r; + x0r = y5r - y7i; + x0i = y5i + y7r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[8] = x1r + x2r; + a[9] = x1i + x2i; + a[10] = x1r - x2r; + a[11] = x1i - x2i; + x1r = y4r + y6i; + x1i = y4i - y6r; + x0r = y5r + y7i; + x0i = y5i - y7r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[12] = x1r - x2i; + a[13] = x1i + x2r; + a[14] = x1r + x2i; + a[15] = x1i - x2r; + x1r = y8r + y10r; + x1i = y8i + y10i; + x2r = y9r - y11r; + x2i = y9i - y11i; + a[16] = x1r + x2r; + a[17] = x1i + x2i; + a[18] = x1r - x2r; + a[19] = x1i - x2i; + x1r = y8r - y10r; + x1i = y8i - y10i; + x2r = y9r + y11r; + x2i = y9i + y11i; + a[20] = x1r - x2i; + a[21] = x1i + x2r; + a[22] = x1r + x2i; + a[23] = x1i - x2r; + x1r = y12r - y14i; + x1i = y12i + y14r; + x0r = y13r + y15i; + x0i = y13i - y15r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[24] = x1r + x2r; + a[25] = x1i + x2i; + a[26] = x1r - x2r; + a[27] = x1i - x2i; + x1r = y12r + y14i; + x1i = y12i - y14r; + x0r = y13r - y15i; + x0i = y13i + y15r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[28] = x1r - x2i; + a[29] = x1i + x2r; + a[30] = x1r + x2i; + a[31] = x1i - x2r; +} + + +void cftf081(double *a, double *w) +{ + double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; + + wn4r = w[1]; + x0r = a[0] + a[8]; + x0i = a[1] + a[9]; + x1r = a[0] - a[8]; + x1i = a[1] - a[9]; + x2r = a[4] + a[12]; + x2i = a[5] + a[13]; + x3r = a[4] - a[12]; + x3i = a[5] - a[13]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y2r = x0r - x2r; + y2i = x0i - x2i; + y1r = x1r - x3i; + y1i = x1i + x3r; + y3r = x1r + x3i; + y3i = x1i - x3r; + x0r = a[2] + a[10]; + x0i = a[3] + a[11]; + x1r = a[2] - a[10]; + x1i = a[3] - a[11]; + x2r = a[6] + a[14]; + x2i = a[7] + a[15]; + x3r = a[6] - a[14]; + x3i = a[7] - a[15]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x1i - x3r; + y5r = wn4r * (x0r - x0i); + y5i = wn4r * (x0r + x0i); + y7r = wn4r * (x2r - x2i); + y7i = wn4r * (x2r + x2i); + a[8] = y1r + y5r; + a[9] = y1i + y5i; + a[10] = y1r - y5r; + a[11] = y1i - y5i; + a[12] = y3r - y7i; + a[13] = y3i + y7r; + a[14] = y3r + y7i; + a[15] = y3i - y7r; + a[0] = y0r + y4r; + a[1] = y0i + y4i; + a[2] = y0r - y4r; + a[3] = y0i - y4i; + a[4] = y2r - y6i; + a[5] = y2i + y6r; + a[6] = y2r + y6i; + a[7] = y2i - y6r; +} + + +void cftf082(double *a, double *w) +{ + double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; + + wn4r = w[1]; + wk1r = w[2]; + wk1i = w[3]; + y0r = a[0] - a[9]; + y0i = a[1] + a[8]; + y1r = a[0] + a[9]; + y1i = a[1] - a[8]; + x0r = a[4] - a[13]; + x0i = a[5] + a[12]; + y2r = wn4r * (x0r - x0i); + y2i = wn4r * (x0i + x0r); + x0r = a[4] + a[13]; + x0i = a[5] - a[12]; + y3r = wn4r * (x0r - x0i); + y3i = wn4r * (x0i + x0r); + x0r = a[2] - a[11]; + x0i = a[3] + a[10]; + y4r = wk1r * x0r - wk1i * x0i; + y4i = wk1r * x0i + wk1i * x0r; + x0r = a[2] + a[11]; + x0i = a[3] - a[10]; + y5r = wk1i * x0r - wk1r * x0i; + y5i = wk1i * x0i + wk1r * x0r; + x0r = a[6] - a[15]; + x0i = a[7] + a[14]; + y6r = wk1i * x0r - wk1r * x0i; + y6i = wk1i * x0i + wk1r * x0r; + x0r = a[6] + a[15]; + x0i = a[7] - a[14]; + y7r = wk1r * x0r - wk1i * x0i; + y7i = wk1r * x0i + wk1i * x0r; + x0r = y0r + y2r; + x0i = y0i + y2i; + x1r = y4r + y6r; + x1i = y4i + y6i; + a[0] = x0r + x1r; + a[1] = x0i + x1i; + a[2] = x0r - x1r; + a[3] = x0i - x1i; + x0r = y0r - y2r; + x0i = y0i - y2i; + x1r = y4r - y6r; + x1i = y4i - y6i; + a[4] = x0r - x1i; + a[5] = x0i + x1r; + a[6] = x0r + x1i; + a[7] = x0i - x1r; + x0r = y1r - y3i; + x0i = y1i + y3r; + x1r = y5r - y7r; + x1i = y5i - y7i; + a[8] = x0r + x1r; + a[9] = x0i + x1i; + a[10] = x0r - x1r; + a[11] = x0i - x1i; + x0r = y1r + y3i; + x0i = y1i - y3r; + x1r = y5r + y7r; + x1i = y5i + y7i; + a[12] = x0r - x1i; + a[13] = x0i + x1r; + a[14] = x0r + x1i; + a[15] = x0i - x1r; +} + + +void cftf040(double *a) +{ + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[4]; + x0i = a[1] + a[5]; + x1r = a[0] - a[4]; + x1i = a[1] - a[5]; + x2r = a[2] + a[6]; + x2i = a[3] + a[7]; + x3r = a[2] - a[6]; + x3i = a[3] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[2] = x1r - x3i; + a[3] = x1i + x3r; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[6] = x1r + x3i; + a[7] = x1i - x3r; +} + + +void cftb040(double *a) +{ + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[4]; + x0i = a[1] + a[5]; + x1r = a[0] - a[4]; + x1i = a[1] - a[5]; + x2r = a[2] + a[6]; + x2i = a[3] + a[7]; + x3r = a[2] - a[6]; + x3i = a[3] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[2] = x1r + x3i; + a[3] = x1i - x3r; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[6] = x1r - x3i; + a[7] = x1i + x3r; +} + + +void cftx020(double *a) +{ + double x0r, x0i; + + x0r = a[0] - a[2]; + x0i = a[1] - a[3]; + a[0] += a[2]; + a[1] += a[3]; + a[2] = x0r; + a[3] = x0i; +} + + +void rftfsub(int n, double *a, int nc, double *c) +{ + int j, k, kk, ks, m; + double wkr, wki, xr, xi, yr, yi; + + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) + { + k = n - j; + kk += ks; + wkr = 0.5 - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + } +} + + +void rftbsub(int n, double *a, int nc, double *c) +{ + int j, k, kk, ks, m; + double wkr, wki, xr, xi, yr, yi; + + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) + { + k = n - j; + kk += ks; + wkr = 0.5 - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr + wki * xi; + yi = wkr * xi - wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + } +} + + +void dctsub(int n, double *a, int nc, double *c) +{ + int j, k, kk, ks, m; + double wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for (j = 1; j < m; j++) + { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[j] - wkr * a[k]; + a[j] = wkr * a[j] + wki * a[k]; + a[k] = xr; + } + a[m] *= c[0]; +} + + +void dstsub(int n, double *a, int nc, double *c) +{ + int j, k, kk, ks, m; + double wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for (j = 1; j < m; j++) + { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[k] - wkr * a[j]; + a[k] = wkr * a[k] + wki * a[j]; + a[j] = xr; + } + a[m] *= c[0]; +} + diff --git a/src/fftsg.h b/src/fftsg.h new file mode 100644 index 0000000..eb7fc8a --- /dev/null +++ b/src/fftsg.h @@ -0,0 +1,21 @@ +/* FFT functions */ +void cdft(int n, int isgn, double *a, int *ip, double *w); +void rdft(int n, int isgn, double *a, int *ip, double *w); +void ddct(int n, int isgn, double *a, int *ip, double *w); +void ddst(int n, int isgn, double *a, int *ip, double *w); +void dfct(int n, double *a, double *t, int *ip, double *w); +void dfst(int n, double *a, double *t, int *ip, double *w); + +/* Auxiliary functions */ +void makewt(int nw, int *ip, double *w); +void bitrv2(int n, int *ip, double *a); +void bitrv2conj(int n, int *ip, double *a); +void cftfsub(int n, double *a, double *w); +void cftbsub(int n, double *a, double *w); +void makect(int nc, int *ip, double *c); +void rftfsub(int n, double *a, int nc, double *c); +void rftbsub(int n, double *a, int nc, double *c); +void dctsub(int n, double *a, int nc, double *c); +void dstsub(int n, double *a, int nc, double *c); +void cft1st(int n, double *a, double *w); +void cftmdl(int n, int l, double *a, double *w); @@ -14,17 +14,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ /* fini.c: Contains library destructor routine */ -#ifdef XTRACT_FFT -#include <fftw3.h> -//#include "xtract_globals_private.h" #include "xtract/libxtract.h" -#endif #ifdef __GNUC__ __attribute__((destructor)) void fini() @@ -32,10 +28,7 @@ __attribute__((destructor)) void fini() void _fini() #endif { -#ifdef XTRACT_FFT -xtract_free_fft(); -fftwf_cleanup(); -#endif + xtract_free_fft(); } diff --git a/src/helper.c b/src/helper.c index e9e79e5..4fd9975 100644 --- a/src/helper.c +++ b/src/helper.c @@ -1,5 +1,5 @@ /* libxtract feature extraction library - * + * * Copyright (C) 2006 Jamie Bullock * * This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ @@ -33,7 +33,8 @@ #define INDEX 1 #endif -int xtract_windowed(const float *data, const int N, const void *argv, float *result){ +int xtract_windowed(const float *data, const int N, const void *argv, float *result) +{ int n; const float *window; @@ -48,7 +49,8 @@ int xtract_windowed(const float *data, const int N, const void *argv, float *res } -int xtract_features_from_subframes(const float *data, const int N, const int feature, const void *argv, float *result){ +int xtract_features_from_subframes(const float *data, const int N, const int feature, const void *argv, float *result) +{ const float *frame1, *frame2; @@ -73,7 +75,8 @@ int xtract_features_from_subframes(const float *data, const int N, const int fea } -inline int xtract_is_denormal(double const d){ +inline int xtract_is_denormal(double const d) +{ if(sizeof(d) != 2 * sizeof(int)) fprintf(stderr, "libxtract: Error: xtract_is_denormal() detects inconsistent wordlength for type 'double'\n"); @@ -81,3 +84,8 @@ inline int xtract_is_denormal(double const d){ return (l&0x7ff00000) == 0 && d!=0; //Check for 0 may not be necessary } +inline bool xtract_is_poweroftwo(unsigned int x) +{ + return ((x != 0) && !(x & (x - 1))); +} + @@ -1,5 +1,5 @@ /* libxtract feature extraction library - * + * * Copyright (C) 2006 Jamie Bullock * * This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ @@ -26,41 +26,38 @@ #include <math.h> #include <stdlib.h> +#include <stdio.h> + +#include "fftsg.h" #include "xtract/libxtract.h" #include "xtract_window_private.h" #define DEFINE_GLOBALS #include "xtract_globals_private.h" -#ifdef XTRACT_FFT -#include <fftw3.h> -#ifndef XTRACT_FFT_OPTIMISATION_LEVEL -/* This should never happen */ -#define XTRACT_FFT_OPTIMISATION_LEVEL 1 -#endif - -int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq_max, int freq_bands, float **fft_tables){ +int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq_max, int freq_bands, float **fft_tables) +{ - int n, i, k, *fft_peak, M, next_peak; - float norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, + int n, i, k, *fft_peak, M, next_peak; + float norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, freq_bw_mel, *mel_peak, *height_norm, *lin_peak; mel_peak = height_norm = lin_peak = NULL; fft_peak = NULL; - norm = 1; + norm = 1; mel_freq_max = 1127 * log(1 + freq_max / 700); mel_freq_min = 1127 * log(1 + freq_min / 700); freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands; - mel_peak = (float *)malloc((freq_bands + 2) * sizeof(float)); + mel_peak = (float *)malloc((freq_bands + 2) * sizeof(float)); /* +2 for zeros at start and end */ lin_peak = (float *)malloc((freq_bands + 2) * sizeof(float)); fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int)); height_norm = (float *)malloc(freq_bands * sizeof(float)); - if(mel_peak == NULL || height_norm == NULL || + if(mel_peak == NULL || height_norm == NULL || lin_peak == NULL || fft_peak == NULL) return XTRACT_MALLOC_FAILED; @@ -71,20 +68,24 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq fft_peak[0] = lin_peak[0] / nyquist * M; - for (n = 1; n < freq_bands + 2; n++){ - //roll out peak locations - mel, linear and linear on fft window scale + for (n = 1; n < freq_bands + 2; n++) + { + //roll out peak locations - mel, linear and linear on fft window scale mel_peak[n] = mel_peak[n - 1] + freq_bw_mel; lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1); fft_peak[n] = lin_peak[n] / nyquist * M; } - for (n = 0; n < freq_bands; n++){ + for (n = 0; n < freq_bands; n++) + { //roll out normalised gain of each peak - if (style == XTRACT_EQUAL_GAIN){ - height = 1; + if (style == XTRACT_EQUAL_GAIN) + { + height = 1; norm_fact = norm; } - else{ + else + { height = 2 / (lin_peak[n + 2] - lin_peak[n]); norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0])); } @@ -93,21 +94,23 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq i = 0; - for(n = 0; n < freq_bands; n++){ + for(n = 0; n < freq_bands; n++) + { // calculate the rise increment if(n==0) inc = height_norm[n] / fft_peak[n]; else inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]); - val = 0; + val = 0; // zero the start of the array for(k = 0; k < i; k++) fft_tables[n][k] = 0.f; // fill in the rise - for(; i <= fft_peak[n]; i++){ + for(; i <= fft_peak[n]; i++) + { fft_tables[n][i] = val; val += inc; } @@ -118,8 +121,9 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq val = 0; next_peak = fft_peak[n + 1]; - // reverse fill the 'fall' - for(i = next_peak; i > fft_peak[n]; i--){ + // reverse fill the 'fall' + for(i = next_peak; i > fft_peak[n]; i--) + { fft_tables[n][i] = val; val += inc; } @@ -131,7 +135,10 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq /* Initialise the fft_plan for the DCT */ + /* + * Ooura doesn't support non power-of-two DCT xtract_init_fft(freq_bands, XTRACT_MFCC); + */ free(mel_peak); free(lin_peak); @@ -142,82 +149,95 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq } -int xtract_init_fft(int N, int feature_name){ +void xtract_init_ooura(xtract_ooura_data *ooura_data, unsigned int N) +{ + ooura_data->ooura_ip = (int *)calloc((2 + sqrt(N)), sizeof(int)); + ooura_data->ooura_w = (double *)calloc((N - 1), sizeof(double)); + ooura_data->initialised = true; +} - float *input, *output; - int optimisation; +void xtract_free_ooura(xtract_ooura_data *ooura_data) +{ + free(ooura_data->ooura_ip); + free(ooura_data->ooura_w); + ooura_data->ooura_ip = NULL; + ooura_data->ooura_w = NULL; + ooura_data->initialised = false; +} - input = output = NULL; +int xtract_init_fft(int N, int feature_name) +{ - //fprintf(stderr, "Optimisation level: %d\n", XTRACT_FFT_OPTIMISATION_LEVEL); + int M = N >> 1; - if(XTRACT_FFT_OPTIMISATION_LEVEL == 0) - optimisation = FFTW_ESTIMATE; - else if(XTRACT_FFT_OPTIMISATION_LEVEL == 1) - optimisation = FFTW_MEASURE; - else if(XTRACT_FFT_OPTIMISATION_LEVEL == 2) - optimisation = FFTW_PATIENT; - else - optimisation = FFTW_MEASURE; /* The default */ + if(!xtract_is_poweroftwo(N)) + { + fprintf(stderr, + "libxtract: error: only power-of-two FFT sizes are supported.\n"); + exit(EXIT_FAILURE); + } if(feature_name == XTRACT_AUTOCORRELATION_FFT) - N <<= 1; - - input = malloc(N * sizeof(float)); - output = malloc(N * sizeof(float)); - - switch(feature_name){ - case XTRACT_SPECTRUM: - if(fft_plans.spectrum_plan != NULL) - fftwf_destroy_plan(fft_plans.spectrum_plan); - fft_plans.spectrum_plan = - fftwf_plan_r2r_1d(N, input, output, FFTW_R2HC, optimisation); - break; - case XTRACT_AUTOCORRELATION_FFT: - if(fft_plans.autocorrelation_fft_plan_1 != NULL) - fftwf_destroy_plan(fft_plans.autocorrelation_fft_plan_1); - if(fft_plans.autocorrelation_fft_plan_2 != NULL) - fftwf_destroy_plan(fft_plans.autocorrelation_fft_plan_2); - fft_plans.autocorrelation_fft_plan_1 = - fftwf_plan_r2r_1d(N, input, output, FFTW_R2HC, optimisation); - fft_plans.autocorrelation_fft_plan_2 = - fftwf_plan_r2r_1d(N, input, output, FFTW_HC2R, optimisation); - break; - case XTRACT_DCT: - if(fft_plans.dct_plan != NULL) - fftwf_destroy_plan(fft_plans.dct_plan); - fft_plans.dct_plan = - fftwf_plan_r2r_1d(N, input, output, FFTW_REDFT10, optimisation); - case XTRACT_MFCC: - if(fft_plans.dct_plan != NULL) - fftwf_destroy_plan(fft_plans.dct_plan); - fft_plans.dct_plan = - fftwf_plan_r2r_1d(N, output, output, FFTW_REDFT00, optimisation); - break; + { + M = N; /* allow for zero padding */ } - free(input); - free(output); + switch(feature_name) + { + case XTRACT_SPECTRUM: + if(ooura_data_spectrum.initialised) + { + xtract_free_ooura(&ooura_data_spectrum); + } + xtract_init_ooura(&ooura_data_spectrum, M); + break; + case XTRACT_AUTOCORRELATION_FFT: + if(ooura_data_autocorrelation_fft.initialised) + { + xtract_free_ooura(&ooura_data_autocorrelation_fft); + } + xtract_init_ooura(&ooura_data_autocorrelation_fft, M); + break; + case XTRACT_DCT: + if(ooura_data_dct.initialised) + { + xtract_free_ooura(&ooura_data_dct); + } + xtract_init_ooura(&ooura_data_dct, M); + case XTRACT_MFCC: + if(ooura_data_mfcc.initialised) + { + xtract_free_ooura(&ooura_data_mfcc); + } + xtract_init_ooura(&ooura_data_mfcc, M); + break; + } return XTRACT_SUCCESS; - } -void xtract_free_fft(void){ - if(fft_plans.spectrum_plan != NULL) - fftwf_destroy_plan(fft_plans.spectrum_plan); - if(fft_plans.autocorrelation_fft_plan_1 != NULL) - fftwf_destroy_plan(fft_plans.autocorrelation_fft_plan_1); - if(fft_plans.autocorrelation_fft_plan_2 != NULL) - fftwf_destroy_plan(fft_plans.autocorrelation_fft_plan_2); - if(fft_plans.dct_plan != NULL) - fftwf_destroy_plan(fft_plans.dct_plan); -// fftwf_cleanup(); +void xtract_free_fft(void) +{ + if(ooura_data_spectrum.initialised) + { + xtract_free_ooura(&ooura_data_spectrum); + } + if(ooura_data_autocorrelation_fft.initialised) + { + xtract_free_ooura(&ooura_data_autocorrelation_fft); + } + if(ooura_data_dct.initialised) + { + xtract_free_ooura(&ooura_data_dct); + } + if(ooura_data_mfcc.initialised) + { + xtract_free_ooura(&ooura_data_mfcc); + } } -#endif - -int xtract_init_bark(int N, float sr, int *band_limits){ +int xtract_init_bark(int N, float sr, int *band_limits) +{ float edges[] = {0, 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500, 20500, 27000}; /* Takes us up to sr = 54kHz (CCRMA: JOS)*/ @@ -230,65 +250,62 @@ int xtract_init_bark(int N, float sr, int *band_limits){ return XTRACT_SUCCESS; } -float *xtract_init_window(const int N, const int type){ - +float *xtract_init_window(const int N, const int type) +{ float *window; window = malloc(N * sizeof(float)); - switch (type) { - case XTRACT_GAUSS: - gauss(window, N, 0.4); - break; - case XTRACT_HAMMING: - hamming(window, N); - break; - case XTRACT_HANN: - hann(window, N); - break; - case XTRACT_BARTLETT: - bartlett(window, N); - break; - case XTRACT_TRIANGULAR: - triangular(window, N); - break; - case XTRACT_BARTLETT_HANN: - bartlett_hann(window, N); - break; - case XTRACT_BLACKMAN: - blackman(window, N); - break; - case XTRACT_KAISER: - kaiser(window, N, 3 * PI); - break; - case XTRACT_BLACKMAN_HARRIS: - blackman_harris(window, N); - break; - default: - hann(window, N); - break; + switch (type) + { + case XTRACT_GAUSS: + gauss(window, N, 0.4); + break; + case XTRACT_HAMMING: + hamming(window, N); + break; + case XTRACT_HANN: + hann(window, N); + break; + case XTRACT_BARTLETT: + bartlett(window, N); + break; + case XTRACT_TRIANGULAR: + triangular(window, N); + break; + case XTRACT_BARTLETT_HANN: + bartlett_hann(window, N); + break; + case XTRACT_BLACKMAN: + blackman(window, N); + break; + case XTRACT_KAISER: + kaiser(window, N, 3 * PI); + break; + case XTRACT_BLACKMAN_HARRIS: + blackman_harris(window, N); + break; + default: + hann(window, N); + break; } return window; - } -void xtract_free_window(float *window){ - +void xtract_free_window(float *window) +{ free(window); - } #ifdef __GNUC__ __attribute__((constructor)) void init() #else - void _init()· +void _init()· #endif { -#ifdef XTRACT_FFT - fft_plans.spectrum_plan = NULL; - fft_plans.autocorrelation_fft_plan_1 = NULL; - fft_plans.autocorrelation_fft_plan_2 = NULL; - fft_plans.dct_plan = NULL; -#endif + ooura_data_dct.initialised = false; + ooura_data_spectrum.initialised = false; + ooura_data_autocorrelation_fft.initialised = false; + ooura_data_mfcc.initialised = false; } diff --git a/src/libxtract.c b/src/libxtract.c index a77c990..9e476b5 100644 --- a/src/libxtract.c +++ b/src/libxtract.c @@ -1,5 +1,5 @@ /* libxtract feature extraction library - * + * * Copyright (C) 2006 Jamie Bullock * * This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ @@ -22,7 +22,8 @@ #include "xtract/libxtract.h" #define XTRACT_H -int(*xtract[])(const float *, const int, const void *, float *) = { +int(*xtract[])(const float *, const int, const void *, float *) = +{ /* xtract_scalar.h */ xtract_mean, xtract_variance, diff --git a/src/scalar.c b/src/scalar.c index a82dda0..4aab5a4 100644 --- a/src/scalar.c +++ b/src/scalar.c @@ -1,5 +1,5 @@ /* libxtract feature extraction library - * + * * Copyright (C) 2006 Jamie Bullock * * This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ @@ -33,79 +33,85 @@ #include "xtract_macros_private.h" #ifndef powf - #define powf pow +#define powf pow #endif #ifndef expf - #define expf exp +#define expf exp #endif #ifndef sqrtf - #define sqrtf sqrt +#define sqrtf sqrt #endif #ifndef fabsf - #define fabsf fabs +#define fabsf fabs #endif -void test(void){ +void test(void) +{ printf("Hello world\n"); #ifdef WORDS_BIGENDIAN printf("Big endian!\n"); #endif } -int xtract_mean(const float *data, const int N, const void *argv, float *result){ +int xtract_mean(const float *data, const int N, const void *argv, float *result) +{ int n = N; - + *result = 0.f; while(n--) - *result += data[n]; - + *result += data[n]; + *result /= N; return XTRACT_SUCCESS; } -int xtract_variance(const float *data, const int N, const void *argv, float *result){ +int xtract_variance(const float *data, const int N, const void *argv, float *result) +{ int n = N; *result = 0.f; while(n--) - *result += powf(data[n] - *(float *)argv, 2); + *result += powf(data[n] - *(float *)argv, 2); *result = *result / (N - 1); return XTRACT_SUCCESS; } -int xtract_standard_deviation(const float *data, const int N, const void *argv, float *result){ +int xtract_standard_deviation(const float *data, const int N, const void *argv, float *result) +{ *result = sqrtf(*(float *)argv); return XTRACT_SUCCESS; } -int xtract_average_deviation(const float *data, const int N, const void *argv, float *result){ +int xtract_average_deviation(const float *data, const int N, const void *argv, float *result) +{ int n = N; *result = 0.f; while(n--) - *result += fabsf(data[n] - *(float *)argv); + *result += fabsf(data[n] - *(float *)argv); *result /= N; return XTRACT_SUCCESS; } -int xtract_skewness(const float *data, const int N, const void *argv, float *result){ +int xtract_skewness(const float *data, const int N, const void *argv, float *result) +{ int n = N; @@ -113,9 +119,10 @@ int xtract_skewness(const float *data, const int N, const void *argv, float *re *result = 0.f; - while(n--){ - temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1]; - *result += powf(temp, 3); + while(n--) + { + temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1]; + *result += powf(temp, 3); } *result /= N; @@ -124,7 +131,8 @@ int xtract_skewness(const float *data, const int N, const void *argv, float *re return XTRACT_SUCCESS; } -int xtract_kurtosis(const float *data, const int N, const void *argv, float *result){ +int xtract_kurtosis(const float *data, const int N, const void *argv, float *result) +{ int n = N; @@ -132,9 +140,10 @@ int xtract_kurtosis(const float *data, const int N, const void *argv, float *re *result = 0.f; - while(n--){ - temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1]; - *result += powf(temp, 4); + while(n--) + { + temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1]; + *result += powf(temp, 4); } *result /= N; @@ -143,7 +152,8 @@ int xtract_kurtosis(const float *data, const int N, const void *argv, float *re return XTRACT_SUCCESS; } -int xtract_spectral_centroid(const float *data, const int N, const void *argv, float *result){ +int xtract_spectral_centroid(const float *data, const int N, const void *argv, float *result) +{ int n = (N >> 1); @@ -153,9 +163,10 @@ int xtract_spectral_centroid(const float *data, const int N, const void *argv, amps = data; freqs = data + n; - while(n--){ - FA += freqs[n] * amps[n]; - A += amps[n]; + while(n--) + { + FA += freqs[n] * amps[n]; + A += amps[n]; } if(A == 0.f) @@ -166,13 +177,15 @@ int xtract_spectral_centroid(const float *data, const int N, const void *argv, return XTRACT_SUCCESS; } -int xtract_spectral_mean(const float *data, const int N, const void *argv, float *result){ +int xtract_spectral_mean(const float *data, const int N, const void *argv, float *result) +{ return xtract_spectral_centroid(data, N, argv, result); } -int xtract_spectral_variance(const float *data, const int N, const void *argv, float *result){ +int xtract_spectral_variance(const float *data, const int N, const void *argv, float *result) +{ int m; float A = 0.f; @@ -185,7 +198,8 @@ int xtract_spectral_variance(const float *data, const int N, const void *argv, f *result = 0.f; - while(m--){ + while(m--) + { A += amps[m]; *result += powf(freqs[m] - ((float *)argv)[0], 2) * amps[m]; } @@ -195,9 +209,10 @@ int xtract_spectral_variance(const float *data, const int N, const void *argv, f return XTRACT_SUCCESS; } -int xtract_spectral_standard_deviation(const float *data, const int N, const void *argv, float *result){ +int xtract_spectral_standard_deviation(const float *data, const int N, const void *argv, float *result) +{ - *result = sqrtf(*(float *)argv); + *result = sqrtf(*(float *)argv); return XTRACT_SUCCESS; } @@ -225,7 +240,8 @@ int xtract_spectral_standard_deviation(const float *data, const int N, const voi return XTRACT_SUCCESS; }*/ -int xtract_spectral_skewness(const float *data, const int N, const void *argv, float *result){ +int xtract_spectral_skewness(const float *data, const int N, const void *argv, float *result) +{ int m; const float *freqs, *amps; @@ -245,7 +261,8 @@ int xtract_spectral_skewness(const float *data, const int N, const void *argv, return XTRACT_SUCCESS; } -int xtract_spectral_kurtosis(const float *data, const int N, const void *argv, float *result){ +int xtract_spectral_kurtosis(const float *data, const int N, const void *argv, float *result) +{ int m; const float *freqs, *amps; @@ -266,28 +283,31 @@ int xtract_spectral_kurtosis(const float *data, const int N, const void *argv, return XTRACT_SUCCESS; } -int xtract_irregularity_k(const float *data, const int N, const void *argv, float *result){ +int xtract_irregularity_k(const float *data, const int N, const void *argv, float *result) +{ int n, - M = N - 1; - + M = N - 1; + *result = 0.f; - + for(n = 1; n < M; n++) - *result += fabsf(data[n] - (data[n-1] + data[n] + data[n+1]) / 3.f); + *result += fabsf(data[n] - (data[n-1] + data[n] + data[n+1]) / 3.f); return XTRACT_SUCCESS; } -int xtract_irregularity_j(const float *data, const int N, const void *argv, float *result){ +int xtract_irregularity_j(const float *data, const int N, const void *argv, float *result) +{ int n = N; double num = 0.f, den = 0.f; - while(n--){ - num += powf(data[n] - data[n+1], 2); - den += powf(data[n], 2); + while(n--) + { + num += powf(data[n] - data[n+1], 2); + den += powf(data[n], 2); } *result = (float)(num / den); @@ -295,7 +315,8 @@ int xtract_irregularity_j(const float *data, const int N, const void *argv, floa return XTRACT_SUCCESS; } -int xtract_tristimulus_1(const float *data, const int N, const void *argv, float *result){ +int xtract_tristimulus_1(const float *data, const int N, const void *argv, float *result) +{ int n = N; @@ -303,25 +324,30 @@ int xtract_tristimulus_1(const float *data, const int N, const void *argv, float den = p1 = temp = 0.f; - for(n = 0; n < N; n++){ - if((temp = data[n])){ - den += temp; - if(!p1) - p1 = temp; - } + for(n = 0; n < N; n++) + { + if((temp = data[n])) + { + den += temp; + if(!p1) + p1 = temp; + } } - if(den == 0.f || p1 == 0.f){ + if(den == 0.f || p1 == 0.f) + { *result = 0.f; return XTRACT_NO_RESULT; } - else{ + else + { *result = p1 / den; return XTRACT_SUCCESS; } } -int xtract_tristimulus_2(const float *data, const int N, const void *argv, float *result){ +int xtract_tristimulus_2(const float *data, const int N, const void *argv, float *result) +{ int n = N; @@ -329,32 +355,37 @@ int xtract_tristimulus_2(const float *data, const int N, const void *argv, float den = p2 = p3 = p4 = ps = temp = 0.f; - for(n = 0; n < N; n++){ - if((temp = data[n])){ - den += temp; - if(!p2) - p2 = temp; - else if(!p3) - p3 = temp; - else if(!p4) - p4 = temp; - } + for(n = 0; n < N; n++) + { + if((temp = data[n])) + { + den += temp; + if(!p2) + p2 = temp; + else if(!p3) + p3 = temp; + else if(!p4) + p4 = temp; + } } ps = p2 + p3 + p4; - if(den == 0.f || ps == 0.f){ + if(den == 0.f || ps == 0.f) + { *result = 0.f; return XTRACT_NO_RESULT; } - else{ + else + { *result = ps / den; return XTRACT_SUCCESS; } } -int xtract_tristimulus_3(const float *data, const int N, const void *argv, float *result){ +int xtract_tristimulus_3(const float *data, const int N, const void *argv, float *result) +{ int n = N, count = 0; @@ -362,26 +393,31 @@ int xtract_tristimulus_3(const float *data, const int N, const void *argv, float den = num = temp = 0.f; - for(n = 0; n < N; n++){ - if((temp = data[n])){ - den += temp; - if(count >= 5) - num += temp; - count++; - } + for(n = 0; n < N; n++) + { + if((temp = data[n])) + { + den += temp; + if(count >= 5) + num += temp; + count++; + } } - if(den == 0.f || num == 0.f){ + if(den == 0.f || num == 0.f) + { *result = 0.f; return XTRACT_NO_RESULT; } - else{ + else + { *result = num / den; return XTRACT_SUCCESS; } } -int xtract_smoothness(const float *data, const int N, const void *argv, float *result){ +int xtract_smoothness(const float *data, const int N, const void *argv, float *result) +{ int n, M; @@ -390,18 +426,19 @@ int xtract_smoothness(const float *data, const int N, const void *argv, float *r input = (float *)malloc(N * sizeof(float)); memcpy(input, data, N * sizeof(float)); - if (input[0] <= 0) + if (input[0] <= 0) input[0] = XTRACT_LOG_LIMIT; - if (input[1] <= 0) + if (input[1] <= 0) input[1] = XTRACT_LOG_LIMIT; M = N - 1; - for(n = 1; n < M; n++){ - if(input[n+1] <= 0) + for(n = 1; n < M; n++) + { + if(input[n+1] <= 0) input[n+1] = XTRACT_LOG_LIMIT; - *result += fabsf(20.f * logf(input[n]) - (20.f * logf(input[n-1]) + - 20.f * logf(input[n]) + 20.f * logf(input[n+1])) / 3.f); + *result += fabsf(20.f * logf(input[n]) - (20.f * logf(input[n-1]) + + 20.f * logf(input[n]) + 20.f * logf(input[n+1])) / 3.f); } free(input); @@ -409,24 +446,27 @@ int xtract_smoothness(const float *data, const int N, const void *argv, float *r return XTRACT_SUCCESS; } -int xtract_spread(const float *data, const int N, const void *argv, float *result){ +int xtract_spread(const float *data, const int N, const void *argv, float *result) +{ - return xtract_spectral_variance(data, N, argv, result); + return xtract_spectral_variance(data, N, argv, result); } -int xtract_zcr(const float *data, const int N, const void *argv, float *result){ +int xtract_zcr(const float *data, const int N, const void *argv, float *result) +{ int n = N; for(n = 1; n < N; n++) - if(data[n] * data[n-1] < 0) (*result)++; + if(data[n] * data[n-1] < 0) (*result)++; *result /= (float)N; return XTRACT_SUCCESS; } -int xtract_rolloff(const float *data, const int N, const void *argv, float *result){ +int xtract_rolloff(const float *data, const int N, const void *argv, float *result) +{ int n = N; float pivot, temp, percentile; @@ -434,12 +474,12 @@ int xtract_rolloff(const float *data, const int N, const void *argv, float *resu pivot = temp = 0.f; percentile = ((float *)argv)[1]; - while(n--) pivot += data[n]; + while(n--) pivot += data[n]; pivot *= percentile / 100.f; for(n = 0; temp < pivot; n++) - temp += data[n]; + temp += data[n]; *result = n * ((float *)argv)[0]; /* *result = (n / (float)N) * (((float *)argv)[1] * .5); */ @@ -447,30 +487,33 @@ int xtract_rolloff(const float *data, const int N, const void *argv, float *resu return XTRACT_SUCCESS; } -int xtract_loudness(const float *data, const int N, const void *argv, float *result){ +int xtract_loudness(const float *data, const int N, const void *argv, float *result) +{ int n = N, rv; *result = 0.f; - if(n > XTRACT_BARK_BANDS){ - n = XTRACT_BARK_BANDS; - rv = XTRACT_BAD_VECTOR_SIZE; + if(n > XTRACT_BARK_BANDS) + { + n = XTRACT_BARK_BANDS; + rv = XTRACT_BAD_VECTOR_SIZE; } else - rv = XTRACT_SUCCESS; + rv = XTRACT_SUCCESS; while(n--) - *result += powf(data[n], 0.23); + *result += powf(data[n], 0.23); return rv; } -int xtract_flatness(const float *data, const int N, const void *argv, float *result){ +int xtract_flatness(const float *data, const int N, const void *argv, float *result) +{ int n, count, denormal_found; - double num, den, temp; + double num, den, temp; num = 1.f; den = temp = 0.f; @@ -478,9 +521,12 @@ int xtract_flatness(const float *data, const int N, const void *argv, float *res denormal_found = 0; count = 0; - for(n = 0; n < N; n++){ - if((temp = data[n]) != 0.f) { - if (xtract_is_denormal(num)){ + for(n = 0; n < N; n++) + { + if((temp = data[n]) != 0.f) + { + if (xtract_is_denormal(num)) + { denormal_found = 1; break; } @@ -490,7 +536,8 @@ int xtract_flatness(const float *data, const int N, const void *argv, float *res } } - if(!count){ + if(!count) + { *result = 0.f; return XTRACT_NO_RESULT; } @@ -505,16 +552,17 @@ int xtract_flatness(const float *data, const int N, const void *argv, float *res return XTRACT_DENORMAL_FOUND; else return XTRACT_SUCCESS; - + } -int xtract_flatness_db(const float *data, const int N, const void *argv, float *result){ +int xtract_flatness_db(const float *data, const int N, const void *argv, float *result) +{ float flatness; flatness = *(float *)argv; - if (flatness <= 0) + if (flatness <= 0) flatness = XTRACT_LOG_LIMIT; *result = 10 * log10f(flatness); @@ -523,7 +571,8 @@ int xtract_flatness_db(const float *data, const int N, const void *argv, float * } -int xtract_tonality(const float *data, const int N, const void *argv, float *result){ +int xtract_tonality(const float *data, const int N, const void *argv, float *result) +{ float sfmdb; @@ -534,9 +583,10 @@ int xtract_tonality(const float *data, const int N, const void *argv, float *res return XTRACT_SUCCESS; } -int xtract_crest(const float *data, const int N, const void *argv, float *result){ +int xtract_crest(const float *data, const int N, const void *argv, float *result) +{ - float max, mean; + float max, mean; max = mean = 0.f; @@ -549,7 +599,8 @@ int xtract_crest(const float *data, const int N, const void *argv, float *result } -int xtract_noisiness(const float *data, const int N, const void *argv, float *result){ +int xtract_noisiness(const float *data, const int N, const void *argv, float *result) +{ float h, i, p; /*harmonics, inharmonics, partials */ @@ -566,7 +617,8 @@ int xtract_noisiness(const float *data, const int N, const void *argv, float *re } -int xtract_rms_amplitude(const float *data, const int N, const void *argv, float *result){ +int xtract_rms_amplitude(const float *data, const int N, const void *argv, float *result) +{ int n = N; @@ -579,81 +631,94 @@ int xtract_rms_amplitude(const float *data, const int N, const void *argv, float return XTRACT_SUCCESS; } -int xtract_spectral_inharmonicity(const float *data, const int N, const void *argv, float *result){ +int xtract_spectral_inharmonicity(const float *data, const int N, const void *argv, float *result) +{ int n = N >> 1; - float num = 0.f, den = 0.f, fund; + float num = 0.f, den = 0.f, fund; const float *freqs, *amps; fund = *(float *)argv; amps = data; freqs = data + n; - while(n--){ - if(amps[n]){ - num += fabsf(freqs[n] - n * fund) * XTRACT_SQ(amps[n]); - den += XTRACT_SQ(amps[n]); - } + while(n--) + { + if(amps[n]) + { + num += fabsf(freqs[n] - n * fund) * XTRACT_SQ(amps[n]); + den += XTRACT_SQ(amps[n]); + } } - *result = (2 * num) / (fund * den); + *result = (2 * num) / (fund * den); return XTRACT_SUCCESS; } -int xtract_power(const float *data, const int N, const void *argv, float *result){ +int xtract_power(const float *data, const int N, const void *argv, float *result) +{ return XTRACT_FEATURE_NOT_IMPLEMENTED; } -int xtract_odd_even_ratio(const float *data, const int N, const void *argv, float *result){ +int xtract_odd_even_ratio(const float *data, const int N, const void *argv, float *result) +{ int M = (N >> 1), n; float odd = 0.f, even = 0.f, temp; - for(n = 0; n < M; n++){ - if((temp = data[n])){ - if(XTRACT_IS_ODD(n)){ - odd += temp; - } - else{ - even += temp; - } - } + for(n = 0; n < M; n++) + { + if((temp = data[n])) + { + if(XTRACT_IS_ODD(n)) + { + odd += temp; + } + else + { + even += temp; + } + } } - if(odd == 0.f || even == 0.f){ + if(odd == 0.f || even == 0.f) + { *result = 0.f; return XTRACT_NO_RESULT; } - else { + else + { *result = odd / even; return XTRACT_SUCCESS; } } -int xtract_sharpness(const float *data, const int N, const void *argv, float *result){ +int xtract_sharpness(const float *data, const int N, const void *argv, float *result) +{ int n = N, rv; float sl, g; /* sl = specific loudness */ - double temp; + double temp; sl = g = 0.f; temp = 0.f; - if(n > XTRACT_BARK_BANDS) - rv = XTRACT_BAD_VECTOR_SIZE; + if(n > XTRACT_BARK_BANDS) + rv = XTRACT_BAD_VECTOR_SIZE; else - rv = XTRACT_SUCCESS; + rv = XTRACT_SUCCESS; - while(n--){ - sl = powf(data[n], 0.23); - g = (n < 15 ? 1.f : 0.066 * expf(0.171 * n)); - temp += n * g * sl; + while(n--) + { + sl = powf(data[n], 0.23); + g = (n < 15 ? 1.f : 0.066 * expf(0.171 * n)); + temp += n * g * sl; } temp = 0.11 * temp / (float)N; @@ -663,97 +728,105 @@ int xtract_sharpness(const float *data, const int N, const void *argv, float *re } -int xtract_spectral_slope(const float *data, const int N, const void *argv, float *result){ +int xtract_spectral_slope(const float *data, const int N, const void *argv, float *result) +{ - const float *freqs, *amps; + const float *freqs, *amps; float f, a, - F, A, FA, FXTRACT_SQ; /* sums of freqs, amps, freq * amps, freq squared */ - int n, M; - + F, A, FA, FXTRACT_SQ; /* sums of freqs, amps, freq * amps, freq squared */ + int n, M; + F = A = FA = FXTRACT_SQ = 0.f; n = M = N >> 1; amps = data; freqs = data + n; - while(n--){ - f = freqs[n]; - a = amps[n]; - F += f; - A += a; - FA += f * a; - FXTRACT_SQ += f * f; + while(n--) + { + f = freqs[n]; + a = amps[n]; + F += f; + A += a; + FA += f * a; + FXTRACT_SQ += f * f; } - *result = (1.f / A) * (M * FA - F * A) / (M * FXTRACT_SQ - F * F); + *result = (1.f / A) * (M * FA - F * A) / (M * FXTRACT_SQ - F * F); return XTRACT_SUCCESS; } -int xtract_lowest_value(const float *data, const int N, const void *argv, float *result){ +int xtract_lowest_value(const float *data, const int N, const void *argv, float *result) +{ int n = N; float temp; *result = data[--n]; - while(n--){ - if((temp = data[n]) > *(float *)argv) - *result = XTRACT_MIN(*result, data[n]); + while(n--) + { + if((temp = data[n]) > *(float *)argv) + *result = XTRACT_MIN(*result, data[n]); } return XTRACT_SUCCESS; } -int xtract_highest_value(const float *data, const int N, const void *argv, float *result){ +int xtract_highest_value(const float *data, const int N, const void *argv, float *result) +{ int n = N; *result = data[--n]; - while(n--) - *result = XTRACT_MAX(*result, data[n]); + while(n--) + *result = XTRACT_MAX(*result, data[n]); return XTRACT_SUCCESS; } -int xtract_sum(const float *data, const int N, const void *argv, float *result){ +int xtract_sum(const float *data, const int N, const void *argv, float *result) +{ int n = N; *result = 0.f; while(n--) - *result += *data++; + *result += *data++; return XTRACT_SUCCESS; } -int xtract_nonzero_count(const float *data, const int N, const void *argv, float *result){ +int xtract_nonzero_count(const float *data, const int N, const void *argv, float *result) +{ int n = N; - + *result = 0.f; while(n--) - *result += (*data++ ? 1 : 0); + *result += (*data++ ? 1 : 0); return XTRACT_SUCCESS; } -int xtract_hps(const float *data, const int N, const void *argv, float *result){ +int xtract_hps(const float *data, const int N, const void *argv, float *result) +{ int n = N, M, m, l, peak_index, position1_lwr; - float *coeffs2, *coeffs3, *product, L, - largest1_lwr, peak, ratio1, sr; + float *coeffs2, *coeffs3, *product, L, + largest1_lwr, peak, ratio1, sr; sr = *(float*)argv; if(sr == 0) - sr = 44100.f; + sr = 44100.f; coeffs2 = (float *)malloc(N * sizeof(float)); coeffs3 = (float *)malloc(N * sizeof(float)); @@ -764,42 +837,48 @@ int xtract_hps(const float *data, const int N, const void *argv, float *result){ M = N >> 1; L = N / 3.f; - while(M--){ - m = M << 1; - coeffs2[M] = (data[m] + data[m+1]) * 0.5f; + while(M--) + { + m = M << 1; + coeffs2[M] = (data[m] + data[m+1]) * 0.5f; - if(M < L){ - l = M * 3; - coeffs3[M] = (data[l] + data[l+1] + data[l+2]) / 3.f; - } + if(M < L) + { + l = M * 3; + coeffs3[M] = (data[l] + data[l+1] + data[l+2]) / 3.f; + } } peak_index = peak = 0; - for(n = 1; n < N; n++){ - product[n] = data[n] * coeffs2[n] * coeffs3[n]; - if(product[n] > peak){ - peak_index = n; - peak = product[n]; - } + for(n = 1; n < N; n++) + { + product[n] = data[n] * coeffs2[n] * coeffs3[n]; + if(product[n] > peak) + { + peak_index = n; + peak = product[n]; + } } largest1_lwr = position1_lwr = 0; - for(n = 0; n < N; n++){ - if(data[n] > largest1_lwr && n != peak_index){ - largest1_lwr = data[n]; - position1_lwr = n; - } + for(n = 0; n < N; n++) + { + if(data[n] > largest1_lwr && n != peak_index) + { + largest1_lwr = data[n]; + position1_lwr = n; + } } ratio1 = data[position1_lwr] / data[peak_index]; - if(position1_lwr > peak_index * 0.4 && position1_lwr < - peak_index * 0.6 && ratio1 > 0.1) - peak_index = position1_lwr; + if(position1_lwr > peak_index * 0.4 && position1_lwr < + peak_index * 0.6 && ratio1 > 0.1) + peak_index = position1_lwr; - *result = sr / (float)peak_index; + *result = sr / (float)peak_index; free(coeffs2); free(coeffs3); @@ -809,24 +888,25 @@ int xtract_hps(const float *data, const int N, const void *argv, float *result){ } -int xtract_f0(const float *data, const int N, const void *argv, float *result){ +int xtract_f0(const float *data, const int N, const void *argv, float *result) +{ int M, tau, n; float sr; size_t bytes; - float f0, err_tau_1, err_tau_x, array_max, - threshold_peak, threshold_centre, - *input; + float f0, err_tau_1, err_tau_x, array_max, + threshold_peak, threshold_centre, + *input; sr = *(float *)argv; if(sr == 0) - sr = 44100.f; + sr = 44100.f; input = (float *)malloc(bytes = N * sizeof(float)); input = memcpy(input, data, bytes); /* threshold_peak = *((float *)argv+1); - threshold_centre = *((float *)argv+2); - printf("peak: %.2f\tcentre: %.2f\n", threshold_peak, threshold_centre);*/ + threshold_centre = *((float *)argv+2); + printf("peak: %.2f\tcentre: %.2f\n", threshold_peak, threshold_centre);*/ /* add temporary dynamic control over thresholds to test clipping effects */ /* FIX: tweak and make into macros */ @@ -837,75 +917,83 @@ int xtract_f0(const float *data, const int N, const void *argv, float *result){ array_max = 0; /* Find the array max */ - for(n = 0; n < N; n++){ - if (input[n] > array_max) - array_max = input[n]; + for(n = 0; n < N; n++) + { + if (input[n] > array_max) + array_max = input[n]; } threshold_peak *= array_max; /* peak clip */ - for(n = 0; n < N; n++){ - if(input[n] > threshold_peak) - input[n] = threshold_peak; - else if(input[n] < -threshold_peak) - input[n] = -threshold_peak; + for(n = 0; n < N; n++) + { + if(input[n] > threshold_peak) + input[n] = threshold_peak; + else if(input[n] < -threshold_peak) + input[n] = -threshold_peak; } threshold_centre *= array_max; /* Centre clip */ - for(n = 0; n < N; n++){ - if (input[n] < threshold_centre) - input[n] = 0; - else - input[n] -= threshold_centre; + for(n = 0; n < N; n++) + { + if (input[n] < threshold_centre) + input[n] = 0; + else + input[n] -= threshold_centre; } /* Estimate fundamental freq */ for (n = 1; n < M; n++) - err_tau_1 = err_tau_1 + fabsf(input[n] - input[n+1]); - /* FIX: this doesn't pose too much load if it returns 'early', but if it can't find f0, load can be significant for larger block sizes M^2 iterations! */ - for (tau = 2; tau < M; tau++){ - err_tau_x = 0; - for (n = 1; n < M; n++){ - err_tau_x = err_tau_x + fabsf(input[n] - input[n+tau]); - } - if (err_tau_x < err_tau_1) { - f0 = sr / (tau + (err_tau_x / err_tau_1)); - *result = f0; - free(input); - return XTRACT_SUCCESS; - } + err_tau_1 = err_tau_1 + fabsf(input[n] - input[n+1]); + /* FIX: this doesn't pose too much load if it returns 'early', but if it can't find f0, load can be significant for larger block sizes M^2 iterations! */ + for (tau = 2; tau < M; tau++) + { + err_tau_x = 0; + for (n = 1; n < M; n++) + { + err_tau_x = err_tau_x + fabsf(input[n] - input[n+tau]); + } + if (err_tau_x < err_tau_1) + { + f0 = sr / (tau + (err_tau_x / err_tau_1)); + *result = f0; + free(input); + return XTRACT_SUCCESS; + } } *result = -0; free(input); return XTRACT_NO_RESULT; } -int xtract_failsafe_f0(const float *data, const int N, const void *argv, float *result){ +int xtract_failsafe_f0(const float *data, const int N, const void *argv, float *result) +{ float *spectrum = NULL, argf[2], *peaks = NULL, return_code, sr; return_code = xtract_f0(data, N, argv, result); - if(return_code == XTRACT_NO_RESULT){ - - sr = *(float *)argv; - if(sr == 0) - sr = 44100.f; - spectrum = (float *)malloc(N * sizeof(float)); - peaks = (float *)malloc(N * sizeof(float)); - argf[0] = sr; - argf[1] = XTRACT_MAGNITUDE_SPECTRUM; - xtract_spectrum(data, N, argf, spectrum); - argf[1] = 10.f; - xtract_peak_spectrum(spectrum, N >> 1, argf, peaks); - argf[0] = 0.f; - xtract_lowest_value(peaks+(N >> 1), N >> 1, argf, result); - - free(spectrum); - free(peaks); + if(return_code == XTRACT_NO_RESULT) + { + + sr = *(float *)argv; + if(sr == 0) + sr = 44100.f; + spectrum = (float *)malloc(N * sizeof(float)); + peaks = (float *)malloc(N * sizeof(float)); + argf[0] = sr; + argf[1] = XTRACT_MAGNITUDE_SPECTRUM; + xtract_spectrum(data, N, argf, spectrum); + argf[1] = 10.f; + xtract_peak_spectrum(spectrum, N >> 1, argf, peaks); + argf[0] = 0.f; + xtract_lowest_value(peaks+(N >> 1), N >> 1, argf, result); + + free(spectrum); + free(peaks); } return XTRACT_SUCCESS; diff --git a/src/vector.c b/src/vector.c index 9c29762..73e437f 100644 --- a/src/vector.c +++ b/src/vector.c @@ -1,5 +1,5 @@ /* libxtract feature extraction library - * + * * Copyright (C) 2006 Jamie Bullock * * This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ @@ -25,16 +25,19 @@ #include <string.h> #include <stdlib.h> +#include "fftsg.h" + #include "xtract/libxtract.h" #include "xtract_macros_private.h" #ifndef roundf - float roundf(float f){ - if (f - (int)f >= 0.5) - return (float)((int)f + 1); - else - return (float)((int)f); - } +float roundf(float f) +{ + if (f - (int)f >= 0.5) + return (float)((int)f + 1); + else + return (float)((int)f); +} #endif #ifndef powf @@ -53,185 +56,208 @@ #define fabsf fabs #endif -#ifdef XTRACT_FFT - -#include <fftw3.h> #include "xtract_globals_private.h" #include "xtract_macros_private.h" -int xtract_spectrum(const float *data, const int N, const void *argv, float *result){ - - float *input, *rfft, q, temp, max, NxN; - size_t bytes; - int n, - m, - M, - vector, - withDC, - argc, - normalise; - - vector = argc = withDC = normalise = 0; - - M = N >> 1; - NxN = XTRACT_SQ(N); - - rfft = (float *)fftwf_malloc(N * sizeof(float)); - input = (float *)malloc(bytes = N * sizeof(float)); - input = memcpy(input, data, bytes); +int xtract_spectrum(const float *data, const int N, const void *argv, float *result) +{ + + int vector = 0; + int withDC = 0; + int normalise = 0; + float q = 0.f; + float temp = 0.f; + float max = 0.f; + float NxN = XTRACT_SQ(N); + float *marker = NULL; + size_t bytes = N * sizeof(double); + double *rfft = NULL; + unsigned int n = 0; + unsigned int m = 0; + unsigned int nx2 = 0; + unsigned int M = N >> 1; + + rfft = (double *)malloc(bytes); + //memcpy(rfft, data, bytes); + + for(n = 0; n < N; ++n){ + rfft[n] = (double)data[n]; + } q = *(float *)argv; vector = (int)*((float *)argv+1); withDC = (int)*((float *)argv+2); normalise = (int)*((float *)argv+3); - temp = 0.f; - max = 0.f; - XTRACT_CHECK_q; - if(fft_plans.spectrum_plan == NULL){ - fprintf(stderr, - "libxtract: Error: xtract_spectrum() has uninitialised plan\n"); + if(!ooura_data_spectrum.initialised) + { + fprintf(stderr, + "libxtract: error: xtract_spectrum() failed, " + "fft data unitialised.\n"); return XTRACT_NO_RESULT; } - fftwf_execute_r2r(fft_plans.spectrum_plan, input, rfft); + /* ooura is in-place + * the output format seems to be + * a[0] - DC, a[1] - nyquist, a[2...N-1] - remaining bins + */ + rdft(N, 1, rfft, ooura_data_spectrum.ooura_ip, + ooura_data_spectrum.ooura_w); - switch(vector){ + switch(vector) + { case XTRACT_LOG_MAGNITUDE_SPECTRUM: - for(n = 0, m = 0; m < M; ++n, ++m){ - if(!withDC && n == 0){ - ++n; - } - if ((temp = XTRACT_SQ(rfft[n]) + - XTRACT_SQ(rfft[N - n])) > XTRACT_LOG_LIMIT) - temp = logf(sqrtf(temp) / (float)N); - else - temp = XTRACT_LOG_LIMIT_DB; - - result[m] = - /* Scaling */ - (temp + XTRACT_DB_SCALE_OFFSET) / - XTRACT_DB_SCALE_OFFSET; - - XTRACT_SET_FREQUENCY; - XTRACT_GET_MAX; + for(n = 0, m = 0; m < M; ++n, ++m) + { + if(!withDC && n == 0) + { + continue; } - break; - - case XTRACT_POWER_SPECTRUM: - for(n = 0, m = 0; m < M; ++n, ++m){ - if(!withDC && n == 0){ - ++n; - } - result[m] = (XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) / NxN; - XTRACT_SET_FREQUENCY; - XTRACT_GET_MAX; + nx2 = n * 2; + temp = XTRACT_SQ(rfft[nx2]) + XTRACT_SQ(rfft[nx2+1]); + if (temp > XTRACT_LOG_LIMIT) + { + temp = logf(sqrtf(temp) / (float)N); } - break; - - case XTRACT_LOG_POWER_SPECTRUM: - for(n = 0, m = 0; m < M; ++n, ++m){ - if(!withDC && n == 0){ - ++n; - } - if ((temp = XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) > - XTRACT_LOG_LIMIT) - temp = logf(temp / NxN); - else - temp = XTRACT_LOG_LIMIT_DB; - - result[m] = (temp + XTRACT_DB_SCALE_OFFSET) / - XTRACT_DB_SCALE_OFFSET; - XTRACT_SET_FREQUENCY; - XTRACT_GET_MAX; + else + { + temp = XTRACT_LOG_LIMIT_DB; } - break; + result[m] = + /* Scaling */ + (temp + XTRACT_DB_SCALE_OFFSET) / + XTRACT_DB_SCALE_OFFSET; - default: - /* MAGNITUDE_SPECTRUM */ - for(n = 0, m = 0; m < M; ++n, ++m){ - if(!withDC && n == 0){ - ++n; - } - result[m] = sqrtf(XTRACT_SQ(rfft[n]) + - XTRACT_SQ(rfft[N - n])) / (float)N; - XTRACT_SET_FREQUENCY; - XTRACT_GET_MAX; + XTRACT_SET_FREQUENCY; + XTRACT_GET_MAX; + } + break; + + case XTRACT_POWER_SPECTRUM: + for(n = 0, m = 0; m < M; ++n, ++m) + { + if(!withDC && n == 0) + { + ++n; } - break; + result[m] = (XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) / NxN; + XTRACT_SET_FREQUENCY; + XTRACT_GET_MAX; + } + break; + + case XTRACT_LOG_POWER_SPECTRUM: + for(n = 0, m = 0; m < M; ++n, ++m) + { + if(!withDC && n == 0) + { + ++n; + } + if ((temp = XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) > + XTRACT_LOG_LIMIT) + temp = logf(temp / NxN); + else + temp = XTRACT_LOG_LIMIT_DB; + + result[m] = (temp + XTRACT_DB_SCALE_OFFSET) / + XTRACT_DB_SCALE_OFFSET; + XTRACT_SET_FREQUENCY; + XTRACT_GET_MAX; + } + break; + + default: + /* MAGNITUDE_SPECTRUM */ + for(n = 0, m = 0; m < M; ++n, ++m) + { + marker = &result[m]; + + if(n==0 && !withDC) /* discard DC and keep Nyquist */ + { + ++n; + marker = &result[M-1]; + } + if(n==1 && withDC) /* discard Nyquist */ + { + ++n; + } + + *marker = (float)(sqrt(XTRACT_SQ(rfft[n*2]) + + XTRACT_SQ(rfft[n*2+1])) / (double)N); + XTRACT_SET_FREQUENCY; + XTRACT_GET_MAX; + + } + break; } - if(normalise){ + if(normalise) + { for(n = 0; n < M; n++) result[n] /= max; } - fftwf_free(rfft); - free(input); + free(rfft); return XTRACT_SUCCESS; } -int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *result){ +int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *result) +{ - float *freq, *time; - int n, M; - //fftwf_plan plan; + double *rfft = NULL; + int n = 0; + int M = 0; M = N << 1; - freq = (float *)fftwf_malloc(M * sizeof(float)); /* Zero pad the input vector */ - time = (float *)calloc(M, sizeof(float)); - time = memcpy(time, data, N * sizeof(float)); - - fftwf_execute_r2r(fft_plans.autocorrelation_fft_plan_1, time, freq); - //plan = fftwf_plan_r2r_1d(M, time, freq, FFTW_R2HC, FFTW_ESTIMATE); + rfft = (double *)calloc(M, sizeof(double)); + memcpy(rfft, data, N * sizeof(float)); - //fftwf_execute(plan); + rdft(M, 1, rfft, ooura_data_autocorrelation_fft.ooura_ip, + ooura_data_autocorrelation_fft.ooura_w); - for(n = 1; n < N; n++){ - freq[n] = XTRACT_SQ(freq[n]) + XTRACT_SQ(freq[M - n]); - freq[M - n] = 0.f; + for(n = 2; n < M; n++) + { + rfft[n*2] = XTRACT_SQ(rfft[n*2]) + XTRACT_SQ(rfft[n*2+1]); + rfft[n*2+1] = 0.f; } - freq[0] = XTRACT_SQ(freq[0]); - freq[N] = XTRACT_SQ(freq[N]); - - //plan = fftwf_plan_r2r_1d(M, freq, time, FFTW_HC2R, FFTW_ESTIMATE); - - //fftwf_execute(plan); + rfft[0] = XTRACT_SQ(rfft[0]); + rfft[1] = XTRACT_SQ(rfft[1]); - fftwf_execute_r2r(fft_plans.autocorrelation_fft_plan_2, freq, time); + rdft(M, -1, rfft, ooura_data_autocorrelation_fft.ooura_ip, + ooura_data_autocorrelation_fft.ooura_w); /* Normalisation factor */ M = M * N; for(n = 0; n < N; n++) - result[n] = time[n] / (float)M; - /* result[n] = time[n+1] / (float)M; */ + result[n] = rfft[n] / (float)M; - //fftwf_destroy_plan(plan); - fftwf_free(freq); - free(time); + free(rfft); return XTRACT_SUCCESS; } -int xtract_mfcc(const float *data, const int N, const void *argv, float *result){ +int xtract_mfcc(const float *data, const int N, const void *argv, float *result) +{ xtract_mel_filter *f; int n, filter; f = (xtract_mel_filter *)argv; - for(filter = 0; filter < f->n_filters; filter++){ + for(filter = 0; filter < f->n_filters; filter++) + { result[filter] = 0.f; - for(n = 0; n < N; n++){ + for(n = 0; n < N; n++) + { result[filter] += data[n] * f->filters[filter][n]; } result[filter] = logf(result[filter] < XTRACT_LOG_LIMIT ? XTRACT_LOG_LIMIT : result[filter]); @@ -242,53 +268,25 @@ int xtract_mfcc(const float *data, const int N, const void *argv, float *result) return XTRACT_SUCCESS; } -int xtract_dct(const float *data, const int N, const void *argv, float *result){ +int xtract_dct(const float *data, const int N, const void *argv, float *result) +{ - //fftwf_plan plan; + int n; + int m; + float *temp = calloc(N, sizeof(float)); - //plan = - // fftwf_plan_r2r_1d(N, (float *) data, result, FFTW_REDFT00, FFTW_ESTIMATE); - - fftwf_execute_r2r(fft_plans.dct_plan, (float *)data, result); - //fftwf_execute(plan); - //fftwf_destroy_plan(plan); - - return XTRACT_SUCCESS; -} - -#else - -int xtract_spectrum(const float *data, const int N, const void *argv, float *result){ - - XTRACT_NEEDS_FFTW; - return XTRACT_NO_RESULT; - -} - -int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *result){ - - XTRACT_NEEDS_FFTW; - return XTRACT_NO_RESULT; - -} - -int xtract_mfcc(const float *data, const int N, const void *argv, float *result){ - - XTRACT_NEEDS_FFTW; - return XTRACT_NO_RESULT; - -} - -int xtract_dct(const float *data, const int N, const void *argv, float *result){ - - XTRACT_NEEDS_FFTW; - return XTRACT_NO_RESULT; + for (n = 0; n < N; ++n) + { + for(m = 1; m <= N; ++m) { + temp[n] += data[m - 1] * cos(M_PI * (n / (float)N) * (m - 0.5)); + } + } + return XTRACT_SUCCESS; } -#endif - -int xtract_autocorrelation(const float *data, const int N, const void *argv, float *result){ +int xtract_autocorrelation(const float *data, const int N, const void *argv, float *result) +{ /* Naive time domain implementation */ @@ -296,9 +294,11 @@ int xtract_autocorrelation(const float *data, const int N, const void *argv, flo float corr; - while(n--){ + while(n--) + { corr = 0; - for(i = 0; i < N - n; i++){ + for(i = 0; i < N - n; i++) + { corr += data[i] * data[i + n]; } result[n] = corr / N; @@ -307,15 +307,18 @@ int xtract_autocorrelation(const float *data, const int N, const void *argv, flo return XTRACT_SUCCESS; } -int xtract_amdf(const float *data, const int N, const void *argv, float *result){ +int xtract_amdf(const float *data, const int N, const void *argv, float *result) +{ int n = N, i; float md, temp; - while(n--){ + while(n--) + { md = 0.f; - for(i = 0; i < N - n; i++){ + for(i = 0; i < N - n; i++) + { temp = data[i] - data[i + n]; temp = (temp < 0 ? -temp : temp); md += temp; @@ -326,15 +329,18 @@ int xtract_amdf(const float *data, const int N, const void *argv, float *result) return XTRACT_SUCCESS; } -int xtract_asdf(const float *data, const int N, const void *argv, float *result){ +int xtract_asdf(const float *data, const int N, const void *argv, float *result) +{ int n = N, i; float sd; - while(n--){ + while(n--) + { sd = 0.f; - for(i = 0; i < N - n; i++){ + for(i = 0; i < N - n; i++) + { /*sd = 1;*/ sd += XTRACT_SQ(data[i] - data[i + n]); } @@ -344,13 +350,15 @@ int xtract_asdf(const float *data, const int N, const void *argv, float *result) return XTRACT_SUCCESS; } -int xtract_bark_coefficients(const float *data, const int N, const void *argv, float *result){ +int xtract_bark_coefficients(const float *data, const int N, const void *argv, float *result) +{ int *limits, band, n; limits = (int *)argv; - for(band = 0; band < XTRACT_BARK_BANDS - 1; band++){ + for(band = 0; band < XTRACT_BARK_BANDS - 1; band++) + { result[band] = 0.f; for(n = limits[band]; n < limits[band + 1]; n++) result[band] += data[n]; @@ -359,7 +367,8 @@ int xtract_bark_coefficients(const float *data, const int N, const void *argv, f return XTRACT_SUCCESS; } -int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result){ +int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result) +{ float threshold, max, y, y2, y3, p, q, *input = NULL; size_t bytes; @@ -367,14 +376,16 @@ int xtract_peak_spectrum(const float *data, const int N, const void *argv, float threshold = max = y = y2 = y3 = p = q = 0.f; - if(argv != NULL){ + if(argv != NULL) + { q = ((float *)argv)[0]; threshold = ((float *)argv)[1]; } else rv = XTRACT_BAD_ARGV; - if(threshold < 0 || threshold > 100){ + if(threshold < 0 || threshold > 100) + { threshold = 0; rv = XTRACT_BAD_ARGV; } @@ -398,32 +409,38 @@ int xtract_peak_spectrum(const float *data, const int N, const void *argv, float result[0] = 0; result[N] = 0; - for(n = 1; n < N; n++){ - if(input[n] >= threshold){ - if(input[n] > input[n - 1] && n + 1 < N && input[n] > input[n + 1]){ - result[N + n] = q * (n + (p = .5 * ((y = input[n-1]) - - (y3 = input[n+1])) / (input[n - 1] - 2 * - (y2 = input[n]) + input[n + 1]))); + for(n = 1; n < N; n++) + { + if(input[n] >= threshold) + { + if(input[n] > input[n - 1] && n + 1 < N && input[n] > input[n + 1]) + { + result[N + n] = q * (n + (p = .5 * ((y = input[n-1]) - + (y3 = input[n+1])) / (input[n - 1] - 2 * + (y2 = input[n]) + input[n + 1]))); result[n] = y2 - .25 * (y - y3) * p; } - else{ + else + { result[n] = 0; result[N + n] = 0; } } - else{ + else + { result[n] = 0; result[N + n] = 0; } - } + } free(input); return (rv ? rv : XTRACT_SUCCESS); } -int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, float *result){ +int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, float *result) +{ - int n = (N >> 1), M = n; + int n = (N >> 1), M = n; const float *freqs, *amps; float f0, threshold, ratio, nearest, distance; @@ -435,14 +452,17 @@ int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, f ratio = nearest = distance = 0.f; - while(n--){ - if(freqs[n]){ + while(n--) + { + if(freqs[n]) + { ratio = freqs[n] / f0; nearest = roundf(ratio); distance = fabs(nearest - ratio); if(distance > threshold) result[n] = result[M + n] = 0.f; - else { + else + { result[n] = amps[n]; result[M + n] = freqs[n]; } @@ -453,14 +473,15 @@ int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, f return XTRACT_SUCCESS; } -int xtract_lpc(const float *data, const int N, const void *argv, float *result){ +int xtract_lpc(const float *data, const int N, const void *argv, float *result) +{ int i, j, k, M, L; - float r = 0.f, + float r = 0.f, error = 0.f; float *ref = NULL, - *lpc = NULL ; + *lpc = NULL ; error = data[0]; k = N; /* The length of *data */ @@ -469,24 +490,27 @@ int xtract_lpc(const float *data, const int N, const void *argv, float *result){ ref = result; lpc = result+L; - if(error == 0.0){ + if(error == 0.0) + { memset(result, 0, M * sizeof(float)); return XTRACT_NO_RESULT; } memset(result, 0, M * sizeof(float)); - for (i = 0; i < L; i++) { + for (i = 0; i < L; i++) + { /* Sum up this iteration's reflection coefficient. */ r = -data[i + 1]; - for (j = 0; j < i; j++) + for (j = 0; j < i; j++) r -= lpc[j] * data[i - j]; ref[i] = r /= error; /* Update LPC coefficients and total error. */ lpc[i] = r; - for (j = 0; j < i / 2; j++) { + for (j = 0; j < i / 2; j++) + { float tmp = lpc[j]; lpc[j] = r * lpc[i - 1 - j]; lpc[i - 1 - j] += r * tmp; @@ -499,7 +523,8 @@ int xtract_lpc(const float *data, const int N, const void *argv, float *result){ return XTRACT_SUCCESS; } -int xtract_lpcc(const float *data, const int N, const void *argv, float *result){ +int xtract_lpcc(const float *data, const int N, const void *argv, float *result) +{ /* Given N lpc coefficients extract an LPC cepstrum of size argv[0] */ /* Based on an an algorithm by rabiner and Juang */ @@ -507,7 +532,7 @@ int xtract_lpcc(const float *data, const int N, const void *argv, float *result) int n, k; float sum; int order = N - 1; /* Eventually change this to Q = 3/2 p as suggested in Rabiner */ - int cep_length; + int cep_length; if(argv == NULL) cep_length = N - 1; /* FIX: if we're going to have default values, they should come from the descriptor */ @@ -517,7 +542,8 @@ int xtract_lpcc(const float *data, const int N, const void *argv, float *result) memset(result, 0, cep_length * sizeof(float)); - for (n = 1; n <= order && n <= cep_length; n++){ + for (n = 1; n <= order && n <= cep_length; n++) + { sum = 0.f; for (k = 1; k < n; k++) sum += k * result[k-1] * data[n - k]; @@ -525,7 +551,8 @@ int xtract_lpcc(const float *data, const int N, const void *argv, float *result) } /* be wary of these interpolated values */ - for(n = order + 1; n <= cep_length; n++){ + for(n = order + 1; n <= cep_length; n++) + { sum = 0.f; for (k = n - (order - 1); k < n; k++) sum += k * result[k-1] * data[n - k]; @@ -539,7 +566,8 @@ int xtract_lpcc(const float *data, const int N, const void *argv, float *result) // return XTRACT_SUCCESS; //} -int xtract_subbands(const float *data, const int N, const void *argv, float *result){ +int xtract_subbands(const float *data, const int N, const void *argv, float *result) +{ int n, bw, xtract_func, nbands, scale, start, lower, *argi, rv; @@ -558,10 +586,12 @@ int xtract_subbands(const float *data, const int N, const void *argv, float *res lower = start; rv = XTRACT_SUCCESS; - for(n = 0; n < nbands; n++){ + for(n = 0; n < nbands; n++) + { /* Bounds sanity check */ - if(lower >= N || lower + bw >= N){ + if(lower >= N || lower + bw >= N) + { // printf("n: %d\n", n); result[n] = 0.f; continue; @@ -572,14 +602,15 @@ int xtract_subbands(const float *data, const int N, const void *argv, float *res if(rv != XTRACT_SUCCESS) return rv; - switch(scale){ - case XTRACT_OCTAVE_SUBBANDS: - lower += bw; - bw = lower; - break; - case XTRACT_LINEAR_SUBBANDS: - lower += bw; - break; + switch(scale) + { + case XTRACT_OCTAVE_SUBBANDS: + lower += bw; + bw = lower; + break; + case XTRACT_LINEAR_SUBBANDS: + lower += bw; + break; } } diff --git a/src/window.c b/src/window.c index f2ceecc..d967bfd 100644 --- a/src/window.c +++ b/src/window.c @@ -1,5 +1,5 @@ /* libxtract feature extraction library - * + * * Copyright (C) 2006 Jamie Bullock * * This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ @@ -24,7 +24,8 @@ #include "xtract_window_private.h" -void gauss(float *window, const int N, const float sd){ +void gauss(float *window, const int N, const float sd) +{ int n; const float M = N - 1; @@ -32,11 +33,12 @@ void gauss(float *window, const int N, const float sd){ den, exponent; - for (n = 0; n < N; n++) { + for (n = 0; n < N; n++) + { num = n - M / 2.f; den = sd * M / 2.f; - + exponent = -0.5 * powf(num / den, 2); window[n] = exp(exponent); @@ -44,7 +46,8 @@ void gauss(float *window, const int N, const float sd){ } } -void hamming(float *window, const int N){ +void hamming(float *window, const int N) +{ int n; const float M = N - 1; @@ -54,7 +57,8 @@ void hamming(float *window, const int N){ } -void hann(float *window, const int N){ +void hann(float *window, const int N) +{ int n; const float M = N - 1; @@ -64,7 +68,8 @@ void hann(float *window, const int N){ } -void bartlett(float *window, const int N){ +void bartlett(float *window, const int N) +{ int n; const float M = N - 1; @@ -74,7 +79,8 @@ void bartlett(float *window, const int N){ } -void triangular(float *window, const int N){ +void triangular(float *window, const int N) +{ int n; const float M = N - 1; @@ -83,17 +89,19 @@ void triangular(float *window, const int N){ window[n] = 2.f / N * (N / 2.f - fabsf(n - M / 2.f)); } -void bartlett_hann(float *window, const int N){ +void bartlett_hann(float *window, const int N) +{ int n; const float M = N - 1, - a0 = 0.62, - a1 = 0.5, - a2 = 0.38; + a0 = 0.62, + a1 = 0.5, + a2 = 0.38; float term1 = 0.f, term2 = 0.f; - for (n = 0; n < N; n++){ + for (n = 0; n < N; n++) + { term1 = a1 * fabsf(n / M - 0.5); term2 = a2 * cosf(2.0 * PI * (float)n / M); @@ -102,18 +110,20 @@ void bartlett_hann(float *window, const int N){ } } -void blackman(float *window, const int N){ +void blackman(float *window, const int N) +{ int n; const float M = N - 1, - a0 = 0.42, - a1 = 0.5, - a2 = 0.08; + a0 = 0.42, + a1 = 0.5, + a2 = 0.08; float term1 = 0.f, term2 = 0.f; - for (n = 0; n < N; n++) { - + for (n = 0; n < N; n++) + { + term1 = a1 * cosf(2.0 * PI * (float)n / M); term2 = a2 * cosf(4.0 * PI * (float)n / M); @@ -124,54 +134,61 @@ void blackman(float *window, const int N){ #define BIZ_EPSILON 1E-21 // Max error acceptable /* Based on code from mplayer window.c, and somewhat beyond me */ -float besselI0(float x){ +float besselI0(float x) +{ - float temp; - float sum = 1.0; - float u = 1.0; - float halfx = x/2.0; - int n = 1; + float temp; + float sum = 1.0; + float u = 1.0; + float halfx = x/2.0; + int n = 1; - do { + do + { - temp = halfx/(float)n; - u *=temp * temp; - sum += u; - n++; + temp = halfx/(float)n; + u *=temp * temp; + sum += u; + n++; - } while (u >= BIZ_EPSILON * sum); + } + while (u >= BIZ_EPSILON * sum); - return(sum); + return(sum); } -void kaiser(float *window, const int N, const float alpha){ +void kaiser(float *window, const int N, const float alpha) +{ int n; const float M = N - 1; float num; - for (n = 0; n < N; n++) { + for (n = 0; n < N; n++) + { num = besselI0(alpha * sqrtf(1.0 - powf((2.0 * n / M - 1), 2))); window[n] = num / besselI0(alpha); - + } } -void blackman_harris(float *window, const int N){ +void blackman_harris(float *window, const int N) +{ int n; const float M = N - 1, - a0 = 0.35875, - a1 = 0.48829, - a2 = 0.14128, - a3 = 0.01168; + a0 = 0.35875, + a1 = 0.48829, + a2 = 0.14128, + a3 = 0.01168; float term1 = 0.f, term2 = 0.f, term3 = 0.f; - for (n = 0; n < N; n++) { + for (n = 0; n < N; n++) + { term1 = a1 * cosf(2.0 * PI * n / M); term2 = a2 * cosf(4.0 * PI * n / M); diff --git a/src/xtract_globals_private.h b/src/xtract_globals_private.h index cab1660..d280985 100644 --- a/src/xtract_globals_private.h +++ b/src/xtract_globals_private.h @@ -23,17 +23,12 @@ #ifndef XTRACT_GLOBALS_PRIVATE_H #define XTRACT_GLOBALS_PRIVATE_H -#ifdef XTRACT_FFT -#include <fftw3.h> - -struct xtract_fft_plans_ { - - fftwf_plan spectrum_plan; - fftwf_plan autocorrelation_fft_plan_1; - fftwf_plan autocorrelation_fft_plan_2; - fftwf_plan dct_plan; - -}; +typedef struct xtract_ooura_data_ +{ + int *ooura_ip; + double *ooura_w; + bool initialised; +} xtract_ooura_data; #ifdef DEFINE_GLOBALS #define GLOBAL @@ -41,9 +36,10 @@ struct xtract_fft_plans_ { #define GLOBAL extern #endif -GLOBAL struct xtract_fft_plans_ fft_plans; - -#endif /* FFT */ +GLOBAL struct xtract_ooura_data_ ooura_data_dct; +GLOBAL struct xtract_ooura_data_ ooura_data_mfcc; +GLOBAL struct xtract_ooura_data_ ooura_data_spectrum; +GLOBAL struct xtract_ooura_data_ ooura_data_autocorrelation_fft; #endif /* Header guard */ diff --git a/swig/java/Makefile.am b/swig/java/Makefile.am index 26cc5b9..1e935ca 100644 --- a/swig/java/Makefile.am +++ b/swig/java/Makefile.am @@ -1,3 +1,4 @@ +MAINTAINERCLEANFILES = all-local $(javasources) Makefile.in javasources = \ SWIGTYPE_p_float.java \ @@ -61,8 +62,6 @@ javaclasses = \ xtract_vector_t.class \ xtract_window_types_.class -MAINTAINERCLEANFILES = $(javasources) Makefile.in - BUILT_SOURCES = $(srcdir)/xtract_wrap.c SWIG_SOURCES = jxtract.i diff --git a/swig/java/SWIG.java b/swig/java/SWIG.java deleted file mode 100644 index 0d6c47b..0000000 --- a/swig/java/SWIG.java +++ /dev/null @@ -1,16 +0,0 @@ -package xtract.core; - -public abstract class SWIG { - protected abstract long getPointer(); - - public boolean equals(Object obj) { - boolean equal = false; - if (obj instanceof SWIG) - equal = (((SWIG)obj).getPointer() == this.getPointer()); - return equal; - } - - public SWIGTYPE_p_void getVoidPointer() { - return new SWIGTYPE_p_void(getPointer(), false); - } -} diff --git a/xtract/xtract_helper.h b/xtract/xtract_helper.h index a77cf5b..52851c1 100644 --- a/xtract/xtract_helper.h +++ b/xtract/xtract_helper.h @@ -27,6 +27,8 @@ extern "C" { #endif +#include <stdbool.h> + /** * \defgroup helper helper functions * @@ -66,6 +68,9 @@ int xtract_features_from_subframes(const float *data, const int N, const int fea /** \brief Test whether a number is denormal */ int xtract_is_denormal(double const d); +/** \brief Test whether a number is a power of two */ +bool xtract_is_poweroftwo(unsigned int x); + /** @} */ #ifdef __cplusplus |