diff options
| author | James Fung <james34602@gmail.com> | 2018-11-21 00:28:12 +0800 |
|---|---|---|
| committer | James Fung <james34602@gmail.com> | 2018-11-21 00:28:12 +0800 |
| commit | 76c563acb4ca73695a8b365b0a51396b54101cfc (patch) | |
| tree | 37bc6fea1e6afbfaf9e04ad4f6047b30b0d96818 | |
| parent | 2fdb6ad1e764120d53724088e84ab74d060dc9ad (diff) | |
Change FFT library to commercial friendly implementation
1. Fix memory leaks
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﹪</item> <item>Truncate to 50﹪</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 – 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 Binary files differdeleted file mode 100644 index 272d2de..0000000 --- a/Misc/fftw/DoubleARM/libfftw3.a +++ /dev/null diff --git a/Misc/fftw/DoubleARM/libfftw3_threads.a b/Misc/fftw/DoubleARM/libfftw3_threads.a Binary files differdeleted file mode 100644 index 44f3ae0..0000000 --- a/Misc/fftw/DoubleARM/libfftw3_threads.a +++ /dev/null diff --git a/Misc/fftw/DoubleARM64/libfftw3.a b/Misc/fftw/DoubleARM64/libfftw3.a Binary files differdeleted file mode 100644 index 1429805..0000000 --- a/Misc/fftw/DoubleARM64/libfftw3.a +++ /dev/null diff --git a/Misc/fftw/DoubleARM64/libfftw3_threads.a b/Misc/fftw/DoubleARM64/libfftw3_threads.a Binary files differdeleted file mode 100644 index a8c515d..0000000 --- a/Misc/fftw/DoubleARM64/libfftw3_threads.a +++ /dev/null diff --git a/Misc/fftw/Doublex86/libfftw3.a b/Misc/fftw/Doublex86/libfftw3.a Binary files differdeleted file mode 100644 index dddbde5..0000000 --- a/Misc/fftw/Doublex86/libfftw3.a +++ /dev/null diff --git a/Misc/fftw/Doublex86/libfftw3_threads.a b/Misc/fftw/Doublex86/libfftw3_threads.a Binary files differdeleted file mode 100644 index 57bdccb..0000000 --- a/Misc/fftw/Doublex86/libfftw3_threads.a +++ /dev/null diff --git a/Misc/fftw/FloatARM64NEON/libfftw3f.a b/Misc/fftw/FloatARM64NEON/libfftw3f.a Binary files differdeleted file mode 100644 index dfbd21b..0000000 --- a/Misc/fftw/FloatARM64NEON/libfftw3f.a +++ /dev/null diff --git a/Misc/fftw/FloatARM64NEON/libfftw3f_threads.a b/Misc/fftw/FloatARM64NEON/libfftw3f_threads.a Binary files differdeleted file mode 100644 index 484fbde..0000000 --- a/Misc/fftw/FloatARM64NEON/libfftw3f_threads.a +++ /dev/null diff --git a/Misc/fftw/FloatARMNEON/libfftw3fNeon.a b/Misc/fftw/FloatARMNEON/libfftw3fNeon.a Binary files differdeleted file mode 100644 index d7a8f9e..0000000 --- a/Misc/fftw/FloatARMNEON/libfftw3fNeon.a +++ /dev/null diff --git a/Misc/fftw/FloatARMNEON/libfftw3f_threadsNeon.a b/Misc/fftw/FloatARMNEON/libfftw3f_threadsNeon.a Binary files differdeleted file mode 100644 index 6e34104..0000000 --- a/Misc/fftw/FloatARMNEON/libfftw3f_threadsNeon.a +++ /dev/null diff --git a/Misc/fftw/Floatx86/libfftw3f.a b/Misc/fftw/Floatx86/libfftw3f.a Binary files differdeleted file mode 100644 index e356a83..0000000 --- a/Misc/fftw/Floatx86/libfftw3f.a +++ /dev/null diff --git a/Misc/fftw/Floatx86/libfftw3f_threads.a b/Misc/fftw/Floatx86/libfftw3f_threads.a Binary files differdeleted file mode 100644 index e61f7b3..0000000 --- a/Misc/fftw/Floatx86/libfftw3f_threads.a +++ /dev/null |
