Help complete newby understand some code

basically, it’s a wake word script using edge impulse and it pulls its data from a modelfile.eim I think so I’m stumped at how to do an (if my wake word is above the threshold % then run what I would like it to run)

say if(wakeword%) > 80% runscript


import os
import sys, getopt
import signal
import time
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)

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

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

sorry if the post is butchered its my first time touching python and this forum

By simon via Discussions on Python.org at 31May2022 12:30:

basically, it’s a wake word script using edge impulse and it pulls its
data from a modelfile.eim I think so I’m stumped at how to do an (if my
wake word is above the threshold % then run what I would like it to
run)

say if(wakeword%) > 80% runscript

Do you know how the threshold is expressed? Is it the “score” variable
in the for res, audio in runner.classifier… loop down the bottom?
That loop prints labels and scores. Is the score what you want?

If it is, I’d put an if-statement after the last print(), eg:

print('', flush=True)
if score > my_threshold:
    my_function(label,score)

where my_threshold is set to your threshold earlier in the main()
function, perhaps by the command line or an environment variable, but
most easily 9for testing) with a default. Eg put:

DEFAULT_THRESHOLD = 0.6

at the top of the script right after the imports, then set:

my_threshold = DEFAULT_THRESHOLD

at the top of main(). That way (a) your script can run sensibly even
without some command line or environment variable and (b) you can add
those later.

Then define my_function(label, score) to run your script, sketch:

def my_function(label, scrore):
    ... act on label here ...

If you really need to run an external script, use the run() function
from the subprocess module:
https://docs.python.org/3/library/subprocess.html#module-subprocess

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like
result (17 ms.) Hey Bmo: 0.02    Noise: 0.94   Unkown: 0.04

result (17 ms.) Hey Bmo: 0.90    Noise: 0.10   Unkown: 0.15

result (17 ms.) Hey Bmo: 0.05    Noise: 0.80   Unkown: 0.20

result (17 ms.) Hey Bmo: 0.10    Noise: 0.40   Unkown: 0.01

result (17 ms.) Hey Bmo: 0.01    Noise: 0.50   Unkown: 0.5

that’s the readout of the terminal

This has been a great help and has started working my only problem is it checking the percentage of the unknown variable and not the Hey Bmo percentage.

My fault for not disclosing there were multiple options.

Is there a way to define which one I would like it to read because ideally, I would like it to do a


 ( if Hey Bmo > 0.80 and Noise < 0.40 Unkown < 0.40) do action

@Major, will you please edit your post to replace the screen photo with text characters? You can precede the copy-pasted screen text with ‘>’ (w/o quotes) to make a scrollable text block frame for large amounts of text.

Also, that run-on sentence with no punctuation is truly something to behold! :upside_down_face: The no-punctuation habit may be easy for the sender but it’s rough on the receiver. Please use full punctuation here–and [Enter]–and reserve the quickie practices for SMS texting friends who might only glance at the message.

You’ll have a much higher chance of getting some quality help if you present your situation clearly and in a way that’s easy for someone else to read and digest. The more experienced programmers simply don’t have the time to sort through the jumble; these are the folks who will help you the most and are happy and more than willing to help you.

You might want to compare your second post here to Cameron’s first reply. You pasted your code into a code block in your original post. Continue those best practices. :sunglasses:

hopefully fixed?

1 Like

By simon via Discussions on Python.org at 01Jun2022 03:05:

This has been a great help and has started working my only problem is
it checking the percentage of the unknown variable and not the Hey Bmo
percentage my fault for not disclosing there were multiple options is
there a way to define which one I would like it to read because
ideally, I would like it to do a:

( if Hey Bmo > 0.80 and Noise < 0.40 Unkown < 0.40) do action

Based on your output code:

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)

It looks like Hey Bmo is a value from label above. You could examine
the classification values for each label. Example (untested) for after
the final print above:

# avoid a lot of tedious repetition
classification = res['result']['classification']
if (
    classification['Hey Bmo'] > 0.80
    and classification['Noise'] < 0.40
    and classification['Unkown'] < 0.40
):
    print("a match!")
    ... whatever other action you intend goes here ...

You don’t need brackets in if-statements, but using them lets me spread
the condition over 3 lines to make it easier to read. Without the
brackets that would all be on one line.

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like

Once again perfectly working, Thank you so much.