Commit 1d6e5d50 authored by Daniel Clarke's avatar Daniel Clarke

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

parent 72be9abd
This diff is collapsed.
......@@ -418,7 +418,7 @@ fft::fft(int fftSize) {
in_img = (float *) malloc(n * sizeof(float));
out_real = (float *) malloc(n * sizeof(float));
out_img = (float *) malloc(n * sizeof(float));
#ifdef __APPLE_CC__
log2n = log2(n);
A.realp = (float *) malloc(half * sizeof(float));
......@@ -532,6 +532,7 @@ void fft::convToDB_vdsp(float *in, float *out) {
#endif
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;
/* get real and imag part */
......@@ -559,6 +560,7 @@ void fft::inversePowerSpectrum(int start, float *finalOut, float *window, float
#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, vector<float>& magnitude, std::vector<float>& phase) {
uint32_t i;
for (i = 0; i < half; i++) {
......
......@@ -41,7 +41,7 @@
#include <Accelerate/Accelerate.h>
#endif
#include <vector>
class fft {
......@@ -60,15 +60,20 @@ public:
FFTSetup setupReal;
COMPLEX_SPLIT A;
float *polar;
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 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, std::vector<float>& magnitude, std::vector<float>& phase);
void convToDB_vdsp(float *in, float *out);
#endif
/* Calculate the power spectrum */
void powerSpectrum(int start, float *data, float *window, float *magnitude, float *phase);
/* ... 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);
static void genWindow(int whichFunction, int NumSamples, float *window);
......
......@@ -147,14 +147,17 @@ void maxiIFFT::setup(int _fftSize, int _windowSize, int _hopSize) {
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) {
//do ifft
memset(ifftOut, 0, fftSize * sizeof(float));
// use data() to pass first adrress of vectors
#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
_fft->inversePowerSpectrum(0, ifftOut, window, magnitudes, phases);
_fft->inversePowerSpectrum(0, ifftOut, window, magnitudes.data(), phases.data());
#endif
//add to output
//shift back by one hop
......@@ -249,8 +252,8 @@ void maxiFFTOctaveAnalyzer::setup(float samplingRate, int nBandsInTheFFT, int nA
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
float sum = 0.0f; // running total of spectrum data
int count = 0; // count of spectrums accumulated (for averaging)
......
......@@ -6,7 +6,7 @@
* Copyright 2009 Mick Grierson & Strangeloop Limited. All rights reserved.
* Thanks to the Goldsmiths Creative Computing Team.
* Special thanks to Arturo Castro for the PortAudio implementation.
*
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
......@@ -15,11 +15,11 @@
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
*
* The above copyright notice and this permission notice shall be
* 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
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
......@@ -39,12 +39,13 @@
#include "fft.h"
#include "stddef.h"
#include "../maxi_emscr_new.h"
#include <vector>
class maxiFFT {
public:
maxiFFT(){
_fft = NULL;
_fft = NULL;
buffer = magnitudes = phases = window = avgPower = NULL;
};
~maxiFFT();
......@@ -57,6 +58,8 @@ public:
int hopSize;
int bins;
// properties (emscr)
float getMagnitude(int n){
return magnitudes[n];
}
......@@ -69,10 +72,35 @@ public:
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
float spectralFlatness();
float spectralCentroid();
private:
float *buffer, *window;
int pos;
......@@ -80,7 +108,7 @@ private:
int fftSize;
fft *_fft;
bool newFFT;
};
class maxiIFFT {
......@@ -91,8 +119,8 @@ public:
};
~maxiIFFT();
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:
float *ifftOut, *buffer, *window;
int windowSize;
......@@ -106,8 +134,8 @@ private:
class maxiFFTOctaveAnalyzer {
/*based on code by David Bollinger, http://www.davebollinger.com/
*/
/*based on code by David Bollinger, http://www.davebollinger.com/
*/
public:
float samplingRate; // sampling rate in Hz (needed to calculate frequency spans)
......@@ -123,18 +151,132 @@ public:
int peakHoldTime; // how long do we hold peaks? (in fft frames)
float peakDecayRate; // how quickly the peaks decay: 0f=instantly .. 1f=not at all
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 spectrum values into log-sized average bins) so here's a quick-and-dirty linear
// equalizer instead:
// 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
// equalizer instead:
float linearEQSlope; // the rate of linear eq
float linearEQIntercept; // the base linear scaling used at the first averaging bin
// the formula is: spectrum[i] * (linearEQIntercept + i * linearEQSlope)
// 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)
// the formula is: spectrum[i] * (linearEQIntercept + i * linearEQSlope)
// 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)
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) {
// LIBS
// MAXI MAXI CLOCK
// MAXI FFT
class_<maxiFFT>("maxiFFT")
// .constructor<>()
// .constructor<int>()
// .constructor<>()
// .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("process", &maxiFFT::process)
.function("magsToDB", &maxiFFT::magsToDB)
......@@ -31,12 +31,52 @@ EMSCRIPTEN_BINDINGS(my_module_maxiFFT) {
.function("getMagnitude", &maxiFFT::getMagnitude)
.function("getMagnitudeDB", &maxiFFT::getMagnitudeDB)
.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) {
.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
Markdown is supported
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