Skip to content

Instantly share code, notes, and snippets.

@0x07dc
Created October 10, 2020 01:15
Show Gist options
  • Save 0x07dc/e70936b97bd44d147ca8c0ae9570c881 to your computer and use it in GitHub Desktop.
Save 0x07dc/e70936b97bd44d147ca8c0ae9570c881 to your computer and use it in GitHub Desktop.
DFT
// 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