summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Fung <james34602@gmail.com>2018-11-21 00:28:12 +0800
committerJames Fung <james34602@gmail.com>2018-11-21 00:28:12 +0800
commit76c563acb4ca73695a8b365b0a51396b54101cfc (patch)
tree37bc6fea1e6afbfaf9e04ad4f6047b30b0d96818
parent2fdb6ad1e764120d53724088e84ab74d060dc9ad (diff)
Change FFT library to commercial friendly implementation
1. Fix memory leaks
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/Android.mk24
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.c556
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.h30
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.c450
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.h16
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.cpp40
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.h9
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/_kiss_fft_guts.h103
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fft.c402
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fft.h121
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fftr.c153
-rw-r--r--Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fftr.h54
-rw-r--r--DSPManager_Free/jni/main/Android.mk24
-rw-r--r--DSPManager_Free/jni/main/AutoConvolver.c422
-rw-r--r--DSPManager_Free/jni/main/AutoConvolver.h2
-rw-r--r--DSPManager_Free/jni/main/fftw3.h416
-rw-r--r--DSPManager_Free/jni/main/kissfft/_kiss_fft_guts.h103
-rw-r--r--DSPManager_Free/jni/main/kissfft/kiss_fft.c402
-rw-r--r--DSPManager_Free/jni/main/kissfft/kiss_fft.h121
-rw-r--r--DSPManager_Free/jni/main/kissfft/kiss_fftr.c153
-rw-r--r--DSPManager_Free/jni/main/kissfft/kiss_fftr.h54
-rw-r--r--DSPManager_Free/res/values-zh-rTW/arrays.xml20
-rw-r--r--DSPManager_Free/res/values-zh-rTW/strings.xml1
-rw-r--r--DSPManager_Free/res/values/arrays.xml34
-rw-r--r--DSPManager_Free/res/values/strings.xml1
-rw-r--r--DSPManager_Free/res/xml/bluetooth_preferences.xml7
-rw-r--r--DSPManager_Free/res/xml/headset_preferences.xml7
-rw-r--r--DSPManager_Free/res/xml/speaker_preferences.xml86
-rw-r--r--DSPManager_Free/src/james/dsp/service/HeadsetService.java5
-rw-r--r--DSPManager_Free_BitPerfect/jni/main/Android.mk24
-rw-r--r--DSPManager_Free_BitPerfect/jni/main/AutoConvolver.c709
-rw-r--r--DSPManager_Free_BitPerfect/jni/main/AutoConvolver.h13
-rw-r--r--DSPManager_Free_BitPerfect/jni/main/fftw3.h416
-rw-r--r--DSPManager_Free_BitPerfect/jni/main/kissfft/_kiss_fft_guts.h103
-rw-r--r--DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fft.c402
-rw-r--r--DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fft.h121
-rw-r--r--DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fftr.c153
-rw-r--r--DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fftr.h54
-rw-r--r--DSPManager_Free_BitPerfect/res/values-zh-rTW/strings.xml13
-rw-r--r--DSPManager_Free_BitPerfect/res/values/arrays.xml10
-rw-r--r--DSPManager_Free_BitPerfect/res/values/strings.xml15
-rw-r--r--DSPManager_Free_BitPerfect/res/xml/bluetooth_preferences.xml56
-rw-r--r--DSPManager_Free_BitPerfect/res/xml/headset_preferences.xml56
-rw-r--r--DSPManager_Free_BitPerfect/res/xml/speaker_preferences.xml97
-rw-r--r--DSPManager_Free_BitPerfect/src/james/dsp/service/HeadsetService.java43
-rw-r--r--Misc/fftw/DoubleARM/libfftw3.abin1297300 -> 0 bytes
-rw-r--r--Misc/fftw/DoubleARM/libfftw3_threads.abin32324 -> 0 bytes
-rw-r--r--Misc/fftw/DoubleARM64/libfftw3.abin2273554 -> 0 bytes
-rw-r--r--Misc/fftw/DoubleARM64/libfftw3_threads.abin42592 -> 0 bytes
-rw-r--r--Misc/fftw/Doublex86/libfftw3.abin5980532 -> 0 bytes
-rw-r--r--Misc/fftw/Doublex86/libfftw3_threads.abin40172 -> 0 bytes
-rw-r--r--Misc/fftw/FloatARM64NEON/libfftw3f.abin2352990 -> 0 bytes
-rw-r--r--Misc/fftw/FloatARM64NEON/libfftw3f_threads.abin42728 -> 0 bytes
-rw-r--r--Misc/fftw/FloatARMNEON/libfftw3fNeon.abin2003118 -> 0 bytes
-rw-r--r--Misc/fftw/FloatARMNEON/libfftw3f_threadsNeon.abin32428 -> 0 bytes
-rw-r--r--Misc/fftw/Floatx86/libfftw3f.abin6229268 -> 0 bytes
-rw-r--r--Misc/fftw/Floatx86/libfftw3f_threads.abin40320 -> 0 bytes
57 files changed, 3404 insertions, 2697 deletions
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/Android.mk b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/Android.mk
index aa71b1c..6cc0d94 100644
--- a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/Android.mk
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/Android.mk
@@ -1,28 +1,10 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE := fftw3
-ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
-LOCAL_SRC_FILES := fftw/DoubleARM/libfftw3.a
-else ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
-LOCAL_SRC_FILES := fftw/DoubleARM64/libfftw3.a
-else ifeq ($(TARGET_ARCH_ABI), x86)
-LOCAL_SRC_FILES := fftw/Doublex86/libfftw3.a
-endif
-include $(PREBUILT_STATIC_LIBRARY)
-include $(CLEAR_VARS)
-LOCAL_MODULE := fftw3thread
-ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
-LOCAL_SRC_FILES := fftw/DoubleARM/libfftw3_threads.a
-else ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
-LOCAL_SRC_FILES := fftw/DoubleARM64/libfftw3_threads.a
-else ifeq ($(TARGET_ARCH_ABI), x86)
-LOCAL_SRC_FILES := fftw/Doublex86/libfftw3_threads.a
-endif
-include $(PREBUILT_STATIC_LIBRARY)
-include $(CLEAR_VARS)
LOCAL_MODULE := libjamesdsp
LOCAL_PRELINK_MODULE := false
LOCAL_SRC_FILES := \
+ kissfft/kiss_fft.c \
+ kissfft/kiss_fftr.c \
jamesdsp.cpp \
Effect.cpp \
EffectDSPMain.cpp \
@@ -40,8 +22,6 @@ LOCAL_SRC_FILES := \
# valve/wavechild670/wdfcircuits.c \
# valve/wavechild670/wavechild670.c \
# terminator
-
-LOCAL_STATIC_LIBRARIES := fftw3thread fftw3
#LOCAL_LDLIBS := -llog
ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
LOCAL_CPPFLAGS += -Wall -Wextra -ffunction-sections -fdata-sections -Ofast -march=armv7-a -mfpu=neon -ftree-vectorize -DNDEBUG# -DDEBUG
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.c b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.c
index 0567f56..52d2007 100644
--- a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.c
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.c
@@ -2,46 +2,47 @@
#include <string.h>
#include <math.h>
#include <errno.h>
+#include "kissfft/kiss_fftr.h"
#include "ArbFIRGen.h"
#define PI 3.141592653589793
#define PI2 6.283185307179586
int get_double(char *val, double *F)
{
- char *eptr;
- errno = 0;
- double f = strtof(val, &eptr);
- if (eptr != val && errno != ERANGE)
- {
- *F = f;
- return 1;
- }
- return 0;
+ char *eptr;
+ errno = 0;
+ double f = strtof(val, &eptr);
+ if (eptr != val && errno != ERANGE)
+ {
+ *F = f;
+ return 1;
+ }
+ return 0;
}
int cmpfuncD(const void *a, const void *b)
{
- if (*(double*)a - *(double*)b < 0)
- return -1;
- if (*(double*)a - *(double*)b > 0)
- return 1;
- return 0;
+ if (*(double*)a - *(double*)b < 0)
+ return -1;
+ if (*(double*)a - *(double*)b > 0)
+ return 1;
+ return 0;
}
int lower_bound(EqNode **array, int size, double key)
{
- int first = 0, half, len, middle;
- len = size;
- while (len > 0)
- {
- half = len >> 1;
- middle = first + half;
- if (array[middle]->freq < key)
- {
- first = middle + 1;
- len = len - half - 1;
- }
- else
- len = half;
- }
- return first;
+ int first = 0, half, len, middle;
+ len = size;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first + half;
+ if (array[middle]->freq < key)
+ {
+ first = middle + 1;
+ len = len - half - 1;
+ }
+ else
+ len = half;
+ }
+ return first;
}
#define EPS 1E-16
double bessi0(double x)
@@ -146,7 +147,7 @@ double* fir2(int *nn, double *ff, double *aa, int ffsz)
lap = (int)(npt / 25);
if (fabs(ff[0]) > 0 || fabs(ff[ffsz - 1] - 1) > 1)
{
-// printf("The first frequency must be 0 and the last 1");
+ // printf("The first frequency must be 0 and the last 1");
return 0;
}
// Interpolate breakpoints onto large grid
@@ -155,7 +156,7 @@ double* fir2(int *nn, double *ff, double *aa, int ffsz)
diff(ff, df, ffsz);
if (isneg(df, ffsz - 1))
{
-// printf("Frequencies must be non-decreasing");
+ // printf("Frequencies must be non-decreasing");
return 0;
}
npt = npt + 1; // Length of [dc 1 2 ... nyquist] frequencies.
@@ -177,7 +178,7 @@ double* fir2(int *nn, double *ff, double *aa, int ffsz)
ne = (int)(ff[i + 1] * npt) - 1;
if (nb < 0 || ne > npt)
{
-// printf("Too abrupt an amplitude change near end of frequency interval");
+ // printf("Too abrupt an amplitude change near end of frequency interval");
return 0;
}
int j;
@@ -187,42 +188,42 @@ double* fir2(int *nn, double *ff, double *aa, int ffsz)
inc = 0;
else
inc = (double)(j - nb) / (double)(ne - nb);
- H[j] = inc*aa[i + 1] + (1.0 - inc)*aa[i];
+ H[j] = inc * aa[i + 1] + (1.0 - inc)*aa[i];
}
nb = ne + 1;
}
// Fourier time-shift.
double dt = 0.5 * (double)(*nn - 1);
- fftw_complex *Hz2 = (fftw_complex*)fftw_malloc(npt * sizeof(fftw_complex));
- fftw_complex *Hz = (fftw_complex*)fftw_malloc(npt2 * sizeof(fftw_complex));
+ kiss_fft_cpx *Hz2 = (kiss_fft_cpx*)malloc(npt * sizeof(kiss_fft_cpx));
+ kiss_fft_cpx *Hz = (kiss_fft_cpx*)malloc(npt2 * sizeof(kiss_fft_cpx));
for (i = 0; i < npt; i++)
{
double rad = -dt * PI * (double)i / ((double)(npt - 1));
double Hz1Real = H[i] * cos(rad);
double Hz1Imag = H[i] * sin(rad);
- Hz2[npt - 1 - i][1] = -1.0 * Hz1Imag;
- Hz2[npt - 1 - i][0] = Hz1Real;
- Hz[i][0] = Hz1Real;
- Hz[i][1] = Hz1Imag;
+ Hz2[npt - 1 - i].i = -1.0 * Hz1Imag;
+ Hz2[npt - 1 - i].r = Hz1Real;
+ Hz[i].r = Hz1Real;
+ Hz[i].i = Hz1Imag;
}
for (i = npt; i < npt2; i++)
{
- Hz[i][0] = Hz2[i - npt][0];
- Hz[i][1] = Hz2[i - npt][1];
+ Hz[i].r = Hz2[i - npt].r;
+ Hz[i].i = Hz2[i - npt].i;
}
int nfft = npt2 - 2;
- double *fo = (double*)fftw_malloc(sizeof(double) * npt2);
- fftw_plan plan = fftw_plan_dft_c2r_1d(nfft, Hz, fo, FFTW_ESTIMATE);
- fftw_execute(plan);
+ double *fo = (double*)malloc(sizeof(double) * npt2);
+ kiss_fftr_cfg plan = kiss_fftr_alloc(nfft, 1, 0, 0);
+ kiss_fftri(plan, Hz, fo);
inc = (double)(*nn - 1);
double kfft = 1. / nfft;
double *retArray = (double*)malloc(*nn * sizeof(double));
for (i = 0; i < *nn; i++)
retArray[i] = (double)(0.54 - (0.46*cos(PI2*(double)i / (double)inc))) * fo[i] * kfft;
- fftw_destroy_plan(plan);
- fftw_free(Hz);
- fftw_free(fo);
- fftw_free(Hz2);
+ free(plan);
+ free(Hz);
+ free(fo);
+ free(Hz2);
free(df);
free(H);
return retArray;
@@ -230,235 +231,236 @@ double* fir2(int *nn, double *ff, double *aa, int ffsz)
/////////////////////////////////////////////////////////////////////////////
// Log grid interpolated arbitrary response FIR filter design
/////////////////////////////////////////////////////////////////////////////
-void minimumPhaseSpectrum(fftw_complex* timeData, fftw_complex* freqData, fftw_plan planForward, fftw_plan planReverse, unsigned int filterLength)
+void minimumPhaseSpectrum(kiss_fft_cpx* timeData, kiss_fft_cpx* freqData, kiss_fft_cfg planForward, kiss_fft_cfg planReverse, unsigned int filterLength)
{
- unsigned int i, fLMul2 = filterLength << 1;
- double threshold = pow(10.0, -100.0 / 20.0);
- double logThreshold = log(threshold);
- for (i = 0; i < fLMul2; i++)
- {
- if (freqData[i][0] < threshold)
- freqData[i][0] = logThreshold;
- else
- freqData[i][0] = log(freqData[i][0]);
- freqData[i][1] = 0;
- }
- fftw_execute(planReverse);
- for (i = 0; i < fLMul2; i++)
- {
- timeData[i][0] /= fLMul2;
- timeData[i][1] /= fLMul2;
- }
- for (i = 1; i < filterLength; i++)
- {
- timeData[i][0] += timeData[fLMul2 - i][0];
- timeData[i][1] -= timeData[fLMul2 - i][1];
- timeData[fLMul2 - i][0] = 0;
- timeData[fLMul2 - i][1] = 0;
- }
- timeData[filterLength][1] *= -1.0;
- fftw_execute(planForward);
- for (i = 0; i < fLMul2; i++)
- {
- double eR = exp(freqData[i][0]);
- freqData[i][0] = eR * cos(freqData[i][1]);
- freqData[i][1] = eR * sin(freqData[i][1]);
- }
+ unsigned int i, fLMul2 = filterLength << 1;
+ double threshold = pow(10.0, -100.0 / 20.0);
+ double logThreshold = log(threshold);
+ for (i = 0; i < fLMul2; i++)
+ {
+ if (freqData[i].r < threshold)
+ freqData[i].r = logThreshold;
+ else
+ freqData[i].r = log(freqData[i].r);
+ freqData[i].i = 0;
+ }
+ kiss_fft(planReverse, freqData, timeData);
+ for (i = 0; i < fLMul2; i++)
+ {
+ timeData[i].r /= fLMul2;
+ timeData[i].i /= fLMul2;
+ }
+ for (i = 1; i < filterLength; i++)
+ {
+ timeData[i].r += timeData[fLMul2 - i].r;
+ timeData[i].i -= timeData[fLMul2 - i].i;
+ timeData[fLMul2 - i].r = 0;
+ timeData[fLMul2 - i].i = 0;
+ }
+ timeData[filterLength].i *= -1.0;
+ kiss_fft(planForward, timeData, freqData);
+ for (i = 0; i < fLMul2; i++)
+ {
+ double eR = exp(freqData[i].r);
+ freqData[i].r = eR * cos(freqData[i].i);
+ freqData[i].i = eR * sin(freqData[i].i);
+ }
}
double gainAtLogGrid(ArbitraryEq *gains, double freq)
{
- double dbGain = 0.0, logLeft, logRightMinusLeft;
- if (!gains->nodesCount)
- return dbGain;
- if (gains->nodesCount == 1)
- return gains->nodes[0]->gain;
- else
- {
- if (freq > gains->nodes[gains->nodesCount - 1]->freq)
- return gains->nodes[gains->nodesCount - 1]->gain;
- else
- {
- int pos = lower_bound(gains->nodes, gains->nodesCount, freq);
- if (pos < 1)
- return gains->nodes[0]->gain;
- double tmpfreq = gains->nodes[pos - 1]->freq;
- if (tmpfreq < 2.0)
- logLeft = tmpfreq;
- else
- logLeft = log(tmpfreq);
- tmpfreq = gains->nodes[pos]->freq;
- if (tmpfreq < 2.0)
- logRightMinusLeft = tmpfreq - logLeft;
- else
- logRightMinusLeft = log(tmpfreq) - logLeft;
- double t;
- if (freq < 2.0)
- t = (freq - logLeft) / logRightMinusLeft;
- else
- t = (log(freq) - logLeft) / logRightMinusLeft;
- if (gains->nodes[pos - 1]->gain == gains->nodes[pos]->gain)
- dbGain = gains->nodes[pos]->gain;
- else
- dbGain = gains->nodes[pos - 1]->gain + t * (gains->nodes[pos]->gain - gains->nodes[pos - 1]->gain);
- }
- }
- return dbGain;
+ double dbGain = 0.0, logLeft, logRightMinusLeft;
+ if (!gains->nodesCount)
+ return dbGain;
+ if (gains->nodesCount == 1)
+ return gains->nodes[0]->gain;
+ else
+ {
+ if (freq > gains->nodes[gains->nodesCount - 1]->freq)
+ return gains->nodes[gains->nodesCount - 1]->gain;
+ else
+ {
+ int pos = lower_bound(gains->nodes, gains->nodesCount, freq);
+ if (pos < 1)
+ return gains->nodes[0]->gain;
+ double tmpfreq = gains->nodes[pos - 1]->freq;
+ if (tmpfreq < 2.0)
+ logLeft = tmpfreq;
+ else
+ logLeft = log(tmpfreq);
+ tmpfreq = gains->nodes[pos]->freq;
+ if (tmpfreq < 2.0)
+ logRightMinusLeft = tmpfreq - logLeft;
+ else
+ logRightMinusLeft = log(tmpfreq) - logLeft;
+ double t;
+ if (freq < 2.0)
+ t = (freq - logLeft) / logRightMinusLeft;
+ else
+ t = (log(freq) - logLeft) / logRightMinusLeft;
+ if (gains->nodes[pos - 1]->gain == gains->nodes[pos]->gain)
+ dbGain = gains->nodes[pos]->gain;
+ else
+ dbGain = gains->nodes[pos - 1]->gain + t * (gains->nodes[pos]->gain - gains->nodes[pos - 1]->gain);
+ }
+ }
+ return dbGain;
}
double *ArbitraryEqMinimumPhase(ArbitraryEq *gains, double fs)
{
- unsigned int fLMul2 = gains->fLMul2;
- unsigned int flMul2Minus1 = fLMul2 - 1;
- fftw_complex* timeData = gains->timeData;
- fftw_complex* freqData = gains->freqData;
- fftw_plan planForward = gains->planForward;
- fftw_plan planReverse = gains->planReverse;
- // Log grid interpolation
- unsigned int i;
- for (i = 0; i < gains->filterLength; i++)
- {
- double freq = (double)i * fs / (double)fLMul2;
- double dbGain = gainAtLogGrid(gains, freq);
- double gain = pow(10.0, dbGain / 20.0);
- freqData[i][0] = gain;
- freqData[i][1] = 0;
- freqData[flMul2Minus1 - i][0] = gain;
- freqData[flMul2Minus1 - i][1] = 0;
- }
- minimumPhaseSpectrum(timeData, freqData, planForward, planReverse, gains->filterLength);
- fftw_execute(planReverse);
+ unsigned int fLMul2 = gains->fLMul2;
+ unsigned int flMul2Minus1 = fLMul2 - 1;
+ kiss_fft_cpx* timeData = gains->timeData;
+ kiss_fft_cpx* freqData = gains->freqData;
+ kiss_fft_cfg planForward = gains->planForward;
+ kiss_fft_cfg planReverse = gains->planReverse;
+ // Log grid interpolation
+ unsigned int i;
+ for (i = 0; i < gains->filterLength; i++)
+ {
+ double freq = (double)i * fs / (double)fLMul2;
+ double dbGain = gainAtLogGrid(gains, freq);
+ double gain = pow(10.0, dbGain / 20.0);
+ freqData[i].r = gain;
+ freqData[i].i = 0;
+ freqData[flMul2Minus1 - i].r = gain;
+ freqData[flMul2Minus1 - i].i = 0;
+ }
+ minimumPhaseSpectrum(timeData, freqData, planForward, planReverse, gains->filterLength);
+ kiss_fft(planReverse, freqData, timeData);
double factor, *finalImpulse = gains->impulseResponse;
- for (i = 0; i < gains->filterLength; i++)
- {
- factor = 0.5 * (1.0 + cos(PI2 * (double)i / (double)fLMul2));
- finalImpulse[i] = factor / (double)fLMul2 * timeData[i][0];
- }
- return finalImpulse;
+ for (i = 0; i < gains->filterLength; i++)
+ {
+ factor = 0.5 * (1.0 + cos(PI2 * (double)i / (double)fLMul2));
+ finalImpulse[i] = factor / (double)fLMul2 * timeData[i].r;
+ }
+ return finalImpulse;
}
double *ArbitraryEqLinearPhase(ArbitraryEq *gains, double fs)
{
- unsigned int fLMul2 = gains->fLMul2;
- unsigned int flMul2Minus1 = fLMul2 - 1;
- fftw_complex* timeData = gains->timeData;
- fftw_complex* freqData = gains->freqData;
- fftw_plan planReverse = gains->planReverse;
- // Log grid interpolation
- unsigned int i;
- for (i = 0; i < gains->filterLength; i++)
- {
- double freq = (double)i * fs / (double)fLMul2;
- double dbGain = gainAtLogGrid(gains, freq);
- double gain = pow(10.0, dbGain / 20.0);
- freqData[i][0] = gain;
- freqData[i][1] = 0;
- freqData[flMul2Minus1 - i][0] = gain;
- freqData[flMul2Minus1 - i][1] = 0;
- }
- fftw_execute(planReverse);
- double *finalImpulse = gains->impulseResponse;
- flMul2Minus1 = gains->filterLength - 1;
+ unsigned int fLMul2 = gains->fLMul2;
+ unsigned int flMul2Minus1 = fLMul2 - 1;
+ kiss_fft_cpx* timeData = gains->timeData;
+ kiss_fft_cpx* freqData = gains->freqData;
+ kiss_fft_cfg planReverse = gains->planReverse;
+ // Log grid interpolation
+ unsigned int i;
+ for (i = 0; i < gains->filterLength; i++)
+ {
+ double freq = (double)i * fs / (double)fLMul2;
+ double dbGain = gainAtLogGrid(gains, freq);
+ double gain = pow(10.0, dbGain / 20.0);
+ freqData[i].r = gain;
+ freqData[i].i = 0;
+ freqData[flMul2Minus1 - i].r = gain;
+ freqData[flMul2Minus1 - i].i = 0;
+ }
+ kiss_fft(planReverse, freqData, timeData);
+ double *finalImpulse = gains->impulseResponse;
+ flMul2Minus1 = gains->filterLength - 1;
for (i = 0; i < gains->filterLength; i++)
{
- double timeIntermediate = timeData[i][0] * 0.5 * ((1.0 + cos(PI2 * (double)i / (double)fLMul2)) / (double)fLMul2);
+ double timeIntermediate = timeData[i].r * 0.5 * ((1.0 + cos(PI2 * (double)i / (double)fLMul2)) / (double)fLMul2);
finalImpulse[flMul2Minus1 - i] = finalImpulse[flMul2Minus1 + i] = timeIntermediate;
}
- return finalImpulse;
+ return finalImpulse;
}
void InitArbitraryEq(ArbitraryEq* eqgain, int *filterLength, int isLinearPhase)
{
- eqgain->fLMul2 = *filterLength << 1;
- eqgain->timeData = fftw_alloc_complex(eqgain->fLMul2);
- eqgain->freqData = fftw_alloc_complex(eqgain->fLMul2);
- eqgain->filterLength = *filterLength;
- eqgain->isLinearPhase = isLinearPhase;
+ eqgain->fLMul2 = *filterLength << 1;
+ eqgain->timeData = (kiss_fft_cpx*)malloc(eqgain->fLMul2 * sizeof(kiss_fft_cpx));
+ eqgain->freqData = (kiss_fft_cpx*)malloc(eqgain->fLMul2 * sizeof(kiss_fft_cpx));
+ eqgain->filterLength = *filterLength;
+ eqgain->isLinearPhase = isLinearPhase;
eqgain->nodes = 0;
eqgain->nodesCount = 0;
- if (!isLinearPhase)
- {
- eqgain->planForward = fftw_plan_dft_1d(eqgain->fLMul2, eqgain->timeData, eqgain->freqData, FFTW_FORWARD, FFTW_ESTIMATE);
- eqgain->impulseResponse = (double*)malloc(*filterLength * sizeof(double));
- eqgain->GetFilter = &ArbitraryEqMinimumPhase;
- }
- else
- {
- eqgain->impulseResponse = (double*)malloc(eqgain->fLMul2 * sizeof(double));
- eqgain->GetFilter = &ArbitraryEqLinearPhase;
- *filterLength = eqgain->fLMul2;
- }
- eqgain->planReverse = fftw_plan_dft_1d(eqgain->fLMul2, eqgain->freqData, eqgain->timeData, FFTW_BACKWARD, FFTW_ESTIMATE);
+ if (!isLinearPhase)
+ {
+ eqgain->planForward = kiss_fft_alloc(eqgain->fLMul2, 0, 0, 0);
+ eqgain->impulseResponse = (double*)malloc(*filterLength * sizeof(double));
+ eqgain->GetFilter = &ArbitraryEqMinimumPhase;
+ }
+ else
+ {
+ eqgain->impulseResponse = (double*)malloc(eqgain->fLMul2 * sizeof(double));
+ eqgain->GetFilter = &ArbitraryEqLinearPhase;
+ *filterLength = eqgain->fLMul2 - 1;
+ }
+ eqgain->planReverse = kiss_fft_alloc(eqgain->fLMul2, 1, 0, 0);
}
void EqNodesFree(ArbitraryEq *eqgain)
{
- for (unsigned int i = 0; i < eqgain->nodesCount; i++)
- free(eqgain->nodes[i]);
- free(eqgain->nodes);
- eqgain->nodes = 0;
- eqgain->nodesCount = 0;
+ for (unsigned int i = 0; i < eqgain->nodesCount; i++)
+ free(eqgain->nodes[i]);
+ free(eqgain->nodes);
+ eqgain->nodes = 0;
+ eqgain->nodesCount = 0;
}
void ArbitraryEqFree(ArbitraryEq *eqgain)
{
- EqNodesFree(eqgain);
- if (!eqgain->isLinearPhase)
- fftw_destroy_plan(eqgain->planForward);
- fftw_free(eqgain->freqData);
- fftw_destroy_plan(eqgain->planReverse);
- free(eqgain->impulseResponse);
+ EqNodesFree(eqgain);
+ if (!eqgain->isLinearPhase)
+ free(eqgain->planForward);
+ free(eqgain->timeData);
+ free(eqgain->freqData);
+ free(eqgain->planReverse);
+ free(eqgain->impulseResponse);
}
void NodesSorter(ArbitraryEq *eqgain)
{
- unsigned int i, numOfNodes = eqgain->nodesCount;
- double *freqArray = (double*)malloc(numOfNodes * sizeof(double));
- for (i = 0; i < numOfNodes; i++)
- freqArray[i] = eqgain->nodes[i]->freq;
- qsort(freqArray, numOfNodes, sizeof(double), cmpfuncD);
- for (unsigned int j = 0; j < numOfNodes; j++)
- {
- for (i = 0; i < numOfNodes; i++)
- {
- if (freqArray[j] == eqgain->nodes[i]->freq)
- {
- double tmpFreq1 = eqgain->nodes[j]->freq;
- double tmpGain1 = eqgain->nodes[j]->gain;
- double tmpFreq2 = eqgain->nodes[i]->freq;
- double tmpGain2 = eqgain->nodes[i]->gain;
- eqgain->nodes[i]->freq = tmpFreq1;
- eqgain->nodes[i]->gain = tmpGain1;
- eqgain->nodes[j]->freq = tmpFreq2;
- eqgain->nodes[j]->gain = tmpGain2;
- }
- }
- }
- free(freqArray);
+ unsigned int i, numOfNodes = eqgain->nodesCount;
+ double *freqArray = (double*)malloc(numOfNodes * sizeof(double));
+ for (i = 0; i < numOfNodes; i++)
+ freqArray[i] = eqgain->nodes[i]->freq;
+ qsort(freqArray, numOfNodes, sizeof(double), cmpfuncD);
+ for (unsigned int j = 0; j < numOfNodes; j++)
+ {
+ for (i = 0; i < numOfNodes; i++)
+ {
+ if (freqArray[j] == eqgain->nodes[i]->freq)
+ {
+ double tmpFreq1 = eqgain->nodes[j]->freq;
+ double tmpGain1 = eqgain->nodes[j]->gain;
+ double tmpFreq2 = eqgain->nodes[i]->freq;
+ double tmpGain2 = eqgain->nodes[i]->gain;
+ eqgain->nodes[i]->freq = tmpFreq1;
+ eqgain->nodes[i]->gain = tmpGain1;
+ eqgain->nodes[j]->freq = tmpFreq2;
+ eqgain->nodes[j]->gain = tmpGain2;
+ }
+ }
+ }
+ free(freqArray);
}
int ArbitraryEqInsertNode(ArbitraryEq *eqgain, double freq, double gain, int sortNodes)
{
- if (!eqgain)
- return -1;
- if (!eqgain->nodesCount)
- {
- eqgain->nodes = (EqNode**)malloc((eqgain->nodesCount + 1) * sizeof(EqNode*));
- eqgain->nodes[0] = (EqNode*)malloc(sizeof(EqNode));
- eqgain->nodes[0]->freq = freq;
- eqgain->nodes[0]->gain = gain;
- eqgain->nodesCount = 1;
+ if (!eqgain)
+ return -1;
+ if (!eqgain->nodesCount)
+ {
+ eqgain->nodes = (EqNode**)malloc((eqgain->nodesCount + 1) * sizeof(EqNode*));
+ eqgain->nodes[0] = (EqNode*)malloc(sizeof(EqNode));
+ eqgain->nodes[0]->freq = freq;
+ eqgain->nodes[0]->gain = gain;
+ eqgain->nodesCount = 1;
return 1;
- }
- EqNode **tmpNode = (EqNode**)realloc(eqgain->nodes, (eqgain->nodesCount + 1) * sizeof(EqNode*));
- if (!tmpNode)
- {
- ArbitraryEqFree(eqgain);
- return -1;
- }
- else
- {
- tmpNode[eqgain->nodesCount] = (EqNode*)malloc(sizeof(EqNode));
- tmpNode[eqgain->nodesCount]->freq = freq;
- tmpNode[eqgain->nodesCount]->gain = gain;
- eqgain->nodes = tmpNode;
- eqgain->nodesCount++;
+ }
+ EqNode **tmpNode = (EqNode**)realloc(eqgain->nodes, (eqgain->nodesCount + 1) * sizeof(EqNode*));
+ if (!tmpNode)
+ {
+ ArbitraryEqFree(eqgain);
+ return -1;
+ }
+ else
+ {
+ tmpNode[eqgain->nodesCount] = (EqNode*)malloc(sizeof(EqNode));
+ tmpNode[eqgain->nodesCount]->freq = freq;
+ tmpNode[eqgain->nodesCount]->gain = gain;
+ eqgain->nodes = tmpNode;
+ eqgain->nodesCount++;
if (sortNodes)
NodesSorter(eqgain);
- }
- return 1;
+ }
+ return 1;
}
unsigned int ArbitraryEqFindNode(ArbitraryEq *eqgain, double freq)
{
@@ -473,41 +475,41 @@ unsigned int ArbitraryEqFindNode(ArbitraryEq *eqgain, double freq)
}
int ArbitraryEqRemoveNode(ArbitraryEq *eqgain, double freq, int sortNodes)
{
- if (!eqgain)
- return -1;
- if (!eqgain->nodes)
- return -2;
- unsigned int i, findResult = 0;
- for (i = 0; i < eqgain->nodesCount; i++)
- {
- if (eqgain->nodes[i]->freq == freq)
- {
- findResult = i;
- free(eqgain->nodes[i]);
- break;
- }
- }
- if (!findResult)
- return 0;
- else
- {
- for (i = findResult; i < eqgain->nodesCount; i++)
- eqgain->nodes[i] = eqgain->nodes[i + 1];
- EqNode **tmpNode = (EqNode**)realloc(eqgain->nodes, (eqgain->nodesCount - 1) * sizeof(EqNode*));
- if (!tmpNode)
- {
- ArbitraryEqFree(eqgain);
- return -1;
- }
- else
- {
- eqgain->nodes = tmpNode;
- eqgain->nodesCount--;
- if (sortNodes)
- NodesSorter(eqgain);
- }
- }
- return 1;
+ if (!eqgain)
+ return -1;
+ if (!eqgain->nodes)
+ return -2;
+ unsigned int i, findResult = 0;
+ for (i = 0; i < eqgain->nodesCount; i++)
+ {
+ if (eqgain->nodes[i]->freq == freq)
+ {
+ findResult = i;
+ free(eqgain->nodes[i]);
+ break;
+ }
+ }
+ if (!findResult)
+ return 0;
+ else
+ {
+ for (i = findResult; i < eqgain->nodesCount; i++)
+ eqgain->nodes[i] = eqgain->nodes[i + 1];
+ EqNode **tmpNode = (EqNode**)realloc(eqgain->nodes, (eqgain->nodesCount - 1) * sizeof(EqNode*));
+ if (!tmpNode)
+ {
+ ArbitraryEqFree(eqgain);
+ return -1;
+ }
+ else
+ {
+ eqgain->nodes = tmpNode;
+ eqgain->nodesCount--;
+ if (sortNodes)
+ NodesSorter(eqgain);
+ }
+ }
+ return 1;
}
void ArbitraryEqString2SortedNodes(ArbitraryEq *eqgain, char *frArbitraryEqString)
{
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.h b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.h
index afd8b54..c20e18a 100644
--- a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.h
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/ArbFIRGen.h
@@ -1,25 +1,25 @@
#ifndef ARBFIRGEN_H
#define ARBFIRGEN_H
-#include "fftw3.h"
+#include "kissfft/kiss_fft.h"
double* fir2(int *nn, double *ff, double *aa, int ffsz);
typedef struct str_EqNodes
{
- double freq;
- double gain;
+ double freq;
+ double gain;
} EqNode;
typedef struct str_ArbitraryEq
{
- EqNode **nodes;
- unsigned int nodesCount;
- unsigned int isLinearPhase;
- unsigned int filterLength;
- unsigned int fLMul2;
- fftw_complex* timeData;
- fftw_complex* freqData;
- fftw_plan planForward;
- fftw_plan planReverse;
- double *impulseResponse;
- double* (*GetFilter)(struct str_ArbitraryEq*, double);
+ EqNode **nodes;
+ unsigned int nodesCount;
+ unsigned int isLinearPhase;
+ unsigned int filterLength;
+ unsigned int fLMul2;
+ kiss_fft_cpx* timeData;
+ kiss_fft_cpx* freqData;
+ kiss_fft_cfg planForward;
+ kiss_fft_cfg planReverse;
+ double *impulseResponse;
+ double* (*GetFilter)(struct str_ArbitraryEq*, double);
} ArbitraryEq;
void InitArbitraryEq(ArbitraryEq* eqgain, int *filterLength, int isLinearPhase);
void ArbitraryEqFree(ArbitraryEq *eqgain);
@@ -27,4 +27,4 @@ int ArbitraryEqInsertNode(ArbitraryEq *eqgain, double freq, double gain, int sor
unsigned int ArbitraryEqFindNode(ArbitraryEq *eqgain, double freq);
int ArbitraryEqRemoveNode(ArbitraryEq *eqgain, double freq, int sortNodes);
void ArbitraryEqString2SortedNodes(ArbitraryEq *eqgain, char *frArbitraryEqString);
-#endif
+#endif \ No newline at end of file
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.c b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.c
index 60e3d2c..db1caf2 100644
--- a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.c
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.c
@@ -2,7 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
-#include "fftw3.h"
+#include "kissfft/kiss_fftr.h"
#include "AutoConvolver.h"
typedef struct str_dffirfilter
{
@@ -17,21 +17,22 @@ typedef struct str_HConv1Stage
int framelength; // number of samples per audio frame
int *steptask; // processing tasks per step
double *dft_time; // DFT buffer (time domain)
- fftw_complex *dft_freq; // DFT buffer (frequency domain)
+ kiss_fft_cpx *dft_freq; // DFT buffer (frequency domain)
double *in_freq_real; // input buffer (frequency domain)
double *in_freq_imag; // input buffer (frequency domain)
int num_filterbuf; // number of filter segments
- double **filterbuf_freq_real; // filter segments (frequency domain)
- double **filterbuf_freq_imag; // filter segments (frequency domain)
+ double **filterbuf_freq_realChannel1; // filter segments (frequency domain)
+ double **filterbuf_freq_imagChannel1; // filter segments (frequency domain)
int num_mixbuf; // number of mixing segments
double **mixbuf_freq_real; // mixing segments (frequency domain)
double **mixbuf_freq_imag; // mixing segments (frequency domain)
double *history_time; // history buffer (time domain)
double normalizationGain;
double gain;
- fftw_plan fft; // FFT transformation plan
- fftw_plan ifft; // IFFT transformation plan
-} HConv1Stage;
+ kiss_fftr_cfg fft; // FFT transformation plan
+ kiss_fftr_cfg ifft; // IFFT transformation plan
+ int memSize;
+} HConv1Stage1x1;
typedef struct str_HConv2Stage
{
int step; // processing step counter
@@ -40,9 +41,9 @@ typedef struct str_HConv2Stage
int flen_short; // number of samples per short audio frame
double *in_long; // input buffer (long frame)
double *out_long; // output buffer (long frame)
- HConv1Stage *f_long; // convolution filter (long segments)
- HConv1Stage *f_short; // convolution filter (short segments)
-} HConv2Stage;
+ HConv1Stage1x1 *f_long; // convolution filter (long segments)
+ HConv1Stage1x1 *f_short; // convolution filter (short segments)
+} HConv2Stage1x1;
typedef struct str_HConv3Stage
{
int step; // processing step counter
@@ -51,36 +52,13 @@ typedef struct str_HConv3Stage
int flen_short; // number of samples per short audio frame
double *in_medium; // input buffer (long frame)
double *out_medium; // output buffer (long frame)
- HConv2Stage *f_medium; // convolution filter (long segments)
- HConv1Stage *f_short; // convolution filter (short segments)
-} HConv3Stage;
-typedef struct str_HConv4Stage
-{
- int step; // processing step counter
- int maxstep; // number of processing steps per long audio frame
- int flen_medium; // number of samples per long audio frame
- int flen_short; // number of samples per short audio frame
- double *in_medium; // input buffer (long frame)
- double *out_medium; // output buffer (long frame)
- HConv3Stage *f_medium; // convolution filter (long segments)
- HConv1Stage *f_short; // convolution filter (short segments)
-} HConv4Stage;
-int ACFFTWThreadInit()
-{
- return fftw_init_threads();
-}
-void ACFFTWClean(int threads)
-{
- if (threads)
- fftw_cleanup_threads();
- else
- fftw_cleanup();
-}
+ HConv2Stage1x1 *f_medium; // convolution filter (long segments)
+ HConv1Stage1x1 *f_short; // convolution filter (short segments)
+} HConv3Stage1x1;
void DFFIRInit(DFFIR *fir, double *h, int hlen)
{
int i, size;
fir->pos = 0;
- fir->gain = 1.0;
fir->coeffslength = hlen;
size = hlen * sizeof(double);
fir->coeffs = (double*)malloc(size);
@@ -101,7 +79,7 @@ double DFFIRProcess(DFFIR *fir, double x)
double *coeff_end = fir->coeffs + fir->coeffslength;
double *buf_val = fir->delayLine + fir->pos;
*buf_val = x;
- double y = 0.0;
+ double y = 0.0f;
while (buf_val >= fir->delayLine)
y += *buf_val-- * *coeff++ * fir->gain;
buf_val = fir->delayLine + fir->coeffslength - 1;
@@ -111,21 +89,21 @@ double DFFIRProcess(DFFIR *fir, double x)
fir->pos = 0;
return y;
}
-inline void hcPut1Stage(HConv1Stage *filter, double *x)
+inline void hcPut1Stage(HConv1Stage1x1 *filter, double *x)
{
int j, flen, size;
flen = filter->framelength;
- size = sizeof(double) * flen;
+ size = filter->memSize;
memcpy(filter->dft_time, x, size);
memset(&(filter->dft_time[flen]), 0, size);
- fftw_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->in_freq_real[j] = filter->dft_freq[j][0];
- filter->in_freq_imag[j] = filter->dft_freq[j][1];
+ filter->in_freq_real[j] = filter->dft_freq[j].r;
+ filter->in_freq_imag[j] = filter->dft_freq[j].i;
}
}
-void hcProcess1Stage(HConv1Stage *filter)
+void hcProcess1Stage(HConv1Stage1x1 *filter)
{
int s, n, start, stop, flen;
double *x_real;
@@ -144,17 +122,17 @@ void hcProcess1Stage(HConv1Stage *filter)
n = (s + filter->mixpos) % filter->num_mixbuf;
y_real = filter->mixbuf_freq_real[n];
y_imag = filter->mixbuf_freq_imag[n];
- h_real = filter->filterbuf_freq_real[s];
- h_imag = filter->filterbuf_freq_imag[s];
+ h_real = filter->filterbuf_freq_realChannel1[s];
+ h_imag = filter->filterbuf_freq_imagChannel1[s];
for (n = 0; n < flen + 1; n++)
{
- y_real[n] += (x_real[n] * h_real[n] - x_imag[n] * h_imag[n]) * filter->gain;
- y_imag[n] += (x_real[n] * h_imag[n] + x_imag[n] * h_real[n]) * filter->gain;
+ y_real[n] += (x_real[n] * h_real[n] - x_imag[n] * h_imag[n]);
+ y_imag[n] += (x_real[n] * h_imag[n] + x_imag[n] * h_real[n]);
}
}
filter->step = (filter->step + 1) % filter->maxstep;
}
-inline void hcGet1Stage(HConv1Stage *filter, double *y)
+inline void hcGet1Stage(HConv1Stage1x1 *filter, double *y)
{
int flen, mpos;
double *out;
@@ -166,21 +144,19 @@ inline void hcGet1Stage(HConv1Stage *filter, double *y)
hist = filter->history_time;
for (j = 0; j < flen + 1; j++)
{
- filter->dft_freq[j][0] = filter->mixbuf_freq_real[mpos][j];
- filter->dft_freq[j][1] = filter->mixbuf_freq_imag[mpos][j];
- filter->mixbuf_freq_real[mpos][j] = 0.0;
- filter->mixbuf_freq_imag[mpos][j] = 0.0;
+ filter->dft_freq[j].r = filter->mixbuf_freq_real[mpos][j];
+ filter->dft_freq[j].i = filter->mixbuf_freq_imag[mpos][j];
+ filter->mixbuf_freq_real[mpos][j] = 0.0f;
+ filter->mixbuf_freq_imag[mpos][j] = 0.0f;
}
- fftw_execute(filter->ifft);
+ kiss_fftri(filter->ifft, filter->dft_freq, filter->dft_time);
for (n = 0; n < flen; n++)
- {
- y[n] = out[n] + hist[n];
- }
- size = sizeof(double) * flen;
+ y[n] = (out[n] + hist[n]) * filter->gain;
+ size = filter->memSize;
memcpy(hist, &(out[flen]), size);
filter->mixpos = (filter->mixpos + 1) % filter->num_mixbuf;
}
-void hcInit1Stage(HConv1Stage *filter, double *h, int hlen, int flen, int steps, int fftwThreads)
+void hcInit1Stage(HConv1Stage1x1 *filter, double *h, int hlen, int flen, int steps)
{
int i, j, size, num, pos;
// processing step counter
@@ -193,14 +169,14 @@ void hcInit1Stage(HConv1Stage *filter, double *h, int hlen, int flen, int steps,
filter->framelength = flen;
// DFT buffer (time domain)
size = sizeof(double) * 2 * flen;
- filter->dft_time = (double *)fftw_malloc(size);
+ filter->dft_time = (double *)malloc(size);
// DFT buffer (frequency domain)
- size = sizeof(fftw_complex) * (flen + 1);
- filter->dft_freq = (fftw_complex*)fftw_malloc(size);
+ size = sizeof(kiss_fft_cpx) * (flen + 1);
+ filter->dft_freq = (kiss_fft_cpx*)malloc(size);
// input buffer (frequency domain)
size = sizeof(double) * (flen + 1);
- filter->in_freq_real = (double*)fftw_malloc(size);
- filter->in_freq_imag = (double*)fftw_malloc(size);
+ filter->in_freq_real = (double*)malloc(size);
+ filter->in_freq_imag = (double*)malloc(size);
// number of filter segments
filter->num_filterbuf = (hlen + flen - 1) / flen;
// processing tasks per step
@@ -221,38 +197,36 @@ void hcInit1Stage(HConv1Stage *filter, double *h, int hlen, int flen, int steps,
}
// filter segments (frequency domain)
size = sizeof(double*) * filter->num_filterbuf;
- filter->filterbuf_freq_real = (double**)fftw_malloc(size);
- filter->filterbuf_freq_imag = (double**)fftw_malloc(size);
+ filter->filterbuf_freq_realChannel1 = (double**)malloc(size);
+ filter->filterbuf_freq_imagChannel1 = (double**)malloc(size);
+ size = sizeof(double) * (flen + 1);
for (i = 0; i < filter->num_filterbuf; i++)
{
- size = sizeof(double) * (flen + 1);
- filter->filterbuf_freq_real[i] = (double*)fftw_malloc(size);
- filter->filterbuf_freq_imag[i] = (double*)fftw_malloc(size);
+ filter->filterbuf_freq_realChannel1[i] = (double*)malloc(size);
+ filter->filterbuf_freq_imagChannel1[i] = (double*)malloc(size);
}
// number of mixing segments
filter->num_mixbuf = filter->num_filterbuf + 1;
// mixing segments (frequency domain)
size = sizeof(double*) * filter->num_mixbuf;
- filter->mixbuf_freq_real = (double**)fftw_malloc(size);
- filter->mixbuf_freq_imag = (double**)fftw_malloc(size);
+ filter->mixbuf_freq_real = (double**)malloc(size);
+ filter->mixbuf_freq_imag = (double**)malloc(size);
for (i = 0; i < filter->num_mixbuf; i++)
{
size = sizeof(double) * (flen + 1);
- filter->mixbuf_freq_real[i] = (double*)fftw_malloc(size);
- filter->mixbuf_freq_imag[i] = (double*)fftw_malloc(size);
+ filter->mixbuf_freq_real[i] = (double*)malloc(size);
+ filter->mixbuf_freq_imag[i] = (double*)malloc(size);
memset(filter->mixbuf_freq_real[i], 0, size);
memset(filter->mixbuf_freq_imag[i], 0, size);
}
// history buffer (time domain)
size = sizeof(double) * flen;
- filter->history_time = (double *)fftw_malloc(size);
+ filter->history_time = (double *)malloc(size);
memset(filter->history_time, 0, size);
- if (fftwThreads)
- fftw_plan_with_nthreads(fftwThreads);
// FFT transformation plan
- filter->fft = fftw_plan_dft_r2c_1d(2 * flen, filter->dft_time, filter->dft_freq, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT);
+ filter->fft = kiss_fftr_alloc(2 * flen, 0, 0, 0);
// IFFT transformation plan
- filter->ifft = fftw_plan_dft_c2r_1d(2 * flen, filter->dft_freq, filter->dft_time, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT);
+ filter->ifft = kiss_fftr_alloc(2 * flen, 1, 0, 0);
// generate filter segments
filter->normalizationGain = 0.5 / (double)flen;
filter->gain = filter->normalizationGain;
@@ -262,25 +236,26 @@ void hcInit1Stage(HConv1Stage *filter, double *h, int hlen, int flen, int steps,
{
for (j = 0; j < flen; j++)
filter->dft_time[j] = h[i * flen + j];
- fftw_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
+ filter->filterbuf_freq_realChannel1[i][j] = filter->dft_freq[j].r;
+ filter->filterbuf_freq_imagChannel1[i][j] = filter->dft_freq[j].i;
}
}
for (j = 0; j < hlen - i * flen; j++)
filter->dft_time[j] = h[i * flen + j];
size = sizeof(double) * ((i + 1) * flen - hlen);
memset(&(filter->dft_time[hlen - i * flen]), 0, size);
- fftw_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
+ filter->filterbuf_freq_realChannel1[i][j] = filter->dft_freq[j].r;
+ filter->filterbuf_freq_imagChannel1[i][j] = filter->dft_freq[j].i;
}
+ filter->memSize = sizeof(double) * flen;
}
-void hcProcess2Stage(HConv2Stage *filter, double *in, double *out)
+void hcProcess2Stage(HConv2Stage1x1 *filter, double *in, double *out)
{
int lpos, size, i;
// convolution with short segments
@@ -304,7 +279,7 @@ void hcProcess2Stage(HConv2Stage *filter, double *in, double *out)
// increase step counter
filter->step = (filter->step + 1) % filter->maxstep;
}
-void hcInit2Stage(HConv2Stage *filter, double *h, int hlen, int sflen, int lflen, int fftwThreads)
+void hcInit2Stage(HConv2Stage1x1 *filter, double *h, int hlen, int sflen, int lflen)
{
int size;
double *h2 = NULL;
@@ -314,7 +289,7 @@ void hcInit2Stage(HConv2Stage *filter, double *h, int hlen, int sflen, int lflen
if (hlen < h2len)
{
size = sizeof(double) * h2len;
- h2 = (double*)fftw_malloc(size);
+ h2 = (double*)malloc(size);
memset(h2, 0, size);
size = sizeof(double) * hlen;
memcpy(h2, h, size);
@@ -331,24 +306,24 @@ void hcInit2Stage(HConv2Stage *filter, double *h, int hlen, int sflen, int lflen
filter->flen_short = sflen;
// input buffer (long frame)
size = sizeof(double) * lflen;
- filter->in_long = (double *)fftw_malloc(size);
+ filter->in_long = (double *)malloc(size);
memset(filter->in_long, 0, size);
// output buffer (long frame)
size = sizeof(double) * lflen;
- filter->out_long = (double *)fftw_malloc(size);
+ filter->out_long = (double *)malloc(size);
memset(filter->out_long, 0, size);
// convolution filter (short segments)
- size = sizeof(HConv1Stage);
- filter->f_short = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_short, h, 2 * lflen, sflen, 1, fftwThreads);
+ size = sizeof(HConv1Stage1x1);
+ filter->f_short = (HConv1Stage1x1 *)malloc(size);
+ hcInit1Stage(filter->f_short, h, 2 * lflen, sflen, 1);
// convolution filter (long segments)
- size = sizeof(HConv1Stage);
- filter->f_long = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_long, &(h[2 * lflen]), hlen - 2 * lflen, lflen, lflen / sflen, fftwThreads);
+ size = sizeof(HConv1Stage1x1);
+ filter->f_long = (HConv1Stage1x1 *)malloc(size);
+ hcInit1Stage(filter->f_long, &(h[2 * lflen]), hlen - 2 * lflen, lflen, lflen / sflen);
if (h2 != NULL)
- fftw_free(h2);
+ free(h2);
}
-void hcProcess3Stage(HConv3Stage *filter, double *in, double *out)
+void hcProcess3Stage(HConv3Stage1x1 *filter, double *in, double *out)
{
int lpos, size, i;
// convolution with short segments
@@ -369,7 +344,7 @@ void hcProcess3Stage(HConv3Stage *filter, double *in, double *out)
// increase step counter
filter->step = (filter->step + 1) % filter->maxstep;
}
-void hcInit3Stage(HConv3Stage *filter, double *h, int hlen, int sflen, int mflen, int lflen, int fftwThreads)
+void hcInit3Stage(HConv3Stage1x1 *filter, double *h, int hlen, int sflen, int mflen, int lflen)
{
int size;
double *h2 = NULL;
@@ -379,7 +354,7 @@ void hcInit3Stage(HConv3Stage *filter, double *h, int hlen, int sflen, int mflen
if (hlen < h2len)
{
size = sizeof(double) * h2len;
- h2 = (double*)fftw_malloc(size);
+ h2 = (double*)malloc(size);
memset(h2, 0, size);
size = sizeof(double) * hlen;
memcpy(h2, h, size);
@@ -396,94 +371,29 @@ void hcInit3Stage(HConv3Stage *filter, double *h, int hlen, int sflen, int mflen
filter->flen_short = sflen;
// input buffer (medium frame)
size = sizeof(double) * mflen;
- filter->in_medium = (double *)fftw_malloc(size);
+ filter->in_medium = (double *)malloc(size);
memset(filter->in_medium, 0, size);
// output buffer (medium frame)
size = sizeof(double) * mflen;
- filter->out_medium = (double *)fftw_malloc(size);
- memset(filter->out_medium, 0, size);
- // convolution filter (short segments)
- size = sizeof(HConv1Stage);
- filter->f_short = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_short, h, mflen, sflen, 1, fftwThreads);
- // convolution filter (medium segments)
- size = sizeof(HConv2Stage);
- filter->f_medium = (HConv2Stage *)malloc(size);
- hcInit2Stage(filter->f_medium, &(h[mflen]), hlen - mflen, mflen, lflen, fftwThreads);
- if (h2 != NULL)
- fftw_free(h2);
-}
-void hcProcess4Stage(HConv4Stage *filter, double *in, double *out)
-{
- int lpos, size, i;
- // convolution with short segments
- hcPut1Stage(filter->f_short, in);
- hcProcess1Stage(filter->f_short);
- hcGet1Stage(filter->f_short, out);
- // add contribution from last medium frame
- lpos = filter->step * filter->flen_short;
- for (i = 0; i < filter->flen_short; i++)
- out[i] += filter->out_medium[lpos + i];
- // add current frame to medium input buffer
- lpos = filter->step * filter->flen_short;
- size = sizeof(double) * filter->flen_short;
- memcpy(&(filter->in_medium[lpos]), in, size);
- // convolution with medium segments
- if (filter->step == filter->maxstep - 1)
- hcProcess3Stage(filter->f_medium, filter->in_medium, filter->out_medium);
- // increase step counter
- filter->step = (filter->step + 1) % filter->maxstep;
-}
-void hcInit4Stage(HConv4Stage *filter, double *h, int hlen, int ssflen, int sflen, int mflen, int lflen, int fftwThreads)
-{
- int size;
- double *h2 = NULL;
- int h2len;
- // sanity check: minimum impulse response length
- h2len = sflen + mflen + 2 * lflen + 1;
- if (hlen < h2len)
- {
- size = sizeof(double) * h2len;
- h2 = (double*)fftw_malloc(size);
- memset(h2, 0, size);
- size = sizeof(double) * hlen;
- memcpy(h2, h, size);
- h = h2;
- hlen = h2len;
- }
- // processing step counter
- filter->step = 0;
- // number of processing steps per medium audio frame
- filter->maxstep = sflen / ssflen;
- // number of samples per medium audio frame
- filter->flen_medium = sflen;
- // number of samples per short audio frame
- filter->flen_short = ssflen;
- // input buffer (medium frame)
- size = sizeof(double) * sflen;
- filter->in_medium = (double *)fftw_malloc(size);
- memset(filter->in_medium, 0, size);
- // output buffer (medium frame)
- size = sizeof(double) * sflen;
- filter->out_medium = (double *)fftw_malloc(size);
+ filter->out_medium = (double *)malloc(size);
memset(filter->out_medium, 0, size);
// convolution filter (short segments)
- size = sizeof(HConv1Stage);
- filter->f_short = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_short, h, sflen, ssflen, 1, fftwThreads);
+ size = sizeof(HConv1Stage1x1);
+ filter->f_short = (HConv1Stage1x1 *)malloc(size);
+ hcInit1Stage(filter->f_short, h, mflen, sflen, 1);
// convolution filter (medium segments)
- size = sizeof(HConv3Stage);
- filter->f_medium = (HConv3Stage *)malloc(size);
- hcInit3Stage(filter->f_medium, &(h[sflen]), hlen - sflen, sflen, mflen, lflen, fftwThreads);
+ size = sizeof(HConv2Stage1x1);
+ filter->f_medium = (HConv2Stage1x1 *)malloc(size);
+ hcInit2Stage(filter->f_medium, &(h[mflen]), hlen - mflen, mflen, lflen);
if (h2 != NULL)
- fftw_free(h2);
+ free(h2);
}
-void Convolver4StageProcessArbitrarySignalLengthMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int sigLen)
+void Convolver2StageProcessArbitrarySignalLength1x1(AutoConvolver1x1 *autoConv, double* inputs, double* outputs, int sigLen)
{
int m_lenShort = autoConv->hnShortLen;
double *m_inbuf = autoConv->inbuf;
double *m_outbuf = autoConv->outbuf;
- HConv4Stage *m_filter = (HConv4Stage*)autoConv->filter;
+ HConv2Stage1x1 *m_filter = (HConv2Stage1x1*)autoConv->filter;
int pos = autoConv->bufpos;
for (int s = 0; s < sigLen; s++)
{
@@ -492,18 +402,18 @@ void Convolver4StageProcessArbitrarySignalLengthMono(AutoConvolverMono *autoConv
pos++;
if (pos == m_lenShort)
{
- hcProcess4Stage(m_filter, m_inbuf, m_outbuf);
+ hcProcess2Stage(m_filter, m_inbuf, m_outbuf);
pos = 0;
}
}
autoConv->bufpos = pos;
}
-void Convolver3StageProcessArbitrarySignalLengthMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int sigLen)
+void Convolver3StageProcessArbitrarySignalLength1x1(AutoConvolver1x1 *autoConv, double* inputs, double* outputs, int sigLen)
{
int m_lenShort = autoConv->hnShortLen;
double *m_inbuf = autoConv->inbuf;
double *m_outbuf = autoConv->outbuf;
- HConv3Stage *m_filter = (HConv3Stage*)autoConv->filter;
+ HConv3Stage1x1 *m_filter = (HConv3Stage1x1*)autoConv->filter;
int pos = autoConv->bufpos;
for (int s = 0; s < sigLen; s++)
{
@@ -518,34 +428,14 @@ void Convolver3StageProcessArbitrarySignalLengthMono(AutoConvolverMono *autoConv
}
autoConv->bufpos = pos;
}
-void Convolver2StageProcessArbitrarySignalLengthMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int sigLen)
-{
- int m_lenShort = autoConv->hnShortLen;
- double *m_inbuf = autoConv->inbuf;
- double *m_outbuf = autoConv->outbuf;
- HConv2Stage *m_filter = (HConv2Stage*)autoConv->filter;
- int pos = autoConv->bufpos;
- for (int s = 0; s < sigLen; s++)
- {
- m_inbuf[pos] = inputs[s];
- outputs[s] = m_outbuf[pos];
- pos++;
- if (pos == m_lenShort)
- {
- hcProcess2Stage(m_filter, m_inbuf, m_outbuf);
- pos = 0;
- }
- }
- autoConv->bufpos = pos;
-}
-void Convolver1StageLowLatencyProcessMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int unused)
+void Convolver1StageLowLatencyProcess1x1(AutoConvolver1x1 *autoConv, double* inputs, double* outputs, int unused)
{
- HConv1Stage *m_filter = (HConv1Stage*)autoConv->filter;
+ HConv1Stage1x1 *m_filter = (HConv1Stage1x1*)autoConv->filter;
hcPut1Stage(m_filter, inputs);
hcProcess1Stage(m_filter);
hcGet1Stage(m_filter, outputs);
}
-void Convolver1DirectFormProcessMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int sigLen)
+void Convolver1DirectFormProcess1x1(AutoConvolver1x1 *autoConv, double* inputs, double* outputs, int sigLen)
{
DFFIR *m_filter = (DFFIR*)autoConv->filter;
for (int i = 0; i < sigLen; i++)
@@ -635,10 +525,9 @@ int PartitionerAnalyser(int hlen, int latency, int strategy, int fs, int entries
}
return type_best;
}
-AutoConvolverMono* InitAutoConvolverMono(double *impulseResponse, int hlen, int audioBufferSize, double gaindB, double **recommendation, int items, int fftwThreads)
+AutoConvolver1x1* InitAutoConvolver1x1(double *impulseResponse, int hlen, int audioBufferSize, double gaindB, double **recommendation, int items)
{
- int bestMethod = 1, sflen_best = 4096, mflen_best = 8192, lflen_best = 16384, llflen_best = 32768;
- hlen = abs(hlen);
+ int bestMethod = 1, sflen_best = 4096, mflen_best = 8192, lflen_best = 16384;
if (!hlen)
return 0;
if (recommendation)
@@ -665,10 +554,8 @@ AutoConvolverMono* InitAutoConvolverMono(double *impulseResponse, int hlen, int
}
else if (hlen > 1000000 && hlen < 2000001 && bestMethod < 2)
bestMethod = 3;
- else if (hlen > 2000000 && bestMethod < 2)
- bestMethod = 4;
- double linGain = pow(10.0, gaindB / 20.0);
- AutoConvolverMono *autoConv = (AutoConvolverMono*)calloc(1, sizeof(AutoConvolverMono));
+ double linGain = powf(10.0f, gaindB / 20.0f);
+ AutoConvolver1x1 *autoConv = (AutoConvolver1x1*)calloc(1, sizeof(AutoConvolver1x1));
autoConv->methods = bestMethod;
if (bestMethod > 1)
{
@@ -678,33 +565,22 @@ AutoConvolverMono* InitAutoConvolverMono(double *impulseResponse, int hlen, int
}
if (bestMethod == 3)
{
- HConv3Stage* stage = (HConv3Stage*)malloc(sizeof(HConv3Stage));
- hcInit3Stage(stage, impulseResponse, hlen, sflen_best, mflen_best, lflen_best, fftwThreads);
+ HConv3Stage1x1* stage = (HConv3Stage1x1*)malloc(sizeof(HConv3Stage1x1));
+ hcInit3Stage(stage, impulseResponse, hlen, sflen_best, mflen_best, lflen_best);
stage->f_medium->f_long->gain = stage->f_medium->f_long->normalizationGain * linGain;
stage->f_medium->f_short->gain = stage->f_medium->f_short->normalizationGain * linGain;
stage->f_short->gain = stage->f_short->normalizationGain * linGain;
autoConv->filter = (void*)stage;
- autoConv->process = &Convolver3StageProcessArbitrarySignalLengthMono;
+ autoConv->process = &Convolver3StageProcessArbitrarySignalLength1x1;
}
else if (bestMethod == 2)
{
- HConv2Stage* stage = (HConv2Stage*)malloc(sizeof(HConv2Stage));
- hcInit2Stage(stage, impulseResponse, hlen, sflen_best, mflen_best, fftwThreads);
+ HConv2Stage1x1* stage = (HConv2Stage1x1*)malloc(sizeof(HConv2Stage1x1));
+ hcInit2Stage(stage, impulseResponse, hlen, sflen_best, mflen_best);
stage->f_long->gain = stage->f_long->normalizationGain * linGain;
stage->f_short->gain = stage->f_short->normalizationGain * linGain;
autoConv->filter = (void*)stage;
- autoConv->process = &Convolver2StageProcessArbitrarySignalLengthMono;
- }
- else if (bestMethod == 4)
- {
- HConv4Stage* stage = (HConv4Stage*)malloc(sizeof(HConv4Stage));
- hcInit4Stage(stage, impulseResponse, hlen, sflen_best, mflen_best, lflen_best, llflen_best, fftwThreads);
- stage->f_medium->f_medium->f_long->gain = stage->f_medium->f_medium->f_long->normalizationGain * linGain;
- stage->f_medium->f_medium->f_short->gain = stage->f_medium->f_medium->f_short->normalizationGain * linGain;
- stage->f_medium->f_short->gain = stage->f_medium->f_short->normalizationGain * linGain;
- stage->f_short->gain = stage->f_short->normalizationGain * linGain;
- autoConv->filter = (void*)stage;
- autoConv->process = &Convolver4StageProcessArbitrarySignalLengthMono;
+ autoConv->process = &Convolver2StageProcessArbitrarySignalLength1x1;
}
else if (bestMethod == 999)
{
@@ -712,29 +588,29 @@ AutoConvolverMono* InitAutoConvolverMono(double *impulseResponse, int hlen, int
DFFIRInit(stage, impulseResponse, hlen);
stage->gain = linGain;
autoConv->filter = (void*)stage;
- autoConv->process = &Convolver1DirectFormProcessMono;
+ autoConv->process = &Convolver1DirectFormProcess1x1;
}
else
{
- HConv1Stage* stage = (HConv1Stage*)malloc(sizeof(HConv1Stage));
- hcInit1Stage(stage, impulseResponse, hlen, audioBufferSize, 1, fftwThreads);
+ HConv1Stage1x1* stage = (HConv1Stage1x1*)malloc(sizeof(HConv1Stage1x1));
+ hcInit1Stage(stage, impulseResponse, hlen, audioBufferSize, 1);
stage->gain = stage->normalizationGain * linGain;
autoConv->filter = (void*)stage;
- autoConv->process = &Convolver1StageLowLatencyProcessMono;
+ autoConv->process = &Convolver1StageLowLatencyProcess1x1;
}
return autoConv;
}
-AutoConvolverMono* AllocateAutoConvolverMonoZeroLatency(double *impulseResponse, int hlen, int audioBufferSize, int fftwThreads)
+AutoConvolver1x1* AllocateAutoConvolver1x1ZeroLatency(double *impulseResponse, int hlen, int audioBufferSize)
{
- AutoConvolverMono *autoConv = (AutoConvolverMono*)calloc(1, sizeof(AutoConvolverMono));
+ AutoConvolver1x1 *autoConv = (AutoConvolver1x1*)calloc(1, sizeof(AutoConvolver1x1));
autoConv->methods = 1;
- HConv1Stage* stage = (HConv1Stage*)calloc(1, sizeof(HConv1Stage));
- hcInit1Stage(stage, impulseResponse, hlen, audioBufferSize, 1, fftwThreads);
+ HConv1Stage1x1* stage = (HConv1Stage1x1*)calloc(1, sizeof(HConv1Stage1x1));
+ hcInit1Stage(stage, impulseResponse, hlen, audioBufferSize, 1);
autoConv->filter = (void*)stage;
- autoConv->process = &Convolver1StageLowLatencyProcessMono;
+ autoConv->process = &Convolver1StageLowLatencyProcess1x1;
return autoConv;
}
-void hcInit1StageDeterminedAllocation(HConv1Stage *filter, double *h, int hlen)
+void hcInit1StageDeterminedAllocation(HConv1Stage1x1 *filter, double *h, int hlen)
{
int i, j, size;
int flen = filter->framelength;
@@ -745,86 +621,76 @@ void hcInit1StageDeterminedAllocation(HConv1Stage *filter, double *h, int hlen)
{
for (j = 0; j < flen; j++)
filter->dft_time[j] = h[i * flen + j];
- fftw_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
+ filter->filterbuf_freq_realChannel1[i][j] = filter->dft_freq[j].r;
+ filter->filterbuf_freq_imagChannel1[i][j] = filter->dft_freq[j].i;
}
}
for (j = 0; j < hlen - i * flen; j++)
filter->dft_time[j] = h[i * flen + j];
size = sizeof(double) * ((i + 1) * flen - hlen);
memset(&(filter->dft_time[hlen - i * flen]), 0, size);
- fftw_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
+ filter->filterbuf_freq_realChannel1[i][j] = filter->dft_freq[j].r;
+ filter->filterbuf_freq_imagChannel1[i][j] = filter->dft_freq[j].i;
}
}
-void UpdateAutoConvolverMonoZeroLatency(AutoConvolverMono *autoConv, double *impulseResponse, int hlen)
+void UpdateAutoConvolver1x1ZeroLatency(AutoConvolver1x1 *autoConv, double *impulseResponse, int hlen)
{
- hcInit1StageDeterminedAllocation((HConv1Stage*)autoConv->filter, impulseResponse, hlen);
+ hcInit1StageDeterminedAllocation((HConv1Stage1x1*)autoConv->filter, impulseResponse, hlen);
}
-void hcClose1Stage(HConv1Stage *filter)
+void hcClose1Stage(HConv1Stage1x1 *filter)
{
int i;
- fftw_destroy_plan(filter->ifft);
- fftw_destroy_plan(filter->fft);
- fftw_free(filter->history_time);
+ free(filter->ifft);
+ free(filter->fft);
+ free(filter->history_time);
for (i = 0; i < filter->num_mixbuf; i++)
{
- fftw_free(filter->mixbuf_freq_real[i]);
- fftw_free(filter->mixbuf_freq_imag[i]);
+ free(filter->mixbuf_freq_real[i]);
+ free(filter->mixbuf_freq_imag[i]);
}
- fftw_free(filter->mixbuf_freq_real);
- fftw_free(filter->mixbuf_freq_imag);
+ free(filter->mixbuf_freq_real);
+ free(filter->mixbuf_freq_imag);
for (i = 0; i < filter->num_filterbuf; i++)
{
- fftw_free(filter->filterbuf_freq_real[i]);
- fftw_free(filter->filterbuf_freq_imag[i]);
+ free(filter->filterbuf_freq_realChannel1[i]);
+ free(filter->filterbuf_freq_imagChannel1[i]);
}
- fftw_free(filter->filterbuf_freq_real);
- fftw_free(filter->filterbuf_freq_imag);
- fftw_free(filter->in_freq_real);
- fftw_free(filter->in_freq_imag);
- fftw_free(filter->dft_freq);
- fftw_free(filter->dft_time);
+ free(filter->filterbuf_freq_realChannel1);
+ free(filter->filterbuf_freq_imagChannel1);
+ free(filter->in_freq_real);
+ free(filter->in_freq_imag);
+ free(filter->dft_freq);
+ free(filter->dft_time);
free(filter->steptask);
- memset(filter, 0, sizeof(HConv1Stage));
+ memset(filter, 0, sizeof(HConv1Stage1x1));
}
-void hcClose2Stage(HConv2Stage *filter)
+void hcClose2Stage(HConv2Stage1x1 *filter)
{
hcClose1Stage(filter->f_short);
free(filter->f_short);
hcClose1Stage(filter->f_long);
free(filter->f_long);
- fftw_free(filter->out_long);
- fftw_free(filter->in_long);
- memset(filter, 0, sizeof(HConv2Stage));
+ free(filter->out_long);
+ free(filter->in_long);
+ memset(filter, 0, sizeof(HConv2Stage1x1));
}
-void hcClose3Stage(HConv3Stage *filter)
+void hcClose3Stage(HConv3Stage1x1 *filter)
{
hcClose1Stage(filter->f_short);
free(filter->f_short);
hcClose2Stage(filter->f_medium);
free(filter->f_medium);
- fftw_free(filter->out_medium);
- fftw_free(filter->in_medium);
- memset(filter, 0, sizeof(HConv3Stage));
-}
-void hcClose4Stage(HConv4Stage *filter)
-{
- hcClose1Stage(filter->f_short);
- free(filter->f_short);
- hcClose3Stage(filter->f_medium);
- free(filter->f_medium);
- fftw_free(filter->out_medium);
- fftw_free(filter->in_medium);
- memset(filter, 0, sizeof(HConv4Stage));
+ free(filter->out_medium);
+ free(filter->in_medium);
+ memset(filter, 0, sizeof(HConv3Stage1x1));
}
-void AutoConvolverMonoFree(AutoConvolverMono *autoConv)
+void AutoConvolver1x1Free(AutoConvolver1x1 *autoConv)
{
if (autoConv->methods > 1)
{
@@ -833,28 +699,22 @@ void AutoConvolverMonoFree(AutoConvolverMono *autoConv)
}
if (autoConv->methods == 1)
{
- HConv1Stage* stage = (HConv1Stage*)autoConv->filter;
+ HConv1Stage1x1* stage = (HConv1Stage1x1*)autoConv->filter;
hcClose1Stage(stage);
free(stage);
}
else if (autoConv->methods == 2)
{
- HConv2Stage* stage = (HConv2Stage*)autoConv->filter;
+ HConv2Stage1x1* stage = (HConv2Stage1x1*)autoConv->filter;
hcClose2Stage(stage);
free(stage);
}
else if (autoConv->methods == 3)
{
- HConv3Stage* stage = (HConv3Stage*)autoConv->filter;
+ HConv3Stage1x1* stage = (HConv3Stage1x1*)autoConv->filter;
hcClose3Stage(stage);
free(stage);
}
- else if (autoConv->methods == 4)
- {
- HConv4Stage* stage = (HConv4Stage*)autoConv->filter;
- hcClose4Stage(stage);
- free(stage);
- }
else if (autoConv->methods == 999)
{
DFFIR* stage = (DFFIR*)autoConv->filter;
@@ -881,7 +741,7 @@ double hcTime(void)
#endif
double getProcTime(int flen, int num, double dur)
{
- HConv1Stage filter;
+ HConv1Stage1x1 filter;
double *x;
double *h;
double *y;
@@ -895,7 +755,7 @@ double getProcTime(int flen, int num, double dur)
xlen = 2048 * 2048;
size = sizeof(double) * xlen;
- x = (double *)fftw_malloc(size);
+ x = (double *)malloc(size);
lin = pow(10.0, -100.0 / 20.0); // 0.00001 = -100dB
mul = pow(lin, 1.0 / (double)xlen);
x[0] = 1.0;
@@ -904,7 +764,7 @@ double getProcTime(int flen, int num, double dur)
hlen = flen * num;
size = sizeof(double) * hlen;
- h = (double *)fftw_malloc(size);
+ h = (double *)malloc(size);
lin = pow(10.0, -60.0 / 20.0); // 0.001 = -60dB
mul = pow(lin, 1.0 / (double)hlen);
h[0] = 1.0;
@@ -913,9 +773,9 @@ double getProcTime(int flen, int num, double dur)
ylen = flen;
size = sizeof(double) * ylen;
- y = (double *)fftw_malloc(size);
+ y = (double *)malloc(size);
- hcInit1Stage(&filter, h, hlen, flen, 1, 0);
+ hcInit1Stage(&filter, h, hlen, flen, 1);
t_diff = 0.0;
t_start = hcTime();
@@ -934,9 +794,9 @@ double getProcTime(int flen, int num, double dur)
proc_time = t_diff / counter;
printf("Processing time: %7.3f us\n", 1000000.0 * proc_time);
hcClose1Stage(&filter);
- fftw_free(x);
- fftw_free(h);
- fftw_free(y);
+ free(x);
+ free(h);
+ free(y);
return proc_time;
}
double** PartitionHelperWisdomGetFromFile(const char *file, int *itemRet)
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.h b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.h
index c579827..5b87691 100644
--- a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.h
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/AutoConvolver.h
@@ -1,18 +1,16 @@
#ifndef __AUTOCONVOLVER_H__
#define __AUTOCONVOLVER_H__
-typedef struct str_AutoConvolverMono
+typedef struct str_AutoConvolver1x1
{
int methods, hnShortLen, bufpos;
double *inbuf, *outbuf;
void *filter;
- void(*process)(struct str_AutoConvolverMono*, double*, double*, int);
-} AutoConvolverMono;
-int ACFFTWThreadInit();
-void ACFFTWClean(int threads);
-AutoConvolverMono* InitAutoConvolverMono(double *impulseResponse, int hlen, int audioBufferSize, double gaindB, double **recommendation, int items, int fftwThreads);
-AutoConvolverMono* AllocateAutoConvolverMonoZeroLatency(double *impulseResponse, int hlen, int audioBufferSize, int fftwThreads);
-void UpdateAutoConvolverMonoZeroLatency(AutoConvolverMono *autoConv, double *impulseResponse, int hlen);
-void AutoConvolverMonoFree(AutoConvolverMono *autoConv);
+ void(*process)(struct str_AutoConvolver1x1*, double*, double*, int);
+} AutoConvolver1x1;
+AutoConvolver1x1* InitAutoConvolver1x1(double *impulseResponse, int hlen, int audioBufferSize, double gaindB, double **recommendation, int items);
+AutoConvolver1x1* AllocateAutoConvolver1x1ZeroLatency(double *impulseResponse, int hlen, int audioBufferSize);
+void UpdateAutoConvolver1x1ZeroLatency(AutoConvolver1x1 *autoConv, double *impulseResponse, int hlen);
+void AutoConvolver1x1Free(AutoConvolver1x1 *autoConv);
double** PartitionHelperWisdomGetFromFile(const char *file, int *itemRet);
char* PartitionHelper(int s_max, int fs);
double** PartitionHelperDirect(int s_max, int fs);
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.cpp b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.cpp
index 81c0084..dba0fc1 100644
--- a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.cpp
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.cpp
@@ -18,16 +18,12 @@ typedef struct
const double interpFreq[NUM_BANDS] = { 25.0, 40.0, 63.0, 100.0, 160.0, 250.0, 400.0, 630.0, 1000.0, 1600.0, 2500.0, 4000.0, 6300.0, 10000.0, 16000.0 };
EffectDSPMain::EffectDSPMain()
- : DSPbufferLength(1024), inOutRWPosition(0), equalizerEnabled(0), ramp(1.0), pregain(12.0), threshold(-60.0), knee(30.0), ratio(12.0), attack(0.001), release(0.24), isBenchData(0), mPreset(0), reverbEnabled(0), threadResult(0)
+ : DSPbufferLength(1024), inOutRWPosition(0), equalizerEnabled(0), ramp(1.0), pregain(12.0), threshold(-60.0), knee(30.0), ratio(12.0), attack(0.001), release(0.24), isBenchData(0), mPreset(0), reverbEnabled(0)
, mMatrixMCoeff(1.0), mMatrixSCoeff(1.0), bassBoostLp(0), FIREq(0), convolver(0), fullStereoConvolver(0), sosCount(0), resampledSOSCount(0), usedSOSCount(0), df441(0), df48(0), dfResampled(0)
, tempImpulseIncoming(0), tempImpulsedouble(0), finalImpulse(0), convolverReady(-1), bassLpReady(-1), analogModelEnable(0), tubedrive(2.0), eqFilterType(0), arbEq(0), xaxis(0), yaxis(0), eqFIRReady(0)
{
double c0[12] = { 2.138018534150542e-5, 4.0608501987194246e-5, 7.950414700590711e-5, 1.4049065318523225e-4, 2.988065284903209e-4, 0.0013061668170781858, 0.0036204239724680425, 0.008959629624060151, 0.027083658741258742, 0.08156916666666666, 0.1978822177777778, 0.4410733777777778 };
double c1[12] = { 5.88199398839289e-6, 1.1786813951189911e-5, 2.5600214528512222e-5, 8.53041086120132e-5, 2.656291374239004e-4, 5.047717001008378e-4, 8.214255850540808e-4, 0.0016754651127819551, 0.0033478867132867136, 0.006705333333333334, 0.013496382222222221, 0.02673028888888889 };
- if (ACFFTWThreadInit())
- threadResult = 2;
- else
- threadResult = 0;
benchmarkValue[0] = (double*)malloc(12 * sizeof(double));
benchmarkValue[1] = (double*)malloc(12 * sizeof(double));
memcpy(benchmarkValue[0], c0, sizeof(c0));
@@ -72,10 +68,6 @@ EffectDSPMain::~EffectDSPMain()
free(tempImpulseIncoming);
if (tempImpulsedouble)
free(tempImpulsedouble);
- if (threadResult)
- ACFFTWClean(1);
- else
- ACFFTWClean(0);
if (benchmarkValue[0])
free(benchmarkValue[0]);
if (benchmarkValue[1])
@@ -109,7 +101,7 @@ void EffectDSPMain::FreeBassBoost()
{
for (unsigned int i = 0; i < NUMCHANNEL; i++)
{
- AutoConvolverMonoFree(bassBoostLp[i]);
+ AutoConvolver1x1Free(bassBoostLp[i]);
free(bassBoostLp[i]);
}
free(bassBoostLp);
@@ -139,7 +131,7 @@ void EffectDSPMain::FreeEq()
{
for (unsigned int i = 0; i < NUMCHANNEL; i++)
{
- AutoConvolverMonoFree(FIREq[i]);
+ AutoConvolver1x1Free(FIREq[i]);
free(FIREq[i]);
}
free(FIREq);
@@ -156,7 +148,7 @@ void EffectDSPMain::FreeConvolver()
{
if (convolver[i])
{
- AutoConvolverMonoFree(convolver[i]);
+ AutoConvolver1x1Free(convolver[i]);
free(convolver[i]);
convolver[i] = 0;
}
@@ -170,7 +162,7 @@ void EffectDSPMain::FreeConvolver()
{
if (fullStereoConvolver[i])
{
- AutoConvolverMonoFree(fullStereoConvolver[i]);
+ AutoConvolver1x1Free(fullStereoConvolver[i]);
free(fullStereoConvolver[i]);
fullStereoConvolver[i] = 0;
}
@@ -937,15 +929,15 @@ void EffectDSPMain::refreshBassLinearPhase(uint32_t DSPbufferLength, uint32_t ta
unsigned int i;
if (!bassBoostLp)
{
- bassBoostLp = (AutoConvolverMono**)malloc(sizeof(AutoConvolverMono*) * NUMCHANNEL);
+ bassBoostLp = (AutoConvolver1x1**)malloc(sizeof(AutoConvolver1x1*) * NUMCHANNEL);
for (i = 0; i < NUMCHANNEL; i++)
- bassBoostLp[i] = AllocateAutoConvolverMonoZeroLatency(freqSamplImp, filterLength, DSPbufferLength, threadResult);
+ bassBoostLp[i] = AllocateAutoConvolver1x1ZeroLatency(freqSamplImp, filterLength, DSPbufferLength);
ramp = 0.4;
}
else
{
for (i = 0; i < NUMCHANNEL; i++)
- UpdateAutoConvolverMonoZeroLatency(bassBoostLp[i], freqSamplImp, filterLength);
+ UpdateAutoConvolver1x1ZeroLatency(bassBoostLp[i], freqSamplImp, filterLength);
}
free(freqSamplImp);
#ifdef DEBUG
@@ -966,15 +958,15 @@ int EffectDSPMain::refreshConvolver(uint32_t DSPbufferLength)
{
if (impChannels < 3)
{
- convolver = (AutoConvolverMono**)malloc(sizeof(AutoConvolverMono*) * 2);
+ convolver = (AutoConvolver1x1**)malloc(sizeof(AutoConvolver1x1*) * 2);
if (!convolver)
return 0;
for (i = 0; i < 2; i++)
{
if (impChannels == 1)
- convolver[i] = InitAutoConvolverMono(finalImpulse[0], impulseLengthActual, DSPbufferLength, convGaindB, benchmarkValue, 12, threadResult);
+ convolver[i] = InitAutoConvolver1x1(finalImpulse[0], impulseLengthActual, DSPbufferLength, convGaindB, benchmarkValue, 12);
else
- convolver[i] = InitAutoConvolverMono(finalImpulse[i], impulseLengthActual, DSPbufferLength, convGaindB, benchmarkValue, 12, threadResult);
+ convolver[i] = InitAutoConvolver1x1(finalImpulse[i], impulseLengthActual, DSPbufferLength, convGaindB, benchmarkValue, 12);
}
fullStconvparams.conv = convolver;
fullStconvparams.out = outputBuffer;
@@ -997,11 +989,11 @@ int EffectDSPMain::refreshConvolver(uint32_t DSPbufferLength)
}
else if (impChannels == 4)
{
- fullStereoConvolver = (AutoConvolverMono**)malloc(sizeof(AutoConvolverMono*) * 4);
+ fullStereoConvolver = (AutoConvolver1x1**)malloc(sizeof(AutoConvolver1x1*) * 4);
if (!fullStereoConvolver)
return 0;
for (i = 0; i < 4; i++)
- fullStereoConvolver[i] = InitAutoConvolverMono(finalImpulse[i], impulseLengthActual, DSPbufferLength, convGaindB, benchmarkValue, 12, threadResult);
+ fullStereoConvolver[i] = InitAutoConvolver1x1(finalImpulse[i], impulseLengthActual, DSPbufferLength, convGaindB, benchmarkValue, 12);
fullStconvparams.conv = fullStereoConvolver;
fullStconvparams1.conv = fullStereoConvolver;
fullStconvparams.out = tempBuf;
@@ -1078,14 +1070,14 @@ void EffectDSPMain::refreshEqBands(uint32_t DSPbufferLength, double *bands)
double *eqImpulseResponse = arbEq->GetFilter(arbEq, mSamplingRate);
if (!FIREq)
{
- FIREq = (AutoConvolverMono**)malloc(sizeof(AutoConvolverMono*) * NUMCHANNEL);
+ FIREq = (AutoConvolver1x1**)malloc(sizeof(AutoConvolver1x1*) * NUMCHANNEL);
for (i = 0; i < NUMCHANNEL; i++)
- FIREq[i] = AllocateAutoConvolverMonoZeroLatency(eqImpulseResponse, eqfilterLength, DSPbufferLength, threadResult);
+ FIREq[i] = AllocateAutoConvolver1x1ZeroLatency(eqImpulseResponse, eqfilterLength, DSPbufferLength);
}
else
{
for (i = 0; i < NUMCHANNEL; i++)
- UpdateAutoConvolverMonoZeroLatency(FIREq[i], eqImpulseResponse, eqfilterLength);
+ UpdateAutoConvolver1x1ZeroLatency(FIREq[i], eqImpulseResponse, eqfilterLength);
}
#ifdef DEBUG
LOGI("FIR Equalizer allocate all done: total taps %d", eqfilterLength);
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.h b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.h
index 1b3ccdb..54790bf 100644
--- a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.h
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/EffectDSPMain.h
@@ -27,7 +27,7 @@ protected:
DirectForm2 **df441, **df48, **dfResampled, **sosPointer;
int sosCount, resampledSOSCount, usedSOSCount;
typedef struct threadParamsConv {
- AutoConvolverMono **conv;
+ AutoConvolver1x1 **conv;
double **in, **out;
size_t frameCount;
} ptrThreadParamsFullStConv;
@@ -54,16 +54,15 @@ protected:
JLimiter kLimiter;
sf_compressor_state_st compressor;
sf_reverb_state_st myreverb;
- AutoConvolverMono **bassBoostLp;
- AutoConvolverMono **convolver, **fullStereoConvolver;
+ AutoConvolver1x1 **bassBoostLp;
+ AutoConvolver1x1 **convolver, **fullStereoConvolver;
tubeFilter tubeP[2];
t_bs2bdp bs2b;
// Wavechild670 *compressor670;
- int threadResult;
ArbitraryEq *arbEq;
double *xaxis, *yaxis;
int eqfilterLength;
- AutoConvolverMono **FIREq;
+ AutoConvolver1x1 **FIREq;
// Variables
double pregain, threshold, knee, ratio, attack, release, tubedrive, bassBoostCentreFreq, convGaindB, mMatrixMCoeff, mMatrixSCoeff;
int16_t bassBoostStrength, bassBoostFilterType, eqFilterType, bs2bLv, compressionEnabled, bassBoostEnabled, equalizerEnabled, reverbEnabled,
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/_kiss_fft_guts.h b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/_kiss_fft_guts.h
new file mode 100644
index 0000000..6721eb7
--- /dev/null
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/_kiss_fft_guts.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+/* kiss_fft.h
+ defines kiss_fft_scalar as either short or a float type
+ and defines
+ typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
+#include "kiss_fft.h"
+#include <limits.h>
+
+#define MAXFACTORS 32
+/* e.g. an fft of length 128 has 4 factors
+ as far as kissfft is concerned
+ 4*4*4*2
+ */
+
+struct kiss_fft_state{
+ int nfft;
+ int inverse;
+ int factors[2*MAXFACTORS];
+ kiss_fft_cpx twiddles[1];
+};
+
+/*
+ Explanation of macros dealing with complex math:
+
+ C_MUL(m,a,b) : m = a*b
+ C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
+ C_SUB( res, a,b) : res = a - b
+ C_SUBFROM( res , a) : res -= a
+ C_ADDTO( res , a) : res += a
+ * */
+# define S_MUL(a,b) ( (a)*(b) )
+#define C_MUL(m,a,b) \
+ do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
+ (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
+# define C_FIXDIV(c,div) /* NOOP */
+# define C_MULBYSCALAR( c, s ) \
+ do{ (c).r *= (s);\
+ (c).i *= (s); }while(0)
+#ifndef CHECK_OVERFLOW_OP
+# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
+#endif
+
+#define C_ADD( res, a,b)\
+ do { \
+ CHECK_OVERFLOW_OP((a).r,+,(b).r)\
+ CHECK_OVERFLOW_OP((a).i,+,(b).i)\
+ (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
+ }while(0)
+#define C_SUB( res, a,b)\
+ do { \
+ CHECK_OVERFLOW_OP((a).r,-,(b).r)\
+ CHECK_OVERFLOW_OP((a).i,-,(b).i)\
+ (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
+ }while(0)
+#define C_ADDTO( res , a)\
+ do { \
+ CHECK_OVERFLOW_OP((res).r,+,(a).r)\
+ CHECK_OVERFLOW_OP((res).i,+,(a).i)\
+ (res).r += (a).r; (res).i += (a).i;\
+ }while(0)
+
+#define C_SUBFROM( res , a)\
+ do {\
+ CHECK_OVERFLOW_OP((res).r,-,(a).r)\
+ CHECK_OVERFLOW_OP((res).i,-,(a).i)\
+ (res).r -= (a).r; (res).i -= (a).i; \
+ }while(0)
+
+
+# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
+# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
+# define HALF_OF(x) ((x)*.5f)
+#define kf_cexp(x,phase) \
+ do{ \
+ (x)->r = KISS_FFT_COS(phase);\
+ (x)->i = KISS_FFT_SIN(phase);\
+ }while(0)
+
+
+/* a debugging function */
+#define pcpx(c)\
+ fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
+
+
+#ifdef KISS_FFT_USE_ALLOCA
+// define this to allow use of alloca instead of malloc for temporary buffers
+// Temporary buffers are used in two case:
+// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
+// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform.
+#include <alloca.h>
+#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
+#define KISS_FFT_TMP_FREE(ptr)
+#else
+#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
+#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
+#endif
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fft.c b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fft.c
new file mode 100644
index 0000000..af2f695
--- /dev/null
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fft.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+
+#include "_kiss_fft_guts.h"
+/* The guts header contains all the multiplication and addition macros that are defined for
+ fixed or floating point complex numbers. It also delares the kf_ internal functions.
+ */
+
+static void kf_bfly2(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ int m
+ )
+{
+ kiss_fft_cpx * Fout2;
+ kiss_fft_cpx * tw1 = st->twiddles;
+ kiss_fft_cpx t;
+ Fout2 = Fout + m;
+ do{
+ C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
+
+ C_MUL (t, *Fout2 , *tw1);
+ tw1 += fstride;
+ C_SUB( *Fout2 , *Fout , t );
+ C_ADDTO( *Fout , t );
+ ++Fout2;
+ ++Fout;
+ }while (--m);
+}
+
+static void kf_bfly4(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ const size_t m
+ )
+{
+ kiss_fft_cpx *tw1,*tw2,*tw3;
+ kiss_fft_cpx scratch[6];
+ size_t k=m;
+ const size_t m2=2*m;
+ const size_t m3=3*m;
+
+
+ tw3 = tw2 = tw1 = st->twiddles;
+
+ do {
+ C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
+
+ C_MUL(scratch[0],Fout[m] , *tw1 );
+ C_MUL(scratch[1],Fout[m2] , *tw2 );
+ C_MUL(scratch[2],Fout[m3] , *tw3 );
+
+ C_SUB( scratch[5] , *Fout, scratch[1] );
+ C_ADDTO(*Fout, scratch[1]);
+ C_ADD( scratch[3] , scratch[0] , scratch[2] );
+ C_SUB( scratch[4] , scratch[0] , scratch[2] );
+ C_SUB( Fout[m2], *Fout, scratch[3] );
+ tw1 += fstride;
+ tw2 += fstride*2;
+ tw3 += fstride*3;
+ C_ADDTO( *Fout , scratch[3] );
+
+ if(st->inverse) {
+ Fout[m].r = scratch[5].r - scratch[4].i;
+ Fout[m].i = scratch[5].i + scratch[4].r;
+ Fout[m3].r = scratch[5].r + scratch[4].i;
+ Fout[m3].i = scratch[5].i - scratch[4].r;
+ }else{
+ Fout[m].r = scratch[5].r + scratch[4].i;
+ Fout[m].i = scratch[5].i - scratch[4].r;
+ Fout[m3].r = scratch[5].r - scratch[4].i;
+ Fout[m3].i = scratch[5].i + scratch[4].r;
+ }
+ ++Fout;
+ }while(--k);
+}
+
+static void kf_bfly3(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ size_t m
+ )
+{
+ size_t k=m;
+ const size_t m2 = 2*m;
+ kiss_fft_cpx *tw1,*tw2;
+ kiss_fft_cpx scratch[5];
+ kiss_fft_cpx epi3;
+ epi3 = st->twiddles[fstride*m];
+
+ tw1=tw2=st->twiddles;
+
+ do{
+ C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
+
+ C_MUL(scratch[1],Fout[m] , *tw1);
+ C_MUL(scratch[2],Fout[m2] , *tw2);
+
+ C_ADD(scratch[3],scratch[1],scratch[2]);
+ C_SUB(scratch[0],scratch[1],scratch[2]);
+ tw1 += fstride;
+ tw2 += fstride*2;
+
+ Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
+ Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
+
+ C_MULBYSCALAR( scratch[0] , epi3.i );
+
+ C_ADDTO(*Fout,scratch[3]);
+
+ Fout[m2].r = Fout[m].r + scratch[0].i;
+ Fout[m2].i = Fout[m].i - scratch[0].r;
+
+ Fout[m].r -= scratch[0].i;
+ Fout[m].i += scratch[0].r;
+
+ ++Fout;
+ }while(--k);
+}
+
+static void kf_bfly5(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ int m
+ )
+{
+ kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
+ int u;
+ kiss_fft_cpx scratch[13];
+ kiss_fft_cpx * twiddles = st->twiddles;
+ kiss_fft_cpx *tw;
+ kiss_fft_cpx ya,yb;
+ ya = twiddles[fstride*m];
+ yb = twiddles[fstride*2*m];
+
+ Fout0=Fout;
+ Fout1=Fout0+m;
+ Fout2=Fout0+2*m;
+ Fout3=Fout0+3*m;
+ Fout4=Fout0+4*m;
+
+ tw=st->twiddles;
+ for ( u=0; u<m; ++u ) {
+ C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
+ scratch[0] = *Fout0;
+
+ C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
+ C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
+ C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
+ C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
+
+ C_ADD( scratch[7],scratch[1],scratch[4]);
+ C_SUB( scratch[10],scratch[1],scratch[4]);
+ C_ADD( scratch[8],scratch[2],scratch[3]);
+ C_SUB( scratch[9],scratch[2],scratch[3]);
+
+ Fout0->r += scratch[7].r + scratch[8].r;
+ Fout0->i += scratch[7].i + scratch[8].i;
+
+ scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
+ scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
+
+ scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
+ scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
+
+ C_SUB(*Fout1,scratch[5],scratch[6]);
+ C_ADD(*Fout4,scratch[5],scratch[6]);
+
+ scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
+ scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
+ scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
+ scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
+
+ C_ADD(*Fout2,scratch[11],scratch[12]);
+ C_SUB(*Fout3,scratch[11],scratch[12]);
+
+ ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
+ }
+}
+
+/* perform the butterfly for one stage of a mixed radix FFT */
+static void kf_bfly_generic(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ int m,
+ int p
+ )
+{
+ int u,k,q1,q;
+ kiss_fft_cpx * twiddles = st->twiddles;
+ kiss_fft_cpx t;
+ int Norig = st->nfft;
+
+ kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p);
+
+ for ( u=0; u<m; ++u ) {
+ k=u;
+ for ( q1=0 ; q1<p ; ++q1 ) {
+ scratch[q1] = Fout[ k ];
+ C_FIXDIV(scratch[q1],p);
+ k += m;
+ }
+
+ k=u;
+ for ( q1=0 ; q1<p ; ++q1 ) {
+ int twidx=0;
+ Fout[ k ] = scratch[0];
+ for (q=1;q<p;++q ) {
+ twidx += fstride * k;
+ if (twidx>=Norig) twidx-=Norig;
+ C_MUL(t,scratch[q] , twiddles[twidx] );
+ C_ADDTO( Fout[ k ] ,t);
+ }
+ k += m;
+ }
+ }
+ KISS_FFT_TMP_FREE(scratch);
+}
+
+static
+void kf_work(
+ kiss_fft_cpx * Fout,
+ const kiss_fft_cpx * f,
+ const size_t fstride,
+ int in_stride,
+ int * factors,
+ const kiss_fft_cfg st
+ )
+{
+ kiss_fft_cpx * Fout_beg=Fout;
+ const int p=*factors++; /* the radix */
+ const int m=*factors++; /* stage's fft length/p */
+ const kiss_fft_cpx * Fout_end = Fout + p*m;
+
+#ifdef _OPENMP
+ // use openmp extensions at the
+ // top-level (not recursive)
+ if (fstride==1 && p<=5)
+ {
+ int k;
+
+ // execute the p different work units in different threads
+# pragma omp parallel for
+ for (k=0;k<p;++k)
+ kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
+ // all threads have joined by this point
+
+ switch (p) {
+ case 2: kf_bfly2(Fout,fstride,st,m); break;
+ case 3: kf_bfly3(Fout,fstride,st,m); break;
+ case 4: kf_bfly4(Fout,fstride,st,m); break;
+ case 5: kf_bfly5(Fout,fstride,st,m); break;
+ default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+ }
+ return;
+ }
+#endif
+
+ if (m==1) {
+ do{
+ *Fout = *f;
+ f += fstride*in_stride;
+ }while(++Fout != Fout_end );
+ }else{
+ do{
+ // recursive call:
+ // DFT of size m*p performed by doing
+ // p instances of smaller DFTs of size m,
+ // each one takes a decimated version of the input
+ kf_work( Fout , f, fstride*p, in_stride, factors,st);
+ f += fstride*in_stride;
+ }while( (Fout += m) != Fout_end );
+ }
+
+ Fout=Fout_beg;
+
+ // recombine the p smaller DFTs
+ switch (p) {
+ case 2: kf_bfly2(Fout,fstride,st,m); break;
+ case 3: kf_bfly3(Fout,fstride,st,m); break;
+ case 4: kf_bfly4(Fout,fstride,st,m); break;
+ case 5: kf_bfly5(Fout,fstride,st,m); break;
+ default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+ }
+}
+
+/* facbuf is populated by p1,m1,p2,m2, ...
+ where
+ p[i] * m[i] = m[i-1]
+ m0 = n */
+static
+void kf_factor(int n,int * facbuf)
+{
+ int p=4;
+ double floor_sqrt;
+ floor_sqrt = floor( sqrt((double)n) );
+
+ /*factor out powers of 4, powers of 2, then any remaining primes */
+ do {
+ while (n % p) {
+ switch (p) {
+ case 4: p = 2; break;
+ case 2: p = 3; break;
+ default: p += 2; break;
+ }
+ if (p > floor_sqrt)
+ p = n; /* no more factors, skip to end */
+ }
+ n /= p;
+ *facbuf++ = p;
+ *facbuf++ = n;
+ } while (n > 1);
+}
+
+/*
+ *
+ * User-callable function to allocate all necessary storage space for the fft.
+ *
+ * The return value is a contiguous block of memory, allocated with malloc. As such,
+ * It can be freed with free(), rather than a kiss_fft-specific function.
+ * */
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
+{
+ kiss_fft_cfg st=NULL;
+ size_t memneeded = sizeof(struct kiss_fft_state)
+ + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
+
+ if ( lenmem==NULL ) {
+ st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
+ }else{
+ if (mem != NULL && *lenmem >= memneeded)
+ st = (kiss_fft_cfg)mem;
+ *lenmem = memneeded;
+ }
+ if (st) {
+ int i;
+ st->nfft=nfft;
+ st->inverse = inverse_fft;
+
+ for (i=0;i<nfft;++i) {
+ const double pi=3.141592653589793238462643383279502884197169399375105820974944;
+ double phase = -2*pi*i / nfft;
+ if (st->inverse)
+ phase *= -1;
+ kf_cexp(st->twiddles+i, phase );
+ }
+
+ kf_factor(nfft,st->factors);
+ }
+ return st;
+}
+
+
+void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
+{
+ if (fin == fout) {
+ //NOTE: this is not really an in-place FFT algorithm.
+ //It just performs an out-of-place FFT into a temp buffer
+ kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
+ kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
+ memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
+ KISS_FFT_TMP_FREE(tmpbuf);
+ }else{
+ kf_work( fout, fin, 1,in_stride, st->factors,st );
+ }
+}
+
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
+{
+ kiss_fft_stride(cfg,fin,fout,1);
+}
+
+
+void kiss_fft_cleanup(void)
+{
+ // nothing needed any more
+}
+
+int kiss_fft_next_fast_size(int n)
+{
+ while(1) {
+ int m=n;
+ while ( (m%2) == 0 ) m/=2;
+ while ( (m%3) == 0 ) m/=3;
+ while ( (m%5) == 0 ) m/=5;
+ if (m<=1)
+ break; /* n is completely factorable by twos, threes, and fives */
+ n++;
+ }
+ return n;
+}
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fft.h b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fft.h
new file mode 100644
index 0000000..c02a43d
--- /dev/null
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fft.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#ifndef KISS_FFT_H
+#define KISS_FFT_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ ATTENTION!
+ If you would like a :
+ -- a utility that will handle the caching of fft objects
+ -- real-only (no imaginary time component ) FFT
+ -- a multi-dimensional FFT
+ -- a command-line utility to perform ffts
+ -- a command-line utility to perform fast-convolution filtering
+
+ Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
+ in the tools/ directory.
+*/
+
+#ifdef USE_SIMD
+# include <xmmintrin.h>
+# define kiss_fft_scalar __m128
+#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
+#define KISS_FFT_FREE _mm_free
+#else
+#define KISS_FFT_MALLOC malloc
+#define KISS_FFT_FREE free
+#endif
+# ifndef kiss_fft_scalar
+/* default is float */
+# define kiss_fft_scalar double
+# endif
+
+typedef struct {
+ kiss_fft_scalar r;
+ kiss_fft_scalar i;
+}kiss_fft_cpx;
+
+typedef struct kiss_fft_state* kiss_fft_cfg;
+
+/*
+ * kiss_fft_alloc
+ *
+ * Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
+ *
+ * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
+ *
+ * The return value from fft_alloc is a cfg buffer used internally
+ * by the fft routine or NULL.
+ *
+ * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
+ * The returned value should be free()d when done to avoid memory leaks.
+ *
+ * The state can be placed in a user supplied buffer 'mem':
+ * If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
+ * then the function places the cfg in mem and the size used in *lenmem
+ * and returns mem.
+ *
+ * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
+ * then the function returns NULL and places the minimum cfg
+ * buffer size in *lenmem.
+ * */
+
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
+
+/*
+ * kiss_fft(cfg,in_out_buf)
+ *
+ * Perform an FFT on a complex input buffer.
+ * for a forward FFT,
+ * fin should be f[0] , f[1] , ... ,f[nfft-1]
+ * fout will be F[0] , F[1] , ... ,F[nfft-1]
+ * Note that each element is complex and can be accessed like
+ f[k].r and f[k].i
+ * */
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
+
+/*
+ A more generic version of the above function. It reads its input from every Nth sample.
+ * */
+void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
+
+/* If kiss_fft_alloc allocated a buffer, it is one contiguous
+ buffer and can be simply free()d when no longer needed*/
+#define kiss_fft_free KISS_FFT_FREE
+
+/*
+ Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
+ your compiler output to call this before you exit.
+*/
+void kiss_fft_cleanup(void);
+
+
+/*
+ * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
+ */
+int kiss_fft_next_fast_size(int n);
+
+/* for real ffts, we need an even size */
+#define kiss_fftr_next_fast_size_real(n) \
+ (kiss_fft_next_fast_size( ((n)+1)>>1)<<1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fftr.c b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fftr.c
new file mode 100644
index 0000000..8102132
--- /dev/null
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fftr.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#include "kiss_fftr.h"
+#include "_kiss_fft_guts.h"
+
+struct kiss_fftr_state{
+ kiss_fft_cfg substate;
+ kiss_fft_cpx * tmpbuf;
+ kiss_fft_cpx * super_twiddles;
+#ifdef USE_SIMD
+ void * pad;
+#endif
+};
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
+{
+ int i;
+ kiss_fftr_cfg st = NULL;
+ size_t subsize = 0, memneeded;
+
+ if (nfft & 1) {
+ fprintf(stderr,"Real FFT optimization must be even.\n");
+ return NULL;
+ }
+ nfft >>= 1;
+
+ kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
+ memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2);
+
+ if (lenmem == NULL) {
+ st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
+ } else {
+ if (*lenmem >= memneeded)
+ st = (kiss_fftr_cfg) mem;
+ *lenmem = memneeded;
+ }
+ if (!st)
+ return NULL;
+
+ st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
+ st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
+ st->super_twiddles = st->tmpbuf + nfft;
+ kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
+
+ for (i = 0; i < nfft/2; ++i) {
+ double phase =
+ -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5);
+ if (inverse_fft)
+ phase *= -1;
+ kf_cexp (st->super_twiddles+i,phase);
+ }
+ return st;
+}
+
+void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
+{
+ /* input buffer timedata is stored row-wise */
+ int k,ncfft;
+ kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
+
+ if ( st->substate->inverse) {
+ fprintf(stderr,"kiss fft usage error: improper alloc\n");
+ exit(1);
+ }
+
+ ncfft = st->substate->nfft;
+
+ /*perform the parallel fft of two real signals packed in real,imag*/
+ kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
+ /* The real part of the DC element of the frequency spectrum in st->tmpbuf
+ * contains the sum of the even-numbered elements of the input time sequence
+ * The imag part is the sum of the odd-numbered elements
+ *
+ * The sum of tdc.r and tdc.i is the sum of the input time sequence.
+ * yielding DC of input time sequence
+ * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
+ * yielding Nyquist bin of input time sequence
+ */
+
+ tdc.r = st->tmpbuf[0].r;
+ tdc.i = st->tmpbuf[0].i;
+ C_FIXDIV(tdc,2);
+ CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
+ CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
+ freqdata[0].r = tdc.r + tdc.i;
+ freqdata[ncfft].r = tdc.r - tdc.i;
+#ifdef USE_SIMD
+ freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
+#else
+ freqdata[ncfft].i = freqdata[0].i = 0;
+#endif
+
+ for ( k=1;k <= ncfft/2 ; ++k ) {
+ fpk = st->tmpbuf[k];
+ fpnk.r = st->tmpbuf[ncfft-k].r;
+ fpnk.i = - st->tmpbuf[ncfft-k].i;
+ C_FIXDIV(fpk,2);
+ C_FIXDIV(fpnk,2);
+
+ C_ADD( f1k, fpk , fpnk );
+ C_SUB( f2k, fpk , fpnk );
+ C_MUL( tw , f2k , st->super_twiddles[k-1]);
+
+ freqdata[k].r = HALF_OF(f1k.r + tw.r);
+ freqdata[k].i = HALF_OF(f1k.i + tw.i);
+ freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);
+ freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);
+ }
+}
+
+void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
+{
+ /* input buffer timedata is stored row-wise */
+ int k, ncfft;
+
+ if (st->substate->inverse == 0) {
+ fprintf (stderr, "kiss fft usage error: improper alloc\n");
+ exit (1);
+ }
+
+ ncfft = st->substate->nfft;
+
+ st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
+ st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
+ C_FIXDIV(st->tmpbuf[0],2);
+
+ for (k = 1; k <= ncfft / 2; ++k) {
+ kiss_fft_cpx fk, fnkc, fek, fok, tmp;
+ fk = freqdata[k];
+ fnkc.r = freqdata[ncfft - k].r;
+ fnkc.i = -freqdata[ncfft - k].i;
+ C_FIXDIV( fk , 2 );
+ C_FIXDIV( fnkc , 2 );
+
+ C_ADD (fek, fk, fnkc);
+ C_SUB (tmp, fk, fnkc);
+ C_MUL (fok, tmp, st->super_twiddles[k-1]);
+ C_ADD (st->tmpbuf[k], fek, fok);
+ C_SUB (st->tmpbuf[ncfft - k], fek, fok);
+#ifdef USE_SIMD
+ st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
+#else
+ st->tmpbuf[ncfft - k].i *= -1;
+#endif
+ }
+ kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
+}
diff --git a/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fftr.h b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fftr.h
new file mode 100644
index 0000000..588948d
--- /dev/null
+++ b/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/kissfft/kiss_fftr.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#ifndef KISS_FTR_H
+#define KISS_FTR_H
+
+#include "kiss_fft.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+
+ Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
+
+
+
+ */
+
+typedef struct kiss_fftr_state *kiss_fftr_cfg;
+
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
+/*
+ nfft must be even
+
+ If you don't care to allocate space, use mem = lenmem = NULL
+*/
+
+
+void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
+/*
+ input timedata has nfft scalar points
+ output freqdata has nfft/2+1 complex points
+*/
+
+void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
+/*
+ input freqdata has nfft/2+1 complex points
+ output timedata has nfft scalar points
+*/
+
+#define kiss_fftr_free KISS_FFT_FREE
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/DSPManager_Free/jni/main/Android.mk b/DSPManager_Free/jni/main/Android.mk
index 12ff2ac..b0792cf 100644
--- a/DSPManager_Free/jni/main/Android.mk
+++ b/DSPManager_Free/jni/main/Android.mk
@@ -1,28 +1,8 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE := fftw3
-ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
-LOCAL_SRC_FILES := fftw/FloatARMNEON/libfftw3fNeon.a
-else ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
-LOCAL_SRC_FILES := fftw/FloatARMNEON64/libfftw3f.a
-else ifeq ($(TARGET_ARCH_ABI), x86)
-LOCAL_SRC_FILES := fftw/Floatx86/libfftw3f.a
-endif
-include $(PREBUILT_STATIC_LIBRARY)
-include $(CLEAR_VARS)
-LOCAL_MODULE := fftw3thread
-ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
-LOCAL_SRC_FILES := fftw/FloatARMNEON/libfftw3f_threadsNeon.a
-else ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
-LOCAL_SRC_FILES := fftw/FloatARMNEON64/libfftw3f_threads.a
-else ifeq ($(TARGET_ARCH_ABI), x86)
-LOCAL_SRC_FILES := fftw/Floatx86/libfftw3f_threads.a
-endif
-include $(PREBUILT_STATIC_LIBRARY)
-include $(CLEAR_VARS)
LOCAL_MODULE := jamesDSPImpulseToolbox
-LOCAL_SRC_FILES := JdspImpResToolbox.c AutoConvolver.c
-LOCAL_STATIC_LIBRARIES = libsndfile libsamplerate fftw3thread fftw3
+LOCAL_SRC_FILES := kissfft\kiss_fft.c kissfft\kiss_fftr.c JdspImpResToolbox.c AutoConvolver.c
+LOCAL_STATIC_LIBRARIES = libsndfile libsamplerate
LOCAL_CPPFLAGS += -ffunction-sections -fdata-sections -Ofast -ftree-vectorize -DNDEBUG
LOCAL_CFLAGS += -ffunction-sections -fdata-sections -Ofast -ftree-vectorize -DNDEBUG
LOCAL_LDFLAGS += -Wl,--gc-sections,--exclude-libs,ALL
diff --git a/DSPManager_Free/jni/main/AutoConvolver.c b/DSPManager_Free/jni/main/AutoConvolver.c
index 2bd49e1..baa1048 100644
--- a/DSPManager_Free/jni/main/AutoConvolver.c
+++ b/DSPManager_Free/jni/main/AutoConvolver.c
@@ -2,7 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
-#include "fftw3.h"
+#include "kissfft/kiss_fftr.h"
#include "AutoConvolver.h"
typedef struct str_HConv1Stage
{
@@ -12,67 +12,37 @@ typedef struct str_HConv1Stage
int framelength; // number of samples per audio frame
int *steptask; // processing tasks per step
float *dft_time; // DFT buffer (time domain)
- fftwf_complex *dft_freq; // DFT buffer (frequency domain)
+ kiss_fft_cpx *dft_freq; // DFT buffer (frequency domain)
float *in_freq_real; // input buffer (frequency domain)
float *in_freq_imag; // input buffer (frequency domain)
int num_filterbuf; // number of filter segments
- float **filterbuf_freq_real; // filter segments (frequency domain)
- float **filterbuf_freq_imag; // filter segments (frequency domain)
+ float **filterbuf_freq_realChannel1; // filter segments (frequency domain)
+ float **filterbuf_freq_imagChannel1; // filter segments (frequency domain)
int num_mixbuf; // number of mixing segments
float **mixbuf_freq_real; // mixing segments (frequency domain)
float **mixbuf_freq_imag; // mixing segments (frequency domain)
float *history_time; // history buffer (time domain)
- fftwf_plan fft; // FFT transformation plan
- fftwf_plan ifft; // IFFT transformation plan
-} HConv1Stage;
-typedef struct str_HConv2Stage
-{
- int step; // processing step counter
- int maxstep; // number of processing steps per long audio frame
- int flen_long; // number of samples per long audio frame
- int flen_short; // number of samples per short audio frame
- float *in_long; // input buffer (long frame)
- float *out_long; // output buffer (long frame)
- HConv1Stage *f_long; // convolution filter (long segments)
- HConv1Stage *f_short; // convolution filter (short segments)
-} HConv2Stage;
-typedef struct str_HConv3Stage
-{
- int step; // processing step counter
- int maxstep; // number of processing steps per long audio frame
- int flen_medium; // number of samples per long audio frame
- int flen_short; // number of samples per short audio frame
- float *in_medium; // input buffer (long frame)
- float *out_medium; // output buffer (long frame)
- HConv2Stage *f_medium; // convolution filter (long segments)
- HConv1Stage *f_short; // convolution filter (short segments)
-} HConv3Stage;
-int ACFFTWThreadInit()
-{
- return fftwf_init_threads();
-}
-void ACFFTWClean(int threads)
-{
- if (threads)
- fftwf_cleanup_threads();
- else
- fftwf_cleanup();
-}
-inline void hcPut1Stage(HConv1Stage *filter, float *x)
+ float normalizationGain;
+ float gain;
+ kiss_fftr_cfg fft; // FFT transformation plan
+ kiss_fftr_cfg ifft; // IFFT transformation plan
+ int memSize;
+} HConv1Stage1x1;
+inline void hcPut1Stage(HConv1Stage1x1 *filter, float *x)
{
int j, flen, size;
flen = filter->framelength;
- size = sizeof(float) * flen;
+ size = filter->memSize;
memcpy(filter->dft_time, x, size);
memset(&(filter->dft_time[flen]), 0, size);
- fftwf_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->in_freq_real[j] = filter->dft_freq[j][0];
- filter->in_freq_imag[j] = filter->dft_freq[j][1];
+ filter->in_freq_real[j] = filter->dft_freq[j].r;
+ filter->in_freq_imag[j] = filter->dft_freq[j].i;
}
}
-void hcProcess1Stage(HConv1Stage *filter)
+void hcProcess1Stage(HConv1Stage1x1 *filter)
{
int s, n, start, stop, flen;
float *x_real;
@@ -91,17 +61,17 @@ void hcProcess1Stage(HConv1Stage *filter)
n = (s + filter->mixpos) % filter->num_mixbuf;
y_real = filter->mixbuf_freq_real[n];
y_imag = filter->mixbuf_freq_imag[n];
- h_real = filter->filterbuf_freq_real[s];
- h_imag = filter->filterbuf_freq_imag[s];
+ h_real = filter->filterbuf_freq_realChannel1[s];
+ h_imag = filter->filterbuf_freq_imagChannel1[s];
for (n = 0; n < flen + 1; n++)
{
- y_real[n] += x_real[n] * h_real[n] - x_imag[n] * h_imag[n];
- y_imag[n] += x_real[n] * h_imag[n] + x_imag[n] * h_real[n];
+ y_real[n] += (x_real[n] * h_real[n] - x_imag[n] * h_imag[n]);
+ y_imag[n] += (x_real[n] * h_imag[n] + x_imag[n] * h_real[n]);
}
}
filter->step = (filter->step + 1) % filter->maxstep;
}
-inline void hcGet1Stage(HConv1Stage *filter, float *y)
+inline void hcGet1Stage(HConv1Stage1x1 *filter, float *y)
{
int flen, mpos;
float *out;
@@ -113,24 +83,21 @@ inline void hcGet1Stage(HConv1Stage *filter, float *y)
hist = filter->history_time;
for (j = 0; j < flen + 1; j++)
{
- filter->dft_freq[j][0] = filter->mixbuf_freq_real[mpos][j];
- filter->dft_freq[j][1] = filter->mixbuf_freq_imag[mpos][j];
- filter->mixbuf_freq_real[mpos][j] = 0.0;
- filter->mixbuf_freq_imag[mpos][j] = 0.0;
+ filter->dft_freq[j].r = filter->mixbuf_freq_real[mpos][j];
+ filter->dft_freq[j].i = filter->mixbuf_freq_imag[mpos][j];
+ filter->mixbuf_freq_real[mpos][j] = 0.0f;
+ filter->mixbuf_freq_imag[mpos][j] = 0.0f;
}
- fftwf_execute(filter->ifft);
+ kiss_fftri(filter->ifft, filter->dft_freq, filter->dft_time);
for (n = 0; n < flen; n++)
- {
- y[n] = out[n] + hist[n];
- }
- size = sizeof(float) * flen;
+ y[n] = (out[n] + hist[n]) * filter->gain;
+ size = filter->memSize;
memcpy(hist, &(out[flen]), size);
filter->mixpos = (filter->mixpos + 1) % filter->num_mixbuf;
}
-void hcInit1Stage(HConv1Stage *filter, float *h, int hlen, int flen, int steps, int fftwThreads)
+void hcInit1Stage(HConv1Stage1x1 *filter, float *h, int hlen, int flen, int steps)
{
int i, j, size, num, pos;
- float gain;
// processing step counter
filter->step = 0;
// number of processing steps per audio frame
@@ -141,14 +108,14 @@ void hcInit1Stage(HConv1Stage *filter, float *h, int hlen, int flen, int steps,
filter->framelength = flen;
// DFT buffer (time domain)
size = sizeof(float) * 2 * flen;
- filter->dft_time = (float *)fftwf_malloc(size);
+ filter->dft_time = (float *)malloc(size);
// DFT buffer (frequency domain)
- size = sizeof(fftwf_complex) * (flen + 1);
- filter->dft_freq = (fftwf_complex*)fftwf_malloc(size);
+ size = sizeof(kiss_fft_cpx) * (flen + 1);
+ filter->dft_freq = (kiss_fft_cpx*)malloc(size);
// input buffer (frequency domain)
size = sizeof(float) * (flen + 1);
- filter->in_freq_real = (float*)fftwf_malloc(size);
- filter->in_freq_imag = (float*)fftwf_malloc(size);
+ filter->in_freq_real = (float*)malloc(size);
+ filter->in_freq_imag = (float*)malloc(size);
// number of filter segments
filter->num_filterbuf = (hlen + flen - 1) / flen;
// processing tasks per step
@@ -169,243 +136,174 @@ void hcInit1Stage(HConv1Stage *filter, float *h, int hlen, int flen, int steps,
}
// filter segments (frequency domain)
size = sizeof(float*) * filter->num_filterbuf;
- filter->filterbuf_freq_real = (float**)fftwf_malloc(size);
- filter->filterbuf_freq_imag = (float**)fftwf_malloc(size);
+ filter->filterbuf_freq_realChannel1 = (float**)malloc(size);
+ filter->filterbuf_freq_imagChannel1 = (float**)malloc(size);
+ size = sizeof(float) * (flen + 1);
for (i = 0; i < filter->num_filterbuf; i++)
{
- size = sizeof(float) * (flen + 1);
- filter->filterbuf_freq_real[i] = (float*)fftwf_malloc(size);
- filter->filterbuf_freq_imag[i] = (float*)fftwf_malloc(size);
+ filter->filterbuf_freq_realChannel1[i] = (float*)malloc(size);
+ filter->filterbuf_freq_imagChannel1[i] = (float*)malloc(size);
}
// number of mixing segments
filter->num_mixbuf = filter->num_filterbuf + 1;
// mixing segments (frequency domain)
size = sizeof(float*) * filter->num_mixbuf;
- filter->mixbuf_freq_real = (float**)fftwf_malloc(size);
- filter->mixbuf_freq_imag = (float**)fftwf_malloc(size);
+ filter->mixbuf_freq_real = (float**)malloc(size);
+ filter->mixbuf_freq_imag = (float**)malloc(size);
for (i = 0; i < filter->num_mixbuf; i++)
{
size = sizeof(float) * (flen + 1);
- filter->mixbuf_freq_real[i] = (float*)fftwf_malloc(size);
- filter->mixbuf_freq_imag[i] = (float*)fftwf_malloc(size);
+ filter->mixbuf_freq_real[i] = (float*)malloc(size);
+ filter->mixbuf_freq_imag[i] = (float*)malloc(size);
memset(filter->mixbuf_freq_real[i], 0, size);
memset(filter->mixbuf_freq_imag[i], 0, size);
}
// history buffer (time domain)
size = sizeof(float) * flen;
- filter->history_time = (float *)fftwf_malloc(size);
+ filter->history_time = (float *)malloc(size);
memset(filter->history_time, 0, size);
- if (fftwThreads)
- fftwf_plan_with_nthreads(fftwThreads);
// FFT transformation plan
- filter->fft = fftwf_plan_dft_r2c_1d(2 * flen, filter->dft_time, filter->dft_freq, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT);
+ filter->fft = kiss_fftr_alloc(2 * flen, 0, 0, 0);
// IFFT transformation plan
- filter->ifft = fftwf_plan_dft_c2r_1d(2 * flen, filter->dft_freq, filter->dft_time, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT);
+ filter->ifft = kiss_fftr_alloc(2 * flen, 1, 0, 0);
// generate filter segments
- gain = 0.5f / flen;
+ filter->normalizationGain = 0.5f / (float)flen;
+ filter->gain = filter->normalizationGain;
size = sizeof(float) * 2 * flen;
memset(filter->dft_time, 0, size);
for (i = 0; i < filter->num_filterbuf - 1; i++)
{
for (j = 0; j < flen; j++)
- filter->dft_time[j] = gain * h[i * flen + j];
- fftwf_execute(filter->fft);
+ filter->dft_time[j] = h[i * flen + j];
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
+ filter->filterbuf_freq_realChannel1[i][j] = filter->dft_freq[j].r;
+ filter->filterbuf_freq_imagChannel1[i][j] = filter->dft_freq[j].i;
}
}
for (j = 0; j < hlen - i * flen; j++)
- filter->dft_time[j] = gain * h[i * flen + j];
+ filter->dft_time[j] = h[i * flen + j];
size = sizeof(float) * ((i + 1) * flen - hlen);
memset(&(filter->dft_time[hlen - i * flen]), 0, size);
- fftwf_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
+ filter->filterbuf_freq_realChannel1[i][j] = filter->dft_freq[j].r;
+ filter->filterbuf_freq_imagChannel1[i][j] = filter->dft_freq[j].i;
}
+ filter->memSize = sizeof(float) * flen;
}
-void hcProcess2Stage(HConv2Stage *filter, float *in, float *out)
+int PartitionerAnalyser(int hlen, int latency, int strategy, int fs, int entriesResult, double **result_c0_c1, int *sflen_best, int *mflen_best, int *lflen_best)
{
- int lpos, size, i;
- // convolution with short segments
- hcPut1Stage(filter->f_short, in);
- hcProcess1Stage(filter->f_short);
- hcGet1Stage(filter->f_short, out);
- // add contribution from last long frame
- lpos = filter->step * filter->flen_short;
- for (i = 0; i < filter->flen_short; i++)
- out[i] += filter->out_long[lpos + i];
- // convolution with long segments
- if (filter->step == 0)
- hcPut1Stage(filter->f_long, filter->in_long);
- hcProcess1Stage(filter->f_long);
- if (filter->step == filter->maxstep - 1)
- hcGet1Stage(filter->f_long, filter->out_long);
- // add current frame to long input buffer
- lpos = filter->step * filter->flen_short;
- size = sizeof(float) * filter->flen_short;
- memcpy(&(filter->in_long[lpos]), in, size);
- // increase step counter
- filter->step = (filter->step + 1) % filter->maxstep;
-}
-void hcInit2Stage(HConv2Stage *filter, float *h, int hlen, int sflen, int lflen, int fftwThreads)
-{
- int size;
- float *h2 = NULL;
- int h2len;
- // sanity check: minimum impulse response length
- h2len = 2 * lflen + 1;
- if (hlen < h2len)
+ if (hlen < 0)
+ return 0;
+ else if (hlen < 32)
+ return 999;
+ int s, m, l, begin_m, end_m, type_best, num_s, num_m, num_l, sflen, mflen, lflen;
+ double cpu_load, tau_s, tau_m, tau_l;
+ double *c0 = result_c0_c1[0];
+ double *c1 = result_c0_c1[1];
+ if (latency < 128)
+ latency = 128;
+ s = (int)log2(latency) - 6;
+ if (!strategy)
{
- size = sizeof(float) * h2len;
- h2 = (float*)fftwf_malloc(size);
- memset(h2, 0, size);
- size = sizeof(float) * hlen;
- memcpy(h2, h, size);
- h = h2;
- hlen = h2len;
+ begin_m = 2;
+ end_m = 3;
}
- // processing step counter
- filter->step = 0;
- // number of processing steps per long audio frame
- filter->maxstep = lflen / sflen;
- // number of samples per long audio frame
- filter->flen_long = lflen;
- // number of samples per short audio frame
- filter->flen_short = sflen;
- // input buffer (long frame)
- size = sizeof(float) * lflen;
- filter->in_long = (float *)fftwf_malloc(size);
- memset(filter->in_long, 0, size);
- // output buffer (long frame)
- size = sizeof(float) * lflen;
- filter->out_long = (float *)fftwf_malloc(size);
- memset(filter->out_long, 0, size);
- // convolution filter (short segments)
- size = sizeof(HConv1Stage);
- filter->f_short = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_short, h, 2 * lflen, sflen, 1, fftwThreads);
- // convolution filter (long segments)
- size = sizeof(HConv1Stage);
- filter->f_long = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_long, &(h[2 * lflen]), hlen - 2 * lflen, lflen, lflen / sflen, fftwThreads);
- if (h2 != NULL)
- fftwf_free(h2);
-}
-void hcProcess3Stage(HConv3Stage *filter, float *in, float *out)
-{
- int lpos, size, i;
- // convolution with short segments
- hcPut1Stage(filter->f_short, in);
- hcProcess1Stage(filter->f_short);
- hcGet1Stage(filter->f_short, out);
- // add contribution from last medium frame
- lpos = filter->step * filter->flen_short;
- for (i = 0; i < filter->flen_short; i++)
- out[i] += filter->out_medium[lpos + i];
- // add current frame to medium input buffer
- lpos = filter->step * filter->flen_short;
- size = sizeof(float) * filter->flen_short;
- memcpy(&(filter->in_medium[lpos]), in, size);
- // convolution with medium segments
- if (filter->step == filter->maxstep - 1)
- hcProcess2Stage(filter->f_medium, filter->in_medium, filter->out_medium);
- // increase step counter
- filter->step = (filter->step + 1) % filter->maxstep;
-}
-void hcInit3Stage(HConv3Stage *filter, float *h, int hlen, int sflen, int mflen, int lflen, int fftwThreads)
-{
- int size;
- float *h2 = NULL;
- int h2len;
- // sanity check: minimum impulse response length
- h2len = mflen + 2 * lflen + 1;
- if (hlen < h2len)
+ else
{
- size = sizeof(float) * h2len;
- h2 = (float*)fftwf_malloc(size);
- memset(h2, 0, size);
- size = sizeof(float) * hlen;
- memcpy(h2, h, size);
- h = h2;
- hlen = h2len;
+ begin_m = 1;
+ end_m = entriesResult - s - 1;
}
- // processing step counter
- filter->step = 0;
- // number of processing steps per medium audio frame
- filter->maxstep = mflen / sflen;
- // number of samples per medium audio frame
- filter->flen_medium = mflen;
- // number of samples per short audio frame
- filter->flen_short = sflen;
- // input buffer (medium frame)
- size = sizeof(float) * mflen;
- filter->in_medium = (float *)fftwf_malloc(size);
- memset(filter->in_medium, 0, size);
- // output buffer (medium frame)
- size = sizeof(float) * mflen;
- filter->out_medium = (float *)fftwf_malloc(size);
- memset(filter->out_medium, 0, size);
- // convolution filter (short segments)
- size = sizeof(HConv1Stage);
- filter->f_short = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_short, h, mflen, sflen, 1, fftwThreads);
- // convolution filter (medium segments)
- size = sizeof(HConv2Stage);
- filter->f_medium = (HConv2Stage *)malloc(size);
- hcInit2Stage(filter->f_medium, &(h[mflen]), hlen - mflen, mflen, lflen, fftwThreads);
- if (h2 != NULL)
- fftwf_free(h2);
+ sflen = latency;
+ double cpu_load_best = 1e12;
+ // performance prediction with 3 segment lengths
+ for (m = begin_m; m < end_m; m++)
+ {
+ for (l = 1; l + m + s < entriesResult; l++)
+ {
+ mflen = sflen << m;
+ lflen = mflen << l;
+ num_s = mflen / sflen;
+ num_m = 2 * lflen / mflen;
+ num_l = (int)(ceil((hlen - num_s * sflen - num_m * mflen) / (double)lflen));
+ if (num_l < 1)
+ num_l = 1;
+ tau_s = c0[s] + c1[s] * num_s;
+ tau_m = c0[s + m] + c1[s + m] * num_m;
+ tau_l = c0[s + m + l] + c1[s + m + l] * num_l;
+ cpu_load = 400.0 * (tau_s * lflen / sflen + tau_m * lflen / mflen + tau_l) * fs / (double)lflen;
+ if (cpu_load < cpu_load_best)
+ {
+ cpu_load_best = cpu_load;
+ *sflen_best = sflen;
+ *mflen_best = mflen;
+ *lflen_best = lflen;
+ type_best = 3;
+ }
+ }
+ }
+ // performance prediction with 2 segment lengths
+ begin_m = 1;
+ end_m = entriesResult - s;
+ for (m = begin_m; m < end_m; m++)
+ {
+ mflen = sflen << m;
+ num_s = 2 * mflen / sflen;
+ num_m = (int)(ceil((hlen - num_s * sflen) / (double)mflen));
+ if (num_m < 1)
+ num_m = 1;
+ tau_s = c0[s] + c1[s] * num_s;
+ tau_m = c0[s + m] + c1[s + m] * num_m;
+ cpu_load = 400.0 * (tau_s * mflen / sflen + tau_m) * fs / (double)mflen;
+ if (cpu_load < cpu_load_best)
+ {
+ cpu_load_best = cpu_load;
+ *sflen_best = sflen;
+ *mflen_best = mflen;
+ type_best = 2;
+ }
+ }
+ // performance prediction with 1 segment length
+ num_s = (int)(ceil(hlen / (double)sflen));
+ tau_s = c0[s] + c1[s] * num_s;
+ cpu_load = 400.0 * tau_s * fs / (double)sflen;
+ if (cpu_load < cpu_load_best)
+ {
+ cpu_load_best = cpu_load;
+ *sflen_best = hlen;
+ type_best = 1;
+ }
+ return type_best;
}
-void hcClose1Stage(HConv1Stage *filter)
+void hcClose1Stage(HConv1Stage1x1 *filter)
{
int i;
- fftwf_destroy_plan(filter->ifft);
- fftwf_destroy_plan(filter->fft);
- fftwf_free(filter->history_time);
+ free(filter->ifft);
+ free(filter->fft);
+ free(filter->history_time);
for (i = 0; i < filter->num_mixbuf; i++)
{
- fftwf_free(filter->mixbuf_freq_real[i]);
- fftwf_free(filter->mixbuf_freq_imag[i]);
+ free(filter->mixbuf_freq_real[i]);
+ free(filter->mixbuf_freq_imag[i]);
}
- fftwf_free(filter->mixbuf_freq_real);
- fftwf_free(filter->mixbuf_freq_imag);
+ free(filter->mixbuf_freq_real);
+ free(filter->mixbuf_freq_imag);
for (i = 0; i < filter->num_filterbuf; i++)
{
- fftwf_free(filter->filterbuf_freq_real[i]);
- fftwf_free(filter->filterbuf_freq_imag[i]);
+ free(filter->filterbuf_freq_realChannel1[i]);
+ free(filter->filterbuf_freq_imagChannel1[i]);
}
- fftwf_free(filter->filterbuf_freq_real);
- fftwf_free(filter->filterbuf_freq_imag);
- fftwf_free(filter->in_freq_real);
- fftwf_free(filter->in_freq_imag);
- fftwf_free(filter->dft_freq);
- fftwf_free(filter->dft_time);
+ free(filter->filterbuf_freq_realChannel1);
+ free(filter->filterbuf_freq_imagChannel1);
+ free(filter->in_freq_real);
+ free(filter->in_freq_imag);
+ free(filter->dft_freq);
+ free(filter->dft_time);
free(filter->steptask);
- memset(filter, 0, sizeof(HConv1Stage));
-}
-void hcClose2Stage(HConv2Stage *filter)
-{
- hcClose1Stage(filter->f_short);
- free(filter->f_short);
- hcClose1Stage(filter->f_long);
- free(filter->f_long);
- fftwf_free(filter->out_long);
- fftwf_free(filter->in_long);
- memset(filter, 0, sizeof(HConv2Stage));
-}
-void hcClose3Stage(HConv3Stage *filter)
-{
- hcClose1Stage(filter->f_short);
- free(filter->f_short);
- hcClose2Stage(filter->f_medium);
- free(filter->f_medium);
- fftwf_free(filter->out_medium);
- fftwf_free(filter->in_medium);
- memset(filter, 0, sizeof(HConv3Stage));
+ memset(filter, 0, sizeof(HConv1Stage1x1));
}
#ifdef _WIN32
#include <Windows.h>
@@ -426,7 +324,7 @@ double hcTime(void)
#endif
double getProcTime(int flen, int num, double dur)
{
- HConv1Stage filter;
+ HConv1Stage1x1 filter;
float *x;
float *h;
float *y;
@@ -440,7 +338,7 @@ double getProcTime(int flen, int num, double dur)
xlen = 2048 * 2048;
size = sizeof(float) * xlen;
- x = (float *)fftwf_malloc(size);
+ x = (float *)malloc(size);
lin = pow(10.0, -100.0 / 20.0); // 0.00001 = -100dB
mul = pow(lin, 1.0 / (double)xlen);
x[0] = 1.0;
@@ -449,7 +347,7 @@ double getProcTime(int flen, int num, double dur)
hlen = flen * num;
size = sizeof(float) * hlen;
- h = (float *)fftwf_malloc(size);
+ h = (float *)malloc(size);
lin = pow(10.0, -60.0 / 20.0); // 0.001 = -60dB
mul = pow(lin, 1.0 / (double)hlen);
h[0] = 1.0;
@@ -458,9 +356,9 @@ double getProcTime(int flen, int num, double dur)
ylen = flen;
size = sizeof(float) * ylen;
- y = (float *)fftwf_malloc(size);
+ y = (float *)malloc(size);
- hcInit1Stage(&filter, h, hlen, flen, 1, 0);
+ hcInit1Stage(&filter, h, hlen, flen, 1);
t_diff = 0.0;
t_start = hcTime();
@@ -479,9 +377,9 @@ double getProcTime(int flen, int num, double dur)
proc_time = t_diff / counter;
printf("Processing time: %7.3f us\n", 1000000.0 * proc_time);
hcClose1Stage(&filter);
- fftwf_free(x);
- fftwf_free(h);
- fftwf_free(y);
+ free(x);
+ free(h);
+ free(y);
return proc_time;
}
double** PartitionHelperWisdomGetFromFile(const char *file, int *itemRet)
diff --git a/DSPManager_Free/jni/main/AutoConvolver.h b/DSPManager_Free/jni/main/AutoConvolver.h
index 35a9bfa..20cdc93 100644
--- a/DSPManager_Free/jni/main/AutoConvolver.h
+++ b/DSPManager_Free/jni/main/AutoConvolver.h
@@ -1,7 +1,5 @@
#ifndef __AUTOCONVOLVER_H__
#define __AUTOCONVOLVER_H__
-int ACFFTWThreadInit();
-void ACFFTWClean(int threads);
double** PartitionHelperWisdomGetFromFile(const char *file, int *itemRet);
char* PartitionHelper(int s_max, int fs);
double** PartitionHelperDirect(int s_max, int fs);
diff --git a/DSPManager_Free/jni/main/fftw3.h b/DSPManager_Free/jni/main/fftw3.h
deleted file mode 100644
index de69b4b..0000000
--- a/DSPManager_Free/jni/main/fftw3.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (c) 2003, 2007-14 Matteo Frigo
- * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
- *
- * The following statement of license applies *only* to this header file,
- * and *not* to the other files distributed with FFTW or derived therefrom:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/***************************** NOTE TO USERS *********************************
- *
- * THIS IS A HEADER FILE, NOT A MANUAL
- *
- * If you want to know how to use FFTW, please read the manual,
- * online at http://www.fftw.org/doc/ and also included with FFTW.
- * For a quick start, see the manual's tutorial section.
- *
- * (Reading header files to learn how to use a library is a habit
- * stemming from code lacking a proper manual. Arguably, it's a
- * *bad* habit in most cases, because header files can contain
- * interfaces that are not part of the public, stable API.)
- *
- ****************************************************************************/
-
-#ifndef FFTW3_H
-#define FFTW3_H
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/* If <complex.h> is included, use the C99 complex type. Otherwise
- define a type bit-compatible with C99 complex */
-#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
-# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
-#else
-# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
-#endif
-
-#define FFTW_CONCAT(prefix, name) prefix ## name
-#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
-#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
-#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
-#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name)
-
-/* IMPORTANT: for Windows compilers, you should add a line
- #define FFTW_DLL
- here and in kernel/ifftw.h if you are compiling/using FFTW as a
- DLL, in order to do the proper importing/exporting, or
- alternatively compile with -DFFTW_DLL or the equivalent
- command-line flag. This is not necessary under MinGW/Cygwin, where
- libtool does the imports/exports automatically. */
-#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
-/* annoying Windows syntax for shared-library declarations */
-# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
-# define FFTW_EXTERN extern __declspec(dllexport)
-# else /* user is calling FFTW; import symbol */
-# define FFTW_EXTERN extern __declspec(dllimport)
-# endif
-#else
-# define FFTW_EXTERN extern
-#endif
-
-enum fftw_r2r_kind_do_not_use_me
-{
- FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
- FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
- FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
-};
-
-struct fftw_iodim_do_not_use_me
-{
- int n; /* dimension size */
- int is; /* input stride */
- int os; /* output stride */
-};
-
-#include <stddef.h> /* for ptrdiff_t */
-struct fftw_iodim64_do_not_use_me
-{
- ptrdiff_t n; /* dimension size */
- ptrdiff_t is; /* input stride */
- ptrdiff_t os; /* output stride */
-};
-
-typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *);
-typedef int (*fftw_read_char_func_do_not_use_me)(void *);
-
-/*
- huge second-order macro that defines prototypes for all API
- functions. We expand this macro for each supported precision
-
- X: name-mangling macro
- R: real data type
- C: complex data type
-*/
-
-#define FFTW_DEFINE_API(X, R, C) \
- \
-FFTW_DEFINE_COMPLEX(R, C); \
- \
-typedef struct X(plan_s) *X(plan); \
- \
-typedef struct fftw_iodim_do_not_use_me X(iodim); \
-typedef struct fftw_iodim64_do_not_use_me X(iodim64); \
- \
-typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \
- \
-typedef fftw_write_char_func_do_not_use_me X(write_char_func); \
-typedef fftw_read_char_func_do_not_use_me X(read_char_func); \
- \
-FFTW_EXTERN void X(execute)(const X(plan) p); \
- \
-FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \
- C *in, C *out, int sign, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \
- C *in, C *out, int sign, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \
- C *in, C *out, int sign, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \
- int howmany, \
- C *in, const int *inembed, \
- int istride, int idist, \
- C *out, const int *onembed, \
- int ostride, int odist, \
- int sign, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- C *in, C *out, \
- int sign, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *ri, R *ii, R *ro, R *io, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \
- const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- C *in, C *out, \
- int sign, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \
- const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *ri, R *ii, R *ro, R *io, \
- unsigned flags); \
- \
-FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \
-FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \
- R *ro, R *io); \
- \
-FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \
- int howmany, \
- R *in, const int *inembed, \
- int istride, int idist, \
- C *out, const int *onembed, \
- int ostride, int odist, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \
- R *in, C *out, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \
- R *in, C *out, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \
- int n2, \
- R *in, C *out, unsigned flags); \
- \
- \
-FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \
- int howmany, \
- C *in, const int *inembed, \
- int istride, int idist, \
- R *out, const int *onembed, \
- int ostride, int odist, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \
- C *in, R *out, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \
- C *in, R *out, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \
- int n2, \
- C *in, R *out, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *in, C *out, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- C *in, R *out, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \
- int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *in, R *ro, R *io, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \
- int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *ri, R *ii, R *out, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \
- const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *in, C *out, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \
- const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- C *in, R *out, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \
- int rank, const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *in, R *ro, R *io, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \
- int rank, const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *ri, R *ii, R *out, \
- unsigned flags); \
- \
-FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \
-FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \
- \
-FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \
- R *in, R *ro, R *io); \
-FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \
- R *ri, R *ii, R *out); \
- \
-FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \
- int howmany, \
- R *in, const int *inembed, \
- int istride, int idist, \
- R *out, const int *onembed, \
- int ostride, int odist, \
- const X(r2r_kind) *kind, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \
- const X(r2r_kind) *kind, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \
- X(r2r_kind) kind, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \
- X(r2r_kind) kind0, X(r2r_kind) kind1, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \
- R *in, R *out, X(r2r_kind) kind0, \
- X(r2r_kind) kind1, X(r2r_kind) kind2, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *in, R *out, \
- const X(r2r_kind) *kind, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *in, R *out, \
- const X(r2r_kind) *kind, unsigned flags); \
- \
-FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \
- \
-FFTW_EXTERN void X(destroy_plan)(X(plan) p); \
-FFTW_EXTERN void X(forget_wisdom)(void); \
-FFTW_EXTERN void X(cleanup)(void); \
- \
-FFTW_EXTERN void X(set_timelimit)(double t); \
- \
-FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \
-FFTW_EXTERN int X(init_threads)(void); \
-FFTW_EXTERN void X(cleanup_threads)(void); \
-FFTW_EXTERN void X(make_planner_thread_safe)(void); \
- \
-FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \
-FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \
-FFTW_EXTERN char *X(export_wisdom_to_string)(void); \
-FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \
- void *data); \
-FFTW_EXTERN int X(import_system_wisdom)(void); \
-FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \
-FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \
-FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \
-FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \
- \
-FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \
-FFTW_EXTERN void X(print_plan)(const X(plan) p); \
-FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \
- \
-FFTW_EXTERN void *X(malloc)(size_t n); \
-FFTW_EXTERN R *X(alloc_real)(size_t n); \
-FFTW_EXTERN C *X(alloc_complex)(size_t n); \
-FFTW_EXTERN void X(free)(void *p); \
- \
-FFTW_EXTERN void X(flops)(const X(plan) p, \
- double *add, double *mul, double *fmas); \
-FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \
-FFTW_EXTERN double X(cost)(const X(plan) p); \
- \
-FFTW_EXTERN int X(alignment_of)(R *p); \
-FFTW_EXTERN const char X(version)[]; \
-FFTW_EXTERN const char X(cc)[]; \
-FFTW_EXTERN const char X(codelet_optim)[];
-
-
-/* end of FFTW_DEFINE_API macro */
-
-FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
-FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
-FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
-
-/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64
- for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \
- && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \
- && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__))
-# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
-/* note: __float128 is a typedef, which is not supported with the _Complex
- keyword in gcc, so instead we use this ugly __attribute__ version.
- However, we can't simply pass the __attribute__ version to
- FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer
- types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */
-# undef FFTW_DEFINE_COMPLEX
-# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C
-# endif
-FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex)
-#endif
-
-#define FFTW_FORWARD (-1)
-#define FFTW_BACKWARD (+1)
-
-#define FFTW_NO_TIMELIMIT (-1.0)
-
-/* documented flags */
-#define FFTW_MEASURE (0U)
-#define FFTW_DESTROY_INPUT (1U << 0)
-#define FFTW_UNALIGNED (1U << 1)
-#define FFTW_CONSERVE_MEMORY (1U << 2)
-#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
-#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
-#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
-#define FFTW_ESTIMATE (1U << 6)
-#define FFTW_WISDOM_ONLY (1U << 21)
-
-/* undocumented beyond-guru flags */
-#define FFTW_ESTIMATE_PATIENT (1U << 7)
-#define FFTW_BELIEVE_PCOST (1U << 8)
-#define FFTW_NO_DFT_R2HC (1U << 9)
-#define FFTW_NO_NONTHREADED (1U << 10)
-#define FFTW_NO_BUFFERING (1U << 11)
-#define FFTW_NO_INDIRECT_OP (1U << 12)
-#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
-#define FFTW_NO_RANK_SPLITS (1U << 14)
-#define FFTW_NO_VRANK_SPLITS (1U << 15)
-#define FFTW_NO_VRECURSE (1U << 16)
-#define FFTW_NO_SIMD (1U << 17)
-#define FFTW_NO_SLOW (1U << 18)
-#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
-#define FFTW_ALLOW_PRUNING (1U << 20)
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* FFTW3_H */
diff --git a/DSPManager_Free/jni/main/kissfft/_kiss_fft_guts.h b/DSPManager_Free/jni/main/kissfft/_kiss_fft_guts.h
new file mode 100644
index 0000000..6721eb7
--- /dev/null
+++ b/DSPManager_Free/jni/main/kissfft/_kiss_fft_guts.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+/* kiss_fft.h
+ defines kiss_fft_scalar as either short or a float type
+ and defines
+ typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
+#include "kiss_fft.h"
+#include <limits.h>
+
+#define MAXFACTORS 32
+/* e.g. an fft of length 128 has 4 factors
+ as far as kissfft is concerned
+ 4*4*4*2
+ */
+
+struct kiss_fft_state{
+ int nfft;
+ int inverse;
+ int factors[2*MAXFACTORS];
+ kiss_fft_cpx twiddles[1];
+};
+
+/*
+ Explanation of macros dealing with complex math:
+
+ C_MUL(m,a,b) : m = a*b
+ C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
+ C_SUB( res, a,b) : res = a - b
+ C_SUBFROM( res , a) : res -= a
+ C_ADDTO( res , a) : res += a
+ * */
+# define S_MUL(a,b) ( (a)*(b) )
+#define C_MUL(m,a,b) \
+ do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
+ (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
+# define C_FIXDIV(c,div) /* NOOP */
+# define C_MULBYSCALAR( c, s ) \
+ do{ (c).r *= (s);\
+ (c).i *= (s); }while(0)
+#ifndef CHECK_OVERFLOW_OP
+# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
+#endif
+
+#define C_ADD( res, a,b)\
+ do { \
+ CHECK_OVERFLOW_OP((a).r,+,(b).r)\
+ CHECK_OVERFLOW_OP((a).i,+,(b).i)\
+ (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
+ }while(0)
+#define C_SUB( res, a,b)\
+ do { \
+ CHECK_OVERFLOW_OP((a).r,-,(b).r)\
+ CHECK_OVERFLOW_OP((a).i,-,(b).i)\
+ (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
+ }while(0)
+#define C_ADDTO( res , a)\
+ do { \
+ CHECK_OVERFLOW_OP((res).r,+,(a).r)\
+ CHECK_OVERFLOW_OP((res).i,+,(a).i)\
+ (res).r += (a).r; (res).i += (a).i;\
+ }while(0)
+
+#define C_SUBFROM( res , a)\
+ do {\
+ CHECK_OVERFLOW_OP((res).r,-,(a).r)\
+ CHECK_OVERFLOW_OP((res).i,-,(a).i)\
+ (res).r -= (a).r; (res).i -= (a).i; \
+ }while(0)
+
+
+# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
+# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
+# define HALF_OF(x) ((x)*.5f)
+#define kf_cexp(x,phase) \
+ do{ \
+ (x)->r = KISS_FFT_COS(phase);\
+ (x)->i = KISS_FFT_SIN(phase);\
+ }while(0)
+
+
+/* a debugging function */
+#define pcpx(c)\
+ fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
+
+
+#ifdef KISS_FFT_USE_ALLOCA
+// define this to allow use of alloca instead of malloc for temporary buffers
+// Temporary buffers are used in two case:
+// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
+// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform.
+#include <alloca.h>
+#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
+#define KISS_FFT_TMP_FREE(ptr)
+#else
+#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
+#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
+#endif
diff --git a/DSPManager_Free/jni/main/kissfft/kiss_fft.c b/DSPManager_Free/jni/main/kissfft/kiss_fft.c
new file mode 100644
index 0000000..af2f695
--- /dev/null
+++ b/DSPManager_Free/jni/main/kissfft/kiss_fft.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+
+#include "_kiss_fft_guts.h"
+/* The guts header contains all the multiplication and addition macros that are defined for
+ fixed or floating point complex numbers. It also delares the kf_ internal functions.
+ */
+
+static void kf_bfly2(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ int m
+ )
+{
+ kiss_fft_cpx * Fout2;
+ kiss_fft_cpx * tw1 = st->twiddles;
+ kiss_fft_cpx t;
+ Fout2 = Fout + m;
+ do{
+ C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
+
+ C_MUL (t, *Fout2 , *tw1);
+ tw1 += fstride;
+ C_SUB( *Fout2 , *Fout , t );
+ C_ADDTO( *Fout , t );
+ ++Fout2;
+ ++Fout;
+ }while (--m);
+}
+
+static void kf_bfly4(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ const size_t m
+ )
+{
+ kiss_fft_cpx *tw1,*tw2,*tw3;
+ kiss_fft_cpx scratch[6];
+ size_t k=m;
+ const size_t m2=2*m;
+ const size_t m3=3*m;
+
+
+ tw3 = tw2 = tw1 = st->twiddles;
+
+ do {
+ C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
+
+ C_MUL(scratch[0],Fout[m] , *tw1 );
+ C_MUL(scratch[1],Fout[m2] , *tw2 );
+ C_MUL(scratch[2],Fout[m3] , *tw3 );
+
+ C_SUB( scratch[5] , *Fout, scratch[1] );
+ C_ADDTO(*Fout, scratch[1]);
+ C_ADD( scratch[3] , scratch[0] , scratch[2] );
+ C_SUB( scratch[4] , scratch[0] , scratch[2] );
+ C_SUB( Fout[m2], *Fout, scratch[3] );
+ tw1 += fstride;
+ tw2 += fstride*2;
+ tw3 += fstride*3;
+ C_ADDTO( *Fout , scratch[3] );
+
+ if(st->inverse) {
+ Fout[m].r = scratch[5].r - scratch[4].i;
+ Fout[m].i = scratch[5].i + scratch[4].r;
+ Fout[m3].r = scratch[5].r + scratch[4].i;
+ Fout[m3].i = scratch[5].i - scratch[4].r;
+ }else{
+ Fout[m].r = scratch[5].r + scratch[4].i;
+ Fout[m].i = scratch[5].i - scratch[4].r;
+ Fout[m3].r = scratch[5].r - scratch[4].i;
+ Fout[m3].i = scratch[5].i + scratch[4].r;
+ }
+ ++Fout;
+ }while(--k);
+}
+
+static void kf_bfly3(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ size_t m
+ )
+{
+ size_t k=m;
+ const size_t m2 = 2*m;
+ kiss_fft_cpx *tw1,*tw2;
+ kiss_fft_cpx scratch[5];
+ kiss_fft_cpx epi3;
+ epi3 = st->twiddles[fstride*m];
+
+ tw1=tw2=st->twiddles;
+
+ do{
+ C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
+
+ C_MUL(scratch[1],Fout[m] , *tw1);
+ C_MUL(scratch[2],Fout[m2] , *tw2);
+
+ C_ADD(scratch[3],scratch[1],scratch[2]);
+ C_SUB(scratch[0],scratch[1],scratch[2]);
+ tw1 += fstride;
+ tw2 += fstride*2;
+
+ Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
+ Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
+
+ C_MULBYSCALAR( scratch[0] , epi3.i );
+
+ C_ADDTO(*Fout,scratch[3]);
+
+ Fout[m2].r = Fout[m].r + scratch[0].i;
+ Fout[m2].i = Fout[m].i - scratch[0].r;
+
+ Fout[m].r -= scratch[0].i;
+ Fout[m].i += scratch[0].r;
+
+ ++Fout;
+ }while(--k);
+}
+
+static void kf_bfly5(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ int m
+ )
+{
+ kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
+ int u;
+ kiss_fft_cpx scratch[13];
+ kiss_fft_cpx * twiddles = st->twiddles;
+ kiss_fft_cpx *tw;
+ kiss_fft_cpx ya,yb;
+ ya = twiddles[fstride*m];
+ yb = twiddles[fstride*2*m];
+
+ Fout0=Fout;
+ Fout1=Fout0+m;
+ Fout2=Fout0+2*m;
+ Fout3=Fout0+3*m;
+ Fout4=Fout0+4*m;
+
+ tw=st->twiddles;
+ for ( u=0; u<m; ++u ) {
+ C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
+ scratch[0] = *Fout0;
+
+ C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
+ C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
+ C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
+ C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
+
+ C_ADD( scratch[7],scratch[1],scratch[4]);
+ C_SUB( scratch[10],scratch[1],scratch[4]);
+ C_ADD( scratch[8],scratch[2],scratch[3]);
+ C_SUB( scratch[9],scratch[2],scratch[3]);
+
+ Fout0->r += scratch[7].r + scratch[8].r;
+ Fout0->i += scratch[7].i + scratch[8].i;
+
+ scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
+ scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
+
+ scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
+ scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
+
+ C_SUB(*Fout1,scratch[5],scratch[6]);
+ C_ADD(*Fout4,scratch[5],scratch[6]);
+
+ scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
+ scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
+ scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
+ scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
+
+ C_ADD(*Fout2,scratch[11],scratch[12]);
+ C_SUB(*Fout3,scratch[11],scratch[12]);
+
+ ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
+ }
+}
+
+/* perform the butterfly for one stage of a mixed radix FFT */
+static void kf_bfly_generic(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ int m,
+ int p
+ )
+{
+ int u,k,q1,q;
+ kiss_fft_cpx * twiddles = st->twiddles;
+ kiss_fft_cpx t;
+ int Norig = st->nfft;
+
+ kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p);
+
+ for ( u=0; u<m; ++u ) {
+ k=u;
+ for ( q1=0 ; q1<p ; ++q1 ) {
+ scratch[q1] = Fout[ k ];
+ C_FIXDIV(scratch[q1],p);
+ k += m;
+ }
+
+ k=u;
+ for ( q1=0 ; q1<p ; ++q1 ) {
+ int twidx=0;
+ Fout[ k ] = scratch[0];
+ for (q=1;q<p;++q ) {
+ twidx += fstride * k;
+ if (twidx>=Norig) twidx-=Norig;
+ C_MUL(t,scratch[q] , twiddles[twidx] );
+ C_ADDTO( Fout[ k ] ,t);
+ }
+ k += m;
+ }
+ }
+ KISS_FFT_TMP_FREE(scratch);
+}
+
+static
+void kf_work(
+ kiss_fft_cpx * Fout,
+ const kiss_fft_cpx * f,
+ const size_t fstride,
+ int in_stride,
+ int * factors,
+ const kiss_fft_cfg st
+ )
+{
+ kiss_fft_cpx * Fout_beg=Fout;
+ const int p=*factors++; /* the radix */
+ const int m=*factors++; /* stage's fft length/p */
+ const kiss_fft_cpx * Fout_end = Fout + p*m;
+
+#ifdef _OPENMP
+ // use openmp extensions at the
+ // top-level (not recursive)
+ if (fstride==1 && p<=5)
+ {
+ int k;
+
+ // execute the p different work units in different threads
+# pragma omp parallel for
+ for (k=0;k<p;++k)
+ kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
+ // all threads have joined by this point
+
+ switch (p) {
+ case 2: kf_bfly2(Fout,fstride,st,m); break;
+ case 3: kf_bfly3(Fout,fstride,st,m); break;
+ case 4: kf_bfly4(Fout,fstride,st,m); break;
+ case 5: kf_bfly5(Fout,fstride,st,m); break;
+ default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+ }
+ return;
+ }
+#endif
+
+ if (m==1) {
+ do{
+ *Fout = *f;
+ f += fstride*in_stride;
+ }while(++Fout != Fout_end );
+ }else{
+ do{
+ // recursive call:
+ // DFT of size m*p performed by doing
+ // p instances of smaller DFTs of size m,
+ // each one takes a decimated version of the input
+ kf_work( Fout , f, fstride*p, in_stride, factors,st);
+ f += fstride*in_stride;
+ }while( (Fout += m) != Fout_end );
+ }
+
+ Fout=Fout_beg;
+
+ // recombine the p smaller DFTs
+ switch (p) {
+ case 2: kf_bfly2(Fout,fstride,st,m); break;
+ case 3: kf_bfly3(Fout,fstride,st,m); break;
+ case 4: kf_bfly4(Fout,fstride,st,m); break;
+ case 5: kf_bfly5(Fout,fstride,st,m); break;
+ default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+ }
+}
+
+/* facbuf is populated by p1,m1,p2,m2, ...
+ where
+ p[i] * m[i] = m[i-1]
+ m0 = n */
+static
+void kf_factor(int n,int * facbuf)
+{
+ int p=4;
+ double floor_sqrt;
+ floor_sqrt = floor( sqrt((double)n) );
+
+ /*factor out powers of 4, powers of 2, then any remaining primes */
+ do {
+ while (n % p) {
+ switch (p) {
+ case 4: p = 2; break;
+ case 2: p = 3; break;
+ default: p += 2; break;
+ }
+ if (p > floor_sqrt)
+ p = n; /* no more factors, skip to end */
+ }
+ n /= p;
+ *facbuf++ = p;
+ *facbuf++ = n;
+ } while (n > 1);
+}
+
+/*
+ *
+ * User-callable function to allocate all necessary storage space for the fft.
+ *
+ * The return value is a contiguous block of memory, allocated with malloc. As such,
+ * It can be freed with free(), rather than a kiss_fft-specific function.
+ * */
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
+{
+ kiss_fft_cfg st=NULL;
+ size_t memneeded = sizeof(struct kiss_fft_state)
+ + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
+
+ if ( lenmem==NULL ) {
+ st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
+ }else{
+ if (mem != NULL && *lenmem >= memneeded)
+ st = (kiss_fft_cfg)mem;
+ *lenmem = memneeded;
+ }
+ if (st) {
+ int i;
+ st->nfft=nfft;
+ st->inverse = inverse_fft;
+
+ for (i=0;i<nfft;++i) {
+ const double pi=3.141592653589793238462643383279502884197169399375105820974944;
+ double phase = -2*pi*i / nfft;
+ if (st->inverse)
+ phase *= -1;
+ kf_cexp(st->twiddles+i, phase );
+ }
+
+ kf_factor(nfft,st->factors);
+ }
+ return st;
+}
+
+
+void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
+{
+ if (fin == fout) {
+ //NOTE: this is not really an in-place FFT algorithm.
+ //It just performs an out-of-place FFT into a temp buffer
+ kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
+ kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
+ memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
+ KISS_FFT_TMP_FREE(tmpbuf);
+ }else{
+ kf_work( fout, fin, 1,in_stride, st->factors,st );
+ }
+}
+
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
+{
+ kiss_fft_stride(cfg,fin,fout,1);
+}
+
+
+void kiss_fft_cleanup(void)
+{
+ // nothing needed any more
+}
+
+int kiss_fft_next_fast_size(int n)
+{
+ while(1) {
+ int m=n;
+ while ( (m%2) == 0 ) m/=2;
+ while ( (m%3) == 0 ) m/=3;
+ while ( (m%5) == 0 ) m/=5;
+ if (m<=1)
+ break; /* n is completely factorable by twos, threes, and fives */
+ n++;
+ }
+ return n;
+}
diff --git a/DSPManager_Free/jni/main/kissfft/kiss_fft.h b/DSPManager_Free/jni/main/kissfft/kiss_fft.h
new file mode 100644
index 0000000..9a98223
--- /dev/null
+++ b/DSPManager_Free/jni/main/kissfft/kiss_fft.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#ifndef KISS_FFT_H
+#define KISS_FFT_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ ATTENTION!
+ If you would like a :
+ -- a utility that will handle the caching of fft objects
+ -- real-only (no imaginary time component ) FFT
+ -- a multi-dimensional FFT
+ -- a command-line utility to perform ffts
+ -- a command-line utility to perform fast-convolution filtering
+
+ Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
+ in the tools/ directory.
+*/
+
+#ifdef USE_SIMD
+# include <xmmintrin.h>
+# define kiss_fft_scalar __m128
+#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
+#define KISS_FFT_FREE _mm_free
+#else
+#define KISS_FFT_MALLOC malloc
+#define KISS_FFT_FREE free
+#endif
+# ifndef kiss_fft_scalar
+/* default is float */
+# define kiss_fft_scalar float
+# endif
+
+typedef struct {
+ kiss_fft_scalar r;
+ kiss_fft_scalar i;
+}kiss_fft_cpx;
+
+typedef struct kiss_fft_state* kiss_fft_cfg;
+
+/*
+ * kiss_fft_alloc
+ *
+ * Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
+ *
+ * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
+ *
+ * The return value from fft_alloc is a cfg buffer used internally
+ * by the fft routine or NULL.
+ *
+ * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
+ * The returned value should be free()d when done to avoid memory leaks.
+ *
+ * The state can be placed in a user supplied buffer 'mem':
+ * If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
+ * then the function places the cfg in mem and the size used in *lenmem
+ * and returns mem.
+ *
+ * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
+ * then the function returns NULL and places the minimum cfg
+ * buffer size in *lenmem.
+ * */
+
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
+
+/*
+ * kiss_fft(cfg,in_out_buf)
+ *
+ * Perform an FFT on a complex input buffer.
+ * for a forward FFT,
+ * fin should be f[0] , f[1] , ... ,f[nfft-1]
+ * fout will be F[0] , F[1] , ... ,F[nfft-1]
+ * Note that each element is complex and can be accessed like
+ f[k].r and f[k].i
+ * */
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
+
+/*
+ A more generic version of the above function. It reads its input from every Nth sample.
+ * */
+void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
+
+/* If kiss_fft_alloc allocated a buffer, it is one contiguous
+ buffer and can be simply free()d when no longer needed*/
+#define kiss_fft_free KISS_FFT_FREE
+
+/*
+ Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
+ your compiler output to call this before you exit.
+*/
+void kiss_fft_cleanup(void);
+
+
+/*
+ * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
+ */
+int kiss_fft_next_fast_size(int n);
+
+/* for real ffts, we need an even size */
+#define kiss_fftr_next_fast_size_real(n) \
+ (kiss_fft_next_fast_size( ((n)+1)>>1)<<1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/DSPManager_Free/jni/main/kissfft/kiss_fftr.c b/DSPManager_Free/jni/main/kissfft/kiss_fftr.c
new file mode 100644
index 0000000..8102132
--- /dev/null
+++ b/DSPManager_Free/jni/main/kissfft/kiss_fftr.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#include "kiss_fftr.h"
+#include "_kiss_fft_guts.h"
+
+struct kiss_fftr_state{
+ kiss_fft_cfg substate;
+ kiss_fft_cpx * tmpbuf;
+ kiss_fft_cpx * super_twiddles;
+#ifdef USE_SIMD
+ void * pad;
+#endif
+};
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
+{
+ int i;
+ kiss_fftr_cfg st = NULL;
+ size_t subsize = 0, memneeded;
+
+ if (nfft & 1) {
+ fprintf(stderr,"Real FFT optimization must be even.\n");
+ return NULL;
+ }
+ nfft >>= 1;
+
+ kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
+ memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2);
+
+ if (lenmem == NULL) {
+ st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
+ } else {
+ if (*lenmem >= memneeded)
+ st = (kiss_fftr_cfg) mem;
+ *lenmem = memneeded;
+ }
+ if (!st)
+ return NULL;
+
+ st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
+ st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
+ st->super_twiddles = st->tmpbuf + nfft;
+ kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
+
+ for (i = 0; i < nfft/2; ++i) {
+ double phase =
+ -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5);
+ if (inverse_fft)
+ phase *= -1;
+ kf_cexp (st->super_twiddles+i,phase);
+ }
+ return st;
+}
+
+void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
+{
+ /* input buffer timedata is stored row-wise */
+ int k,ncfft;
+ kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
+
+ if ( st->substate->inverse) {
+ fprintf(stderr,"kiss fft usage error: improper alloc\n");
+ exit(1);
+ }
+
+ ncfft = st->substate->nfft;
+
+ /*perform the parallel fft of two real signals packed in real,imag*/
+ kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
+ /* The real part of the DC element of the frequency spectrum in st->tmpbuf
+ * contains the sum of the even-numbered elements of the input time sequence
+ * The imag part is the sum of the odd-numbered elements
+ *
+ * The sum of tdc.r and tdc.i is the sum of the input time sequence.
+ * yielding DC of input time sequence
+ * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
+ * yielding Nyquist bin of input time sequence
+ */
+
+ tdc.r = st->tmpbuf[0].r;
+ tdc.i = st->tmpbuf[0].i;
+ C_FIXDIV(tdc,2);
+ CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
+ CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
+ freqdata[0].r = tdc.r + tdc.i;
+ freqdata[ncfft].r = tdc.r - tdc.i;
+#ifdef USE_SIMD
+ freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
+#else
+ freqdata[ncfft].i = freqdata[0].i = 0;
+#endif
+
+ for ( k=1;k <= ncfft/2 ; ++k ) {
+ fpk = st->tmpbuf[k];
+ fpnk.r = st->tmpbuf[ncfft-k].r;
+ fpnk.i = - st->tmpbuf[ncfft-k].i;
+ C_FIXDIV(fpk,2);
+ C_FIXDIV(fpnk,2);
+
+ C_ADD( f1k, fpk , fpnk );
+ C_SUB( f2k, fpk , fpnk );
+ C_MUL( tw , f2k , st->super_twiddles[k-1]);
+
+ freqdata[k].r = HALF_OF(f1k.r + tw.r);
+ freqdata[k].i = HALF_OF(f1k.i + tw.i);
+ freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);
+ freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);
+ }
+}
+
+void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
+{
+ /* input buffer timedata is stored row-wise */
+ int k, ncfft;
+
+ if (st->substate->inverse == 0) {
+ fprintf (stderr, "kiss fft usage error: improper alloc\n");
+ exit (1);
+ }
+
+ ncfft = st->substate->nfft;
+
+ st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
+ st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
+ C_FIXDIV(st->tmpbuf[0],2);
+
+ for (k = 1; k <= ncfft / 2; ++k) {
+ kiss_fft_cpx fk, fnkc, fek, fok, tmp;
+ fk = freqdata[k];
+ fnkc.r = freqdata[ncfft - k].r;
+ fnkc.i = -freqdata[ncfft - k].i;
+ C_FIXDIV( fk , 2 );
+ C_FIXDIV( fnkc , 2 );
+
+ C_ADD (fek, fk, fnkc);
+ C_SUB (tmp, fk, fnkc);
+ C_MUL (fok, tmp, st->super_twiddles[k-1]);
+ C_ADD (st->tmpbuf[k], fek, fok);
+ C_SUB (st->tmpbuf[ncfft - k], fek, fok);
+#ifdef USE_SIMD
+ st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
+#else
+ st->tmpbuf[ncfft - k].i *= -1;
+#endif
+ }
+ kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
+}
diff --git a/DSPManager_Free/jni/main/kissfft/kiss_fftr.h b/DSPManager_Free/jni/main/kissfft/kiss_fftr.h
new file mode 100644
index 0000000..588948d
--- /dev/null
+++ b/DSPManager_Free/jni/main/kissfft/kiss_fftr.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#ifndef KISS_FTR_H
+#define KISS_FTR_H
+
+#include "kiss_fft.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+
+ Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
+
+
+
+ */
+
+typedef struct kiss_fftr_state *kiss_fftr_cfg;
+
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
+/*
+ nfft must be even
+
+ If you don't care to allocate space, use mem = lenmem = NULL
+*/
+
+
+void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
+/*
+ input timedata has nfft scalar points
+ output freqdata has nfft/2+1 complex points
+*/
+
+void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
+/*
+ input freqdata has nfft/2+1 complex points
+ output timedata has nfft scalar points
+*/
+
+#define kiss_fftr_free KISS_FFT_FREE
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/DSPManager_Free/res/values-zh-rTW/arrays.xml b/DSPManager_Free/res/values-zh-rTW/arrays.xml
index 012b44e..0752c1d 100644
--- a/DSPManager_Free/res/values-zh-rTW/arrays.xml
+++ b/DSPManager_Free/res/values-zh-rTW/arrays.xml
@@ -53,4 +53,24 @@
<item>更弱</item>
<item>弱</item>
</string-array>
+ <string-array name="pamss_wrap">
+ <item>30度</item>
+ <item>50度</item>
+ <item>70度</item>
+ <item>90度</item>
+ <item>100度</item>
+ <item>120度</item>
+ <item>140度</item>
+ <item>160度</item>
+ <item>180度</item>
+ <item>200度</item>
+ <item>220度</item>
+ <item>240度</item>
+ <item>260度</item>
+ <item>280度</item>
+ <item>300度</item>
+ <item>320度</item>
+ <item>340度</item>
+ <item>360度</item>
+ </string-array>
</resources> \ No newline at end of file
diff --git a/DSPManager_Free/res/values-zh-rTW/strings.xml b/DSPManager_Free/res/values-zh-rTW/strings.xml
index 265ea22..a9a25dd 100644
--- a/DSPManager_Free/res/values-zh-rTW/strings.xml
+++ b/DSPManager_Free/res/values-zh-rTW/strings.xml
@@ -117,6 +117,7 @@
<string name="pref_headset_pamss_summary_on">已啟用TruCentre環繞</string>
<string name="pref_headset_pamss_summary_off">已停用TruCentre環繞</string>
<string name="pref_headset_pamss_enable">使用TruCentre環繞</string>
+ <string name="dialog_pamss_wrap">揚聲器包圍角度</string>
<string name="eq_preset_flat">平淡</string>
<string name="eq_preset_custom">自訂</string>
diff --git a/DSPManager_Free/res/values/arrays.xml b/DSPManager_Free/res/values/arrays.xml
index 237996c..319af5c 100644
--- a/DSPManager_Free/res/values/arrays.xml
+++ b/DSPManager_Free/res/values/arrays.xml
@@ -142,4 +142,38 @@
<item>1</item>
<item>2</item>
</string-array>
+
+ <string-array name="pamss_wrap">
+ <item>30 Degree</item>
+ <item>50 Degree</item>
+ <item>70 Degree</item>
+ <item>90 Degree</item>
+ <item>100 Degree</item>
+ <item>120 Degree</item>
+ <item>140 Degree</item>
+ <item>160 Degree</item>
+ <item>180 Degree</item>
+ <item>200 Degree</item>
+ <item>220 Degree</item>
+ <item>240 Degree</item>
+ <item>260 Degree</item>
+ <item>270 Degree</item>
+ </string-array>
+
+ <string-array name="pamss_wrap_values" translatable="false">
+ <item>30</item>
+ <item>50</item>
+ <item>70</item>
+ <item>90</item>
+ <item>100</item>
+ <item>120</item>
+ <item>140</item>
+ <item>160</item>
+ <item>180</item>
+ <item>200</item>
+ <item>220</item>
+ <item>240</item>
+ <item>260</item>
+ <item>270</item>
+ </string-array>
</resources> \ No newline at end of file
diff --git a/DSPManager_Free/res/values/strings.xml b/DSPManager_Free/res/values/strings.xml
index 0e3a986..a8a02e9 100644
--- a/DSPManager_Free/res/values/strings.xml
+++ b/DSPManager_Free/res/values/strings.xml
@@ -113,6 +113,7 @@
<string name="pref_headset_pamss_summary_on">TruCentre is enabled</string>
<string name="pref_headset_pamss_summary_off">TruCentre is disabled</string>
<string name="pref_headset_pamss_enable">Enable TruCentre Surround</string>
+ <string name="dialog_pamss_wrap">Speaker wrap angle</string>
<string name="eq_preset_flat">Flat</string>
<string name="eq_preset_custom">Custom</string>
diff --git a/DSPManager_Free/res/xml/bluetooth_preferences.xml b/DSPManager_Free/res/xml/bluetooth_preferences.xml
index 3ebb2b8..10532b1 100644
--- a/DSPManager_Free/res/xml/bluetooth_preferences.xml
+++ b/DSPManager_Free/res/xml/bluetooth_preferences.xml
@@ -271,5 +271,12 @@
android:summaryOn="@string/pref_headset_pamss_summary_on"
android:summaryOff="@string/pref_headset_pamss_summary_off"
android:title="@string/pref_headset_pamss_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreference
+ android:defaultValue="90"
+ android:dialogTitle="@string/dialog_pamss_wrap"
+ android:entries="@array/pamss_wrap"
+ android:entryValues="@array/pamss_wrap_values"
+ android:title="@string/dialog_pamss_wrap"
+ android:key="dsp.pamss.wrap" />
</PreferenceCategory>
</PreferenceScreen> \ No newline at end of file
diff --git a/DSPManager_Free/res/xml/headset_preferences.xml b/DSPManager_Free/res/xml/headset_preferences.xml
index 3ebb2b8..10532b1 100644
--- a/DSPManager_Free/res/xml/headset_preferences.xml
+++ b/DSPManager_Free/res/xml/headset_preferences.xml
@@ -271,5 +271,12 @@
android:summaryOn="@string/pref_headset_pamss_summary_on"
android:summaryOff="@string/pref_headset_pamss_summary_off"
android:title="@string/pref_headset_pamss_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreference
+ android:defaultValue="90"
+ android:dialogTitle="@string/dialog_pamss_wrap"
+ android:entries="@array/pamss_wrap"
+ android:entryValues="@array/pamss_wrap_values"
+ android:title="@string/dialog_pamss_wrap"
+ android:key="dsp.pamss.wrap" />
</PreferenceCategory>
</PreferenceScreen> \ No newline at end of file
diff --git a/DSPManager_Free/res/xml/speaker_preferences.xml b/DSPManager_Free/res/xml/speaker_preferences.xml
index 85a2d01..10532b1 100644
--- a/DSPManager_Free/res/xml/speaker_preferences.xml
+++ b/DSPManager_Free/res/xml/speaker_preferences.xml
@@ -160,21 +160,6 @@
android:inputType="textMultiLine" />
</PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_headset_virtual_title">
- <CheckBoxPreference
- android:key="dsp.headphone.enable"
- android:disableDependentsState="false"
- android:summaryOn="@string/pref_headset_virtual_summary_on"
- android:summaryOff="@string/pref_headset_virtual_summary_off"
- android:title="@string/pref_headset_virtual_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedListPreference
- android:defaultValue="0"
- android:dialogTitle="@string/dialog_room"
- android:entries="@array/headphone_preset"
- android:entryValues="@array/headphone_preset_values"
- android:title="@string/pref_room_title"
- android:key="dsp.headphone.preset" />
- </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_convolver_title"
android:key="dsp.convolver">
<CheckBoxPreference
@@ -207,6 +192,19 @@
android:title="@string/dialog_quality"
android:key="dsp.convolver.quality" />
</PreferenceCategory>
+ <PreferenceCategory android:title="@string/pref_ddc_title" android:key="dsp.ddc">
+ <CheckBoxPreference
+ android:key="dsp.ddc.enable"
+ android:disableDependentsState="false"
+ android:summaryOn="@string/pref_ddc_summary_on"
+ android:summaryOff="@string/pref_ddc_summary_off"
+ android:title="@string/pref_ddc_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreferenceDDC
+ android:title="@string/dialog_sosmatrix"
+ android:key="dsp.ddc.files"
+ android:defaultValue=""
+ android:dialogTitle="@string/dialog_sosmatrix" />
+ </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_analogmodelling_title"
android:key="dsp.analogmodelling">
<CheckBoxPreference
@@ -223,4 +221,62 @@
android:inputType="numberDecimal"
android:digits="0123456789." />
</PreferenceCategory>
+ <PreferenceCategory android:title="@string/pref_headset_soundpos_title">
+ <CheckBoxPreference
+ android:key="dsp.stereowide.enable"
+ android:disableDependentsState="false"
+ android:summaryOn="@string/pref_headset_stereowide_summary_on"
+ android:summaryOff="@string/pref_headset_stereowide_summary_off"
+ android:title="@string/pref_headset_stereowide_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreference
+ android:defaultValue="0"
+ android:dialogTitle="@string/dialog_stereo"
+ android:entries="@array/stereowide_modes"
+ android:entryValues="@array/stereowide_values"
+ android:title="@string/dialog_stereo"
+ android:key="dsp.stereowide.mode" />
+ <CheckBoxPreference
+ android:key="dsp.bs2b.enable"
+ android:disableDependentsState="false"
+ android:summaryOn="@string/pref_headset_bs2b_summary_on"
+ android:summaryOff="@string/pref_headset_bs2b_summary_off"
+ android:title="@string/pref_headset_bs2b_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreference
+ android:defaultValue="0"
+ android:dialogTitle="@string/dialog_bs2b"
+ android:entries="@array/bs2b_modes"
+ android:entryValues="@array/bs2b_values"
+ android:title="@string/dialog_bs2b"
+ android:key="dsp.bs2b.mode" />
+ </PreferenceCategory>
+ <PreferenceCategory android:title="@string/pref_headset_virtual_title">
+ <CheckBoxPreference
+ android:key="dsp.headphone.enable"
+ android:disableDependentsState="false"
+ android:summaryOn="@string/pref_headset_virtual_summary_on"
+ android:summaryOff="@string/pref_headset_virtual_summary_off"
+ android:title="@string/pref_headset_virtual_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreference
+ android:defaultValue="15"
+ android:dialogTitle="@string/dialog_room"
+ android:entries="@array/headphone_preset"
+ android:entryValues="@array/headphone_preset_values"
+ android:title="@string/pref_room_title"
+ android:key="dsp.headphone.preset" />
+ </PreferenceCategory>
+ <PreferenceCategory android:title="@string/pref_headset_pams_title">
+ <CheckBoxPreference
+ android:key="dsp.pamss.enable"
+ android:disableDependentsState="false"
+ android:summaryOn="@string/pref_headset_pamss_summary_on"
+ android:summaryOff="@string/pref_headset_pamss_summary_off"
+ android:title="@string/pref_headset_pamss_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreference
+ android:defaultValue="90"
+ android:dialogTitle="@string/dialog_pamss_wrap"
+ android:entries="@array/pamss_wrap"
+ android:entryValues="@array/pamss_wrap_values"
+ android:title="@string/dialog_pamss_wrap"
+ android:key="dsp.pamss.wrap" />
+ </PreferenceCategory>
</PreferenceScreen> \ No newline at end of file
diff --git a/DSPManager_Free/src/james/dsp/service/HeadsetService.java b/DSPManager_Free/src/james/dsp/service/HeadsetService.java
index d3c8fc6..82df5e2 100644
--- a/DSPManager_Free/src/james/dsp/service/HeadsetService.java
+++ b/DSPManager_Free/src/james/dsp/service/HeadsetService.java
@@ -788,6 +788,11 @@ class StartUpOptimiserThread implements Runnable {
session.setParameterShort(session.JamesDSP, 150, (short) (Float.valueOf(preferences.getString("dsp.analogmodelling.tubedrive", "2"))*1000));
session.setParameterShort(session.JamesDSP, 1206, (short)analogModelEnabled); // Analog modelling switch
session.setParameterShort(session.JamesDSP, 1207, (short)pamssEnabled); // Virtual surround switch
+ if (pamssEnabled == 1 && updateMajor)
+ {
+ float circularWrap = Float.valueOf(preferences.getString("dsp.pamss.wrap", "90"));
+ session.setParameterFloatArray(session.JamesDSP, 1501, new float[]{ 0.0f, circularWrap, 0.0f, 0.0f, 0.0f });
+ }
if (viperddcEnabled == 1 && updateMajor)
{
String ddcFilePath = preferences.getString("dsp.ddc.files", "");
diff --git a/DSPManager_Free_BitPerfect/jni/main/Android.mk b/DSPManager_Free_BitPerfect/jni/main/Android.mk
index 1ab7843..b0792cf 100644
--- a/DSPManager_Free_BitPerfect/jni/main/Android.mk
+++ b/DSPManager_Free_BitPerfect/jni/main/Android.mk
@@ -1,28 +1,8 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE := fftw3
-ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
-LOCAL_SRC_FILES := fftw/DoubleARM/libfftw3.a
-else ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
-LOCAL_SRC_FILES := fftw/DoubleARM64/libfftw3.a
-else ifeq ($(TARGET_ARCH_ABI), x86)
-LOCAL_SRC_FILES := fftw/Doublex86/libfftw3.a
-endif
-include $(PREBUILT_STATIC_LIBRARY)
-include $(CLEAR_VARS)
-LOCAL_MODULE := fftw3thread
-ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
-LOCAL_SRC_FILES := fftw/DoubleARM/libfftw3_threads.a
-else ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
-LOCAL_SRC_FILES := fftw/DoubleARM64/libfftw3_threads.a
-else ifeq ($(TARGET_ARCH_ABI), x86)
-LOCAL_SRC_FILES := fftw/Doublex86/libfftw3_threads.a
-endif
-include $(PREBUILT_STATIC_LIBRARY)
-include $(CLEAR_VARS)
LOCAL_MODULE := jamesDSPImpulseToolbox
-LOCAL_SRC_FILES := JdspImpResToolbox.c AutoConvolver.c
-LOCAL_STATIC_LIBRARIES = libsndfile libsamplerate fftw3thread fftw3
+LOCAL_SRC_FILES := kissfft\kiss_fft.c kissfft\kiss_fftr.c JdspImpResToolbox.c AutoConvolver.c
+LOCAL_STATIC_LIBRARIES = libsndfile libsamplerate
LOCAL_CPPFLAGS += -ffunction-sections -fdata-sections -Ofast -ftree-vectorize -DNDEBUG
LOCAL_CFLAGS += -ffunction-sections -fdata-sections -Ofast -ftree-vectorize -DNDEBUG
LOCAL_LDFLAGS += -Wl,--gc-sections,--exclude-libs,ALL
diff --git a/DSPManager_Free_BitPerfect/jni/main/AutoConvolver.c b/DSPManager_Free_BitPerfect/jni/main/AutoConvolver.c
index 60e3d2c..450bdb6 100644
--- a/DSPManager_Free_BitPerfect/jni/main/AutoConvolver.c
+++ b/DSPManager_Free_BitPerfect/jni/main/AutoConvolver.c
@@ -2,13 +2,8 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
-#include "fftw3.h"
+#include "kissfft/kiss_fftr.h"
#include "AutoConvolver.h"
-typedef struct str_dffirfilter
-{
- unsigned int pos, coeffslength;
- double *coeffs, *delayLine, gain;
-} DFFIR;
typedef struct str_HConv1Stage
{
int step; // processing step counter
@@ -17,115 +12,37 @@ typedef struct str_HConv1Stage
int framelength; // number of samples per audio frame
int *steptask; // processing tasks per step
double *dft_time; // DFT buffer (time domain)
- fftw_complex *dft_freq; // DFT buffer (frequency domain)
+ kiss_fft_cpx *dft_freq; // DFT buffer (frequency domain)
double *in_freq_real; // input buffer (frequency domain)
double *in_freq_imag; // input buffer (frequency domain)
int num_filterbuf; // number of filter segments
- double **filterbuf_freq_real; // filter segments (frequency domain)
- double **filterbuf_freq_imag; // filter segments (frequency domain)
+ double **filterbuf_freq_realChannel1; // filter segments (frequency domain)
+ double **filterbuf_freq_imagChannel1; // filter segments (frequency domain)
int num_mixbuf; // number of mixing segments
double **mixbuf_freq_real; // mixing segments (frequency domain)
double **mixbuf_freq_imag; // mixing segments (frequency domain)
double *history_time; // history buffer (time domain)
double normalizationGain;
double gain;
- fftw_plan fft; // FFT transformation plan
- fftw_plan ifft; // IFFT transformation plan
-} HConv1Stage;
-typedef struct str_HConv2Stage
-{
- int step; // processing step counter
- int maxstep; // number of processing steps per long audio frame
- int flen_long; // number of samples per long audio frame
- int flen_short; // number of samples per short audio frame
- double *in_long; // input buffer (long frame)
- double *out_long; // output buffer (long frame)
- HConv1Stage *f_long; // convolution filter (long segments)
- HConv1Stage *f_short; // convolution filter (short segments)
-} HConv2Stage;
-typedef struct str_HConv3Stage
-{
- int step; // processing step counter
- int maxstep; // number of processing steps per long audio frame
- int flen_medium; // number of samples per long audio frame
- int flen_short; // number of samples per short audio frame
- double *in_medium; // input buffer (long frame)
- double *out_medium; // output buffer (long frame)
- HConv2Stage *f_medium; // convolution filter (long segments)
- HConv1Stage *f_short; // convolution filter (short segments)
-} HConv3Stage;
-typedef struct str_HConv4Stage
-{
- int step; // processing step counter
- int maxstep; // number of processing steps per long audio frame
- int flen_medium; // number of samples per long audio frame
- int flen_short; // number of samples per short audio frame
- double *in_medium; // input buffer (long frame)
- double *out_medium; // output buffer (long frame)
- HConv3Stage *f_medium; // convolution filter (long segments)
- HConv1Stage *f_short; // convolution filter (short segments)
-} HConv4Stage;
-int ACFFTWThreadInit()
-{
- return fftw_init_threads();
-}
-void ACFFTWClean(int threads)
-{
- if (threads)
- fftw_cleanup_threads();
- else
- fftw_cleanup();
-}
-void DFFIRInit(DFFIR *fir, double *h, int hlen)
-{
- int i, size;
- fir->pos = 0;
- fir->gain = 1.0;
- fir->coeffslength = hlen;
- size = hlen * sizeof(double);
- fir->coeffs = (double*)malloc(size);
- for (i = 0; i < hlen; i++)
- fir->coeffs[i] = h[i];
- fir->delayLine = (double*)malloc(size);
- memset(fir->delayLine, 0, size);
-}
-void DFFIRClean(DFFIR *fir)
-{
- free(fir->coeffs);
- free(fir->delayLine);
- memset(fir, 0, sizeof(DFFIR));
-}
-double DFFIRProcess(DFFIR *fir, double x)
-{
- double *coeff = fir->coeffs;
- double *coeff_end = fir->coeffs + fir->coeffslength;
- double *buf_val = fir->delayLine + fir->pos;
- *buf_val = x;
- double y = 0.0;
- while (buf_val >= fir->delayLine)
- y += *buf_val-- * *coeff++ * fir->gain;
- buf_val = fir->delayLine + fir->coeffslength - 1;
- while (coeff < coeff_end)
- y += *buf_val-- * *coeff++ * fir->gain;
- if (++fir->pos >= fir->coeffslength)
- fir->pos = 0;
- return y;
-}
-inline void hcPut1Stage(HConv1Stage *filter, double *x)
+ kiss_fftr_cfg fft; // FFT transformation plan
+ kiss_fftr_cfg ifft; // IFFT transformation plan
+ int memSize;
+} HConv1Stage1x1;
+inline void hcPut1Stage(HConv1Stage1x1 *filter, double *x)
{
int j, flen, size;
flen = filter->framelength;
- size = sizeof(double) * flen;
+ size = filter->memSize;
memcpy(filter->dft_time, x, size);
memset(&(filter->dft_time[flen]), 0, size);
- fftw_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->in_freq_real[j] = filter->dft_freq[j][0];
- filter->in_freq_imag[j] = filter->dft_freq[j][1];
+ filter->in_freq_real[j] = filter->dft_freq[j].r;
+ filter->in_freq_imag[j] = filter->dft_freq[j].i;
}
}
-void hcProcess1Stage(HConv1Stage *filter)
+void hcProcess1Stage(HConv1Stage1x1 *filter)
{
int s, n, start, stop, flen;
double *x_real;
@@ -144,17 +61,17 @@ void hcProcess1Stage(HConv1Stage *filter)
n = (s + filter->mixpos) % filter->num_mixbuf;
y_real = filter->mixbuf_freq_real[n];
y_imag = filter->mixbuf_freq_imag[n];
- h_real = filter->filterbuf_freq_real[s];
- h_imag = filter->filterbuf_freq_imag[s];
+ h_real = filter->filterbuf_freq_realChannel1[s];
+ h_imag = filter->filterbuf_freq_imagChannel1[s];
for (n = 0; n < flen + 1; n++)
{
- y_real[n] += (x_real[n] * h_real[n] - x_imag[n] * h_imag[n]) * filter->gain;
- y_imag[n] += (x_real[n] * h_imag[n] + x_imag[n] * h_real[n]) * filter->gain;
+ y_real[n] += (x_real[n] * h_real[n] - x_imag[n] * h_imag[n]);
+ y_imag[n] += (x_real[n] * h_imag[n] + x_imag[n] * h_real[n]);
}
}
filter->step = (filter->step + 1) % filter->maxstep;
}
-inline void hcGet1Stage(HConv1Stage *filter, double *y)
+inline void hcGet1Stage(HConv1Stage1x1 *filter, double *y)
{
int flen, mpos;
double *out;
@@ -166,21 +83,19 @@ inline void hcGet1Stage(HConv1Stage *filter, double *y)
hist = filter->history_time;
for (j = 0; j < flen + 1; j++)
{
- filter->dft_freq[j][0] = filter->mixbuf_freq_real[mpos][j];
- filter->dft_freq[j][1] = filter->mixbuf_freq_imag[mpos][j];
- filter->mixbuf_freq_real[mpos][j] = 0.0;
- filter->mixbuf_freq_imag[mpos][j] = 0.0;
+ filter->dft_freq[j].r = filter->mixbuf_freq_real[mpos][j];
+ filter->dft_freq[j].i = filter->mixbuf_freq_imag[mpos][j];
+ filter->mixbuf_freq_real[mpos][j] = 0.0f;
+ filter->mixbuf_freq_imag[mpos][j] = 0.0f;
}
- fftw_execute(filter->ifft);
+ kiss_fftri(filter->ifft, filter->dft_freq, filter->dft_time);
for (n = 0; n < flen; n++)
- {
- y[n] = out[n] + hist[n];
- }
- size = sizeof(double) * flen;
+ y[n] = (out[n] + hist[n]) * filter->gain;
+ size = filter->memSize;
memcpy(hist, &(out[flen]), size);
filter->mixpos = (filter->mixpos + 1) % filter->num_mixbuf;
}
-void hcInit1Stage(HConv1Stage *filter, double *h, int hlen, int flen, int steps, int fftwThreads)
+void hcInit1Stage(HConv1Stage1x1 *filter, double *h, int hlen, int flen, int steps)
{
int i, j, size, num, pos;
// processing step counter
@@ -193,14 +108,14 @@ void hcInit1Stage(HConv1Stage *filter, double *h, int hlen, int flen, int steps,
filter->framelength = flen;
// DFT buffer (time domain)
size = sizeof(double) * 2 * flen;
- filter->dft_time = (double *)fftw_malloc(size);
+ filter->dft_time = (double *)malloc(size);
// DFT buffer (frequency domain)
- size = sizeof(fftw_complex) * (flen + 1);
- filter->dft_freq = (fftw_complex*)fftw_malloc(size);
+ size = sizeof(kiss_fft_cpx) * (flen + 1);
+ filter->dft_freq = (kiss_fft_cpx*)malloc(size);
// input buffer (frequency domain)
size = sizeof(double) * (flen + 1);
- filter->in_freq_real = (double*)fftw_malloc(size);
- filter->in_freq_imag = (double*)fftw_malloc(size);
+ filter->in_freq_real = (double*)malloc(size);
+ filter->in_freq_imag = (double*)malloc(size);
// number of filter segments
filter->num_filterbuf = (hlen + flen - 1) / flen;
// processing tasks per step
@@ -221,38 +136,36 @@ void hcInit1Stage(HConv1Stage *filter, double *h, int hlen, int flen, int steps,
}
// filter segments (frequency domain)
size = sizeof(double*) * filter->num_filterbuf;
- filter->filterbuf_freq_real = (double**)fftw_malloc(size);
- filter->filterbuf_freq_imag = (double**)fftw_malloc(size);
+ filter->filterbuf_freq_realChannel1 = (double**)malloc(size);
+ filter->filterbuf_freq_imagChannel1 = (double**)malloc(size);
+ size = sizeof(double) * (flen + 1);
for (i = 0; i < filter->num_filterbuf; i++)
{
- size = sizeof(double) * (flen + 1);
- filter->filterbuf_freq_real[i] = (double*)fftw_malloc(size);
- filter->filterbuf_freq_imag[i] = (double*)fftw_malloc(size);
+ filter->filterbuf_freq_realChannel1[i] = (double*)malloc(size);
+ filter->filterbuf_freq_imagChannel1[i] = (double*)malloc(size);
}
// number of mixing segments
filter->num_mixbuf = filter->num_filterbuf + 1;
// mixing segments (frequency domain)
size = sizeof(double*) * filter->num_mixbuf;
- filter->mixbuf_freq_real = (double**)fftw_malloc(size);
- filter->mixbuf_freq_imag = (double**)fftw_malloc(size);
+ filter->mixbuf_freq_real = (double**)malloc(size);
+ filter->mixbuf_freq_imag = (double**)malloc(size);
for (i = 0; i < filter->num_mixbuf; i++)
{
size = sizeof(double) * (flen + 1);
- filter->mixbuf_freq_real[i] = (double*)fftw_malloc(size);
- filter->mixbuf_freq_imag[i] = (double*)fftw_malloc(size);
+ filter->mixbuf_freq_real[i] = (double*)malloc(size);
+ filter->mixbuf_freq_imag[i] = (double*)malloc(size);
memset(filter->mixbuf_freq_real[i], 0, size);
memset(filter->mixbuf_freq_imag[i], 0, size);
}
// history buffer (time domain)
size = sizeof(double) * flen;
- filter->history_time = (double *)fftw_malloc(size);
+ filter->history_time = (double *)malloc(size);
memset(filter->history_time, 0, size);
- if (fftwThreads)
- fftw_plan_with_nthreads(fftwThreads);
// FFT transformation plan
- filter->fft = fftw_plan_dft_r2c_1d(2 * flen, filter->dft_time, filter->dft_freq, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT);
+ filter->fft = kiss_fftr_alloc(2 * flen, 0, 0, 0);
// IFFT transformation plan
- filter->ifft = fftw_plan_dft_c2r_1d(2 * flen, filter->dft_freq, filter->dft_time, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT);
+ filter->ifft = kiss_fftr_alloc(2 * flen, 1, 0, 0);
// generate filter segments
filter->normalizationGain = 0.5 / (double)flen;
filter->gain = filter->normalizationGain;
@@ -262,294 +175,24 @@ void hcInit1Stage(HConv1Stage *filter, double *h, int hlen, int flen, int steps,
{
for (j = 0; j < flen; j++)
filter->dft_time[j] = h[i * flen + j];
- fftw_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
+ filter->filterbuf_freq_realChannel1[i][j] = filter->dft_freq[j].r;
+ filter->filterbuf_freq_imagChannel1[i][j] = filter->dft_freq[j].i;
}
}
for (j = 0; j < hlen - i * flen; j++)
filter->dft_time[j] = h[i * flen + j];
size = sizeof(double) * ((i + 1) * flen - hlen);
memset(&(filter->dft_time[hlen - i * flen]), 0, size);
- fftw_execute(filter->fft);
+ kiss_fftr(filter->fft, filter->dft_time, filter->dft_freq);
for (j = 0; j < flen + 1; j++)
{
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
- }
-}
-void hcProcess2Stage(HConv2Stage *filter, double *in, double *out)
-{
- int lpos, size, i;
- // convolution with short segments
- hcPut1Stage(filter->f_short, in);
- hcProcess1Stage(filter->f_short);
- hcGet1Stage(filter->f_short, out);
- // add contribution from last long frame
- lpos = filter->step * filter->flen_short;
- for (i = 0; i < filter->flen_short; i++)
- out[i] += filter->out_long[lpos + i];
- // convolution with long segments
- if (filter->step == 0)
- hcPut1Stage(filter->f_long, filter->in_long);
- hcProcess1Stage(filter->f_long);
- if (filter->step == filter->maxstep - 1)
- hcGet1Stage(filter->f_long, filter->out_long);
- // add current frame to long input buffer
- lpos = filter->step * filter->flen_short;
- size = sizeof(double) * filter->flen_short;
- memcpy(&(filter->in_long[lpos]), in, size);
- // increase step counter
- filter->step = (filter->step + 1) % filter->maxstep;
-}
-void hcInit2Stage(HConv2Stage *filter, double *h, int hlen, int sflen, int lflen, int fftwThreads)
-{
- int size;
- double *h2 = NULL;
- int h2len;
- // sanity check: minimum impulse response length
- h2len = 2 * lflen + 1;
- if (hlen < h2len)
- {
- size = sizeof(double) * h2len;
- h2 = (double*)fftw_malloc(size);
- memset(h2, 0, size);
- size = sizeof(double) * hlen;
- memcpy(h2, h, size);
- h = h2;
- hlen = h2len;
- }
- // processing step counter
- filter->step = 0;
- // number of processing steps per long audio frame
- filter->maxstep = lflen / sflen;
- // number of samples per long audio frame
- filter->flen_long = lflen;
- // number of samples per short audio frame
- filter->flen_short = sflen;
- // input buffer (long frame)
- size = sizeof(double) * lflen;
- filter->in_long = (double *)fftw_malloc(size);
- memset(filter->in_long, 0, size);
- // output buffer (long frame)
- size = sizeof(double) * lflen;
- filter->out_long = (double *)fftw_malloc(size);
- memset(filter->out_long, 0, size);
- // convolution filter (short segments)
- size = sizeof(HConv1Stage);
- filter->f_short = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_short, h, 2 * lflen, sflen, 1, fftwThreads);
- // convolution filter (long segments)
- size = sizeof(HConv1Stage);
- filter->f_long = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_long, &(h[2 * lflen]), hlen - 2 * lflen, lflen, lflen / sflen, fftwThreads);
- if (h2 != NULL)
- fftw_free(h2);
-}
-void hcProcess3Stage(HConv3Stage *filter, double *in, double *out)
-{
- int lpos, size, i;
- // convolution with short segments
- hcPut1Stage(filter->f_short, in);
- hcProcess1Stage(filter->f_short);
- hcGet1Stage(filter->f_short, out);
- // add contribution from last medium frame
- lpos = filter->step * filter->flen_short;
- for (i = 0; i < filter->flen_short; i++)
- out[i] += filter->out_medium[lpos + i];
- // add current frame to medium input buffer
- lpos = filter->step * filter->flen_short;
- size = sizeof(double) * filter->flen_short;
- memcpy(&(filter->in_medium[lpos]), in, size);
- // convolution with medium segments
- if (filter->step == filter->maxstep - 1)
- hcProcess2Stage(filter->f_medium, filter->in_medium, filter->out_medium);
- // increase step counter
- filter->step = (filter->step + 1) % filter->maxstep;
-}
-void hcInit3Stage(HConv3Stage *filter, double *h, int hlen, int sflen, int mflen, int lflen, int fftwThreads)
-{
- int size;
- double *h2 = NULL;
- int h2len;
- // sanity check: minimum impulse response length
- h2len = mflen + 2 * lflen + 1;
- if (hlen < h2len)
- {
- size = sizeof(double) * h2len;
- h2 = (double*)fftw_malloc(size);
- memset(h2, 0, size);
- size = sizeof(double) * hlen;
- memcpy(h2, h, size);
- h = h2;
- hlen = h2len;
- }
- // processing step counter
- filter->step = 0;
- // number of processing steps per medium audio frame
- filter->maxstep = mflen / sflen;
- // number of samples per medium audio frame
- filter->flen_medium = mflen;
- // number of samples per short audio frame
- filter->flen_short = sflen;
- // input buffer (medium frame)
- size = sizeof(double) * mflen;
- filter->in_medium = (double *)fftw_malloc(size);
- memset(filter->in_medium, 0, size);
- // output buffer (medium frame)
- size = sizeof(double) * mflen;
- filter->out_medium = (double *)fftw_malloc(size);
- memset(filter->out_medium, 0, size);
- // convolution filter (short segments)
- size = sizeof(HConv1Stage);
- filter->f_short = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_short, h, mflen, sflen, 1, fftwThreads);
- // convolution filter (medium segments)
- size = sizeof(HConv2Stage);
- filter->f_medium = (HConv2Stage *)malloc(size);
- hcInit2Stage(filter->f_medium, &(h[mflen]), hlen - mflen, mflen, lflen, fftwThreads);
- if (h2 != NULL)
- fftw_free(h2);
-}
-void hcProcess4Stage(HConv4Stage *filter, double *in, double *out)
-{
- int lpos, size, i;
- // convolution with short segments
- hcPut1Stage(filter->f_short, in);
- hcProcess1Stage(filter->f_short);
- hcGet1Stage(filter->f_short, out);
- // add contribution from last medium frame
- lpos = filter->step * filter->flen_short;
- for (i = 0; i < filter->flen_short; i++)
- out[i] += filter->out_medium[lpos + i];
- // add current frame to medium input buffer
- lpos = filter->step * filter->flen_short;
- size = sizeof(double) * filter->flen_short;
- memcpy(&(filter->in_medium[lpos]), in, size);
- // convolution with medium segments
- if (filter->step == filter->maxstep - 1)
- hcProcess3Stage(filter->f_medium, filter->in_medium, filter->out_medium);
- // increase step counter
- filter->step = (filter->step + 1) % filter->maxstep;
-}
-void hcInit4Stage(HConv4Stage *filter, double *h, int hlen, int ssflen, int sflen, int mflen, int lflen, int fftwThreads)
-{
- int size;
- double *h2 = NULL;
- int h2len;
- // sanity check: minimum impulse response length
- h2len = sflen + mflen + 2 * lflen + 1;
- if (hlen < h2len)
- {
- size = sizeof(double) * h2len;
- h2 = (double*)fftw_malloc(size);
- memset(h2, 0, size);
- size = sizeof(double) * hlen;
- memcpy(h2, h, size);
- h = h2;
- hlen = h2len;
+ filter->filterbuf_freq_realChannel1[i][j] = filter->dft_freq[j].r;
+ filter->filterbuf_freq_imagChannel1[i][j] = filter->dft_freq[j].i;
}
- // processing step counter
- filter->step = 0;
- // number of processing steps per medium audio frame
- filter->maxstep = sflen / ssflen;
- // number of samples per medium audio frame
- filter->flen_medium = sflen;
- // number of samples per short audio frame
- filter->flen_short = ssflen;
- // input buffer (medium frame)
- size = sizeof(double) * sflen;
- filter->in_medium = (double *)fftw_malloc(size);
- memset(filter->in_medium, 0, size);
- // output buffer (medium frame)
- size = sizeof(double) * sflen;
- filter->out_medium = (double *)fftw_malloc(size);
- memset(filter->out_medium, 0, size);
- // convolution filter (short segments)
- size = sizeof(HConv1Stage);
- filter->f_short = (HConv1Stage *)malloc(size);
- hcInit1Stage(filter->f_short, h, sflen, ssflen, 1, fftwThreads);
- // convolution filter (medium segments)
- size = sizeof(HConv3Stage);
- filter->f_medium = (HConv3Stage *)malloc(size);
- hcInit3Stage(filter->f_medium, &(h[sflen]), hlen - sflen, sflen, mflen, lflen, fftwThreads);
- if (h2 != NULL)
- fftw_free(h2);
-}
-void Convolver4StageProcessArbitrarySignalLengthMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int sigLen)
-{
- int m_lenShort = autoConv->hnShortLen;
- double *m_inbuf = autoConv->inbuf;
- double *m_outbuf = autoConv->outbuf;
- HConv4Stage *m_filter = (HConv4Stage*)autoConv->filter;
- int pos = autoConv->bufpos;
- for (int s = 0; s < sigLen; s++)
- {
- m_inbuf[pos] = inputs[s];
- outputs[s] = m_outbuf[pos];
- pos++;
- if (pos == m_lenShort)
- {
- hcProcess4Stage(m_filter, m_inbuf, m_outbuf);
- pos = 0;
- }
- }
- autoConv->bufpos = pos;
-}
-void Convolver3StageProcessArbitrarySignalLengthMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int sigLen)
-{
- int m_lenShort = autoConv->hnShortLen;
- double *m_inbuf = autoConv->inbuf;
- double *m_outbuf = autoConv->outbuf;
- HConv3Stage *m_filter = (HConv3Stage*)autoConv->filter;
- int pos = autoConv->bufpos;
- for (int s = 0; s < sigLen; s++)
- {
- m_inbuf[pos] = inputs[s];
- outputs[s] = m_outbuf[pos];
- pos++;
- if (pos == m_lenShort)
- {
- hcProcess3Stage(m_filter, m_inbuf, m_outbuf);
- pos = 0;
- }
- }
- autoConv->bufpos = pos;
-}
-void Convolver2StageProcessArbitrarySignalLengthMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int sigLen)
-{
- int m_lenShort = autoConv->hnShortLen;
- double *m_inbuf = autoConv->inbuf;
- double *m_outbuf = autoConv->outbuf;
- HConv2Stage *m_filter = (HConv2Stage*)autoConv->filter;
- int pos = autoConv->bufpos;
- for (int s = 0; s < sigLen; s++)
- {
- m_inbuf[pos] = inputs[s];
- outputs[s] = m_outbuf[pos];
- pos++;
- if (pos == m_lenShort)
- {
- hcProcess2Stage(m_filter, m_inbuf, m_outbuf);
- pos = 0;
- }
- }
- autoConv->bufpos = pos;
-}
-void Convolver1StageLowLatencyProcessMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int unused)
-{
- HConv1Stage *m_filter = (HConv1Stage*)autoConv->filter;
- hcPut1Stage(m_filter, inputs);
- hcProcess1Stage(m_filter);
- hcGet1Stage(m_filter, outputs);
-}
-void Convolver1DirectFormProcessMono(AutoConvolverMono *autoConv, double* inputs, double* outputs, int sigLen)
-{
- DFFIR *m_filter = (DFFIR*)autoConv->filter;
- for (int i = 0; i < sigLen; i++)
- outputs[i] = DFFIRProcess(m_filter, inputs[i]);
+ filter->memSize = sizeof(double) * flen;
}
int PartitionerAnalyser(int hlen, int latency, int strategy, int fs, int entriesResult, double **result_c0_c1, int *sflen_best, int *mflen_best, int *lflen_best)
{
@@ -635,232 +278,32 @@ int PartitionerAnalyser(int hlen, int latency, int strategy, int fs, int entries
}
return type_best;
}
-AutoConvolverMono* InitAutoConvolverMono(double *impulseResponse, int hlen, int audioBufferSize, double gaindB, double **recommendation, int items, int fftwThreads)
-{
- int bestMethod = 1, sflen_best = 4096, mflen_best = 8192, lflen_best = 16384, llflen_best = 32768;
- hlen = abs(hlen);
- if (!hlen)
- return 0;
- if (recommendation)
- bestMethod = PartitionerAnalyser(hlen, 4096, 1, 48000, items, recommendation, &sflen_best, &mflen_best, &lflen_best);
- if (hlen > 0 && hlen < 32)
- bestMethod = 999;
- else if (hlen > 20000 && hlen < 81921 && bestMethod < 2)
- {
- bestMethod = 2;
- sflen_best = 2048;
- mflen_best = 8192;
- }
- else if (hlen > 81920 && hlen < 245764 && bestMethod < 2)
- {
- bestMethod = 2;
- sflen_best = 4096;
- mflen_best = 8192;
- }
- else if (hlen > 245763 && hlen < 1000001 && bestMethod < 2)
- {
- bestMethod = 2;
- sflen_best = 4096;
- mflen_best = 16384;
- }
- else if (hlen > 1000000 && hlen < 2000001 && bestMethod < 2)
- bestMethod = 3;
- else if (hlen > 2000000 && bestMethod < 2)
- bestMethod = 4;
- double linGain = pow(10.0, gaindB / 20.0);
- AutoConvolverMono *autoConv = (AutoConvolverMono*)calloc(1, sizeof(AutoConvolverMono));
- autoConv->methods = bestMethod;
- if (bestMethod > 1)
- {
- autoConv->hnShortLen = sflen_best;
- autoConv->inbuf = (double*)calloc(sflen_best, sizeof(double));
- autoConv->outbuf = (double*)calloc(sflen_best, sizeof(double));
- }
- if (bestMethod == 3)
- {
- HConv3Stage* stage = (HConv3Stage*)malloc(sizeof(HConv3Stage));
- hcInit3Stage(stage, impulseResponse, hlen, sflen_best, mflen_best, lflen_best, fftwThreads);
- stage->f_medium->f_long->gain = stage->f_medium->f_long->normalizationGain * linGain;
- stage->f_medium->f_short->gain = stage->f_medium->f_short->normalizationGain * linGain;
- stage->f_short->gain = stage->f_short->normalizationGain * linGain;
- autoConv->filter = (void*)stage;
- autoConv->process = &Convolver3StageProcessArbitrarySignalLengthMono;
- }
- else if (bestMethod == 2)
- {
- HConv2Stage* stage = (HConv2Stage*)malloc(sizeof(HConv2Stage));
- hcInit2Stage(stage, impulseResponse, hlen, sflen_best, mflen_best, fftwThreads);
- stage->f_long->gain = stage->f_long->normalizationGain * linGain;
- stage->f_short->gain = stage->f_short->normalizationGain * linGain;
- autoConv->filter = (void*)stage;
- autoConv->process = &Convolver2StageProcessArbitrarySignalLengthMono;
- }
- else if (bestMethod == 4)
- {
- HConv4Stage* stage = (HConv4Stage*)malloc(sizeof(HConv4Stage));
- hcInit4Stage(stage, impulseResponse, hlen, sflen_best, mflen_best, lflen_best, llflen_best, fftwThreads);
- stage->f_medium->f_medium->f_long->gain = stage->f_medium->f_medium->f_long->normalizationGain * linGain;
- stage->f_medium->f_medium->f_short->gain = stage->f_medium->f_medium->f_short->normalizationGain * linGain;
- stage->f_medium->f_short->gain = stage->f_medium->f_short->normalizationGain * linGain;
- stage->f_short->gain = stage->f_short->normalizationGain * linGain;
- autoConv->filter = (void*)stage;
- autoConv->process = &Convolver4StageProcessArbitrarySignalLengthMono;
- }
- else if (bestMethod == 999)
- {
- DFFIR* stage = (DFFIR*)malloc(sizeof(DFFIR));
- DFFIRInit(stage, impulseResponse, hlen);
- stage->gain = linGain;
- autoConv->filter = (void*)stage;
- autoConv->process = &Convolver1DirectFormProcessMono;
- }
- else
- {
- HConv1Stage* stage = (HConv1Stage*)malloc(sizeof(HConv1Stage));
- hcInit1Stage(stage, impulseResponse, hlen, audioBufferSize, 1, fftwThreads);
- stage->gain = stage->normalizationGain * linGain;
- autoConv->filter = (void*)stage;
- autoConv->process = &Convolver1StageLowLatencyProcessMono;
- }
- return autoConv;
-}
-AutoConvolverMono* AllocateAutoConvolverMonoZeroLatency(double *impulseResponse, int hlen, int audioBufferSize, int fftwThreads)
-{
- AutoConvolverMono *autoConv = (AutoConvolverMono*)calloc(1, sizeof(AutoConvolverMono));
- autoConv->methods = 1;
- HConv1Stage* stage = (HConv1Stage*)calloc(1, sizeof(HConv1Stage));
- hcInit1Stage(stage, impulseResponse, hlen, audioBufferSize, 1, fftwThreads);
- autoConv->filter = (void*)stage;
- autoConv->process = &Convolver1StageLowLatencyProcessMono;
- return autoConv;
-}
-void hcInit1StageDeterminedAllocation(HConv1Stage *filter, double *h, int hlen)
-{
- int i, j, size;
- int flen = filter->framelength;
- // generate filter segments
- size = sizeof(double) * 2 * flen;
- memset(filter->dft_time, 0, size);
- for (i = 0; i < filter->num_filterbuf - 1; i++)
- {
- for (j = 0; j < flen; j++)
- filter->dft_time[j] = h[i * flen + j];
- fftw_execute(filter->fft);
- for (j = 0; j < flen + 1; j++)
- {
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
- }
- }
- for (j = 0; j < hlen - i * flen; j++)
- filter->dft_time[j] = h[i * flen + j];
- size = sizeof(double) * ((i + 1) * flen - hlen);
- memset(&(filter->dft_time[hlen - i * flen]), 0, size);
- fftw_execute(filter->fft);
- for (j = 0; j < flen + 1; j++)
- {
- filter->filterbuf_freq_real[i][j] = filter->dft_freq[j][0];
- filter->filterbuf_freq_imag[i][j] = filter->dft_freq[j][1];
- }
-}
-void UpdateAutoConvolverMonoZeroLatency(AutoConvolverMono *autoConv, double *impulseResponse, int hlen)
-{
- hcInit1StageDeterminedAllocation((HConv1Stage*)autoConv->filter, impulseResponse, hlen);
-}
-void hcClose1Stage(HConv1Stage *filter)
+void hcClose1Stage(HConv1Stage1x1 *filter)
{
int i;
- fftw_destroy_plan(filter->ifft);
- fftw_destroy_plan(filter->fft);
- fftw_free(filter->history_time);
+ free(filter->ifft);
+ free(filter->fft);
+ free(filter->history_time);
for (i = 0; i < filter->num_mixbuf; i++)
{
- fftw_free(filter->mixbuf_freq_real[i]);
- fftw_free(filter->mixbuf_freq_imag[i]);
+ free(filter->mixbuf_freq_real[i]);
+ free(filter->mixbuf_freq_imag[i]);
}
- fftw_free(filter->mixbuf_freq_real);
- fftw_free(filter->mixbuf_freq_imag);
+ free(filter->mixbuf_freq_real);
+ free(filter->mixbuf_freq_imag);
for (i = 0; i < filter->num_filterbuf; i++)
{
- fftw_free(filter->filterbuf_freq_real[i]);
- fftw_free(filter->filterbuf_freq_imag[i]);
+ free(filter->filterbuf_freq_realChannel1[i]);
+ free(filter->filterbuf_freq_imagChannel1[i]);
}
- fftw_free(filter->filterbuf_freq_real);
- fftw_free(filter->filterbuf_freq_imag);
- fftw_free(filter->in_freq_real);
- fftw_free(filter->in_freq_imag);
- fftw_free(filter->dft_freq);
- fftw_free(filter->dft_time);
+ free(filter->filterbuf_freq_realChannel1);
+ free(filter->filterbuf_freq_imagChannel1);
+ free(filter->in_freq_real);
+ free(filter->in_freq_imag);
+ free(filter->dft_freq);
+ free(filter->dft_time);
free(filter->steptask);
- memset(filter, 0, sizeof(HConv1Stage));
-}
-void hcClose2Stage(HConv2Stage *filter)
-{
- hcClose1Stage(filter->f_short);
- free(filter->f_short);
- hcClose1Stage(filter->f_long);
- free(filter->f_long);
- fftw_free(filter->out_long);
- fftw_free(filter->in_long);
- memset(filter, 0, sizeof(HConv2Stage));
-}
-void hcClose3Stage(HConv3Stage *filter)
-{
- hcClose1Stage(filter->f_short);
- free(filter->f_short);
- hcClose2Stage(filter->f_medium);
- free(filter->f_medium);
- fftw_free(filter->out_medium);
- fftw_free(filter->in_medium);
- memset(filter, 0, sizeof(HConv3Stage));
-}
-void hcClose4Stage(HConv4Stage *filter)
-{
- hcClose1Stage(filter->f_short);
- free(filter->f_short);
- hcClose3Stage(filter->f_medium);
- free(filter->f_medium);
- fftw_free(filter->out_medium);
- fftw_free(filter->in_medium);
- memset(filter, 0, sizeof(HConv4Stage));
-}
-void AutoConvolverMonoFree(AutoConvolverMono *autoConv)
-{
- if (autoConv->methods > 1)
- {
- free(autoConv->inbuf);
- free(autoConv->outbuf);
- }
- if (autoConv->methods == 1)
- {
- HConv1Stage* stage = (HConv1Stage*)autoConv->filter;
- hcClose1Stage(stage);
- free(stage);
- }
- else if (autoConv->methods == 2)
- {
- HConv2Stage* stage = (HConv2Stage*)autoConv->filter;
- hcClose2Stage(stage);
- free(stage);
- }
- else if (autoConv->methods == 3)
- {
- HConv3Stage* stage = (HConv3Stage*)autoConv->filter;
- hcClose3Stage(stage);
- free(stage);
- }
- else if (autoConv->methods == 4)
- {
- HConv4Stage* stage = (HConv4Stage*)autoConv->filter;
- hcClose4Stage(stage);
- free(stage);
- }
- else if (autoConv->methods == 999)
- {
- DFFIR* stage = (DFFIR*)autoConv->filter;
- DFFIRClean(stage);
- free(stage);
- }
+ memset(filter, 0, sizeof(HConv1Stage1x1));
}
#ifdef _WIN32
#include <Windows.h>
@@ -881,7 +324,7 @@ double hcTime(void)
#endif
double getProcTime(int flen, int num, double dur)
{
- HConv1Stage filter;
+ HConv1Stage1x1 filter;
double *x;
double *h;
double *y;
@@ -895,7 +338,7 @@ double getProcTime(int flen, int num, double dur)
xlen = 2048 * 2048;
size = sizeof(double) * xlen;
- x = (double *)fftw_malloc(size);
+ x = (double *)malloc(size);
lin = pow(10.0, -100.0 / 20.0); // 0.00001 = -100dB
mul = pow(lin, 1.0 / (double)xlen);
x[0] = 1.0;
@@ -904,7 +347,7 @@ double getProcTime(int flen, int num, double dur)
hlen = flen * num;
size = sizeof(double) * hlen;
- h = (double *)fftw_malloc(size);
+ h = (double *)malloc(size);
lin = pow(10.0, -60.0 / 20.0); // 0.001 = -60dB
mul = pow(lin, 1.0 / (double)hlen);
h[0] = 1.0;
@@ -913,9 +356,9 @@ double getProcTime(int flen, int num, double dur)
ylen = flen;
size = sizeof(double) * ylen;
- y = (double *)fftw_malloc(size);
+ y = (double *)malloc(size);
- hcInit1Stage(&filter, h, hlen, flen, 1, 0);
+ hcInit1Stage(&filter, h, hlen, flen, 1);
t_diff = 0.0;
t_start = hcTime();
@@ -934,9 +377,9 @@ double getProcTime(int flen, int num, double dur)
proc_time = t_diff / counter;
printf("Processing time: %7.3f us\n", 1000000.0 * proc_time);
hcClose1Stage(&filter);
- fftw_free(x);
- fftw_free(h);
- fftw_free(y);
+ free(x);
+ free(h);
+ free(y);
return proc_time;
}
double** PartitionHelperWisdomGetFromFile(const char *file, int *itemRet)
diff --git a/DSPManager_Free_BitPerfect/jni/main/AutoConvolver.h b/DSPManager_Free_BitPerfect/jni/main/AutoConvolver.h
index c579827..20cdc93 100644
--- a/DSPManager_Free_BitPerfect/jni/main/AutoConvolver.h
+++ b/DSPManager_Free_BitPerfect/jni/main/AutoConvolver.h
@@ -1,18 +1,5 @@
#ifndef __AUTOCONVOLVER_H__
#define __AUTOCONVOLVER_H__
-typedef struct str_AutoConvolverMono
-{
- int methods, hnShortLen, bufpos;
- double *inbuf, *outbuf;
- void *filter;
- void(*process)(struct str_AutoConvolverMono*, double*, double*, int);
-} AutoConvolverMono;
-int ACFFTWThreadInit();
-void ACFFTWClean(int threads);
-AutoConvolverMono* InitAutoConvolverMono(double *impulseResponse, int hlen, int audioBufferSize, double gaindB, double **recommendation, int items, int fftwThreads);
-AutoConvolverMono* AllocateAutoConvolverMonoZeroLatency(double *impulseResponse, int hlen, int audioBufferSize, int fftwThreads);
-void UpdateAutoConvolverMonoZeroLatency(AutoConvolverMono *autoConv, double *impulseResponse, int hlen);
-void AutoConvolverMonoFree(AutoConvolverMono *autoConv);
double** PartitionHelperWisdomGetFromFile(const char *file, int *itemRet);
char* PartitionHelper(int s_max, int fs);
double** PartitionHelperDirect(int s_max, int fs);
diff --git a/DSPManager_Free_BitPerfect/jni/main/fftw3.h b/DSPManager_Free_BitPerfect/jni/main/fftw3.h
deleted file mode 100644
index de69b4b..0000000
--- a/DSPManager_Free_BitPerfect/jni/main/fftw3.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (c) 2003, 2007-14 Matteo Frigo
- * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
- *
- * The following statement of license applies *only* to this header file,
- * and *not* to the other files distributed with FFTW or derived therefrom:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/***************************** NOTE TO USERS *********************************
- *
- * THIS IS A HEADER FILE, NOT A MANUAL
- *
- * If you want to know how to use FFTW, please read the manual,
- * online at http://www.fftw.org/doc/ and also included with FFTW.
- * For a quick start, see the manual's tutorial section.
- *
- * (Reading header files to learn how to use a library is a habit
- * stemming from code lacking a proper manual. Arguably, it's a
- * *bad* habit in most cases, because header files can contain
- * interfaces that are not part of the public, stable API.)
- *
- ****************************************************************************/
-
-#ifndef FFTW3_H
-#define FFTW3_H
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/* If <complex.h> is included, use the C99 complex type. Otherwise
- define a type bit-compatible with C99 complex */
-#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
-# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
-#else
-# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
-#endif
-
-#define FFTW_CONCAT(prefix, name) prefix ## name
-#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
-#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
-#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
-#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name)
-
-/* IMPORTANT: for Windows compilers, you should add a line
- #define FFTW_DLL
- here and in kernel/ifftw.h if you are compiling/using FFTW as a
- DLL, in order to do the proper importing/exporting, or
- alternatively compile with -DFFTW_DLL or the equivalent
- command-line flag. This is not necessary under MinGW/Cygwin, where
- libtool does the imports/exports automatically. */
-#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
-/* annoying Windows syntax for shared-library declarations */
-# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
-# define FFTW_EXTERN extern __declspec(dllexport)
-# else /* user is calling FFTW; import symbol */
-# define FFTW_EXTERN extern __declspec(dllimport)
-# endif
-#else
-# define FFTW_EXTERN extern
-#endif
-
-enum fftw_r2r_kind_do_not_use_me
-{
- FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
- FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
- FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
-};
-
-struct fftw_iodim_do_not_use_me
-{
- int n; /* dimension size */
- int is; /* input stride */
- int os; /* output stride */
-};
-
-#include <stddef.h> /* for ptrdiff_t */
-struct fftw_iodim64_do_not_use_me
-{
- ptrdiff_t n; /* dimension size */
- ptrdiff_t is; /* input stride */
- ptrdiff_t os; /* output stride */
-};
-
-typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *);
-typedef int (*fftw_read_char_func_do_not_use_me)(void *);
-
-/*
- huge second-order macro that defines prototypes for all API
- functions. We expand this macro for each supported precision
-
- X: name-mangling macro
- R: real data type
- C: complex data type
-*/
-
-#define FFTW_DEFINE_API(X, R, C) \
- \
-FFTW_DEFINE_COMPLEX(R, C); \
- \
-typedef struct X(plan_s) *X(plan); \
- \
-typedef struct fftw_iodim_do_not_use_me X(iodim); \
-typedef struct fftw_iodim64_do_not_use_me X(iodim64); \
- \
-typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \
- \
-typedef fftw_write_char_func_do_not_use_me X(write_char_func); \
-typedef fftw_read_char_func_do_not_use_me X(read_char_func); \
- \
-FFTW_EXTERN void X(execute)(const X(plan) p); \
- \
-FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \
- C *in, C *out, int sign, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \
- C *in, C *out, int sign, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \
- C *in, C *out, int sign, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \
- int howmany, \
- C *in, const int *inembed, \
- int istride, int idist, \
- C *out, const int *onembed, \
- int ostride, int odist, \
- int sign, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- C *in, C *out, \
- int sign, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *ri, R *ii, R *ro, R *io, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \
- const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- C *in, C *out, \
- int sign, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \
- const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *ri, R *ii, R *ro, R *io, \
- unsigned flags); \
- \
-FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \
-FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \
- R *ro, R *io); \
- \
-FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \
- int howmany, \
- R *in, const int *inembed, \
- int istride, int idist, \
- C *out, const int *onembed, \
- int ostride, int odist, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \
- R *in, C *out, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \
- R *in, C *out, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \
- int n2, \
- R *in, C *out, unsigned flags); \
- \
- \
-FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \
- int howmany, \
- C *in, const int *inembed, \
- int istride, int idist, \
- R *out, const int *onembed, \
- int ostride, int odist, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \
- C *in, R *out, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \
- C *in, R *out, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \
- int n2, \
- C *in, R *out, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *in, C *out, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- C *in, R *out, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \
- int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *in, R *ro, R *io, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \
- int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *ri, R *ii, R *out, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \
- const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *in, C *out, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \
- const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- C *in, R *out, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \
- int rank, const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *in, R *ro, R *io, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \
- int rank, const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *ri, R *ii, R *out, \
- unsigned flags); \
- \
-FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \
-FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \
- \
-FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \
- R *in, R *ro, R *io); \
-FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \
- R *ri, R *ii, R *out); \
- \
-FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \
- int howmany, \
- R *in, const int *inembed, \
- int istride, int idist, \
- R *out, const int *onembed, \
- int ostride, int odist, \
- const X(r2r_kind) *kind, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \
- const X(r2r_kind) *kind, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \
- X(r2r_kind) kind, unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \
- X(r2r_kind) kind0, X(r2r_kind) kind1, \
- unsigned flags); \
-FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \
- R *in, R *out, X(r2r_kind) kind0, \
- X(r2r_kind) kind1, X(r2r_kind) kind2, \
- unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \
- int howmany_rank, \
- const X(iodim) *howmany_dims, \
- R *in, R *out, \
- const X(r2r_kind) *kind, unsigned flags); \
- \
-FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \
- int howmany_rank, \
- const X(iodim64) *howmany_dims, \
- R *in, R *out, \
- const X(r2r_kind) *kind, unsigned flags); \
- \
-FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \
- \
-FFTW_EXTERN void X(destroy_plan)(X(plan) p); \
-FFTW_EXTERN void X(forget_wisdom)(void); \
-FFTW_EXTERN void X(cleanup)(void); \
- \
-FFTW_EXTERN void X(set_timelimit)(double t); \
- \
-FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \
-FFTW_EXTERN int X(init_threads)(void); \
-FFTW_EXTERN void X(cleanup_threads)(void); \
-FFTW_EXTERN void X(make_planner_thread_safe)(void); \
- \
-FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \
-FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \
-FFTW_EXTERN char *X(export_wisdom_to_string)(void); \
-FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \
- void *data); \
-FFTW_EXTERN int X(import_system_wisdom)(void); \
-FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \
-FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \
-FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \
-FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \
- \
-FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \
-FFTW_EXTERN void X(print_plan)(const X(plan) p); \
-FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \
- \
-FFTW_EXTERN void *X(malloc)(size_t n); \
-FFTW_EXTERN R *X(alloc_real)(size_t n); \
-FFTW_EXTERN C *X(alloc_complex)(size_t n); \
-FFTW_EXTERN void X(free)(void *p); \
- \
-FFTW_EXTERN void X(flops)(const X(plan) p, \
- double *add, double *mul, double *fmas); \
-FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \
-FFTW_EXTERN double X(cost)(const X(plan) p); \
- \
-FFTW_EXTERN int X(alignment_of)(R *p); \
-FFTW_EXTERN const char X(version)[]; \
-FFTW_EXTERN const char X(cc)[]; \
-FFTW_EXTERN const char X(codelet_optim)[];
-
-
-/* end of FFTW_DEFINE_API macro */
-
-FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
-FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
-FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
-
-/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64
- for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \
- && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \
- && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__))
-# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
-/* note: __float128 is a typedef, which is not supported with the _Complex
- keyword in gcc, so instead we use this ugly __attribute__ version.
- However, we can't simply pass the __attribute__ version to
- FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer
- types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */
-# undef FFTW_DEFINE_COMPLEX
-# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C
-# endif
-FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex)
-#endif
-
-#define FFTW_FORWARD (-1)
-#define FFTW_BACKWARD (+1)
-
-#define FFTW_NO_TIMELIMIT (-1.0)
-
-/* documented flags */
-#define FFTW_MEASURE (0U)
-#define FFTW_DESTROY_INPUT (1U << 0)
-#define FFTW_UNALIGNED (1U << 1)
-#define FFTW_CONSERVE_MEMORY (1U << 2)
-#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
-#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
-#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
-#define FFTW_ESTIMATE (1U << 6)
-#define FFTW_WISDOM_ONLY (1U << 21)
-
-/* undocumented beyond-guru flags */
-#define FFTW_ESTIMATE_PATIENT (1U << 7)
-#define FFTW_BELIEVE_PCOST (1U << 8)
-#define FFTW_NO_DFT_R2HC (1U << 9)
-#define FFTW_NO_NONTHREADED (1U << 10)
-#define FFTW_NO_BUFFERING (1U << 11)
-#define FFTW_NO_INDIRECT_OP (1U << 12)
-#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
-#define FFTW_NO_RANK_SPLITS (1U << 14)
-#define FFTW_NO_VRANK_SPLITS (1U << 15)
-#define FFTW_NO_VRECURSE (1U << 16)
-#define FFTW_NO_SIMD (1U << 17)
-#define FFTW_NO_SLOW (1U << 18)
-#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
-#define FFTW_ALLOW_PRUNING (1U << 20)
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* FFTW3_H */
diff --git a/DSPManager_Free_BitPerfect/jni/main/kissfft/_kiss_fft_guts.h b/DSPManager_Free_BitPerfect/jni/main/kissfft/_kiss_fft_guts.h
new file mode 100644
index 0000000..6721eb7
--- /dev/null
+++ b/DSPManager_Free_BitPerfect/jni/main/kissfft/_kiss_fft_guts.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+/* kiss_fft.h
+ defines kiss_fft_scalar as either short or a float type
+ and defines
+ typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
+#include "kiss_fft.h"
+#include <limits.h>
+
+#define MAXFACTORS 32
+/* e.g. an fft of length 128 has 4 factors
+ as far as kissfft is concerned
+ 4*4*4*2
+ */
+
+struct kiss_fft_state{
+ int nfft;
+ int inverse;
+ int factors[2*MAXFACTORS];
+ kiss_fft_cpx twiddles[1];
+};
+
+/*
+ Explanation of macros dealing with complex math:
+
+ C_MUL(m,a,b) : m = a*b
+ C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
+ C_SUB( res, a,b) : res = a - b
+ C_SUBFROM( res , a) : res -= a
+ C_ADDTO( res , a) : res += a
+ * */
+# define S_MUL(a,b) ( (a)*(b) )
+#define C_MUL(m,a,b) \
+ do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
+ (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
+# define C_FIXDIV(c,div) /* NOOP */
+# define C_MULBYSCALAR( c, s ) \
+ do{ (c).r *= (s);\
+ (c).i *= (s); }while(0)
+#ifndef CHECK_OVERFLOW_OP
+# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
+#endif
+
+#define C_ADD( res, a,b)\
+ do { \
+ CHECK_OVERFLOW_OP((a).r,+,(b).r)\
+ CHECK_OVERFLOW_OP((a).i,+,(b).i)\
+ (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
+ }while(0)
+#define C_SUB( res, a,b)\
+ do { \
+ CHECK_OVERFLOW_OP((a).r,-,(b).r)\
+ CHECK_OVERFLOW_OP((a).i,-,(b).i)\
+ (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
+ }while(0)
+#define C_ADDTO( res , a)\
+ do { \
+ CHECK_OVERFLOW_OP((res).r,+,(a).r)\
+ CHECK_OVERFLOW_OP((res).i,+,(a).i)\
+ (res).r += (a).r; (res).i += (a).i;\
+ }while(0)
+
+#define C_SUBFROM( res , a)\
+ do {\
+ CHECK_OVERFLOW_OP((res).r,-,(a).r)\
+ CHECK_OVERFLOW_OP((res).i,-,(a).i)\
+ (res).r -= (a).r; (res).i -= (a).i; \
+ }while(0)
+
+
+# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
+# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
+# define HALF_OF(x) ((x)*.5f)
+#define kf_cexp(x,phase) \
+ do{ \
+ (x)->r = KISS_FFT_COS(phase);\
+ (x)->i = KISS_FFT_SIN(phase);\
+ }while(0)
+
+
+/* a debugging function */
+#define pcpx(c)\
+ fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
+
+
+#ifdef KISS_FFT_USE_ALLOCA
+// define this to allow use of alloca instead of malloc for temporary buffers
+// Temporary buffers are used in two case:
+// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
+// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform.
+#include <alloca.h>
+#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
+#define KISS_FFT_TMP_FREE(ptr)
+#else
+#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
+#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
+#endif
diff --git a/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fft.c b/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fft.c
new file mode 100644
index 0000000..af2f695
--- /dev/null
+++ b/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fft.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+
+#include "_kiss_fft_guts.h"
+/* The guts header contains all the multiplication and addition macros that are defined for
+ fixed or floating point complex numbers. It also delares the kf_ internal functions.
+ */
+
+static void kf_bfly2(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ int m
+ )
+{
+ kiss_fft_cpx * Fout2;
+ kiss_fft_cpx * tw1 = st->twiddles;
+ kiss_fft_cpx t;
+ Fout2 = Fout + m;
+ do{
+ C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
+
+ C_MUL (t, *Fout2 , *tw1);
+ tw1 += fstride;
+ C_SUB( *Fout2 , *Fout , t );
+ C_ADDTO( *Fout , t );
+ ++Fout2;
+ ++Fout;
+ }while (--m);
+}
+
+static void kf_bfly4(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ const size_t m
+ )
+{
+ kiss_fft_cpx *tw1,*tw2,*tw3;
+ kiss_fft_cpx scratch[6];
+ size_t k=m;
+ const size_t m2=2*m;
+ const size_t m3=3*m;
+
+
+ tw3 = tw2 = tw1 = st->twiddles;
+
+ do {
+ C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
+
+ C_MUL(scratch[0],Fout[m] , *tw1 );
+ C_MUL(scratch[1],Fout[m2] , *tw2 );
+ C_MUL(scratch[2],Fout[m3] , *tw3 );
+
+ C_SUB( scratch[5] , *Fout, scratch[1] );
+ C_ADDTO(*Fout, scratch[1]);
+ C_ADD( scratch[3] , scratch[0] , scratch[2] );
+ C_SUB( scratch[4] , scratch[0] , scratch[2] );
+ C_SUB( Fout[m2], *Fout, scratch[3] );
+ tw1 += fstride;
+ tw2 += fstride*2;
+ tw3 += fstride*3;
+ C_ADDTO( *Fout , scratch[3] );
+
+ if(st->inverse) {
+ Fout[m].r = scratch[5].r - scratch[4].i;
+ Fout[m].i = scratch[5].i + scratch[4].r;
+ Fout[m3].r = scratch[5].r + scratch[4].i;
+ Fout[m3].i = scratch[5].i - scratch[4].r;
+ }else{
+ Fout[m].r = scratch[5].r + scratch[4].i;
+ Fout[m].i = scratch[5].i - scratch[4].r;
+ Fout[m3].r = scratch[5].r - scratch[4].i;
+ Fout[m3].i = scratch[5].i + scratch[4].r;
+ }
+ ++Fout;
+ }while(--k);
+}
+
+static void kf_bfly3(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ size_t m
+ )
+{
+ size_t k=m;
+ const size_t m2 = 2*m;
+ kiss_fft_cpx *tw1,*tw2;
+ kiss_fft_cpx scratch[5];
+ kiss_fft_cpx epi3;
+ epi3 = st->twiddles[fstride*m];
+
+ tw1=tw2=st->twiddles;
+
+ do{
+ C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
+
+ C_MUL(scratch[1],Fout[m] , *tw1);
+ C_MUL(scratch[2],Fout[m2] , *tw2);
+
+ C_ADD(scratch[3],scratch[1],scratch[2]);
+ C_SUB(scratch[0],scratch[1],scratch[2]);
+ tw1 += fstride;
+ tw2 += fstride*2;
+
+ Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
+ Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
+
+ C_MULBYSCALAR( scratch[0] , epi3.i );
+
+ C_ADDTO(*Fout,scratch[3]);
+
+ Fout[m2].r = Fout[m].r + scratch[0].i;
+ Fout[m2].i = Fout[m].i - scratch[0].r;
+
+ Fout[m].r -= scratch[0].i;
+ Fout[m].i += scratch[0].r;
+
+ ++Fout;
+ }while(--k);
+}
+
+static void kf_bfly5(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ int m
+ )
+{
+ kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
+ int u;
+ kiss_fft_cpx scratch[13];
+ kiss_fft_cpx * twiddles = st->twiddles;
+ kiss_fft_cpx *tw;
+ kiss_fft_cpx ya,yb;
+ ya = twiddles[fstride*m];
+ yb = twiddles[fstride*2*m];
+
+ Fout0=Fout;
+ Fout1=Fout0+m;
+ Fout2=Fout0+2*m;
+ Fout3=Fout0+3*m;
+ Fout4=Fout0+4*m;
+
+ tw=st->twiddles;
+ for ( u=0; u<m; ++u ) {
+ C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
+ scratch[0] = *Fout0;
+
+ C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
+ C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
+ C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
+ C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
+
+ C_ADD( scratch[7],scratch[1],scratch[4]);
+ C_SUB( scratch[10],scratch[1],scratch[4]);
+ C_ADD( scratch[8],scratch[2],scratch[3]);
+ C_SUB( scratch[9],scratch[2],scratch[3]);
+
+ Fout0->r += scratch[7].r + scratch[8].r;
+ Fout0->i += scratch[7].i + scratch[8].i;
+
+ scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
+ scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
+
+ scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
+ scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
+
+ C_SUB(*Fout1,scratch[5],scratch[6]);
+ C_ADD(*Fout4,scratch[5],scratch[6]);
+
+ scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
+ scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
+ scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
+ scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
+
+ C_ADD(*Fout2,scratch[11],scratch[12]);
+ C_SUB(*Fout3,scratch[11],scratch[12]);
+
+ ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
+ }
+}
+
+/* perform the butterfly for one stage of a mixed radix FFT */
+static void kf_bfly_generic(
+ kiss_fft_cpx * Fout,
+ const size_t fstride,
+ const kiss_fft_cfg st,
+ int m,
+ int p
+ )
+{
+ int u,k,q1,q;
+ kiss_fft_cpx * twiddles = st->twiddles;
+ kiss_fft_cpx t;
+ int Norig = st->nfft;
+
+ kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p);
+
+ for ( u=0; u<m; ++u ) {
+ k=u;
+ for ( q1=0 ; q1<p ; ++q1 ) {
+ scratch[q1] = Fout[ k ];
+ C_FIXDIV(scratch[q1],p);
+ k += m;
+ }
+
+ k=u;
+ for ( q1=0 ; q1<p ; ++q1 ) {
+ int twidx=0;
+ Fout[ k ] = scratch[0];
+ for (q=1;q<p;++q ) {
+ twidx += fstride * k;
+ if (twidx>=Norig) twidx-=Norig;
+ C_MUL(t,scratch[q] , twiddles[twidx] );
+ C_ADDTO( Fout[ k ] ,t);
+ }
+ k += m;
+ }
+ }
+ KISS_FFT_TMP_FREE(scratch);
+}
+
+static
+void kf_work(
+ kiss_fft_cpx * Fout,
+ const kiss_fft_cpx * f,
+ const size_t fstride,
+ int in_stride,
+ int * factors,
+ const kiss_fft_cfg st
+ )
+{
+ kiss_fft_cpx * Fout_beg=Fout;
+ const int p=*factors++; /* the radix */
+ const int m=*factors++; /* stage's fft length/p */
+ const kiss_fft_cpx * Fout_end = Fout + p*m;
+
+#ifdef _OPENMP
+ // use openmp extensions at the
+ // top-level (not recursive)
+ if (fstride==1 && p<=5)
+ {
+ int k;
+
+ // execute the p different work units in different threads
+# pragma omp parallel for
+ for (k=0;k<p;++k)
+ kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
+ // all threads have joined by this point
+
+ switch (p) {
+ case 2: kf_bfly2(Fout,fstride,st,m); break;
+ case 3: kf_bfly3(Fout,fstride,st,m); break;
+ case 4: kf_bfly4(Fout,fstride,st,m); break;
+ case 5: kf_bfly5(Fout,fstride,st,m); break;
+ default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+ }
+ return;
+ }
+#endif
+
+ if (m==1) {
+ do{
+ *Fout = *f;
+ f += fstride*in_stride;
+ }while(++Fout != Fout_end );
+ }else{
+ do{
+ // recursive call:
+ // DFT of size m*p performed by doing
+ // p instances of smaller DFTs of size m,
+ // each one takes a decimated version of the input
+ kf_work( Fout , f, fstride*p, in_stride, factors,st);
+ f += fstride*in_stride;
+ }while( (Fout += m) != Fout_end );
+ }
+
+ Fout=Fout_beg;
+
+ // recombine the p smaller DFTs
+ switch (p) {
+ case 2: kf_bfly2(Fout,fstride,st,m); break;
+ case 3: kf_bfly3(Fout,fstride,st,m); break;
+ case 4: kf_bfly4(Fout,fstride,st,m); break;
+ case 5: kf_bfly5(Fout,fstride,st,m); break;
+ default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+ }
+}
+
+/* facbuf is populated by p1,m1,p2,m2, ...
+ where
+ p[i] * m[i] = m[i-1]
+ m0 = n */
+static
+void kf_factor(int n,int * facbuf)
+{
+ int p=4;
+ double floor_sqrt;
+ floor_sqrt = floor( sqrt((double)n) );
+
+ /*factor out powers of 4, powers of 2, then any remaining primes */
+ do {
+ while (n % p) {
+ switch (p) {
+ case 4: p = 2; break;
+ case 2: p = 3; break;
+ default: p += 2; break;
+ }
+ if (p > floor_sqrt)
+ p = n; /* no more factors, skip to end */
+ }
+ n /= p;
+ *facbuf++ = p;
+ *facbuf++ = n;
+ } while (n > 1);
+}
+
+/*
+ *
+ * User-callable function to allocate all necessary storage space for the fft.
+ *
+ * The return value is a contiguous block of memory, allocated with malloc. As such,
+ * It can be freed with free(), rather than a kiss_fft-specific function.
+ * */
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
+{
+ kiss_fft_cfg st=NULL;
+ size_t memneeded = sizeof(struct kiss_fft_state)
+ + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
+
+ if ( lenmem==NULL ) {
+ st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
+ }else{
+ if (mem != NULL && *lenmem >= memneeded)
+ st = (kiss_fft_cfg)mem;
+ *lenmem = memneeded;
+ }
+ if (st) {
+ int i;
+ st->nfft=nfft;
+ st->inverse = inverse_fft;
+
+ for (i=0;i<nfft;++i) {
+ const double pi=3.141592653589793238462643383279502884197169399375105820974944;
+ double phase = -2*pi*i / nfft;
+ if (st->inverse)
+ phase *= -1;
+ kf_cexp(st->twiddles+i, phase );
+ }
+
+ kf_factor(nfft,st->factors);
+ }
+ return st;
+}
+
+
+void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
+{
+ if (fin == fout) {
+ //NOTE: this is not really an in-place FFT algorithm.
+ //It just performs an out-of-place FFT into a temp buffer
+ kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
+ kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
+ memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
+ KISS_FFT_TMP_FREE(tmpbuf);
+ }else{
+ kf_work( fout, fin, 1,in_stride, st->factors,st );
+ }
+}
+
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
+{
+ kiss_fft_stride(cfg,fin,fout,1);
+}
+
+
+void kiss_fft_cleanup(void)
+{
+ // nothing needed any more
+}
+
+int kiss_fft_next_fast_size(int n)
+{
+ while(1) {
+ int m=n;
+ while ( (m%2) == 0 ) m/=2;
+ while ( (m%3) == 0 ) m/=3;
+ while ( (m%5) == 0 ) m/=5;
+ if (m<=1)
+ break; /* n is completely factorable by twos, threes, and fives */
+ n++;
+ }
+ return n;
+}
diff --git a/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fft.h b/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fft.h
new file mode 100644
index 0000000..c02a43d
--- /dev/null
+++ b/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fft.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#ifndef KISS_FFT_H
+#define KISS_FFT_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ ATTENTION!
+ If you would like a :
+ -- a utility that will handle the caching of fft objects
+ -- real-only (no imaginary time component ) FFT
+ -- a multi-dimensional FFT
+ -- a command-line utility to perform ffts
+ -- a command-line utility to perform fast-convolution filtering
+
+ Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
+ in the tools/ directory.
+*/
+
+#ifdef USE_SIMD
+# include <xmmintrin.h>
+# define kiss_fft_scalar __m128
+#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
+#define KISS_FFT_FREE _mm_free
+#else
+#define KISS_FFT_MALLOC malloc
+#define KISS_FFT_FREE free
+#endif
+# ifndef kiss_fft_scalar
+/* default is float */
+# define kiss_fft_scalar double
+# endif
+
+typedef struct {
+ kiss_fft_scalar r;
+ kiss_fft_scalar i;
+}kiss_fft_cpx;
+
+typedef struct kiss_fft_state* kiss_fft_cfg;
+
+/*
+ * kiss_fft_alloc
+ *
+ * Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
+ *
+ * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
+ *
+ * The return value from fft_alloc is a cfg buffer used internally
+ * by the fft routine or NULL.
+ *
+ * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
+ * The returned value should be free()d when done to avoid memory leaks.
+ *
+ * The state can be placed in a user supplied buffer 'mem':
+ * If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
+ * then the function places the cfg in mem and the size used in *lenmem
+ * and returns mem.
+ *
+ * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
+ * then the function returns NULL and places the minimum cfg
+ * buffer size in *lenmem.
+ * */
+
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
+
+/*
+ * kiss_fft(cfg,in_out_buf)
+ *
+ * Perform an FFT on a complex input buffer.
+ * for a forward FFT,
+ * fin should be f[0] , f[1] , ... ,f[nfft-1]
+ * fout will be F[0] , F[1] , ... ,F[nfft-1]
+ * Note that each element is complex and can be accessed like
+ f[k].r and f[k].i
+ * */
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
+
+/*
+ A more generic version of the above function. It reads its input from every Nth sample.
+ * */
+void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
+
+/* If kiss_fft_alloc allocated a buffer, it is one contiguous
+ buffer and can be simply free()d when no longer needed*/
+#define kiss_fft_free KISS_FFT_FREE
+
+/*
+ Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
+ your compiler output to call this before you exit.
+*/
+void kiss_fft_cleanup(void);
+
+
+/*
+ * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
+ */
+int kiss_fft_next_fast_size(int n);
+
+/* for real ffts, we need an even size */
+#define kiss_fftr_next_fast_size_real(n) \
+ (kiss_fft_next_fast_size( ((n)+1)>>1)<<1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fftr.c b/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fftr.c
new file mode 100644
index 0000000..8102132
--- /dev/null
+++ b/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fftr.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#include "kiss_fftr.h"
+#include "_kiss_fft_guts.h"
+
+struct kiss_fftr_state{
+ kiss_fft_cfg substate;
+ kiss_fft_cpx * tmpbuf;
+ kiss_fft_cpx * super_twiddles;
+#ifdef USE_SIMD
+ void * pad;
+#endif
+};
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
+{
+ int i;
+ kiss_fftr_cfg st = NULL;
+ size_t subsize = 0, memneeded;
+
+ if (nfft & 1) {
+ fprintf(stderr,"Real FFT optimization must be even.\n");
+ return NULL;
+ }
+ nfft >>= 1;
+
+ kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
+ memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2);
+
+ if (lenmem == NULL) {
+ st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
+ } else {
+ if (*lenmem >= memneeded)
+ st = (kiss_fftr_cfg) mem;
+ *lenmem = memneeded;
+ }
+ if (!st)
+ return NULL;
+
+ st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
+ st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
+ st->super_twiddles = st->tmpbuf + nfft;
+ kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
+
+ for (i = 0; i < nfft/2; ++i) {
+ double phase =
+ -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5);
+ if (inverse_fft)
+ phase *= -1;
+ kf_cexp (st->super_twiddles+i,phase);
+ }
+ return st;
+}
+
+void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
+{
+ /* input buffer timedata is stored row-wise */
+ int k,ncfft;
+ kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
+
+ if ( st->substate->inverse) {
+ fprintf(stderr,"kiss fft usage error: improper alloc\n");
+ exit(1);
+ }
+
+ ncfft = st->substate->nfft;
+
+ /*perform the parallel fft of two real signals packed in real,imag*/
+ kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
+ /* The real part of the DC element of the frequency spectrum in st->tmpbuf
+ * contains the sum of the even-numbered elements of the input time sequence
+ * The imag part is the sum of the odd-numbered elements
+ *
+ * The sum of tdc.r and tdc.i is the sum of the input time sequence.
+ * yielding DC of input time sequence
+ * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
+ * yielding Nyquist bin of input time sequence
+ */
+
+ tdc.r = st->tmpbuf[0].r;
+ tdc.i = st->tmpbuf[0].i;
+ C_FIXDIV(tdc,2);
+ CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
+ CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
+ freqdata[0].r = tdc.r + tdc.i;
+ freqdata[ncfft].r = tdc.r - tdc.i;
+#ifdef USE_SIMD
+ freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
+#else
+ freqdata[ncfft].i = freqdata[0].i = 0;
+#endif
+
+ for ( k=1;k <= ncfft/2 ; ++k ) {
+ fpk = st->tmpbuf[k];
+ fpnk.r = st->tmpbuf[ncfft-k].r;
+ fpnk.i = - st->tmpbuf[ncfft-k].i;
+ C_FIXDIV(fpk,2);
+ C_FIXDIV(fpnk,2);
+
+ C_ADD( f1k, fpk , fpnk );
+ C_SUB( f2k, fpk , fpnk );
+ C_MUL( tw , f2k , st->super_twiddles[k-1]);
+
+ freqdata[k].r = HALF_OF(f1k.r + tw.r);
+ freqdata[k].i = HALF_OF(f1k.i + tw.i);
+ freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);
+ freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);
+ }
+}
+
+void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
+{
+ /* input buffer timedata is stored row-wise */
+ int k, ncfft;
+
+ if (st->substate->inverse == 0) {
+ fprintf (stderr, "kiss fft usage error: improper alloc\n");
+ exit (1);
+ }
+
+ ncfft = st->substate->nfft;
+
+ st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
+ st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
+ C_FIXDIV(st->tmpbuf[0],2);
+
+ for (k = 1; k <= ncfft / 2; ++k) {
+ kiss_fft_cpx fk, fnkc, fek, fok, tmp;
+ fk = freqdata[k];
+ fnkc.r = freqdata[ncfft - k].r;
+ fnkc.i = -freqdata[ncfft - k].i;
+ C_FIXDIV( fk , 2 );
+ C_FIXDIV( fnkc , 2 );
+
+ C_ADD (fek, fk, fnkc);
+ C_SUB (tmp, fk, fnkc);
+ C_MUL (fok, tmp, st->super_twiddles[k-1]);
+ C_ADD (st->tmpbuf[k], fek, fok);
+ C_SUB (st->tmpbuf[ncfft - k], fek, fok);
+#ifdef USE_SIMD
+ st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
+#else
+ st->tmpbuf[ncfft - k].i *= -1;
+#endif
+ }
+ kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
+}
diff --git a/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fftr.h b/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fftr.h
new file mode 100644
index 0000000..588948d
--- /dev/null
+++ b/DSPManager_Free_BitPerfect/jni/main/kissfft/kiss_fftr.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#ifndef KISS_FTR_H
+#define KISS_FTR_H
+
+#include "kiss_fft.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+
+ Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
+
+
+
+ */
+
+typedef struct kiss_fftr_state *kiss_fftr_cfg;
+
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
+/*
+ nfft must be even
+
+ If you don't care to allocate space, use mem = lenmem = NULL
+*/
+
+
+void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
+/*
+ input timedata has nfft scalar points
+ output freqdata has nfft/2+1 complex points
+*/
+
+void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
+/*
+ input freqdata has nfft/2+1 complex points
+ output timedata has nfft scalar points
+*/
+
+#define kiss_fftr_free KISS_FFT_FREE
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/DSPManager_Free_BitPerfect/res/values-zh-rTW/strings.xml b/DSPManager_Free_BitPerfect/res/values-zh-rTW/strings.xml
index 265ea22..0baa794 100644
--- a/DSPManager_Free_BitPerfect/res/values-zh-rTW/strings.xml
+++ b/DSPManager_Free_BitPerfect/res/values-zh-rTW/strings.xml
@@ -33,15 +33,6 @@
<string name="dialog_freq">濾波頻率</string>
<string name="dialog_effect">效果程度</string>
<string name="pref_equalizer_title">FIR等化器</string>
- <string name="pref_strequalizer_title">任意響應濾波器</string>
- <string name="pref_strequalizer_summary_on">使用任意響應濾波器</string>
- <string name="pref_strequalizer_summary_off">關閉任意響應濾波器</string>
- <string name="dialog_magnitude_response">幅度增益字串輸入</string>
- <string name="pref_strphase_title">任意移相器</string>
- <string name="pref_strphase_summary_on">使用任意移相器</string>
- <string name="pref_strphase_summary_off">關閉任意移相器</string>
- <string name="dialog_phaseleft_response">左聲道相位響應字串輸入</string>
- <string name="dialog_phaseright_response">右聲道相位響應字串輸入</string>
<string name="pref_equalizer_summary_on">已啟用混合等化器</string>
<string name="pref_equalizer_summary_off">已停用混合等化器</string>
<string name="pref_equalizer_enable">使用混合等化器</string>
@@ -113,10 +104,6 @@
<string name="pref_headset_bs2b_summary_off">已停用BS2B</string>
<string name="dialog_bs2b">BS2B預置</string>
<string name="pref_headset_bs2b_enable">使用BS2B</string>
- <string name="pref_headset_pams_title">TruCentre with Joe0Bloggs filter</string>
- <string name="pref_headset_pamss_summary_on">已啟用TruCentre環繞</string>
- <string name="pref_headset_pamss_summary_off">已停用TruCentre環繞</string>
- <string name="pref_headset_pamss_enable">使用TruCentre環繞</string>
<string name="eq_preset_flat">平淡</string>
<string name="eq_preset_custom">自訂</string>
diff --git a/DSPManager_Free_BitPerfect/res/values/arrays.xml b/DSPManager_Free_BitPerfect/res/values/arrays.xml
index 237996c..dc82df4 100644
--- a/DSPManager_Free_BitPerfect/res/values/arrays.xml
+++ b/DSPManager_Free_BitPerfect/res/values/arrays.xml
@@ -87,16 +87,6 @@
<item>2</item>
</string-array>
- <string-array name="equalizer_stringfiltertype">
- <item>Minimum phase</item>
- <item>Linear phase</item>
- </string-array>
-
- <string-array name="equalizer_stringfiltertype_values" translatable="false">
- <item>0</item>
- <item>1</item>
- </string-array>
-
<string-array name="quality_level">
<item>Truncate to 40&#65130;</item>
<item>Truncate to 50&#65130;</item>
diff --git a/DSPManager_Free_BitPerfect/res/values/strings.xml b/DSPManager_Free_BitPerfect/res/values/strings.xml
index 0e3a986..a047268 100644
--- a/DSPManager_Free_BitPerfect/res/values/strings.xml
+++ b/DSPManager_Free_BitPerfect/res/values/strings.xml
@@ -27,17 +27,6 @@
<string name="pref_effect_freq_title">Cutoff frequency [Int:30 &#8211; 300]Hz</string>
<string name="dialog_effect">Effect strength</string>
<string name="pref_equalizer_title">Mixed Equalizer</string>
- <string name="pref_strequalizer_enable">Enable Arbitrary Magnitude Response Equalizer</string>
- <string name="pref_strphase_enable">Enable Arbitrary Phase Response Equalizer</string>
- <string name="pref_strequalizer_title">Arbitrary Response Equalizer</string>
- <string name="pref_strequalizer_summary_on">Arbitrary magnitude is enabled</string>
- <string name="pref_strequalizer_summary_off">Arbitrary magnitude is disabled</string>
- <string name="dialog_magnitude_response">Magnitude response string</string>
- <string name="pref_strphase_title">Arbitrary Phase Response</string>
- <string name="pref_strphase_summary_on">Arbitrary Phase is enabled</string>
- <string name="pref_strphase_summary_off">Arbitrary Phase is disabled</string>
- <string name="dialog_phaseleft_response">Phase response(Left) string</string>
- <string name="dialog_phaseright_response">Phase response(Right) string</string>
<string name="pref_equalizer_summary_on">Hybrid Equalizer is enabled</string>
<string name="pref_equalizer_summary_off">Hybrid Equalizer is disabled</string>
<string name="pref_equalizer_enable">Enable</string>
@@ -109,10 +98,6 @@
<string name="pref_headset_bs2b_summary_off">BS2B is disabled</string>
<string name="dialog_bs2b">BS2B Preset</string>
<string name="pref_headset_bs2b_enable">Enable BS2B</string>
- <string name="pref_headset_pams_title">TruCentre with Joe0Bloggs filter</string>
- <string name="pref_headset_pamss_summary_on">TruCentre is enabled</string>
- <string name="pref_headset_pamss_summary_off">TruCentre is disabled</string>
- <string name="pref_headset_pamss_enable">Enable TruCentre Surround</string>
<string name="eq_preset_flat">Flat</string>
<string name="eq_preset_custom">Custom</string>
diff --git a/DSPManager_Free_BitPerfect/res/xml/bluetooth_preferences.xml b/DSPManager_Free_BitPerfect/res/xml/bluetooth_preferences.xml
index 519131a..49ecb6d 100644
--- a/DSPManager_Free_BitPerfect/res/xml/bluetooth_preferences.xml
+++ b/DSPManager_Free_BitPerfect/res/xml/bluetooth_preferences.xml
@@ -118,47 +118,6 @@
android:entryValues="@array/equalizer_preset_values" />
<james.dsp.preference.EqualizerPreference android:key="dsp.tone.eq.custom" />
</PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_strequalizer_title">
- <CheckBoxPreference
- android:disableDependentsState="false"
- android:key="dsp.streq.enable"
- android:summaryOn="@string/pref_strequalizer_summary_on"
- android:summaryOff="@string/pref_strequalizer_summary_off"
- android:title="@string/pref_strequalizer_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedListPreference
- android:defaultValue="0"
- android:dialogTitle="@string/dialog_filtertype"
- android:entries="@array/equalizer_stringfiltertype"
- android:entryValues="@array/equalizer_stringfiltertype_values"
- android:title="@string/dialog_filtertype"
- android:key="dsp.streq.filtertype" />
- <james.dsp.preference.SummariedTextPreferenceRanged
- android:key="dsp.streq.stringp"
- android:defaultValue="GraphicEQ: 0.0 0.0; "
- android:dialogTitle="@string/dialog_magnitude_response"
- android:title="@string/dialog_magnitude_response"
- android:inputType="textMultiLine" />
- </PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_strphase_title">
- <CheckBoxPreference
- android:disableDependentsState="false"
- android:key="dsp.strph.enable"
- android:summaryOn="@string/pref_strphase_summary_on"
- android:summaryOff="@string/pref_strphase_summary_off"
- android:title="@string/pref_strphase_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedTextPreferenceRanged
- android:key="dsp.strph.stringleft"
- android:defaultValue="PhaseShifterLeft: 0.0 0.0; "
- android:dialogTitle="@string/dialog_phaseleft_response"
- android:title="@string/dialog_phaseleft_response"
- android:inputType="textMultiLine" />
- <james.dsp.preference.SummariedTextPreferenceRanged
- android:key="dsp.strph.stringright"
- android:defaultValue="PhaseShifterRight: 0.0 180.0; 22000.0 180.0"
- android:dialogTitle="@string/dialog_phaseright_response"
- android:title="@string/dialog_phaseright_response"
- android:inputType="textMultiLine" />
- </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_convolver_title"
android:key="dsp.convolver">
@@ -249,19 +208,4 @@
android:title="@string/dialog_bs2b"
android:key="dsp.bs2b.mode" />
</PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_headset_virtual_title">
- <CheckBoxPreference
- android:key="dsp.headphone.enable"
- android:disableDependentsState="false"
- android:summaryOn="@string/pref_headset_virtual_summary_on"
- android:summaryOff="@string/pref_headset_virtual_summary_off"
- android:title="@string/pref_headset_virtual_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedListPreference
- android:defaultValue="15"
- android:dialogTitle="@string/dialog_room"
- android:entries="@array/headphone_preset"
- android:entryValues="@array/headphone_preset_values"
- android:title="@string/pref_room_title"
- android:key="dsp.headphone.preset" />
- </PreferenceCategory>
</PreferenceScreen> \ No newline at end of file
diff --git a/DSPManager_Free_BitPerfect/res/xml/headset_preferences.xml b/DSPManager_Free_BitPerfect/res/xml/headset_preferences.xml
index 519131a..49ecb6d 100644
--- a/DSPManager_Free_BitPerfect/res/xml/headset_preferences.xml
+++ b/DSPManager_Free_BitPerfect/res/xml/headset_preferences.xml
@@ -118,47 +118,6 @@
android:entryValues="@array/equalizer_preset_values" />
<james.dsp.preference.EqualizerPreference android:key="dsp.tone.eq.custom" />
</PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_strequalizer_title">
- <CheckBoxPreference
- android:disableDependentsState="false"
- android:key="dsp.streq.enable"
- android:summaryOn="@string/pref_strequalizer_summary_on"
- android:summaryOff="@string/pref_strequalizer_summary_off"
- android:title="@string/pref_strequalizer_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedListPreference
- android:defaultValue="0"
- android:dialogTitle="@string/dialog_filtertype"
- android:entries="@array/equalizer_stringfiltertype"
- android:entryValues="@array/equalizer_stringfiltertype_values"
- android:title="@string/dialog_filtertype"
- android:key="dsp.streq.filtertype" />
- <james.dsp.preference.SummariedTextPreferenceRanged
- android:key="dsp.streq.stringp"
- android:defaultValue="GraphicEQ: 0.0 0.0; "
- android:dialogTitle="@string/dialog_magnitude_response"
- android:title="@string/dialog_magnitude_response"
- android:inputType="textMultiLine" />
- </PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_strphase_title">
- <CheckBoxPreference
- android:disableDependentsState="false"
- android:key="dsp.strph.enable"
- android:summaryOn="@string/pref_strphase_summary_on"
- android:summaryOff="@string/pref_strphase_summary_off"
- android:title="@string/pref_strphase_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedTextPreferenceRanged
- android:key="dsp.strph.stringleft"
- android:defaultValue="PhaseShifterLeft: 0.0 0.0; "
- android:dialogTitle="@string/dialog_phaseleft_response"
- android:title="@string/dialog_phaseleft_response"
- android:inputType="textMultiLine" />
- <james.dsp.preference.SummariedTextPreferenceRanged
- android:key="dsp.strph.stringright"
- android:defaultValue="PhaseShifterRight: 0.0 180.0; 22000.0 180.0"
- android:dialogTitle="@string/dialog_phaseright_response"
- android:title="@string/dialog_phaseright_response"
- android:inputType="textMultiLine" />
- </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_convolver_title"
android:key="dsp.convolver">
@@ -249,19 +208,4 @@
android:title="@string/dialog_bs2b"
android:key="dsp.bs2b.mode" />
</PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_headset_virtual_title">
- <CheckBoxPreference
- android:key="dsp.headphone.enable"
- android:disableDependentsState="false"
- android:summaryOn="@string/pref_headset_virtual_summary_on"
- android:summaryOff="@string/pref_headset_virtual_summary_off"
- android:title="@string/pref_headset_virtual_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedListPreference
- android:defaultValue="15"
- android:dialogTitle="@string/dialog_room"
- android:entries="@array/headphone_preset"
- android:entryValues="@array/headphone_preset_values"
- android:title="@string/pref_room_title"
- android:key="dsp.headphone.preset" />
- </PreferenceCategory>
</PreferenceScreen> \ No newline at end of file
diff --git a/DSPManager_Free_BitPerfect/res/xml/speaker_preferences.xml b/DSPManager_Free_BitPerfect/res/xml/speaker_preferences.xml
index 85a2d01..49ecb6d 100644
--- a/DSPManager_Free_BitPerfect/res/xml/speaker_preferences.xml
+++ b/DSPManager_Free_BitPerfect/res/xml/speaker_preferences.xml
@@ -118,63 +118,7 @@
android:entryValues="@array/equalizer_preset_values" />
<james.dsp.preference.EqualizerPreference android:key="dsp.tone.eq.custom" />
</PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_strequalizer_title">
- <CheckBoxPreference
- android:disableDependentsState="false"
- android:key="dsp.streq.enable"
- android:summaryOn="@string/pref_strequalizer_summary_on"
- android:summaryOff="@string/pref_strequalizer_summary_off"
- android:title="@string/pref_strequalizer_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedListPreference
- android:defaultValue="0"
- android:dialogTitle="@string/dialog_filtertype"
- android:entries="@array/equalizer_stringfiltertype"
- android:entryValues="@array/equalizer_stringfiltertype_values"
- android:title="@string/dialog_filtertype"
- android:key="dsp.streq.filtertype" />
- <james.dsp.preference.SummariedTextPreferenceRanged
- android:key="dsp.streq.stringp"
- android:defaultValue="GraphicEQ: 0.0 0.0; "
- android:dialogTitle="@string/dialog_magnitude_response"
- android:title="@string/dialog_magnitude_response"
- android:inputType="textMultiLine" />
- </PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_strphase_title">
- <CheckBoxPreference
- android:disableDependentsState="false"
- android:key="dsp.strph.enable"
- android:summaryOn="@string/pref_strphase_summary_on"
- android:summaryOff="@string/pref_strphase_summary_off"
- android:title="@string/pref_strphase_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedTextPreferenceRanged
- android:key="dsp.strph.stringleft"
- android:defaultValue="PhaseShifterLeft: 0.0 0.0; "
- android:dialogTitle="@string/dialog_phaseleft_response"
- android:title="@string/dialog_phaseleft_response"
- android:inputType="textMultiLine" />
- <james.dsp.preference.SummariedTextPreferenceRanged
- android:key="dsp.strph.stringright"
- android:defaultValue="PhaseShifterRight: 0.0 180.0; 22000.0 180.0"
- android:dialogTitle="@string/dialog_phaseright_response"
- android:title="@string/dialog_phaseright_response"
- android:inputType="textMultiLine" />
- </PreferenceCategory>
- <PreferenceCategory android:title="@string/pref_headset_virtual_title">
- <CheckBoxPreference
- android:key="dsp.headphone.enable"
- android:disableDependentsState="false"
- android:summaryOn="@string/pref_headset_virtual_summary_on"
- android:summaryOff="@string/pref_headset_virtual_summary_off"
- android:title="@string/pref_headset_virtual_enable"></CheckBoxPreference>
- <james.dsp.preference.SummariedListPreference
- android:defaultValue="0"
- android:dialogTitle="@string/dialog_room"
- android:entries="@array/headphone_preset"
- android:entryValues="@array/headphone_preset_values"
- android:title="@string/pref_room_title"
- android:key="dsp.headphone.preset" />
- </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_convolver_title"
android:key="dsp.convolver">
<CheckBoxPreference
@@ -207,6 +151,19 @@
android:title="@string/dialog_quality"
android:key="dsp.convolver.quality" />
</PreferenceCategory>
+ <PreferenceCategory android:title="@string/pref_ddc_title" android:key="dsp.ddc">
+ <CheckBoxPreference
+ android:key="dsp.ddc.enable"
+ android:disableDependentsState="false"
+ android:summaryOn="@string/pref_ddc_summary_on"
+ android:summaryOff="@string/pref_ddc_summary_off"
+ android:title="@string/pref_ddc_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreferenceDDC
+ android:title="@string/dialog_sosmatrix"
+ android:key="dsp.ddc.files"
+ android:defaultValue=""
+ android:dialogTitle="@string/dialog_sosmatrix" />
+ </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_analogmodelling_title"
android:key="dsp.analogmodelling">
<CheckBoxPreference
@@ -223,4 +180,32 @@
android:inputType="numberDecimal"
android:digits="0123456789." />
</PreferenceCategory>
+ <PreferenceCategory android:title="@string/pref_headset_soundpos_title">
+ <CheckBoxPreference
+ android:key="dsp.stereowide.enable"
+ android:disableDependentsState="false"
+ android:summaryOn="@string/pref_headset_stereowide_summary_on"
+ android:summaryOff="@string/pref_headset_stereowide_summary_off"
+ android:title="@string/pref_headset_stereowide_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreference
+ android:defaultValue="0"
+ android:dialogTitle="@string/dialog_stereo"
+ android:entries="@array/stereowide_modes"
+ android:entryValues="@array/stereowide_values"
+ android:title="@string/dialog_stereo"
+ android:key="dsp.stereowide.mode" />
+ <CheckBoxPreference
+ android:key="dsp.bs2b.enable"
+ android:disableDependentsState="false"
+ android:summaryOn="@string/pref_headset_bs2b_summary_on"
+ android:summaryOff="@string/pref_headset_bs2b_summary_off"
+ android:title="@string/pref_headset_bs2b_enable"></CheckBoxPreference>
+ <james.dsp.preference.SummariedListPreference
+ android:defaultValue="0"
+ android:dialogTitle="@string/dialog_bs2b"
+ android:entries="@array/bs2b_modes"
+ android:entryValues="@array/bs2b_values"
+ android:title="@string/dialog_bs2b"
+ android:key="dsp.bs2b.mode" />
+ </PreferenceCategory>
</PreferenceScreen> \ No newline at end of file
diff --git a/DSPManager_Free_BitPerfect/src/james/dsp/service/HeadsetService.java b/DSPManager_Free_BitPerfect/src/james/dsp/service/HeadsetService.java
index 7e1107d..6eabb82 100644
--- a/DSPManager_Free_BitPerfect/src/james/dsp/service/HeadsetService.java
+++ b/DSPManager_Free_BitPerfect/src/james/dsp/service/HeadsetService.java
@@ -661,8 +661,6 @@ class StartUpOptimiserThread implements Runnable {
int compressorEnabled = preferences.getBoolean("dsp.compression.enable", false) ? 1 : 0;
int bassBoostEnabled = preferences.getBoolean("dsp.bass.enable", false) ? 1 : 0;
int equalizerEnabled = preferences.getBoolean("dsp.tone.enable", false) ? 1 : 0;
- int stringEqEnabled = preferences.getBoolean("dsp.streq.enable", false) ? 1 : 0;
- int phaseEqEnabled = preferences.getBoolean("dsp.strph.enable", false) ? 1 : 0;
int reverbEnabled = preferences.getBoolean("dsp.headphone.enable", false) ? 1 : 0;
int stereoWideEnabled = preferences.getBoolean("dsp.stereowide.enable", false) ? 1 : 0;
int bs2bEnabled = preferences.getBoolean("dsp.bs2b.enable", false) ? 1 : 0;
@@ -733,47 +731,6 @@ class StartUpOptimiserThread implements Runnable {
}
session.setParameterFloatArray(session.JamesDSP, 115, eqLevels);
}
- session.setParameterShort(session.JamesDSP, 152, Short.valueOf(preferences.getString("dsp.streq.filtertype", "0")));
- session.setParameterShort(session.JamesDSP, 1210, (short)stringEqEnabled); // String equalizer switch
- if (stringEqEnabled == 1 && updateMajor)
- {
- String eqText = preferences.getString("dsp.streq.stringp", "GraphicEQ: 0.0 0.0; ");
- int arraySize2Send = 256;
- int stringLength = eqText.length();
- int numTime2Send = (int)Math.ceil((double)stringLength / arraySize2Send); // Number of times that have to send
- session.setParameterIntArray(session.JamesDSP, 8888, new int[]{ numTime2Send, arraySize2Send }); // Send buffer info for module to allocate memory
- for (int i = 0; i < numTime2Send; i++)
- {
- session.setParameterShort(session.JamesDSP, 10005, (short)i); // Increment sliced buffer
- session.setParameterCharArray(session.JamesDSP, 12001, eqText.substring(arraySize2Send * i, Math.min(arraySize2Send * i + arraySize2Send, stringLength))); // Commit buffer
- }
- session.setParameterShort(session.JamesDSP, 10006, (short)1); // Notify send array completed and generate filter in native side
- }
- session.setParameterShort(session.JamesDSP, 1211, (short)phaseEqEnabled); // String equalizer switch
- if (phaseEqEnabled == 1 && updateMajor)
- {
- String phTextLeft = preferences.getString("dsp.strph.stringleft", "PhaseShifterLeft: 0.0 0.0; ");
- int arraySize2Send = 256;
- int stringLength = phTextLeft.length();
- int numTime2Send = (int)Math.ceil((double)stringLength / arraySize2Send); // Number of times that have to send
- session.setParameterIntArray(session.JamesDSP, 8888, new int[]{ numTime2Send, arraySize2Send }); // Send buffer info for module to allocate memory
- for (int i = 0; i < numTime2Send; i++)
- {
- session.setParameterShort(session.JamesDSP, 10005, (short)i); // Increment sliced buffer
- session.setParameterCharArray(session.JamesDSP, 12001, phTextLeft.substring(arraySize2Send * i, Math.min(arraySize2Send * i + arraySize2Send, stringLength))); // Commit buffer
- }
- session.setParameterShort(session.JamesDSP, 10007, (short)1); // Notify send array completed and generate filter in native side
- String phTextRight = preferences.getString("dsp.strph.stringright", "PhaseShifterRight: 0.0 180.0; 22000.0 180.0");
- stringLength = phTextRight.length();
- numTime2Send = (int)Math.ceil((double)stringLength / arraySize2Send); // Number of times that have to send
- session.setParameterIntArray(session.JamesDSP, 8888, new int[]{ numTime2Send, arraySize2Send }); // Send buffer info for module to allocate memory
- for (int i = 0; i < numTime2Send; i++)
- {
- session.setParameterShort(session.JamesDSP, 10005, (short)i); // Increment sliced buffer
- session.setParameterCharArray(session.JamesDSP, 12001, phTextRight.substring(arraySize2Send * i, Math.min(arraySize2Send * i + arraySize2Send, stringLength))); // Commit buffer
- }
- session.setParameterShort(session.JamesDSP, 10008, (short)1); // Notify send array completed and generate filter in native side
- }
if (reverbEnabled == 1 && updateMajor)
session.setParameterShort(session.JamesDSP, 128, Short.valueOf(preferences.getString("dsp.headphone.preset", "0")));
session.setParameterShort(session.JamesDSP, 1203, (short)reverbEnabled); // Reverb switch
diff --git a/Misc/fftw/DoubleARM/libfftw3.a b/Misc/fftw/DoubleARM/libfftw3.a
deleted file mode 100644
index 272d2de..0000000
--- a/Misc/fftw/DoubleARM/libfftw3.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/DoubleARM/libfftw3_threads.a b/Misc/fftw/DoubleARM/libfftw3_threads.a
deleted file mode 100644
index 44f3ae0..0000000
--- a/Misc/fftw/DoubleARM/libfftw3_threads.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/DoubleARM64/libfftw3.a b/Misc/fftw/DoubleARM64/libfftw3.a
deleted file mode 100644
index 1429805..0000000
--- a/Misc/fftw/DoubleARM64/libfftw3.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/DoubleARM64/libfftw3_threads.a b/Misc/fftw/DoubleARM64/libfftw3_threads.a
deleted file mode 100644
index a8c515d..0000000
--- a/Misc/fftw/DoubleARM64/libfftw3_threads.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/Doublex86/libfftw3.a b/Misc/fftw/Doublex86/libfftw3.a
deleted file mode 100644
index dddbde5..0000000
--- a/Misc/fftw/Doublex86/libfftw3.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/Doublex86/libfftw3_threads.a b/Misc/fftw/Doublex86/libfftw3_threads.a
deleted file mode 100644
index 57bdccb..0000000
--- a/Misc/fftw/Doublex86/libfftw3_threads.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/FloatARM64NEON/libfftw3f.a b/Misc/fftw/FloatARM64NEON/libfftw3f.a
deleted file mode 100644
index dfbd21b..0000000
--- a/Misc/fftw/FloatARM64NEON/libfftw3f.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/FloatARM64NEON/libfftw3f_threads.a b/Misc/fftw/FloatARM64NEON/libfftw3f_threads.a
deleted file mode 100644
index 484fbde..0000000
--- a/Misc/fftw/FloatARM64NEON/libfftw3f_threads.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/FloatARMNEON/libfftw3fNeon.a b/Misc/fftw/FloatARMNEON/libfftw3fNeon.a
deleted file mode 100644
index d7a8f9e..0000000
--- a/Misc/fftw/FloatARMNEON/libfftw3fNeon.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/FloatARMNEON/libfftw3f_threadsNeon.a b/Misc/fftw/FloatARMNEON/libfftw3f_threadsNeon.a
deleted file mode 100644
index 6e34104..0000000
--- a/Misc/fftw/FloatARMNEON/libfftw3f_threadsNeon.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/Floatx86/libfftw3f.a b/Misc/fftw/Floatx86/libfftw3f.a
deleted file mode 100644
index e356a83..0000000
--- a/Misc/fftw/Floatx86/libfftw3f.a
+++ /dev/null
Binary files differ
diff --git a/Misc/fftw/Floatx86/libfftw3f_threads.a b/Misc/fftw/Floatx86/libfftw3f_threads.a
deleted file mode 100644
index e61f7b3..0000000
--- a/Misc/fftw/Floatx86/libfftw3f_threads.a
+++ /dev/null
Binary files differ