ALSA Recording – Fix ‘Device or Resource Busy’ Error with arecord

alsaaudiorecording

I'm trying to record audio that is being played on separate channels using arecord. I do this by executing the following command in separate threads in a python script:

arecord -D plug:"+str(in_id)+" -c 1 -d "+str(duration)+" -f S16_LE -r "+str(rate)+" "+rec_filename

where in_id is the input channel variable that I pass to each of the threads. But then, the following error is thrown:

ALSA lib pcm_dsnoop.c:606:(snd_pcm_dsnoop_open) unable to open slave
arecord: main:722: audio open error: Device or resource busy

When I run lsof /dev/snd/pcm* right before I start recording using arecord in my record function in the program, I see the following:

COMMAND   PID        USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
aplay   12236       user4  mem    CHR  116,3           493 /dev/snd/pcmC1D0p
aplay   12236       user4    4u   CHR  116,3      0t0  493 /dev/snd/pcmC1D0p

My device definition for input channels in .asoundrc is as follows:

pcm.!default {
    type plug
    slave {
       pcm "hw:1,0"
    }
}

ctl.!default { 
    type hw
    card 1
}

pcm_slave.usb_audio_1 {
    pcm "hw:1,0"
    channels 8
    rate 44100
    buffer_size 4096
    period_size 1024
}

pcm.outch<num> {
    type dshare
    ipc_key <id>
    slave usb_audio_1
    bindings [ <ch_num> ]
    hint.description "USB output/playback channel <num> (from output port <num>)"
}

pcm.inch<num> {
    type dsnoop
    ipc_key <id>
    slave usb_audio_1
    bindings [ <ch_num> ]
    hint.description "USB input/capture channel <num> (from input port <num>)"
}

where <num> takes all values between 1 and 8 and <ch_num> takes all values between 0 and 7.

Since, the error clearly says there is a definite problem with dsnoop, does that mean that it is not meant for simultaneous/multi-channel recording? I mean is there a conflict between dsnoop and dshare or if dsnoop can record/capture from only one channel at a time? Is there another way I can achieve this?

Best Answer

The ipc_key is used for communication between the programs that share the same device. This means that you have to use different values for different hardware devices, but that all virtual devices that access the same hardware device (i.e., the same slave usb_audio_1) must use the same ID.

Related Question