Lower sensitivity/quickness of detection in microbit voice model?

**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.

How can I add code or change the sensitivity in the ”voice activated micro:bit” repository GitHub - edgeimpulse/voice-activated-microbit: Bleep, bloop, I'm a computer that responds to your voice, so that it is less sensitive and ”fast”. I tried changing the confidence level needed to trigger ”keyword heard”, but it does not make a big difference.

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.

Thank you,
Jonas

Hello @Instant_exit,

In your case, you will need to write a custom piece of code to add your logic on the device (a delay or a moving average on the results maybe?).

You might also want to check our performance calibration tool: Performance calibration - Edge Impulse Documentation

Best,

Louis

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 :slight_smile:

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?


/**
 * Microbit implementations for Edge Impulse target-specific functions
 */
EI_IMPULSE_ERROR ei_sleep(int32_t time_ms) {
    uBit.sleep(time_ms);
    return EI_IMPULSE_OK;
}

void ei_printf(const char *format, ...) {
    char print_buf[1024] = { 0 };

    va_list args;
    va_start(args, format);
    int r = vsnprintf(print_buf, sizeof(print_buf), format, args);
    va_end(args);

    uBit.serial.printf("%s", print_buf);
}

It is truly amazing that you can get ai help with the code! What an amazing time to be alive, and… scary :laughing: 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?

Cheers,
J

1 Like

Hello @Instant_exit,

That’s awesome!

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.

Looking forward your results!

Best,

Louis