Skip to content

Commit 0444c7c

Browse files
raphaelgaultmicrobit-carlos
authored andcommitted
fft: Capture microphone's feed and detect fundamental frequency
Signed-off-by: Raphael Gault <[email protected]>
1 parent 094136f commit 0444c7c

File tree

2 files changed

+54
-13
lines changed

2 files changed

+54
-13
lines changed

inc/MicroBitAudioProcessor.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ DEALINGS IN THE SOFTWARE.
3030
#ifndef MICROBIT_AUDIO_PROCESSOR_H
3131
#define MICROBIT_AUDIO_PROCESSOR_H
3232

33-
#define AUDIO_SAMPLES_NUMBER 256
33+
#define MIC_SAMPLE_RATE (11 * 1024)
34+
#define AUDIO_SAMPLES_NUMBER 1024
3435

3536
class MicroBitAudioProcessor : public DataSink
3637
{
@@ -40,13 +41,18 @@ class MicroBitAudioProcessor : public DataSink
4041
arm_rfft_fast_instance_f32 fft_instance;
4142
float *buf;
4243
float *output;
44+
float *mag;
4345
uint16_t position;
46+
bool recording;
47+
float rec[AUDIO_SAMPLES_NUMBER * 2];
4448

4549
public:
4650
MicroBitAudioProcessor(DataSource& source);
4751
~MicroBitAudioProcessor();
4852
virtual int pullRequest();
4953
int setDivisor(int d);
54+
void startRecording();
55+
void stopRecording(MicroBit& uBit);
5056
};
5157

5258
#endif

source/MicroBitAudioProcessor.cpp

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,17 @@ MicroBitAudioProcessor::MicroBitAudioProcessor(DataSource& source) : audiostream
3030
audiostream.connect(*this);
3131
zeroOffset = 0;
3232
divisor = 1;
33-
//arm_rfft_fast_init_f32(&fft_instance, AUDIO_SAMPLES_NUMBER);
33+
arm_rfft_fast_init_f32(&fft_instance, AUDIO_SAMPLES_NUMBER);
3434

3535
/* Double Buffering: We allocate twice the number of samples*/
3636
buf = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER * 2);
3737
output = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER);
38+
mag = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER / 2);
3839

3940
position = 0;
41+
recording = false;
4042

41-
if (buf == NULL || output == NULL) {
43+
if (buf == NULL || output == NULL || mag == NULL) {
4244
DMESG("DEVICE_NO_RESOURCES");
4345
target_panic(DEVICE_OOM);
4446
}
@@ -48,6 +50,7 @@ MicroBitAudioProcessor::~MicroBitAudioProcessor()
4850
{
4951
free(buf);
5052
free(output);
53+
free(mag);
5154
}
5255

5356
int MicroBitAudioProcessor::pullRequest()
@@ -56,40 +59,59 @@ int MicroBitAudioProcessor::pullRequest()
5659
int minimum = 0;
5760
int maximum = 0;
5861
int s;
59-
int8_t result;
62+
int result;
6063

61-
auto mic_samples = audiostream.pull().getBytes();
64+
auto mic_samples = audiostream.pull();
65+
66+
if (!recording)
67+
return DEVICE_OK;
6268

6369
int16_t *data = (int16_t *) &mic_samples[0];
64-
int samples = AUDIO_SAMPLES_NUMBER / 2;
70+
int samples = mic_samples.length() / 2;
6571

6672
for (int i=0; i < samples; i++)
6773
{
6874
z += *data;
6975

7076
s = (int) *data;
71-
s = s - zeroOffset;
72-
s = s / divisor;
73-
result = (int8_t)s;
77+
//s = s - zeroOffset;
78+
//s = s / divisor;
79+
result = s;
7480

7581
if (s < minimum)
7682
minimum = s;
7783

7884
if (s > maximum)
7985
maximum = s;
8086

87+
//if (recording)
88+
// rec[position] = (float)result;
89+
8190
data++;
8291
buf[position++] = (float)result;
8392

93+
8494
if (!(position % AUDIO_SAMPLES_NUMBER))
8595
{
86-
/* We have AUDIO_SAMPLES_NUMBER samples, we can run the FFT on them */
87-
uint8_t offset = position <= AUDIO_SAMPLES_NUMBER ? 0 : AUDIO_SAMPLES_NUMBER;
96+
float maxValue = 0;
97+
uint32_t index = 0;
98+
99+
/* We have AUDIO_SAMPLES_NUMBER samples, we can run the FFT on them */
100+
uint16_t offset = position <= AUDIO_SAMPLES_NUMBER ? 0 : AUDIO_SAMPLES_NUMBER;
88101
if (offset != 0)
89102
position = 0;
90103

91-
//arm_rfft_fast_f32(&fft_instance, buf + offset, output, 0);
92-
DMESG("o[0]: %d", output[0]);
104+
DMESG("Run FFT, %d", offset);
105+
arm_rfft_fast_f32(&fft_instance, buf + offset, output, 0);
106+
arm_cmplx_mag_f32(output, mag, AUDIO_SAMPLES_NUMBER / 2);
107+
arm_max_f32(mag + 1, AUDIO_SAMPLES_NUMBER / 2 - 1, &maxValue, &index);
108+
109+
uint32_t freq = ((uint32_t)MIC_SAMPLE_RATE / AUDIO_SAMPLES_NUMBER) * (index + 1);
110+
DMESG("Freq: %d (max: %d.%d, Index: %d)",
111+
freq,
112+
(int)maxValue,
113+
((int)(maxValue * 100) % 100),
114+
index);
93115
}
94116
}
95117

@@ -103,3 +125,16 @@ int MicroBitAudioProcessor::setDivisor(int d)
103125
divisor = d;
104126
return DEVICE_OK;
105127
}
128+
129+
130+
void MicroBitAudioProcessor::startRecording()
131+
{
132+
this->recording = true;
133+
DMESG("START RECORDING");
134+
}
135+
136+
void MicroBitAudioProcessor::stopRecording(MicroBit& uBit)
137+
{
138+
this->recording = false;
139+
DMESG("STOP RECORDING");
140+
}

0 commit comments

Comments
 (0)