**Question/Issue: Hi! I could not get a hold of any other microcontrollers for my audio detection project but I still had some micro:bits lying around. I am trying to detect when several people are talking at the same time and makes this sort of droning noise you know. Basically a murmur or buzz detector (I hope that is the correct english term).
I made a dataset recording people speaking normally (unknown class) and also went to different venues to record people speaking at the same time to make this noise (”sorl” class)
I also added about 15 minutes of random noises in a noise class.
Then trained with mfe and keras for 550 epoqs, 0.0034 learning rate.
So far it seems to be working …ok, but a few mistriggers happens. It is very sensitive.
Can you make it so it needs to be detected noise for a longer time before it activates the ”keyword heard” condition. Basically so that there is noise for say 5seconds before it reacts or something like that?
Project ID: 159819
Context/Use case: design school project about noisy environments and health in a hearing loss context.
I think there is a moving average in the code, because @janjongboom once told me to disable it to try if the microbit would trigger better (with the risk of more false positives). My main problem is that I dont know c++ at all, so the code available in your microbit example is a bit hard for me to understand. Im gonna have a look at the code where the MA is situated, but if anyone could point me in the right direction, I would be grateful. Ill have a look at the performance calibration tool too, its pretty new right?
cheers, J
Im wondering if the bad results could be because im using the 999ms window time for the microbit? Im guessing here that the 128kb ram in the microbit might be too little to run say 2000ms? The type of noise im trying to detect is when several people are speaking at the same time and make this sort of ”droning” noise, but the model gets confused when shorter bursts of noise appear that it misclassifies as several people making noises. Even one person in a acoustically messy room can make it trigger because of reverb likely.
Im sure there is a simple solution to make it average over say 5 seconds, but I have yet to find it, and all the sbc that use python/upython seems to be not in stock, so I am stuck with the c++ file for the microbit, and im unfortunately having trouble understanding the code.
Any tips appreciated, we have presentations in two weeks. It works ok, but Id like to make it work great of course
Btw, here this sort of noise is called ”sorl” and I am working on a sign that should light up when it is is ”sorly” in the room.
I managed to get chatgpt to help me with the code. Is this code ”correct”? (except for the keyword being microbit, which i will change). I tried to get chatgpt to write a simplified code that will run the inference and if the average comfidence over 5 seconds is over 0.7 turn on a output pin on the microbit.
Anyways. Incredible that the language model can actually help you code.
Are there any obvious errors? The ai was complaining over ”error in the code where the wrong buffer was being checked for allocation”, but was otherwise happy.
#include "MicroBit.h"
#include "ContinuousAudioStreamer.h"
#include "StreamNormalizer.h"
#include "Tests.h"
#include "edge-impulse-sdk/classifier/ei_run_classifier.h"
#include "edge-impulse-sdk/dsp/numpy.hpp"
#define INFERENCING_KEYWORD "microbit"
static NRF52ADCChannel *mic = NULL;
static ContinuousAudioStreamer *streamer = NULL;
static StreamNormalizer *processor = NULL;
static inference_t inference;
int frames_above_threshold = 0;
/**
* Get raw audio signal data
*/
static int microphone_audio_signal_get_data(size_t offset, size_t length, float *out_ptr)
{
numpy::int8_to_float(&inference.buffers[inference.buf_select ^ 1][offset], out_ptr, length);
return 0;
}
void
mic_inference_test()
{
if (mic == NULL){
mic = uBit.adc.getChannel(uBit.io.microphone);
mic->setGain(7,0); // Uncomment for v1.47.2
//mic->setGain(7,1); // Uncomment for v1.46.2
}
// alloc inferencing buffers
inference.buffers[0] = (int8_t *)malloc(EI_CLASSIFIER_SLICE_SIZE * sizeof(int8_t));
if (inference.buffers[1] == NULL) {
uBit.serial.printf("Failed to alloc buffer 1\n");
return;
}
inference.buffers[1] = (int8_t *)malloc(EI_CLASSIFIER_SLICE_SIZE * sizeof(int8_t));
if (inference.buffers[1] == NULL) { // fixed error here
uBit.serial.printf("Failed to alloc buffer 2\n");
free(inference.buffers[0]);
return;
}
uBit.serial.printf("Allocated buffers\n");
inference.buf_select = 0;
inference.buf_count = 0;
inference.n_samples = EI_CLASSIFIER_SLICE_SIZE;
inference.buf_ready = 0;
mic->output.setBlocking(true);
if (processor == NULL)
processor = new StreamNormalizer(mic->output, 0.15f, true, DATASTREAM_FORMAT_8BIT_SIGNED);
if (streamer == NULL)
streamer = new ContinuousAudioStreamer(processor->output, &inference);
uBit.io.runmic.setDigitalValue(1);
uBit.io.runmic.setHighDrive(true);
uBit.serial.printf("Allocated everything else\n");
// number of frames since we heard 'microbit'
int frames_above_threshold = 0; // 2
while(1) {
int err = streamer->read(microphone_audio_signal_get_data);
// End of stream
if (err == 1) {
uBit.display.print("EOS");
break;
}
// If we have a new buffer ready
if (inference.buf_ready) {
inference.buf_ready = 0;
err = ei_run_classifier(&inference);
// Inference was successful, check if we heard 'microbit'
char output[128];
ei_classifier_get_classification_string(output, 128);
// If we heard "microbit" with a confidence level of 0.7 or higher, increment the counter for frames above threshold
if (strstr(output, INFERENCING_KEYWORD)) {
frames_above_threshold++;
}
// Check if we've heard "microbit" for five seconds with a confidence level of 0.7 or higher
if (frames_above_threshold > 200) {
// Set GPIO pin 1 high
uBit.io.pin1.setDigitalValue(1);
frames_above_threshold = 0;
}
// If we haven't heard "microbit" for five seconds or if the confidence level was less than 0.7, reset the counter for frames above threshold
else {
frames_above_threshold = 0;
}
}
}
// Clean up
ei_unload_classifier();
uBit.io.runmic.setDigitalValue(0);
if (inference.buffers[0] != NULL) {
free(inference.buffers[0]);
inference.buffers[0] = NULL;
}
if (inference.buffers[1] != NULL) {
free(inference.buffers[1]);
inference.buffers[1] = NULL;
}
delete(processor);
delete(streamer);
uBit.display.clear();
uBit.serial.printf("done\n");
Besides getting rid of the ”heard_keyword” and ”heard_other” functions I asked it to get rid of to simplify, it also got rid of these lines of code, should I add them back in?
It is truly amazing that you can get ai help with the code! What an amazing time to be alive, and… scary But it is likely doing different errors than what humans would. I dont have a microbit here to test atm, but is there any abvious errors that I should look at before compiling it?
I have to say that we probably won’t have time to debug chatGPT-generated code on our side but I would be more than happy to hear about your results and feedback once you had time to compile and run your project.