-
Notifications
You must be signed in to change notification settings - Fork 5
/
logbins.c
76 lines (65 loc) · 2.16 KB
/
logbins.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
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include "logbins.h"
#define MINIMUM_FREQUENCY 318
#define MAXIMUM_FREQUENCY 2000
static uint16_t bin_indexes[NUMBER_OF_BINS + 1] = { 0xFFFF };
/**
* Given a frequency value between 0Hz and (5512 / 2)Hz, this function
* returns the index between 1 and 1024 that corresponds to the closest
* frequency in the FFT results, where the frequency for index i is given
* by the following formula:
*
* frequency = samplingRate * i / nSamples
*/
static int frequency_to_index(float frequency) {
int index = roundf(1024.0 * frequency / 2756.0);
if (index < 1) {
return 1;
}
if (index > 1024) {
return 1024;
}
return index;
}
/**
* For each of the 32 target bins, this function
* calculates the frequency that corresponds to the
* beginning of the logarithmic interval for this
* bin. Then, this frequency is converted into
* the corresponding index in the FFT results.
*
* This means that in order to calculate the value
* for the bin #i, we need to take into account
* all the FFT values between the indexes bin_indexes[i]
* and bin_indexes[i+1].
*/
static void generate_bin_indexes() {
float log_min = log2f(MINIMUM_FREQUENCY);
float log_max = log2f(MAXIMUM_FREQUENCY);
float delta = (log_max - log_min) / NUMBER_OF_BINS;
float current = log_min;
for (unsigned int i = 0 ; i <= NUMBER_OF_BINS ; i++) {
float frequency = powf(2, current);
current += delta;
bin_indexes[i] = frequency_to_index(frequency);
}
}
void calculate_bins(float* real, float* imaginary, float* bins) {
if (bin_indexes[0] == 0xFFFF) {
// If needed, let's initialize the bin indexes
generate_bin_indexes();
}
for (unsigned int i = 0 ; i < NUMBER_OF_BINS ; i++) {
unsigned int min_index = bin_indexes[i];
unsigned int max_index = bin_indexes[i + 1];
float sum = 0;
for (unsigned int j = min_index ; j < max_index ; j++) {
float re = real[j] / 1024.0;
float im = imaginary[j] / 1024.0;
sum += (re * re) + (im * im);
}
bins[i] = sum / (max_index - min_index);
}
}