-
Notifications
You must be signed in to change notification settings - Fork 0
/
dft.c
90 lines (72 loc) · 2.88 KB
/
dft.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "dft.h"
struct FreqData MultiplyByFreq(struct Wave wave, uint freq)
{
struct Wave sinWave = SinWaveByFreq(freq, wave.samplesPerSecond, wave.duration, 0);
struct Wave cosWave = CosWaveByFreq(freq, wave.samplesPerSecond, wave.duration, 0);
uint size = wave.samplesPerSecond * wave.duration;
double* sinWaveMultiplicationOutput = malloc(size * sizeof(double));
double* cosWaveMultiplicationOutput = malloc(size * sizeof(double));
for(int i = 0; i < size; i++)
{
sinWaveMultiplicationOutput[i] = sinWave.data[i] * wave.data[i];
cosWaveMultiplicationOutput[i] = cosWave.data[i] * wave.data[i];
}
float sinWaveSum = 0;
float cosWaveSum = 0;
for(int i = 0; i < size; i++)
{
sinWaveSum += sinWaveMultiplicationOutput[i];
cosWaveSum += cosWaveMultiplicationOutput[i];
}
sinWaveSum /= wave.samplesPerSecond;
cosWaveSum /= wave.samplesPerSecond;
float phase = atan2f(cosWaveSum, sinWaveSum);
free(sinWave.data);
free(cosWave.data);
free(sinWaveMultiplicationOutput);
free(cosWaveMultiplicationOutput);
return (struct FreqData){freq, phase, (fabsf(sinWaveSum) + fabsf(cosWaveSum)) * 2};
}
struct Wave SinWaveByFreq(uint freq, uint samplesPerSecond, float duration, float phase)
{
uint size = samplesPerSecond * duration;
double* waveData = malloc(size * sizeof(double));
const float divider = samplesPerSecond / TAU / freq;
for(int i = 0; i < size; i++)
{
waveData[i] = sin((i / divider) + (phase));
}
return (struct Wave){waveData, samplesPerSecond, duration};
}
struct Wave CosWaveByFreq(uint freq, uint samplesPerSecond, float duration, float phase)
{
uint size = samplesPerSecond * duration;
double* waveData = malloc(size * sizeof(double));
const float divider = samplesPerSecond / TAU / freq;
for(int i = 0; i < size; i++)
{
waveData[i] = cos((i / divider) + (phase));
}
return (struct Wave){waveData, samplesPerSecond, duration};
}
void PrintFreqData(struct FreqData freqData)
{
printf("Frequecy: %d , Phase: %f , Ampitude: %f \n", freqData.freq, freqData.phase, freqData.ampitude);
}
struct DFT_data DiscreteFourierTranform(struct Wave wave, uint minFreq, uint maxFreq, int increment, bool logProgress)
{
size_t numberOfChecks = ((maxFreq - minFreq ) / increment) + 1;
struct FreqData* output = malloc(numberOfChecks * sizeof(struct FreqData));
if(logProgress)
printf("DFT started.\n");
for(int i = minFreq; i < maxFreq; i+=increment)
{
int idx = (i - minFreq) / increment;
output[idx] = MultiplyByFreq(wave, i);
if(logProgress && (i - minFreq) % (increment) == 0)
printf("Calculated freq: %d , %d remaining.\n", i, maxFreq - i);
}
if(logProgress)
printf("DFT ended.\n");
return (struct DFT_data){minFreq, maxFreq, output, increment};
}