Exporting Audio from AudioImpulseRunner

I am currently running Edge Impulse Linux SDK on my Raspberry Pi classifying sounds. My task is to save classified sounds as .wav files however I cannot find anywhere how to do so and what parameters were used by the model on capturing the sound from microphone.

AudioImpulseRunner returns audio as bytes, then I try to save it using the following code:

sound_array = numpy.array(bytearray(audio), dtype=numpy.int16)
scipy.io.wavfile.write("test.wav", 16000, sound_array)

However, I get a sound file with static noise only. Any help would be much appreciated :slight_smile:

I was able to do so with the following code:

import soundfile

audio_final = np.fromstring(audio, dtype=np.int16)
soundfile.write('out.wav', audio_final, 16000)

However, my next problem is that it returns very short sound files, the duration of these files is only 64 milliseconds. On Edge Impulse ML model configuration, I have set the window size to 1000 milliseconds which is how long I expected the file duration going to be.

Hello @Ruslan,

Sorry for the late reply, could you share your full code so I can try to reproduce on my side please?

Regards,

Louis

Hi @louis ,

Thanks for answering. Sure, I am reusing the audio example - https://github.com/edgeimpulse/linux-sdk-python/blob/master/examples/audio/classify.py

Here is my code:

import os
import sys, getopt
import signal
import time
import datetime
import soundfile
from edge_impulse_linux.audio import AudioImpulseRunner

runner = None

def signal_handler(sig, frame):
    print('Interrupted')
    if (runner):
        runner.stop()
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

def help():
    print('python classify.py <path_to_model.eim> <audio_device_ID, optional>' )

def main(argv):
    try:
        opts, args = getopt.getopt(argv, "h", ["--help"])
    except getopt.GetoptError:
        help()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ('-h', '--help'):
            help()
            sys.exit()

    if len(args) == 0:
        help()
        sys.exit(2)

    model = args[0]

    dir_path = os.path.dirname(os.path.realpath(__file__))
    modelfile = os.path.join(dir_path, model)

    with AudioImpulseRunner(modelfile) as runner:
        try:
            model_info = runner.init()
            labels = model_info['model_parameters']['labels']
            print('Loaded runner for "' + model_info['project']['owner'] + ' / ' + model_info['project']['name'] + '"')

            #Let the library choose an audio interface suitable for this model, or pass device ID parameter to manually select a specific audio interface
            selected_device_id = None
            if len(args) >= 2:
                selected_device_id=int(args[1])
                print("Device ID "+ str(selected_device_id) + " has been provided as an argument.")

            for res, audio in runner.classifier(device_id=selected_device_id):
                print('Result (%d ms.) ' % (res['timing']['dsp'] + res['timing']['classification']), end='')
                for label in labels:
                    score = res['result']['classification'][label]
                    print('%s: %.2f\t' % (label, score), end='')
                print('', flush=True)
                current_time = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
                audio_final = np.fromstring(audio, dtype=np.int16)
                soundfile.write(current_time + '.wav', audio_final, 16000)


        finally:
            if (runner):
                runner.stop()

if __name__ == '__main__':
    main(sys.argv[1:])

Hi @Ruslan

Thank you for sharing your code. I have reproduced the same issue on my side and we are currently looking into it. we will keep you posted on further developments on the issue ASAP.

Regards,
Clinton

2 Likes

Hi @Ruslan,

To save your full .WAV sample, you would want to use the extracted features to be classified and convert them to WAV rather than using the audio itself. To do that, go to the classifier function on the audio.py file in the edge_impulse_linux directory and return features instead of audio as shown below:

classifier(self, device_id = None):
    with Microphone(self.sampling_rate, CHUNK_SIZE, device_id=device_id) as mic:
        generator = mic.generator()
        features = np.array([], dtype=np.int16)
        while not self.closed:
            for audio in generator:
                data = np.frombuffer(audio, dtype=np.int16)
                features = np.concatenate((features, data), axis=0)
                while len(features) >= self.window_size:
                    begin = now()
                    res = self.classify(features[:self.window_size].tolist())
                    features = features[int(self.window_size * OVERLAP):]
                    yield res, features

After that you can write your wav file using scipy in the AudioImpulseRunner(modelfile) of the classify.py as shown below:

            for res, features in runner.classifier(device_id=selected_device_id):
            write('output.wav', model_info['model_parameters']['frequency'], features)  # Save as WAV file 
            print('Result (%d ms.) ' % (res['timing']['dsp'] + res['timing']['classification']), end='')
            for label in labels:
                score = res['result']['classification'][label]
                print('%s: %.2f\t' % (label, score), end='')
            print('', flush=True)

Note that you must first install scipy using pip then then import it using

from scipy.io.wavfile import write

Let me know if this helps!

Thanks,
Clinton

2 Likes

Perfect, all works for me too. Thank you so much for the help :grinning_face_with_smiling_eyes:

1 Like

i don’t know why i get this error while i run my model for rpi4 "inconsistent use of tabs and spaces in indentation " any help ??

The message kind of explains it, your code indentations are a mix of spaces and tabs. This is not supported at least in some editors. I’m assuming you are using Python.
Replace your tabs with spaces, also check your editor preferences what happens when you use the Tab-key.

When i run it i have an error , tried to set features as follow " features = np.array([], dtype=np.int16)" on classify.py but the error still there

Hi @Junior.F,

Just to confirm, have you also modified the audio.py as mentioned in Exporting Audio from AudioImpulseRunner - #6 by oduor_c?

The features array should not be set in classify.py.

You can locate the edge-impulse-linux / audio.py using pip, ie:

pip list -v | grep edge-impulse-linux
edge-impulse-linux             1.0.6               /usr/local/lib/python3.9/site-packages                     pip

Aurelien

Yes i changed “yield res, audio” to “yield res, features”