New microphone not working

Hi Mycrofters,

Got a new boombox prototype (which frickin cranks! … more later) and picked up a new microphone. I set up Mycroft from my docs, and it came up with a pairing code. I paired it and tried a basic command. No dice - Mycroft could not use the new mic. I found this in voice.log:

$ tail -22 voice.log
2022-03-19 08:49:13.974 | INFO     |  2123 | mycroft.client.speech.hotword_factory:load_module:500 | Loading "hey mycroft" wake word via precise
2022-03-19 08:49:16.863 | INFO     |  2123 | mycroft.client.speech.listener:create_wakeup_recognizer:365 | creating stand up word engine
2022-03-19 08:49:16.868 | INFO     |  2123 | mycroft.client.speech.hotword_factory:load_module:500 | Loading "wake up" wake word via pocketsphinx
2022-03-19 08:49:17.129 | INFO     |  2123 | __main__:on_ready:179 | Speech client is ready.
Expression 'paInvalidSampleRate' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2048
Expression 'PaAlsaStreamComponent_InitialConfigure( &self->capture, inParams, self->primeBuffers, hwParamsCapture, &realSr )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2718
Expression 'PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer, &inputLatency, &outputLatency, &hostBufferSizeMode )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2842
Exception in thread Thread-8:
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/home/pi/mycroft-core/mycroft/client/speech/listener.py", line 79, in
  run
    with self.mic as source:
  File "/home/pi/mycroft-core/mycroft/client/speech/mic.py", line 140, in __enter__
    return self._start()
  File "/home/pi/mycroft-core/mycroft/client/speech/mic.py", line 147, in _start
    self.stream = MutableStream(self.audio.open(
  File "/home/pi/mycroft-core/.venv/lib/python3.8/site-packages/pyaudio.py", line 750, in open
    stream = Stream(self, *args, **kwargs)
  File "/home/pi/mycroft-core/.venv/lib/python3.8/site-packages/pyaudio.py", line 441, in __init__
    self._stream = pa.open(**arguments)
OSError: [Errno -9997] Invalid sample rate

So it seems Mycroft does not like either the sample rate or the fact that the mic has two channels.

I also got an error from the helper script testrecord that I wrote because I can never remember the arecord args to make a sample recording. I tried to fix it by querying the microphone’s attributes as follows:

$ cat /usr/local/sbin/testrecord
 #!/bin/bash
#
# test recording with default microphone
#
# get microphone's sample rate, # of channels and format
rate=`grep rate: /proc/asound/card*/pcm0c/sub0/hw_params | awk '{print $2}'` # there could be multiple mic's
if [ ${#rate} = 0 ]; then                  # no mic found
  echo "ERROR: no microphone found with command grep rate: /proc/asound/card*/pcm0c/sub0/hw_params"
  exit 4                                   # cannot perform operation
fi
channels=`grep channels: /proc/asound/card*/pcm0c/sub0/hw_params | awk '{print $2}'`
if [ ${#channels} = 0 ]; then              # number of channels not found
  echo "WARNING: did not find number of channels - assuming 1"
  channels=1                               # assume 1 channel
fi
format=`grep ^format: /proc/asound/card*/pcm0c/sub0/hw_params | awk '{print $2}'`
if [ ${#format} = 0 ]; then                # format not found
  echo "WARNING: did not find number of channels - ignoring" # leave empty
else
  format="-f $format"                      # add -f flag
fi

# put the arecord command together and run it
cmd="arecord $format -c $channels -d 5 -r $rate /tmp/test-mic.wav"
echo "Testing your microphone for 5 seconds - SAY SOMETHING!"
echo "INFO: running command: $cmd"
$cmd                                       # run the command
rc=$?
if [ "$rc" != 0 ]; then                    # something didn't work
  echo "ERROR: command $cmd failed with $rc"
  exit $rc                                 # not successful
fi

So maybe some of the code techniques in the bash code to glean the sample rate, channels and format could be used in the Python file pyaudio.py?

Just a thought … hope this helps

-Mike M

Before sifting through code, have you confirmed that things work outside of Mycroft? Start with making sure everything works as expected in Linux with alsa/pulseaudio tools.

What does arecord -L show for your mic?
How about pacmd list-sources | grep -e 'index:' -e device.string -e 'name:'
Did you step through the Audio Troubleshooting Guide?
Did you modify the mycroft config? If so what?

@msalerno thanks for the quick reply.

For the mic that works, the audio is fine with Mycroft. I ask, it answers.

For the new mic that doesn’t work with Mycroft, the changes to testrecord that I posted above do work. So I can record a 5 sec snippet and play it back with testplay which calls aplay. Here’s an example:

$ testrecord
Testing your microphone for 5 seconds - SAY SOMETHING!
INFO: running command: arecord -f S16_LE -c 2 -d 5 -r 48000 /tmp/test-mic.wav
Recording WAVE '/tmp/test-mic.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo

Here is the output for the mic that does not work:

$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: Audio [GDprofessional Audio], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 1: Device [USB PnP Audio Device], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
$ pacmd list-sources | grep -e 'index:' -e device.string -e 'name:'
  * index: 0
        name: <alsa_input.usb-CMEDIA_USB_PnP_Audio_Device-00.mono-fallback>
                device.string = "hw:1"
    index: 1
        name: <alsa_output.platform-soc_sound.stereo-fallback.monitor>
                device.string = "2"
-Mike M