Skip to content
Snippets Groups Projects
Commit 1d6e5d50 authored by Dr-Dan's avatar Dr-Dan
Browse files

fft, ifft and octave analyser have been transpiled. Exposed properties in maxiFFT

parent 72be9abd
Branches
No related merge requests found
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -418,7 +418,7 @@ fft::fft(int fftSize) { ...@@ -418,7 +418,7 @@ fft::fft(int fftSize) {
in_img = (float *) malloc(n * sizeof(float)); in_img = (float *) malloc(n * sizeof(float));
out_real = (float *) malloc(n * sizeof(float)); out_real = (float *) malloc(n * sizeof(float));
out_img = (float *) malloc(n * sizeof(float)); out_img = (float *) malloc(n * sizeof(float));
#ifdef __APPLE_CC__ #ifdef __APPLE_CC__
log2n = log2(n); log2n = log2(n);
A.realp = (float *) malloc(half * sizeof(float)); A.realp = (float *) malloc(half * sizeof(float));
...@@ -532,6 +532,7 @@ void fft::convToDB_vdsp(float *in, float *out) { ...@@ -532,6 +532,7 @@ void fft::convToDB_vdsp(float *in, float *out) {
#endif #endif
void fft::inversePowerSpectrum(int start, float *finalOut, float *window, float *magnitude,float *phase) { void fft::inversePowerSpectrum(int start, float *finalOut, float *window, float *magnitude,float *phase) {
// void fft::inversePowerSpectrum(int start, float *finalOut, float *window, vector<float>& magnitude,vector<float>& phase) {
int i; int i;
/* get real and imag part */ /* get real and imag part */
...@@ -559,6 +560,7 @@ void fft::inversePowerSpectrum(int start, float *finalOut, float *window, float ...@@ -559,6 +560,7 @@ void fft::inversePowerSpectrum(int start, float *finalOut, float *window, float
#ifdef __APPLE_CC__ #ifdef __APPLE_CC__
void fft::inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, float *magnitude,float *phase) { void fft::inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, float *magnitude,float *phase) {
//void fft::inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, vector<float>& magnitude, std::vector<float>& phase) {
uint32_t i; uint32_t i;
for (i = 0; i < half; i++) { for (i = 0; i < half; i++) {
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#include <Accelerate/Accelerate.h> #include <Accelerate/Accelerate.h>
#endif #endif
#include <vector>
class fft { class fft {
...@@ -60,15 +60,20 @@ public: ...@@ -60,15 +60,20 @@ public:
FFTSetup setupReal; FFTSetup setupReal;
COMPLEX_SPLIT A; COMPLEX_SPLIT A;
float *polar; float *polar;
void powerSpectrum_vdsp(int start, float *data, float *window, float *magnitude,float *phase); void powerSpectrum_vdsp(int start, float *data, float *window, float *magnitude,float *phase);
void inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, float *magnitude,float *phase);
void inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, float *magnitude,float *phase);
// void inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, std::vector<float>& magnitude, std::vector<float>& phase);
void convToDB_vdsp(float *in, float *out); void convToDB_vdsp(float *in, float *out);
#endif #endif
/* Calculate the power spectrum */ /* Calculate the power spectrum */
void powerSpectrum(int start, float *data, float *window, float *magnitude, float *phase); void powerSpectrum(int start, float *data, float *window, float *magnitude, float *phase);
/* ... the inverse */ /* ... the inverse */
void inversePowerSpectrum(int start, float *finalOut, float *window, float *magnitude,float *phase); void inversePowerSpectrum(int start, float *finalOut, float *window, float *magnitude,float *phase);
// void inversePowerSpectrum(int start, float *finalOut, float *window, std::vector<float>& magnitude,std::vector<float>& phase);
void convToDB(float *in, float *out); void convToDB(float *in, float *out);
static void genWindow(int whichFunction, int NumSamples, float *window); static void genWindow(int whichFunction, int NumSamples, float *window);
......
...@@ -147,14 +147,17 @@ void maxiIFFT::setup(int _fftSize, int _windowSize, int _hopSize) { ...@@ -147,14 +147,17 @@ void maxiIFFT::setup(int _fftSize, int _windowSize, int _hopSize) {
fft::genWindow(3, windowSize, window); fft::genWindow(3, windowSize, window);
} }
float maxiIFFT::process(float *magnitudes, float *phases) { //float maxiIFFT::process(float *magnitudes, float *phases) {
float maxiIFFT::process(std::vector<float>& magnitudes, std::vector<float>& phases) {
if (0==pos) { if (0==pos) {
//do ifft //do ifft
memset(ifftOut, 0, fftSize * sizeof(float)); memset(ifftOut, 0, fftSize * sizeof(float));
// use data() to pass first adrress of vectors
#if defined(__APPLE_CC__) && !defined(_NO_VDSP) #if defined(__APPLE_CC__) && !defined(_NO_VDSP)
_fft->inversePowerSpectrum_vdsp(0, ifftOut, window, magnitudes, phases); _fft->inversePowerSpectrum_vdsp(0, ifftOut, window, magnitudes.data(), phases.data());
#else #else
_fft->inversePowerSpectrum(0, ifftOut, window, magnitudes, phases); _fft->inversePowerSpectrum(0, ifftOut, window, magnitudes.data(), phases.data());
#endif #endif
//add to output //add to output
//shift back by one hop //shift back by one hop
...@@ -249,8 +252,8 @@ void maxiFFTOctaveAnalyzer::setup(float samplingRate, int nBandsInTheFFT, int nA ...@@ -249,8 +252,8 @@ void maxiFFTOctaveAnalyzer::setup(float samplingRate, int nBandsInTheFFT, int nA
linearEQSlope = 0.0f; // unity -- no eq by default linearEQSlope = 0.0f; // unity -- no eq by default
} }
void maxiFFTOctaveAnalyzer::calculate(float * fftData){ //void maxiFFTOctaveAnalyzer::calculate(float * fftData){
void maxiFFTOctaveAnalyzer::calculate(vector<float>& fftData){
int last_avgidx = 0; // tracks when we've crossed into a new averaging bin, so store current average int last_avgidx = 0; // tracks when we've crossed into a new averaging bin, so store current average
float sum = 0.0f; // running total of spectrum data float sum = 0.0f; // running total of spectrum data
int count = 0; // count of spectrums accumulated (for averaging) int count = 0; // count of spectrums accumulated (for averaging)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright 2009 Mick Grierson & Strangeloop Limited. All rights reserved. * Copyright 2009 Mick Grierson & Strangeloop Limited. All rights reserved.
* Thanks to the Goldsmiths Creative Computing Team. * Thanks to the Goldsmiths Creative Computing Team.
* Special thanks to Arturo Castro for the PortAudio implementation. * Special thanks to Arturo Castro for the PortAudio implementation.
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without * files (the "Software"), to deal in the Software without
...@@ -15,11 +15,11 @@ ...@@ -15,11 +15,11 @@
* copies of the Software, and to permit persons to whom the * copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following * Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be * The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software. * included in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
...@@ -39,12 +39,13 @@ ...@@ -39,12 +39,13 @@
#include "fft.h" #include "fft.h"
#include "stddef.h" #include "stddef.h"
#include "../maxi_emscr_new.h" #include "../maxi_emscr_new.h"
#include <vector>
class maxiFFT { class maxiFFT {
public: public:
maxiFFT(){ maxiFFT(){
_fft = NULL; _fft = NULL;
buffer = magnitudes = phases = window = avgPower = NULL; buffer = magnitudes = phases = window = avgPower = NULL;
}; };
~maxiFFT(); ~maxiFFT();
...@@ -57,6 +58,8 @@ public: ...@@ -57,6 +58,8 @@ public:
int hopSize; int hopSize;
int bins; int bins;
// properties (emscr)
float getMagnitude(int n){ float getMagnitude(int n){
return magnitudes[n]; return magnitudes[n];
} }
...@@ -69,10 +72,35 @@ public: ...@@ -69,10 +72,35 @@ public:
return phases[n]; return phases[n];
} }
int getWindowSize() const{
return windowSize;
}
void setWindowSize(int size){
this->windowSize = size;
}
int getHopSize() const{
return hopSize;
}
void setHopSize(int size){
this->hopSize = size;
}
int getNumBins() const{
return hopSize;
}
void setNumBins(int n){
this->bins = n;
}
//features //features
float spectralFlatness(); float spectralFlatness();
float spectralCentroid(); float spectralCentroid();
private: private:
float *buffer, *window; float *buffer, *window;
int pos; int pos;
...@@ -80,7 +108,7 @@ private: ...@@ -80,7 +108,7 @@ private:
int fftSize; int fftSize;
fft *_fft; fft *_fft;
bool newFFT; bool newFFT;
}; };
class maxiIFFT { class maxiIFFT {
...@@ -91,8 +119,8 @@ public: ...@@ -91,8 +119,8 @@ public:
}; };
~maxiIFFT(); ~maxiIFFT();
void setup(int fftSize, int windowSize, int hopSize); void setup(int fftSize, int windowSize, int hopSize);
float process(float *magnitudes, float *phases); // float process(float *magnitudes, float *phases);
float process(std::vector<float>& magnitudes, std::vector<float>& phases);
private: private:
float *ifftOut, *buffer, *window; float *ifftOut, *buffer, *window;
int windowSize; int windowSize;
...@@ -106,8 +134,8 @@ private: ...@@ -106,8 +134,8 @@ private:
class maxiFFTOctaveAnalyzer { class maxiFFTOctaveAnalyzer {
/*based on code by David Bollinger, http://www.davebollinger.com/ /*based on code by David Bollinger, http://www.davebollinger.com/
*/ */
public: public:
float samplingRate; // sampling rate in Hz (needed to calculate frequency spans) float samplingRate; // sampling rate in Hz (needed to calculate frequency spans)
...@@ -123,18 +151,132 @@ public: ...@@ -123,18 +151,132 @@ public:
int peakHoldTime; // how long do we hold peaks? (in fft frames) int peakHoldTime; // how long do we hold peaks? (in fft frames)
float peakDecayRate; // how quickly the peaks decay: 0f=instantly .. 1f=not at all float peakDecayRate; // how quickly the peaks decay: 0f=instantly .. 1f=not at all
int * spe2avg; // the mapping between spectrum[] indices and averages[] indices int * spe2avg; // the mapping between spectrum[] indices and averages[] indices
// the fft's log equalizer() is no longer of any use (it would be nonsense to log scale // the fft's log equalizer() is no longer of any use (it would be nonsense to log scale
// the spectrum values into log-sized average bins) so here's a quick-and-dirty linear // the spectrum values into log-sized average bins) so here's a quick-and-dirty linear
// equalizer instead: // equalizer instead:
float linearEQSlope; // the rate of linear eq float linearEQSlope; // the rate of linear eq
float linearEQIntercept; // the base linear scaling used at the first averaging bin float linearEQIntercept; // the base linear scaling used at the first averaging bin
// the formula is: spectrum[i] * (linearEQIntercept + i * linearEQSlope) // the formula is: spectrum[i] * (linearEQIntercept + i * linearEQSlope)
// so.. note that clever use of it can also provide a "gain" control of sorts // so.. note that clever use of it can also provide a "gain" control of sorts
// (fe: set intercept to 2f and slope to 0f to double gain) // (fe: set intercept to 2f and slope to 0f to double gain)
void setup(float samplingRate, int nBandsInTheFFT, int nAveragesPerOctave); void setup(float samplingRate, int nBandsInTheFFT, int nAveragesPerOctave);
void calculate(float * fftData); // void calculate(float * fftData);
void calculate(vector<float>& fftData);
// -------------------------------------------
// Property functions (emscr)
int getSamplingRate() const{
return samplingRate;
}
void setSamplingRate(int rate){
this->samplingRate = rate;
}
int getNSpectrum() const{
return nSpectrum;
}
void setNSpectrum(int nSpectrum){
this->nSpectrum = nSpectrum;
}
int getNAverages() const{
return nAverages;
}
void setNAverages(int nAverages){
this->nAverages = nAverages;
}
int getNAveragesPerOct() const{
return nAveragesPerOctave;
}
void setNAveragesPerOct(int nAverages){
this->nAveragesPerOctave = nAverages;
}
float getSpecFreqSpan() const{
return spectrumFrequencySpan;
}
void setSpecFreqSpan(float span){
this->spectrumFrequencySpan = span;
}
float getFirstOctFreq()const{
return firstOctaveFrequency;
}
void setFirstOctFreq(float freq) {
this->firstOctaveFrequency = freq;
}
float getAvgFreqIncr() const{
return averageFrequencyIncrement;
}
void setAvgFreqIncr(float incr) {
this->averageFrequencyIncrement = incr;
}
float getAverage(int n) const{
return averages[n];
}
float getPeak(int n) const{
return peaks[n];
}
int getPeakHoldTime(int n) const{
return peakHoldTimes[n];
}
int getPeakHoldTimeTotal() const{
return peakHoldTime;
}
void setPeakHoldTimeTotal(int tm){
this->peakHoldTime = tm;
}
float getPeakDecayRate() const{
return peakDecayRate;
}
void setPeakDecayRate(float rate){
this->peakDecayRate = rate;
}
int getSpe2Avg(int n) const{
return spe2avg[n];
}
float getLinEQSlope() const{
return linearEQSlope;
}
void setLinEQSlope(float slope){
this->linearEQSlope = slope;
}
float getLinEQIntercept() const{
return linearEQIntercept;
}
void setLinEQIntercept(float n){
this->linearEQIntercept = n;
}
}; };
......
...@@ -16,13 +16,13 @@ EMSCRIPTEN_BINDINGS(my_module_maxiFFT) { ...@@ -16,13 +16,13 @@ EMSCRIPTEN_BINDINGS(my_module_maxiFFT) {
// LIBS // LIBS
// MAXI MAXI CLOCK // MAXI FFT
class_<maxiFFT>("maxiFFT") class_<maxiFFT>("maxiFFT")
// .constructor<>() // .constructor<>()
// .constructor<int>() // .constructor<int>()
.smart_ptr_constructor("shared_ptr<maxiFFT>",&std::make_shared<maxiFFT>) .smart_ptr_constructor("shared_ptr<maxiFFT>",&std::make_shared<maxiFFT>)
.function("setup", &maxiFFT::setup) .function("setup", &maxiFFT::setup)
.function("process", &maxiFFT::process) .function("process", &maxiFFT::process)
.function("magsToDB", &maxiFFT::magsToDB) .function("magsToDB", &maxiFFT::magsToDB)
...@@ -31,12 +31,52 @@ EMSCRIPTEN_BINDINGS(my_module_maxiFFT) { ...@@ -31,12 +31,52 @@ EMSCRIPTEN_BINDINGS(my_module_maxiFFT) {
.function("getMagnitude", &maxiFFT::getMagnitude) .function("getMagnitude", &maxiFFT::getMagnitude)
.function("getMagnitudeDB", &maxiFFT::getMagnitudeDB) .function("getMagnitudeDB", &maxiFFT::getMagnitudeDB)
.function("getPhase", &maxiFFT::getPhase) .function("getPhase", &maxiFFT::getPhase)
// .function("setTempo", &maxiClock::setTempo)
// .function("setTicksPerBeat", &maxiClock::setTicksPerBeat)
// .function("isTick", &maxiClock::isTick)
// .property("tick", &maxiClock::getTick, &maxiClock::setTick) .property("windowSize", &maxiFFT::getWindowSize, &maxiFFT::setWindowSize)
.property("hopSize", &maxiFFT::getHopSize, &maxiFFT::setHopSize)
.property("bins", &maxiFFT::getNumBins, &maxiFFT::setNumBins)
;
// MAXI IFFT
class_<maxiIFFT>("maxiIFFT")
// .constructor<>()
// .constructor<int>()
.smart_ptr_constructor("shared_ptr<maxiIFFT>",&std::make_shared<maxiIFFT>)
.function("setup", &maxiIFFT::setup)
.function("process", &maxiIFFT::process)
;
// MAXI IFFT
class_<maxiFFTOctaveAnalyzer>("maxiFFTOctaveAnalyzer")
// .constructor<>()
// .constructor<int>()
.smart_ptr_constructor("shared_ptr<maxiFFTOctaveAnalyzer>",&std::make_shared<maxiFFTOctaveAnalyzer>)
.function("setup", &maxiFFTOctaveAnalyzer::setup)
.function("calculate", &maxiFFTOctaveAnalyzer::calculate)
//properties
.property("samplingRate", &maxiFFTOctaveAnalyzer::getSamplingRate, &maxiFFTOctaveAnalyzer::setSamplingRate)
.property("nSpectrum", &maxiFFTOctaveAnalyzer::getNSpectrum, &maxiFFTOctaveAnalyzer::setNSpectrum)
.property("nAverages", &maxiFFTOctaveAnalyzer::getNAverages, &maxiFFTOctaveAnalyzer::setNAverages)
.property("nAveragesPerOctave", &maxiFFTOctaveAnalyzer::getNAveragesPerOct, &maxiFFTOctaveAnalyzer::setNAveragesPerOct)
.property("spectrumFrequencySpan", &maxiFFTOctaveAnalyzer::getSpecFreqSpan, &maxiFFTOctaveAnalyzer::setSpecFreqSpan)
.property("firstOctaveFrequency", &maxiFFTOctaveAnalyzer::getFirstOctFreq, &maxiFFTOctaveAnalyzer::setFirstOctFreq)
.property("averageFrequencyIncrement", &maxiFFTOctaveAnalyzer::getAvgFreqIncr, &maxiFFTOctaveAnalyzer::setAvgFreqIncr)
.function("getAverage", &maxiFFTOctaveAnalyzer::getAverage)
.function("getPeak", &maxiFFTOctaveAnalyzer::getPeak)
.function("getPeakHoldTime", &maxiFFTOctaveAnalyzer::getPeakHoldTime)
.property("peakHoldTime", &maxiFFTOctaveAnalyzer::getPeakHoldTimeTotal, &maxiFFTOctaveAnalyzer::setPeakHoldTimeTotal)
.property("peakDecayRate", &maxiFFTOctaveAnalyzer::getPeakDecayRate, &maxiFFTOctaveAnalyzer::setPeakDecayRate)
.function("getSpe2Avg", &maxiFFTOctaveAnalyzer::getSpe2Avg)
.property("linearEQSlope", &maxiFFTOctaveAnalyzer::getLinEQSlope, &maxiFFTOctaveAnalyzer::setLinEQSlope)
.property("linearEQIntercept", &maxiFFTOctaveAnalyzer::getLinEQIntercept, &maxiFFTOctaveAnalyzer::setLinEQIntercept)
; ;
}; };
......
...@@ -332,21 +332,6 @@ EMSCRIPTEN_BINDINGS(my_module) { ...@@ -332,21 +332,6 @@ EMSCRIPTEN_BINDINGS(my_module) {
.property("tick", &maxiClock::getTick, &maxiClock::setTick) .property("tick", &maxiClock::getTick, &maxiClock::setTick)
; ;
// class_<maxiFFT>("maxiFFT")
// // .constructor<>()
// // .constructor<int>()
// .smart_ptr_constructor("shared_ptr<maxiFFT>",&std::make_shared<maxiFFT>)
// .function("setup", &maxiFFT::setup, allow_raw_pointers())
// .function("process", &maxiFFT::process, allow_raw_pointers())
// .function("magsToDB", &maxiFFT::magsToDB, allow_raw_pointers())
// .function("spectralFlatness", &maxiFFT::spectralFlatness, allow_raw_pointers())
// .function("spectralCentroid", &maxiFFT::spectralCentroid, allow_raw_pointers())
// // .function("setTempo", &maxiClock::setTempo)
// // .function("setTicksPerBeat", &maxiClock::setTicksPerBeat)
// // .function("isTick", &maxiClock::isTick)
//
// // .property("tick", &maxiClock::getTick, &maxiClock::setTick)
// ;
}; };
#endif #endif
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment