larsimmisch / pyalsaaudio

ALSA wrappers for Python
http://larsimmisch.github.io/pyalsaaudio/
Other
215 stars 74 forks source link

alsaaudio.ALSAAudioError: Device or resource busy #47

Closed RobMeades closed 8 months ago

RobMeades commented 6 years ago

First of all, thanks for your Python module, it is going to be very useful for me I think.

I have installed alsaaudio in order to perform PCM capture in Python (2.7.13) on my Raspbian Stretch-lite (4.9.59-v7) Raspberry Pi (B+). My problem is that I always get device or resource busy as soon as I attempt to do anything with the alsaaudio.PCM object I have created. I have verified that:

arecord -Dmic_mono -r16000 -fS32_LE -twav -d10 -Vmono test.wav

...works and produces valid, audible, output. PulseAudio is not installed. What might I be doing wrong?

Here's the Python script, based on your example:

import alsaaudio

mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device='mic_mono')
mic.setchannels(1) # This line triggers the error
mic.setrate(16000)
mic.setformat(alsaaudio.PCM_FORMAT_S32_LE)
mic.setperiodsize(160)

while True:
    length, data = mic.read()
    if length:
        print data

...and this is the output:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    mic.setchannels(1)
alsaaudio.ALSAAudioError: Device or resource busy [mic_mono]

Installation of alsaaudio was performed with pip:

pip install pyalsaaudio

Note that I am no Python expert, I'm a long-time embedded C programmer (so I also have a C version of the above that works on this Pi). I am trying to do something in Python for the first time, so lord knows what I'm doing wrong.

larsimmisch commented 6 years ago

I'd try a setchannels(2) - ALSA error messages are sometimes unhelpful. Also, try to closely study the output of arecord -L (or -l) on the commandline, to understand the installed device's characteristics.

RobMeades commented 6 years ago

Thanks for the swift response: this is mono-ised microphone stream, hence setchannels(1), but the same thing happens if I use the root PCM device mic_hw with setchannels(2):

Traceback (most recent call last):
  File "./test.py", line 4, in <module>
    mic.setchannels(2)
alsaaudio.ALSAAudioError: Device or resource busy [mic_hw]

Why would arecord work but Python not? Could permissions somehow be causing a problem? I'm running all of them in the same way, presumably they are running as the same user (the default pi user).

arecord -l shows the card itself (an I2S MEMS microphone):

**** List of CAPTURE Hardware Devices ****
card 1: memsmic [mems-mic], device 0: bcm2835-i2s-ics43432-hifi ics43432-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

My PCM sound configuration is as follows and I have verified that arecord works with each one:

$ cat .asoundrc
pcm.mic_hw {
    type hw
    card memsmic
    channels 2
    format S32_LE
}
pcm.mic_sv {
    type softvol
    slave.pcm mic_hw
    control {
        name "Boost Capture Volume"
        card memsmic
    }
    min_dB -3.0
    max_dB 50.0
}
pcm.mic_mono {
    type multi
    slaves.a.pcm mic_sv
    slaves.a.channels 2
    bindings.0.slave a
    bindings.0.channel 0
}
larsimmisch commented 6 years ago

If arecord works, the python code should also work (same user, but you know that). My gut feeling is it isn't a permissions issue, but a device name issue - the wrapper is a bit naïve about device names.

Do run:

import alsaaudio

alsaaudio.pcms(alsaaudio.PCM_CAPTURE)

These device names should work.

RobMeades commented 6 years ago

The output from that is:

>>> import alsaaudio
>>> alsaaudio.pcms(alsaaudio.PCM_CAPTURE)
[u'null', u'mic_hw', u'mic_sv', u'mic_mono', u'default:CARD=memsmic', u'sysdefault:CARD=memsmic', u'dmix:CARD=memsmic,DEV=0', u'dsnoop:CARD=memsmic,DEV=0', u'hw:CARD=memsmic,DEV=0', u'plughw:CARD=memsmic,DEV=0']

So I tried changing the device line to be exactly:

mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device=u'mic_hw')

...but that didn't change the outcome. I also tried deliberately mis-spelling the device name, and that results in:

ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM xmic_hw
Traceback (most recent call last):
  File "./test.py", line 13, in <module>
    mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device=u'xmic_hw')
alsaaudio.ALSAAudioError: No such file or directory [xmic_hw]

So the call to instantiate alsaudio.PCM() is at least understanding the device name, it is just not being successful in using it.

Any other clues as to what I might be doing wrong are welcomed, bearing in mind that I'm very new to Python and so may well have made some basic error.

mike01 commented 4 years ago

I had a similar problem and resolved it by executing the script with a normal (non root) user. Seems like using root the config /root/.asoundrc was taken which lead to a different behaviour. By removing the config the behaviour for root was the same as for the normal user.

ossilator commented 2 years ago

is this reproducible with v0.9, using the new method to parameterize the pcm object?

ossilator commented 8 months ago

this was presumably fixed along with #63.