respeaker / respeaker_python_library

To build voice enabled objects/applications with Python and ReSpeaker
Apache License 2.0
149 stars 74 forks source link

snowboy wake word detection is not working with respeaker 2 mic pi hat. #41

Open Arrow66 opened 6 years ago

Arrow66 commented 6 years ago

i've been trying to make respeaker detect my wakeword for 2 days .still cant make it out .i thing the problem is with 16bit mono recording all i can hear is a white noise .but stereo recording is working fine no issue at all.tried pyaudio ,arecord . all of them have same problem while mono recording .

can some one help me fix this problem. i can provide any info u guys want

xiongyihui commented 6 years ago

Have you tried to use audacity to find out if it's the case? Maybe one microphone is broken

Arrow66 commented 6 years ago

Audacity is not working with mono recording .any way to fix ?

xiongyihui commented 6 years ago

image

Which ALSA device do you select? The default will support mono recording

Arrow66 commented 6 years ago

no its not working . do i need to make any changes to .asounrc file

pcm.!default { type hw card 1 format S16_LE }

ctl.!default { type hw card 1 }

``

Arrow66 commented 6 years ago

these are my device info

============================== Default recording device number: 9 Default playback device number: 9

Device ID: 0 Device name: bcm2835 ALSA: - (hw:0,0) Host name: ALSA Recording channels: 0 Playback channels: 2 Low Recording Latency: -1.000000 Low Playback Latency: 0.005805 High Recording Latency: -1.000000 High Playback Latency: 0.034830 Supported Rates: 8000 9600 11025 12000 15000 16000 22050 24000 32000 44100 48000

Device ID: 1 Device name: bcm2835 ALSA: IEC958/HDMI (hw:0,1) Host name: ALSA Recording channels: 0 Playback channels: 2 Low Recording Latency: -1.000000 Low Playback Latency: 0.005805 High Recording Latency: -1.000000 High Playback Latency: 0.034830 Supported Rates: 44100 48000

Device ID: 2 Device name: seeed-2mic-voicecard: - (hw:1,0) Host name: ALSA Recording channels: 2 Playback channels: 2 Low Recording Latency: 0.005805 Low Playback Latency: 0.008707 High Recording Latency: 0.034830 High Playback Latency: 0.034830 Supported Rates: 8000 11025 16000 22050 32000 44100 48000

Device ID: 3 Device name: sysdefault Host name: ALSA Recording channels: 0 Playback channels: 128 Low Recording Latency: -1.000000 Low Playback Latency: 0.005805 High Recording Latency: -1.000000 High Playback Latency: 0.034830 Supported Rates: 8000 9600 11025 12000 15000 16000 22050 24000 32000 44100 48000 88200 176400

Device ID: 4 Device name: playback Host name: ALSA Recording channels: 0 Playback channels: 128 Low Recording Latency: -1.000000 Low Playback Latency: 0.125000 High Recording Latency: -1.000000 High Playback Latency: 0.125000 Supported Rates: 8000 9600 12000 15000 16000 24000 32000 44100 48000 88200 96000 176400 192000

Device ID: 5 Device name: capture Host name: ALSA Recording channels: 128 Playback channels: 0 Low Recording Latency: 0.125000 Low Playback Latency: -1.000000 High Recording Latency: 0.125000 High Playback Latency: -1.000000 Supported Rates:

Device ID: 6 Device name: dmixed Host name: ALSA Recording channels: 0 Playback channels: 2 Low Recording Latency: -1.000000 Low Playback Latency: 0.125000 High Recording Latency: -1.000000 High Playback Latency: 0.125000 Supported Rates: 48000

Device ID: 7 Device name: array Host name: ALSA Recording channels: 2 Playback channels: 0 Low Recording Latency: 0.125000 Low Playback Latency: -1.000000 High Recording Latency: 0.125000 High Playback Latency: -1.000000 Supported Rates:

Device ID: 8 Device name: dmix Host name: ALSA Recording channels: 0 Playback channels: 2 Low Recording Latency: -1.000000 Low Playback Latency: 0.021333 High Recording Latency: -1.000000 High Playback Latency: 0.021333 Supported Rates: 48000

Device ID: 9 Device name: default Host name: ALSA Recording channels: 2 Playback channels: 2 Low Recording Latency: 0.005805 Low Playback Latency: 0.008707 High Recording Latency: 0.034830 High Playback Latency: 0.034830 Supported Rates: 8000 11025 16000 22050 32000 44100 48000

Selected recording device: 9 - default Selected playback device: 9 - default Supported Rates: 8000 11025 16000 22050 32000 44100 48000

Available mixers:

Available recording sources:

Available playback volumes: 0 - PCM:0

Recording volume is emulated Playback volume is emulated

Arrow66 commented 6 years ago

default recording device can record in stereo with no issue . but in the case of mono something is not right .. this is the screen of audacity when i'm recording in stereo .take a look at audio meter screenshot from 2018-04-16 13-51-42 this one when recording mono

Arrow66 commented 6 years ago

screencaptured

Arrow66 commented 6 years ago

can some one please help me fix this issue .i did a fresh install of raspbian stretch today .still the problem exist

xiongyihui commented 6 years ago

Are the volumes of the two microphone the same? You can use alsamixer -c 1 to set the volumes.

If you want to to restore the default volumes, try sudo alsactl --file=/etc/voicecard/wm8960_asound.state restore

xiongyihui commented 6 years ago

By the way, you can remove your alsa configuration file ~/.asound.rc and just use the default alsa configuration file /etc/asound.conf from the driver

Arrow66 commented 6 years ago

@xiongyihui i Tried all of the steps u've mentioned . still the problem exist these are my alsa-infos alsa - info : http://www.alsa-project.org/db/?f=bfd07e437056c0a9560290340fa9b4c0a5ade7e1

Arrow66 commented 6 years ago

checkaudio as you guys can see audio recorded from left input mic is just too noisy .but audio from right one working perfectly . i can findout this by playing tracks individually .but when i play them together there is no issue audio was perfect .

And i noticed that when i'm recording mono left input mic is activated . is there anyway i can use my right mic when recording mono ?.

like this one mentioned in this thread https://unix.stackexchange.com/questions/254219/alsa-capturing-mono-microphone-as-right-channel-of-stereo

Arrow66 commented 6 years ago

@xiongyihui help me bro .

Pillar1989 commented 6 years ago

@arjunan47 I think you need buy new one.

Arrow66 commented 6 years ago

@Pillar1989 is that the only option I've left . any way to fix ?

xiongyihui commented 6 years ago

@arjunan47 When did you buy the mic hat?

@xyu6

Arrow66 commented 6 years ago

my mic hat was just 2 moths old i'm from india and i bought it from indian reseller https://www.fabtolab.com/respeaker-hat my mic hat sometimes automatically turn on its led lights .i need to unplug and replug my rp3 to the power . sometime i need to plugin rp3 adapter to different sockets to make the lights turn off . does this relates to my issue ? is there any firmware updates available for me @xiongyihui any help?

Arrow66 commented 6 years ago

@xyu6 any help

Arrow66 commented 6 years ago
 def get_callback(self):
    def callback(in_data, frame_count, time_info, status):
        sound = AudioSegment(in_data,sample_width=2, channels=1, frame_rate=16000)
        self.wavefile.writeframes(sound.raw_data)
        return in_data, pyaudio.paContinue
    return callback

by this pyaudio callback function i can convert stereo audio to mono in realtime using pydub .but the problem is only 32bit pcm is working . but when i change wavefile.setsampwidth(4) wavefile sampwidth to 2 ie 16bit pcm it becomes completely laggy . any way to fix ?

xiongyihui commented 6 years ago

@arjunan47 Did you want to save audio data to .wav file? You can use wave module, See https://docs.python.org/2/library/wave.html

import wave
wav = wave.open('audio.wav', 'wb')
# ...

PS. As the left channel is broken, before it is fixed, you can recording stereo audio data and select the right channel to use. To get right channel from stereo:

import audioop

stereo = ''  # stereo audio data
width = 2
right = audioop.tomono(stereo, width, 0, 1)
Arrow66 commented 6 years ago

@xiongyihui bro is it possible to record audio in realtime using buffers/chunks and extract mono from it?.may be I could use it for wake word detection using snowboy

Arrow66 commented 6 years ago

Thanks you :smile:guys finally snowboy works

Arrow66 commented 6 years ago

i don't what i did wrong , one day it starts to work .nextday it stops . ``
import pyaudio import wave import time import audioop import snowboydetect import threading import Queue detector = snowboydetect.SnowboyDetect(resource_filename = '/home

            /pi/xxxxxcommon.res'.encode(),model_str ='/home/xxxxx.umdl'.encode())

      class SnowboyRec(threading.Thread):
               def __init__(self,channels = 2,
              rate = 16000, frames_per_buffer = 1024):

            threading.Thread.__init__(self)
            self.channels = channels

            self.rate = rate
            self.frames_per_buffer = frames_per_buffer
            self._pa = pyaudio.PyAudio()

            self._stream = None
   def start_recording(self):
        detector = snowboydetect.SnowboyDetect(resource_filename = 'xxxx'.encode(),model_str ='    
          xxxxxxxx'.encode())
        detector.SetAudioGain(9)
        detector.ApplyFrontend(False)
        detector.SetSensitivity('0.9'.encode())
        print('entered')

        self._stream = self._pa.open(format=pyaudio.paInt16,
                                        channels=self.channels,
                                        rate=self.rate,
                                        input_device_index = 2,
                                        input=True,
                                        frames_per_buffer=self.frames_per_buffer,
                                        stream_callback=self.get_callback())

        print('start')
        self._stream.start_stream()
        return self

def get_callback(self):
        def callback(in_data, frame_count, time_info, status):
            d = audioop.tomono(in_data, 2, 0, 1)
            status = detector.RunDetection(d)
            print(status)
            if status == 1:
                print('keyword spotted')
            return in_data, pyaudio.paContinue
        return callback

if name == 'main': snow = SnowboyRec() snow.start_recording() it works when i speak so loud `