Created
October 10, 2020 01:15
-
-
Save 0x07dc/e70936b97bd44d147ca8c0ae9570c881 to your computer and use it in GitHub Desktop.
DFT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a function that performs the discrete fourier transform | |
// on an input array and returns a magnitude from 0-1 indicating | |
// detection strength (1 being prominent and 0 being silent) | |
// Additionally, it's also implemented here as an example | |
#include <iostream> | |
#include <math.h> | |
#define _USE_MATH_DEFINES | |
using namespace std; | |
float DFT(float* input, float detFreq, int sampleRate){ | |
struct Coords{ | |
float x; | |
float y; | |
Coords(){}; | |
Coords(float newX, float newY){ | |
x = newX; | |
y = newY; | |
} | |
}; | |
// Calculate DFT for freq = detFreq | |
float waveLen = (float)sampleRate/detFreq; | |
Coords coords[sampleRate]; | |
for(int i=0; i<sampleRate;i++){ | |
float x,y; | |
// Get the angle | |
float angle = (fmod((float)i,waveLen))/waveLen; | |
// This is between 0 and 1 | |
// Convert to radians | |
angle *= 2*M_PI; | |
// Do trig to get x and y | |
// sin is y, cos is x | |
x = cos(angle)*input[i]; | |
y = sin(angle)*input[i]; | |
Coords newCoords(x,y); | |
coords[i] = newCoords; | |
} | |
// Get average vector | |
Coords avgVec(0,0); | |
for(Coords i:coords){ | |
avgVec.x += i.x; | |
avgVec.y += i.y; | |
} | |
// Get final magnitude | |
// a^2 + b^2 = c^2 | |
// sqrt(x^2 + y^2) = c | |
float mag = sqrt(pow(avgVec.x,2)+pow(avgVec.y,2))/sampleRate; | |
// Make mag between 0 and 1 | |
mag *= 2; | |
return mag; | |
} | |
int main() { | |
float genFreq = 200; // Frequency to generate (to use as input for detection) | |
float detFreq = 200; // Frequency to detect | |
int sampleRate = 8000; | |
float waveform[8000]; | |
// Create waveform | |
for(int i=0;i<sampleRate;i++){ | |
waveform[i] = sin(genFreq * i * (1/(float)sampleRate) * (2 * M_PI)); | |
} | |
// Run DFT | |
float mag = DFT(waveform,detFreq,sampleRate); | |
// Output Result | |
cout << "The magnitude was: " << mag << endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment