kartable
Posts: 33
Joined: Tue Jun 02, 2020 8:17 am

python error in demo file

Wed Jul 29, 2020 1:25 pm

Hi to all,

I am trying to play from the command line

Code: Select all

python demo3.py resources/snowboy.wav resources/models/snowboy.umdl
and I get this

Code: Select all

Traceback (most recent call last):
  File "demo3.py", line 1, in <module>
    import snowboydecoder
  File "/home/pi/snowboy/examples/Python/snowboydecoder.py", line 5, in <module>
    import snowboydetect
ImportError: No module named snowboydetect
snowboydecoder seems to be loaded, but not snowboydetect

Actually there is a snowboydetect.py file,but with a 'danger' sign.
What does this mean? I'm new to Python.

EDIT : I was supposed to understand I need swig http://docs.kitt.ai/snowboy/
> But when I run 'make', I get another error

Code: Select all

swig -I../../ -c++ -python -o snowboy-detect-swig.cc snowboy-detect-swig.i
g++ -I/usr/include/python2.7 -I/usr/include/arm-linux-gnueabihf/python2.7  -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-InigCj/python2.7-2.7.16=. -fstack-protector-strong -Wformat -Werror=format-security  -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -I../../ -O3 -fPIC -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++0x -c snowboy-detect-swig.cc
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
g++ -I../../ -O3 -fPIC -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++0x  -shared snowboy-detect-swig.o \
../..//lib/rpi/libsnowboy-detect.a -L/usr/lib/python2.7/config-arm-linux-gnueabihf -L/usr/lib -lpython2.7 -lpthread -ldl  -lutil -lm  -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions -lm -ldl -lf77blas -lcblas -llapack -latlas -o _snowboydetect.so
/usr/bin/ld : ne peut trouver -lf77blas
/usr/bin/ld : ne peut trouver -lcblas
/usr/bin/ld : ne peut trouver -llapack
/usr/bin/ld : ne peut trouver -latlas
collect2: error: ld returned 1 exit status
make: *** [Makefile:69: _snowboydetect.so] Error 1
Again, what does this mean?
There is no file named /usr/lib/python2.7/config-arm-linux-gnueabihf if that's what swig is looking for.

And I still get an error when I try to run

Code: Select all

python demo3.py resources/snowboy.wav resources/models/snowboy.umdl
Traceback (most recent call last):
  File "demo3.py", line 1, in <module>
    import snowboydecoder
  File "/home/pi/snowboy/examples/Python/snowboydecoder.py", line 5, in <module>
    import snowboydetect
  File "/home/pi/snowboy/examples/Python/snowboydetect.py", line 17, in <module>
    _snowboydetect = swig_import_helper()
  File "/home/pi/snowboy/examples/Python/snowboydetect.py", line 16, in swig_import_helper
    return importlib.import_module('_snowboydetect')
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
ImportError: No module named _snowboydetect

User avatar
B.Goode
Posts: 10557
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: python error in demo file

Wed Jul 29, 2020 2:05 pm

kartable wrote:
Wed Jul 29, 2020 1:25 pm
Hi to all,

I am trying to play from the command line

Code: Select all

python demo3.py resources/snowboy.wav resources/models/snowboy.umdl
and I get this

Code: Select all

Traceback (most recent call last):
  File "demo3.py", line 1, in <module>
    import snowboydecoder
  File "/home/pi/snowboy/examples/Python/snowboydecoder.py", line 5, in <module>
    import snowboydetect
ImportError: No module named snowboydetect
snowboydecoder seems to be loaded, but not snowboydetect

Actually there is a snowboydetect.py file,but with a 'danger' sign.
What does this mean? I'm new to Python.

EDIT : I was supposed to understand I need swig http://docs.kitt.ai/snowboy/
> But when I run 'make', I get another error

Code: Select all

swig -I../../ -c++ -python -o snowboy-detect-swig.cc snowboy-detect-swig.i
g++ -I/usr/include/python2.7 -I/usr/include/arm-linux-gnueabihf/python2.7  -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-InigCj/python2.7-2.7.16=. -fstack-protector-strong -Wformat -Werror=format-security  -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -I../../ -O3 -fPIC -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++0x -c snowboy-detect-swig.cc
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
g++ -I../../ -O3 -fPIC -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++0x  -shared snowboy-detect-swig.o \
../..//lib/rpi/libsnowboy-detect.a -L/usr/lib/python2.7/config-arm-linux-gnueabihf -L/usr/lib -lpython2.7 -lpthread -ldl  -lutil -lm  -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions -lm -ldl -lf77blas -lcblas -llapack -latlas -o _snowboydetect.so
/usr/bin/ld : ne peut trouver -lf77blas
/usr/bin/ld : ne peut trouver -lcblas
/usr/bin/ld : ne peut trouver -llapack
/usr/bin/ld : ne peut trouver -latlas
collect2: error: ld returned 1 exit status
make: *** [Makefile:69: _snowboydetect.so] Error 1
Again, what does this mean?
There is no file named /usr/lib/python2.7/config-arm-linux-gnueabihf if that's what swig is looking for.

And I still get an error when I try to run

Code: Select all

python demo3.py resources/snowboy.wav resources/models/snowboy.umdl
Traceback (most recent call last):
  File "demo3.py", line 1, in <module>
    import snowboydecoder
  File "/home/pi/snowboy/examples/Python/snowboydecoder.py", line 5, in <module>
    import snowboydetect
  File "/home/pi/snowboy/examples/Python/snowboydetect.py", line 17, in <module>
    _snowboydetect = swig_import_helper()
  File "/home/pi/snowboy/examples/Python/snowboydetect.py", line 16, in swig_import_helper
    return importlib.import_module('_snowboydetect')
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
ImportError: No module named _snowboydetect




I suggest you take a step back and assume that it is unlikely that volunteer helpers here will have any clue what you are talking about.


What are you trying to accomplish? What tutorial or demo are you referring to for misleading guidance?

What is the content of your copy of demo3.py? of snowboydecoder.py? of snowboydetect.py?

kartable
Posts: 33
Joined: Tue Jun 02, 2020 8:17 am

Re: python error in demo file

Wed Jul 29, 2020 2:42 pm

B.Goode wrote:
Wed Jul 29, 2020 2:05 pm
I suggest you take a step back and assume that it is unlikely that volunteer helpers here will have any clue what you are talking about.


What are you trying to accomplish? What tutorial or demo are you referring to for misleading guidance?

What is the content of your copy of demo3.py? of snowboydecoder.py? of snowboydetect.py?

I am following this tutorial http://docs.kitt.ai/snowboy/ and that should be simple but I never used either Python or swig. There is a beginning for everyone...

The content of demo3.py

Code: Select all

import snowboydecoder
import sys
import wave

# Demo code for detecting hotword in a .wav file
# Example Usage:
#  $ python demo3.py resources/snowboy.wav resources/models/snowboy.umdl
# Should print:
#  Hotword Detected!
#
#  $ python demo3.py resources/ding.wav resources/models/snowboy.umdl
# Should print:
#  Hotword Not Detected!


if len(sys.argv) != 3:
    print("Error: need to specify wave file name and model name")
    print("Usage: python demo3.py wave_file model_file")
    sys.exit(-1)

wave_file = sys.argv[1]
model_file = sys.argv[2]

f = wave.open(wave_file)
assert f.getnchannels() == 1, "Error: Snowboy only supports 1 channel of audio (mono, not stereo)"
assert f.getframerate() == 16000, "Error: Snowboy only supports 16K sampling rate"
assert f.getsampwidth() == 2, "Error: Snowboy only supports 16bit per sample"
data = f.readframes(f.getnframes())
f.close()

sensitivity = 0.5
detection = snowboydecoder.HotwordDetector(model_file, sensitivity=sensitivity)

ans = detection.detector.RunDetection(data)

if ans == 1:
    print('Hotword Detected!')
else:
    print('Hotword Not Detected!')

The content of snowboydecoder.py

Code: Select all

#!/usr/bin/env python

import collections
import pyaudio
import snowboydetect
import time
import wave
import os
import logging
from ctypes import *
from contextlib import contextmanager

logging.basicConfig()
logger = logging.getLogger("snowboy")
logger.setLevel(logging.INFO)
TOP_DIR = os.path.dirname(os.path.abspath(__file__))

RESOURCE_FILE = os.path.join(TOP_DIR, "resources/common.res")
DETECT_DING = os.path.join(TOP_DIR, "resources/ding.wav")
DETECT_DONG = os.path.join(TOP_DIR, "resources/dong.wav")

def py_error_handler(filename, line, function, err, fmt):
    pass

ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p)

c_error_handler = ERROR_HANDLER_FUNC(py_error_handler)

@contextmanager
def no_alsa_error():
    try:
        asound = cdll.LoadLibrary('libasound.so')
        asound.snd_lib_error_set_handler(c_error_handler)
        yield
        asound.snd_lib_error_set_handler(None)
    except:
        yield
        pass

class RingBuffer(object):
    """Ring buffer to hold audio from PortAudio"""
    def __init__(self, size = 4096):
        self._buf = collections.deque(maxlen=size)

    def extend(self, data):
        """Adds data to the end of buffer"""
        self._buf.extend(data)

    def get(self):
        """Retrieves data from the beginning of buffer and clears it"""
        tmp = bytes(bytearray(self._buf))
        self._buf.clear()
        return tmp


def play_audio_file(fname=DETECT_DING):
    """Simple callback function to play a wave file. By default it plays
    a Ding sound.

    :param str fname: wave file name
    :return: None
    """
    ding_wav = wave.open(fname, 'rb')
    ding_data = ding_wav.readframes(ding_wav.getnframes())
    with no_alsa_error():
        audio = pyaudio.PyAudio()
    stream_out = audio.open(
        format=audio.get_format_from_width(ding_wav.getsampwidth()),
        channels=ding_wav.getnchannels(),
        rate=ding_wav.getframerate(), input=False, output=True)
    stream_out.start_stream()
    stream_out.write(ding_data)
    time.sleep(0.2)
    stream_out.stop_stream()
    stream_out.close()
    audio.terminate()


class HotwordDetector(object):
    """
    Snowboy decoder to detect whether a keyword specified by `decoder_model`
    exists in a microphone input stream.

    :param decoder_model: decoder model file path, a string or a list of strings
    :param resource: resource file path.
    :param sensitivity: decoder sensitivity, a float of a list of floats.
                              The bigger the value, the more senstive the
                              decoder. If an empty list is provided, then the
                              default sensitivity in the model will be used.
    :param audio_gain: multiply input volume by this factor.
    :param apply_frontend: applies the frontend processing algorithm if True.
    """
    def __init__(self, decoder_model,
                 resource=RESOURCE_FILE,
                 sensitivity=[],
                 audio_gain=1,
                 apply_frontend=False):

        def audio_callback(in_data, frame_count, time_info, status):
            self.ring_buffer.extend(in_data)
            play_data = chr(0) * len(in_data)
            return play_data, pyaudio.paContinue

        tm = type(decoder_model)
        ts = type(sensitivity)
        if tm is not list:
            decoder_model = [decoder_model]
        if ts is not list:
            sensitivity = [sensitivity]
        model_str = ",".join(decoder_model)

        self.detector = snowboydetect.SnowboyDetect(
            resource_filename=resource.encode(), model_str=model_str.encode())
        self.detector.SetAudioGain(audio_gain)
        self.detector.ApplyFrontend(apply_frontend)
        self.num_hotwords = self.detector.NumHotwords()

        if len(decoder_model) > 1 and len(sensitivity) == 1:
            sensitivity = sensitivity*self.num_hotwords
        if len(sensitivity) != 0:
            assert self.num_hotwords == len(sensitivity), \
                "number of hotwords in decoder_model (%d) and sensitivity " \
                "(%d) does not match" % (self.num_hotwords, len(sensitivity))
        sensitivity_str = ",".join([str(t) for t in sensitivity])
        if len(sensitivity) != 0:
            self.detector.SetSensitivity(sensitivity_str.encode())

        self.ring_buffer = RingBuffer(
            self.detector.NumChannels() * self.detector.SampleRate() * 5)
        with no_alsa_error():
            self.audio = pyaudio.PyAudio()
        self.stream_in = self.audio.open(
            input=True, output=False,
            format=self.audio.get_format_from_width(
                self.detector.BitsPerSample() / 8),
            channels=self.detector.NumChannels(),
            rate=self.detector.SampleRate(),
            frames_per_buffer=2048,
            stream_callback=audio_callback)


    def start(self, detected_callback=play_audio_file,
              interrupt_check=lambda: False,
              sleep_time=0.03,
              audio_recorder_callback=None,
              silent_count_threshold=15,
              recording_timeout=100):
        """
        Start the voice detector. For every `sleep_time` second it checks the
        audio buffer for triggering keywords. If detected, then call
        corresponding function in `detected_callback`, which can be a single
        function (single model) or a list of callback functions (multiple
        models). Every loop it also calls `interrupt_check` -- if it returns
        True, then breaks from the loop and return.

        :param detected_callback: a function or list of functions. The number of
                                  items must match the number of models in
                                  `decoder_model`.
        :param interrupt_check: a function that returns True if the main loop
                                needs to stop.
        :param float sleep_time: how much time in second every loop waits.
        :param audio_recorder_callback: if specified, this will be called after
                                        a keyword has been spoken and after the
                                        phrase immediately after the keyword has
                                        been recorded. The function will be
                                        passed the name of the file where the
                                        phrase was recorded.
        :param silent_count_threshold: indicates how long silence must be heard
                                       to mark the end of a phrase that is
                                       being recorded.
        :param recording_timeout: limits the maximum length of a recording.
        :return: None
        """
        if interrupt_check():
            logger.debug("detect voice return")
            return

        tc = type(detected_callback)
        if tc is not list:
            detected_callback = [detected_callback]
        if len(detected_callback) == 1 and self.num_hotwords > 1:
            detected_callback *= self.num_hotwords

        assert self.num_hotwords == len(detected_callback), \
            "Error: hotwords in your models (%d) do not match the number of " \
            "callbacks (%d)" % (self.num_hotwords, len(detected_callback))

        logger.debug("detecting...")

        state = "PASSIVE"
        while True:
            if interrupt_check():
                logger.debug("detect voice break")
                break
            data = self.ring_buffer.get()
            if len(data) == 0:
                time.sleep(sleep_time)
                continue

            status = self.detector.RunDetection(data)
            if status == -1:
                logger.warning("Error initializing streams or reading audio data")

            #small state machine to handle recording of phrase after keyword
            if state == "PASSIVE":
                if status > 0: #key word found
                    self.recordedData = []
                    self.recordedData.append(data)
                    silentCount = 0
                    recordingCount = 0
                    message = "Keyword " + str(status) + " detected at time: "
                    message += time.strftime("%Y-%m-%d %H:%M:%S",
                                         time.localtime(time.time()))
                    logger.info(message)
                    callback = detected_callback[status-1]
                    if callback is not None:
                        callback()

                    if audio_recorder_callback is not None:
                        state = "ACTIVE"
                    continue

            elif state == "ACTIVE":
                stopRecording = False
                if recordingCount > recording_timeout:
                    stopRecording = True
                elif status == -2: #silence found
                    if silentCount > silent_count_threshold:
                        stopRecording = True
                    else:
                        silentCount = silentCount + 1
                elif status == 0: #voice found
                    silentCount = 0

                if stopRecording == True:
                    fname = self.saveMessage()
                    audio_recorder_callback(fname)
                    state = "PASSIVE"
                    continue

                recordingCount = recordingCount + 1
                self.recordedData.append(data)

        logger.debug("finished.")

    def saveMessage(self):
        """
        Save the message stored in self.recordedData to a timestamped file.
        """
        filename = 'output' + str(int(time.time())) + '.wav'
        data = b''.join(self.recordedData)

        #use wave to save data
        wf = wave.open(filename, 'wb')
        wf.setnchannels(1)
        wf.setsampwidth(self.audio.get_sample_size(
            self.audio.get_format_from_width(
                self.detector.BitsPerSample() / 8)))
        wf.setframerate(self.detector.SampleRate())
        wf.writeframes(data)
        wf.close()
        logger.debug("finished saving: " + filename)
        return filename

    def terminate(self):
        """
        Terminate audio stream. Users cannot call start() again to detect.
        :return: None
        """
        self.stream_in.stop_stream()
        self.stream_in.close()
        self.audio.terminate()
The content of snowboydetect.py after I did 'make'

Code: Select all

# This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.12
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
if _swig_python_version_info >= (2, 7, 0):
    def swig_import_helper():
        import importlib
        pkg = __name__.rpartition('.')[0]
        mname = '.'.join((pkg, '_snowboydetect')).lstrip('.')
        try:
            return importlib.import_module(mname)
        except ImportError:
            return importlib.import_module('_snowboydetect')
    _snowboydetect = swig_import_helper()
    del swig_import_helper
elif _swig_python_version_info >= (2, 6, 0):
    def swig_import_helper():
        from os.path import dirname
        import imp
        fp = None
        try:
            fp, pathname, description = imp.find_module('_snowboydetect', [dirname(__file__)])
        except ImportError:
            import _snowboydetect
            return _snowboydetect
        try:
            _mod = imp.load_module('_snowboydetect', fp, pathname, description)
        finally:
            if fp is not None:
                fp.close()
        return _mod
    _snowboydetect = swig_import_helper()
    del swig_import_helper
else:
    import _snowboydetect
del _swig_python_version_info

try:
    _swig_property = property
except NameError:
    pass  # Python < 2.2 doesn't have 'property'.

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
    if (name == "thisown"):
        return self.this.own(value)
    if (name == "this"):
        if type(value).__name__ == 'SwigPyObject':
            self.__dict__[name] = value
            return
    method = class_type.__swig_setmethods__.get(name, None)
    if method:
        return method(self, value)
    if (not static):
        if _newclass:
            object.__setattr__(self, name, value)
        else:
            self.__dict__[name] = value
    else:
        raise AttributeError("You cannot add attributes to %s" % self)


def _swig_setattr(self, class_type, name, value):
    return _swig_setattr_nondynamic(self, class_type, name, value, 0)


def _swig_getattr(self, class_type, name):
    if (name == "thisown"):
        return self.this.own()
    method = class_type.__swig_getmethods__.get(name, None)
    if method:
        return method(self)
    raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))


def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)

try:
    _object = object
    _newclass = 1
except __builtin__.Exception:
    class _object:
        pass
    _newclass = 0

class SnowboyDetect(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, SnowboyDetect, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, SnowboyDetect, name)
    __repr__ = _swig_repr

    def __init__(self, resource_filename, model_str):
        this = _snowboydetect.new_SnowboyDetect(resource_filename, model_str)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def Reset(self):
        return _snowboydetect.SnowboyDetect_Reset(self)

    def RunDetection(self, *args):
        return _snowboydetect.SnowboyDetect_RunDetection(self, *args)

    def SetSensitivity(self, sensitivity_str):
        return _snowboydetect.SnowboyDetect_SetSensitivity(self, sensitivity_str)

    def SetHighSensitivity(self, high_sensitivity_str):
        return _snowboydetect.SnowboyDetect_SetHighSensitivity(self, high_sensitivity_str)

    def GetSensitivity(self):
        return _snowboydetect.SnowboyDetect_GetSensitivity(self)

    def SetAudioGain(self, audio_gain):
        return _snowboydetect.SnowboyDetect_SetAudioGain(self, audio_gain)

    def UpdateModel(self):
        return _snowboydetect.SnowboyDetect_UpdateModel(self)

    def NumHotwords(self):
        return _snowboydetect.SnowboyDetect_NumHotwords(self)

    def ApplyFrontend(self, apply_frontend):
        return _snowboydetect.SnowboyDetect_ApplyFrontend(self, apply_frontend)

    def SampleRate(self):
        return _snowboydetect.SnowboyDetect_SampleRate(self)

    def NumChannels(self):
        return _snowboydetect.SnowboyDetect_NumChannels(self)

    def BitsPerSample(self):
        return _snowboydetect.SnowboyDetect_BitsPerSample(self)
    __swig_destroy__ = _snowboydetect.delete_SnowboyDetect
    __del__ = lambda self: None
SnowboyDetect_swigregister = _snowboydetect.SnowboyDetect_swigregister
SnowboyDetect_swigregister(SnowboyDetect)

class SnowboyVad(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, SnowboyVad, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, SnowboyVad, name)
    __repr__ = _swig_repr

    def __init__(self, resource_filename):
        this = _snowboydetect.new_SnowboyVad(resource_filename)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def Reset(self):
        return _snowboydetect.SnowboyVad_Reset(self)

    def RunVad(self, *args):
        return _snowboydetect.SnowboyVad_RunVad(self, *args)

    def SetAudioGain(self, audio_gain):
        return _snowboydetect.SnowboyVad_SetAudioGain(self, audio_gain)

    def ApplyFrontend(self, apply_frontend):
        return _snowboydetect.SnowboyVad_ApplyFrontend(self, apply_frontend)

    def SampleRate(self):
        return _snowboydetect.SnowboyVad_SampleRate(self)

    def NumChannels(self):
        return _snowboydetect.SnowboyVad_NumChannels(self)

    def BitsPerSample(self):
        return _snowboydetect.SnowboyVad_BitsPerSample(self)
    __swig_destroy__ = _snowboydetect.delete_SnowboyVad
    __del__ = lambda self: None
SnowboyVad_swigregister = _snowboydetect.SnowboyVad_swigregister
SnowboyVad_swigregister(SnowboyVad)

# This file is compatible with both classic and new-style classes.


Before using swig, this file was empty and displayed a kind of a warning sign. Now it's a normal file but there is still _snowboydetect.so with this warning.

EDIT : Maybe I should install libpcre3 libpcre3-dev libatlas-base-dev ?
There was an issue in Github with a solution https://github.com/Kitt-AI/snowboy/issues/303 for Ubuntu 16.4 (I am on Raspbian with a Raspberry)

Return to “Python”