Skip to content

Commit 800c095

Browse files
JoshuaAHillmicrobit-carlos
authored andcommitted
Updating fft branch in line with origin. Added ability to query MicroBitAudioProcessor and sample fft C++ Program
1 parent 6927ecb commit 800c095

File tree

3 files changed

+94
-21
lines changed

3 files changed

+94
-21
lines changed

inc/MicroBitAudioProcessor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ class MicroBitAudioProcessor : public DataSink
4545
uint16_t position;
4646
bool recording;
4747
float rec[AUDIO_SAMPLES_NUMBER * 2];
48+
int lastFreq;
4849

4950
public:
5051
MicroBitAudioProcessor(DataSource& source);
5152
~MicroBitAudioProcessor();
5253
virtual int pullRequest();
54+
int getFrequency();
5355
int setDivisor(int d);
5456
void startRecording();
5557
void stopRecording(MicroBit& uBit);

samples/fft_example.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include "MicroBit.h"
2+
#include "CodalDmesg.h"
3+
#include "MicroBitAudioProcessor.h"
4+
#include "StreamNormalizer.h"
5+
#include "Tests.h"
6+
7+
static NRF52ADCChannel *mic = NULL;
8+
static StreamNormalizer *processor = NULL;
9+
static MicroBitAudioProcessor *fft = NULL;
10+
11+
MicroBit uBit;
12+
13+
/**
14+
* fft_test function - creates an example MicroBitAudioProcessor and then queries it for results.
15+
* Currently configured to use 1024 samples with 8bit signed data.
16+
*/
17+
void fft_test(){
18+
uBit.display.print("L");
19+
if (mic == NULL){
20+
mic = uBit.adc.getChannel(uBit.io.microphone);
21+
mic->setGain(7,0);
22+
}
23+
24+
if (processor == NULL)
25+
processor = new StreamNormalizer(mic->output, 1.0f, true, DATASTREAM_FORMAT_8BIT_SIGNED, 10);
26+
27+
if (fft == NULL)
28+
fft = new MicroBitAudioProcessor(processor->output);
29+
30+
uBit.io.runmic.setDigitalValue(1);
31+
uBit.io.runmic.setHighDrive(true);
32+
33+
34+
//Start fft running
35+
fft->startRecording();
36+
37+
38+
while(1){
39+
//TODO - de-noise : if last X samples are same - display ect.
40+
//The output values depend on the input type (DATASTREAM_FORMAT_8BIT_SIGNED) and the size
41+
//of the FFT - which is changed using the 'AUDIO_SAMPLES_NUMBER' in MicroBitAudioProcessor.h
42+
//default is 1024
43+
uBit.sleep(100);
44+
int freq = fft->getFrequency();
45+
DMESG("%s %d", "frequency: ", freq);
46+
if(freq > 0)
47+
uBit.display.print("?");
48+
if(freq > 530)
49+
uBit.display.print("C");
50+
if(freq > 600)
51+
uBit.display.print("D");
52+
if(freq > 680)
53+
uBit.display.print("E");
54+
if(freq > 710)
55+
uBit.display.print("F");
56+
if(freq > 800)
57+
uBit.display.print("G");
58+
if(freq > 900)
59+
uBit.display.print("A");
60+
if(freq > 1010)
61+
uBit.display.print("B");
62+
if(freq > 1050)
63+
uBit.display.print("?");
64+
}
65+
}
66+
67+
68+
69+
int
70+
main()
71+
{
72+
73+
uBit.init();
74+
fft_test();
75+
76+
}

source/MicroBitAudioProcessor.cpp

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ MicroBitAudioProcessor::~MicroBitAudioProcessor()
5555

5656
int MicroBitAudioProcessor::pullRequest()
5757
{
58-
int z = 0;
59-
int minimum = 0;
60-
int maximum = 0;
58+
6159
int s;
6260
int result;
6361

@@ -66,27 +64,17 @@ int MicroBitAudioProcessor::pullRequest()
6664
if (!recording)
6765
return DEVICE_OK;
6866

67+
//using 8 bits produces more accurate to input results (not 2x like using 16) but issue with
68+
//F and G both producing 363hz -> investigate futher with crossing 8 bit + differnet sample numbers
69+
//int8_t *data = (int8_t *) &mic_samples[0];
6970
int16_t *data = (int16_t *) &mic_samples[0];
7071
int samples = mic_samples.length() / 2;
7172

7273
for (int i=0; i < samples; i++)
7374
{
74-
z += *data;
75-
76-
s = (int) *data;
77-
//s = s - zeroOffset;
78-
//s = s / divisor;
79-
result = s;
80-
81-
if (s < minimum)
82-
minimum = s;
83-
84-
if (s > maximum)
85-
maximum = s;
86-
87-
//if (recording)
88-
// rec[position] = (float)result;
89-
75+
76+
result = (int) *data;
77+
9078
data++;
9179
buf[position++] = (float)result;
9280

@@ -102,9 +90,14 @@ int MicroBitAudioProcessor::pullRequest()
10290
position = 0;
10391

10492
DMESG("Run FFT, %d", offset);
93+
//auto a = system_timer_current_time();
10594
arm_rfft_fast_f32(&fft_instance, buf + offset, output, 0);
10695
arm_cmplx_mag_f32(output, mag, AUDIO_SAMPLES_NUMBER / 2);
10796
arm_max_f32(mag + 1, AUDIO_SAMPLES_NUMBER / 2 - 1, &maxValue, &index);
97+
//auto b = system_timer_current_time();
98+
99+
//DMESG("Before FFT: %d", (int)a);
100+
//DMESG("After FFT: %d (%d)", (int)b, (int)(b - a));
108101

109102
uint32_t freq = ((uint32_t)MIC_SAMPLE_RATE / AUDIO_SAMPLES_NUMBER) * (index + 1);
110103
DMESG("Freq: %d (max: %d.%d, Index: %d)",
@@ -115,11 +108,13 @@ int MicroBitAudioProcessor::pullRequest()
115108
}
116109
}
117110

118-
z = z / samples;
119-
zeroOffset = z;
120111
return DEVICE_OK;
121112
}
122113

114+
int MicroBitAudioProcessor::getFrequency(){
115+
return lastFreq;
116+
}
117+
123118
int MicroBitAudioProcessor::setDivisor(int d)
124119
{
125120
divisor = d;

0 commit comments

Comments
 (0)