Microphone not working: Invalid number of channels

Hello,
I wanted to get started with rhasspy, using a cheap USB microphone I had around. However, I can’t get rhasspy to detect audio from it.

My /etc/asound.conf, which is also mounted via docker-compose:

pcm.!default {
    type asym
    capture.pcm "micfoo"
    playback.pcm "speakerbar"
}
pcm.micfoo {
    type plug
    slave {
        pcm "hw:1,0"
    }
}
pcm.speakerbar {
    type plug
    slave {
        pcm "hw:0,0"
    }
 }

I am able to record audio outside and inside of the docker container with arecord -Dmicfoo -r 16000 -c 1 -f S16_LE test.wav and play it back, but when I select “micfoo” in the audio recording settings and hit “Test”, the “testing microphones” popup closes after ~3s and nothing else happens (I assume it should play the recorded sound back?).

In the logs, I get “OSError: [Errno -9998] Invalid number of channels” , mixed with the occasional “OSError: [Errno -9985] Device unavailable” (Logs here)

Running on a Raspi 4 2GB

Rather than hw: use plughw: then anything wrong in setting alsa will just resample.

Doesn’t answer your question but it will likely work.

Unfortunately that didn’t work.

Just another tip in addition to what @rolyan_trauts said.
I would use the actual hardware name from arecord -l as the card numbers can change on boot depending on which interface gets initialized first.

so if my arecord -l returns

card 1: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]

what would I put? "plughw:Device,USB Audio"?

In that case its just plughw:Device as the name is only the part straight after the card 1:

Do you also use arecord for recording with Rhasspy or do you use pyaudio there.
Have you tried using arecord and defining which device to use in the yaml as shown in the readme? So something like:

"microphone": {
  "system": "arecord",
  "arecord": {
    "device": "micfoo"
  }
}

Tried it, still doesn’t work. When I hit the “Wake Up” button, it just times out after ~30s.

I did a full re-install on a clean raspbian. When I hit “Test” on the arecord devices, I get “Device or resource busy” on almost all devices, especially on the ones I configured in /etc/asound.conf. On PyAudio, I still get “Invalid number of channels” and “Invalid sample rate”, but the logs don’t tell me which error belongs to which device from the list.

Resource busy means something else is using the device. You could try using dsnoop in your asound.conf or try find what is blocking your device. But did you change to using arecord instead of pyaudio from within Rhasspy?
Because if arecord works from the commandline I see no reason why it shouldn’t work from Rhasspy.

I did change to arecord, that’s why I got “Resource busy” instead of “Invalid number of channels”.

The fun part is: Rhasspy seems to be the only thing using the device. I get this sequence:

  • Rhasspy container is stopped: arecord command works (outside of container, obviously)
  • rhasspy running, PyAudio selected in “Audio Recording”: arecord works inside and outside
  • Change “Audio Recording” to arecord: executing arecord manually gives “Resource busy” (understandable since rhasspy is using it), but clicking “Test” also yields “Resource busy” in docker attach
  • Changing the arecord device to “null”: arecord works inside and outside again

I don’t know how all that relates to the TimeoutError I get when pressing “Wake Up”, tho.

Can you try using an asound.conf like this

defaults.pcm.rate_converter "samplerate"

pcm.!default {
    type asym
    playback.pcm "speaker"
    capture.pcm "array"
}

pcm.speaker {
    type plug
    slave.pcm "hw:Headphones"
}

pcm.mic {
    type plug
    slave.pcm "dsnoopmic"
}

pcm.dsnoopmic {
    type dsnoop
    ipc_key 666666
    slave {
        pcm "hw:Device"
        channels 2
    }
}

Than use default alsa or manually use the above defined mic pcm. This should in theory prevent any resource busy errors

I don’t know anything about ALSA, but shouldn’t capture.pcm "array" be capture.pcm "mic"? At least I saw something like “Unknown PCM array” in the logs.

Anyways, it now shows “mic” as working in the settings (both arecord and PyAudio), however pressing “Wake Up” still results in a timeout.

Edit: Nevermind, it now only shows as working when I select PyAudio. However, when I select arecord and hit refresh and test, I get many “Resource busy” errors, but not for the line rhasspymicrophone_cli_hermes: ['arecord', '-q', '-D', 'mic', '-r', '16000', '-f', 'S16_LE', '-c', '1', '-t', 'raw'], which seems good

Sorry my mistake. I adapted a existing one I had to your names and forgot to change it :see_no_evil:
Yes it should be mic there too.

That’s what I thought, but that should only affect the “default” device, right? I changed it anyways

Yes its mainly about the dsnoop configuration as this is what allows several entities to access one hardware card.
The additional mic pcm needs to be used as a dsnoop pcm can only directly work with hw and not with plug hw. So the addition mic pcm is where the plug for conversion is inserted into the chain.

@synesthesiam when using arecord as a standard record method does this happen because Rhasspy is trying to start another record command for the test button which will not work unleast a dsnoop or pulse configuration is used as Rhasspy is already blocking that device?
Maybe something for the docs?

Yes there would be a need for a bit of help on this.
I have spent hours with @JGKK trying to configure PulseAudio or dsnoop. It seems Rhasspy is only happy with Alsa. And it’s impossible to use the microphone for another application in parallel.

Has it got anything to do with the recent Raspbian update where Pulseaudio is now a default install?

That one gives a lot of headaches for sure. The biggest problem is trying to use anything pulseaudio from a headless application like nodered or rhasspy.
You pretty much have to change pulseaudio to systemwide mode and add the user running Rhasspy to the right pulse-access group.
But even with pulseaudio installed and running you should be able to use alsa devices directly from arecord and co. The only thing that happens is that the device disappears from the available pulseaudio sources in that instance if you don’t have a dsnoop setup in the asound.conf.
But in general I have used the combination of pulseaudio in systemwide mode and accessing devices directly at the alsa level before and this gives no general conflicts apart from the above mentioned.
But all my installations are headless so I can’t speak for anything Linux and desktop unfortunately.

You can do it both ways I never new why systemwide mode is frowned on but with Mycroft I had a service that started up with pulse in usermode no problem.
Have a look on their github as the user based is and was done.

I just noticed last update that pulse audio is now the default for the desktop and installed on all in the base image.
Pulse in docker gets confusing for me but I have never been particularly bright.