Continuous audio sampling and continuous Classification in main.cpp file for Raspberry Pi 4

I am interested in running the Response-to-Voice on a raspberry pi 4 using c++. I used the generic main file and make file from the standalone inference tutorial was able to get it to run once but I am not sure how to cycle in the data from the microphone and classify the information continuous. I looked for information on a microphone_continuous function like in the Arduino Nano ble but couldn’t find this same function for the raspberry pi 4 when I looked through my header files. Please advise.

Hi @mdchestn,

The Linux C++ SDK has an example for continuous audio inferencing, you can check the source code here: https://github.com/edgeimpulse/example-standalone-inferencing-linux/blob/master/source/audio.cpp

Let me know if that helps,

Aurelien

Hi @aurel ,

I found this tutorial a few weeks ago but my students were unable to get it to run. If I understand it and you correctly this is pretty much all I need to sample a voice and run it in c++ on the raspberry pi 4.

Hi @aurel ,

I tried running the tutorial you pointed me towards but I get an error when I tried to run the Audio classifier and not the custom sensor version. Do you have any advice?

Hi @mdchestn,

Could you share the error you’re having with the audio example?

Aurelien

Hi @aurel

The following error occurs whenever I type in APP_AUDIO= 1 make -j

source/audio.cpp:238:44: error: ‘classifier_maf’ was not declared in this scope; did you mean ‘classifier_buffer’?
238 | run_moving_average_filter(&classifier_maf[ix], result.classification[ix].value);

@aurel ,

it doesn’t seem to recognize &classifier_maf[ix] and I only could find this variable in two locations within the whole program. My advisor suggested the it could be in the ei_run_classifier.h file but I didn’t see it.

@mdchestn, we did some changes on the moving average filter recently so I’m checking with our embedded team, I will keep you posted.
In the meantime you can also disable the MAF (use_maf = false).

Aurelien

Hi @aurel ,

I commented out the sections that included the classifer_maf[ix], because the use_maf= false didn’t work and this worked for me but now it is saying the following when I run ./build/audio …

Requires one parameter (ID of the sound card) in the form of plughw:1,0 (where 1=card number, 0=device).
You can find these via cat /proc/asound/cards. E.g. for:
0 [Headphones ]: bcm2835_headphonbcm2835 Headphones - bcm2835 Headphones
bcm2835 Headphones
1 [Webcam ]: USB-Audio - C922 Pro Stream Webcam
C922 Pro Stream Webcam at usb-0000:01:00.0-1.3, high speed
The ID for ‘C922 Pro Stream Webcam’ is then plughw:1,0

HI @aurel ,

Do I have to use that particular headset or can I point to the usb headset that I have plugged into the raspberry pi 4

Hi @mdchestn,

Linux and audio equipment (e.g. microphones) is always a tricky battle. I recommend following along with the error output. Run this command with your headphones plugged in:

cat /proc/asound/cards

You should see something like plughw:x,y (e.g. plughw:1,0). Use that as a parameter when calling the compiled binary. For example:

./build/audio plughw:x,y

1 Like

Hi @shawn_edgeimpulse ,

Thank you that worked!

1 Like

Hi @aurel and @shawn_edgeimpulse ,

Thank you both for your help your information allowed my research students to accomplish their task for the week.

1 Like

Hi @shawn_edgeimpulse and @aurel,

Do either of you know why our code would suddenly crash after running? We only made a few modifications but this is coming up:

Failed to read audio data (-32)

Hi @mdchestn,

Without knowing what modifications you made, I cannot say for sure why something is crashing. Does it run if you revert to your old version?

Hi @shawn_edgeimpulse ,

no it does not crash with the old version. We added the following code to the old version to the loop the prints the classifications:

if( result.classification[ix].label == “yes” && result.classification[ix].value >= .5){
yesCount=yesCount+1;

            yesholder=1;
            if(yesCount > 1 && yesCount%10==0){
                sleep_for(milliseconds(1000));
                system("vlc file:///home/mdchestn/Desktop/example-standalone-inferencing-linux/49_MusicBoxHat_790.wav --play-and-exit");
                sleep_for(milliseconds(1000));
                system("vlc file:///home/mdchestn/Desktop/example-standalone-inferencing-linux/49_MusicBoxHat_790.wav --play-and-exit");
                sleep_for(milliseconds(1000));
                system("vlc file:///home/mdchestn/Desktop/example-standalone-inferencing-linux/49_MusicBoxHat_790.wav --play-and-exit");

                
            }
            else{
                sleep_for(milliseconds(1000));
                system("vlc file:///home/mdchestn/Desktop/example-standalone-inferencing-linux/49_MusicBoxHat_790.wav --play-and-exit");
            }
            
        } 
        if( result.classification[ix].label == "no" && result.classification[ix].value >=.5){
            noCount=noCount+1;
            noholder=1;
            if(noCount > 1 && noCount%10==0){
                sleep_for(milliseconds(1000));
                system("vlc file:///home/mdchestn/Desktop/example-standalone-inferencing-linux/150_Upsweep_05_641.wav --play-and-exit");
                sleep_for(milliseconds(1000));
                system("vlc file:///home/mdchestn/Desktop/example-standalone-inferencing-linux/150_Upsweep_05_641.wav --play-and-exit");
                sleep_for(milliseconds(1000));
                system("vlc file:///home/mdchestn/Desktop/example-standalone-inferencing-linux/150_Upsweep_05_641.wav --play-and-exit");
            }
            else{
                    sleep_for(milliseconds(1000));
                    system("vlc file:///home/mdchestn/Desktop/example-standalone-inferencing-linux/150_Upsweep_05_641.wav --play-and-exit");

            }
        } 
        
        if((yesholder == 1) || (noholder == 1)){
            printf("%s: %.05f", result.classification[ix].label, result.classification[ix].value);
            if (ix != EI_CLASSIFIER_LABEL_COUNT - 1) {
                printf(", ");
            }  
        }

Hi @shawn_edgeimpulse ,

To give you brief description of what our code is suppose to do is play a sound on the detection of no and yes, once each has reached multiples of ten play the sound 3 times. And only print out the classification information when yes and no is detected.

@shawn_edgeimpulse ,

Our code runs correctly for about 5 minutes and then all of a sudden the following error pops up:
Failed to read audio data (-32)

And that time length isn’t consistent it does it sometimes after about 2 minutes.

Hi @shawn_edgeimpulse and @aurel ,

Thank you for your help again it was the timers that we included that was making it crash for some reason.

Hi @shawn_edgeimpulse ,

Never mind it just crashed after about 10 minutes, after we removed the timers. The old version of our code was working though.