저는 각각 10개, 18개, 심지어 32개의 입력 채널을 갖춘 여러 개의 USB 오디오 인터페이스를 가지고 있습니다. 주로 밴드의 각 악기를 별도의 트랙에 녹음하는 데 사용됩니다.
나는 원시 WAV 형식(s32le @48kHz)으로 녹음하는데, 이는 모든 채널을 녹음하려면 많은 저장 공간이 필요하다는 것을 의미합니다. 그래서 실제로 녹화하고 싶은 채널만 녹화하면 됩니다. SoX를 사용하면 플래그를 사용하여 필요한 채널 수를 지정 -c
하고 remix
Effects를 사용하여 녹음할 채널을 선택함으로써 이를 달성할 수 있다는 것을 알았습니다.
이 작은 개념 증명은 그것이 실제로 작동한다는 것을 보여줍니다.
$ export SOURCE_NAME="alsa_input.usb-Behringer_FLOW_8_03-FF-02-11-55-44-00.Direct__hw_F8__source"
# Record only 1 channel(s) (-c 1) - The channel(s) to record: 2
$ sox -t pulseaudio "${SOURCE_NAME}" -r 48000 -c 1 -b 16 -e signed-integer output.w64 remix 2
그러나 확장은 작동하지 않습니다.
# Record only 4 channel(s) (-c 4) - The channel(s) to record: 1 2 6 8
$ sox -t pulseaudio "${SOURCE_NAME}" -r 48000 -c 4 -b 32 -e signed-integer output.w64 remix 1 2 6 8
어떤 이유로 SoX는 처음 두 채널만 인식합니다.
Input File : 'alsa_input.usb-Behringer_FLOW_8_03-FF-02-11-55-44-00.Direct__hw_F8__source' (pulseaudio)
Channels : 2
Sample Rate : 48000
Precision : 16-bit
Sample Encoding: 16-bit Signed Integer PCM
sox FAIL remix: too few input channels
2개 이상의 채널을 녹음하는 경우에도 FFmpeg가 실패합니다.
$ ffmpeg -f pulse -i "${SOURCE_NAME}" -c:a pcm_s32le -ar 48000 -ac 10 -channel_layout 0x3ff output.w64
FFmpeg에서 다음 오류가 발생합니다.
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, pulse, from 'alsa_input.usb-Behringer_FLOW_8_03-FF-02-11-55-44-00.Direct__hw_F8__source':
Duration: N/A, start: 1689504465.730127, bitrate: 1536 kb/s
Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Multiple -ac options specified for stream 0, only the last option '-ac 10' will be used.
Stream mapping:
Stream #0:0 -> #0:0 (pcm_s16le (native) -> pcm_s32le (native))
Press [q] to stop, [?] for help
[pcm_s32le @ 0x55bc4d7d6040] Channel layout '10 channels (FL+FR+FC+LFE+BL+BR+FLC+FRC+BC+SL)' with 10 channels does not match number of specified channels 2
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Conversion failed!
이중 점검 ffmpeg probe
:
$ ffprobe -f pulse -i "${SOURCE_NAME}"
Input #0, pulse, from 'alsa_input.usb-Behringer_FLOW_8_03-FF-02-11-55-44-00.Direct__hw_F8__source':
Duration: N/A, start: 1689504633.181940, bitrate: 1536 kb/s
Stream #0:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
그래서 다음으로 생각한 것은 PulseAudio 자체에 버그가 있다는 것이었습니다. 하지만 pactl
다음 유틸리티를 사용하면 오류를 쉽게 확인할 수 있습니다.
$ pactl list sources
Source #1414
...
Name: alsa_input.usb-Behringer_FLOW_8_03-FF-02-11-55-44-00.Direct__hw_F8__source
...
Sample Specification: s32le 10ch 48000Hz
Channel Map: aux0,aux1,aux2,aux3,aux4,aux5,aux6,aux7,aux8,aux9
...
Volume: aux0: 48287 / 74% / -7.96 dB, aux1: 48287 / 74% / -7.96 dB, aux2: 48287 / 74% / -7.96 dB, aux3: 48287 / 74% / -7.96 dB, aux4: 48287 / 74% / -7.96 dB, aux5: 48287 / 74% / -7.96 dB, aux6: 48287 / 74% / -7.96 dB, aux7: 48287 / 74% / -7.96 dB, aux8: 48287 / 74% / -7.96 dB, aux9: 48287 / 74% / -7.96 dB
balance 0.00
...
Properties:
...
audio.channels = "10"
...
이는 PulseAudio가 이 USB 오디오 인터페이스의 10개 입력 채널을 모두 알고 있음을 분명하게 보여줍니다.
그래서 PulseAudio의 도구를 사용해 보았습니다 parecord
.
$ parecord --device=${SOURCE_NAME} --format=s32le --rate=48000 --channels 10 --file-format=w64 output.w64
Warning: failed to write channel map to file.
이 경고가 발생했지만(그게 무엇을 의미하든) 실제로는 10개 채널을 모두 성공적으로 녹음했습니다.
다음과 같이 특정 채널을 선택할 수도 있습니다.
parecord --device=${SOURCE_NAME} --format=s32le --rate=48000 --channels 4 --channel-map=aux0,aux1,aux5,aux7 --file-format=w64 output.w64
그렇다면 이것이 SoX나 FFmpeg에서는 작동하지 않는 이유는 무엇일까요?
또한 SoX에게 ALSA를 대신 사용하라고 지시했지만 전혀 작동하지 않습니다.
$ sox -t alsa "plughw:CARD=F8,DEV=0" -r 48000 -c 4 -b 32 -e signed-integer output.w64 remix 1 2 6 8
sox FAIL formats: can't open input `plughw:CARD=F8,DEV=0': snd_pcm_open error: Device or resource busy
PipeWire와 PulseAudio가 실행 중일 때는 ALSA를 통한 액세스가 작동하지 않는 것 같습니다.
ALSA 유틸리티를 통해 녹화 할 수 있는지 확인했지만 arecord
동일한 "장치 사용 중" 오류가 발생합니다.
$ arecord -D plughw:CARD=F8,DEV=0 -r 48000 -c 10 -f S32_LE -t wav output.wav
arecord: main:867: audio open error: Device or resource busy
그건 그렇고, pw-record
PipeWire 유틸리티를 사용하여 직접 녹음하는 것은 훌륭하게 작동합니다.
$ pw-record --target ${SOURCE_NAME} --format s32 --rate 48000 --channels 10
녹화하려는 채널을 선택할 수도 있습니다.
$ pw-record --target ${SOURCE_NAME} --format s32 --rate 48000 --channels 4 --channel-map=aux0,aux1,aux5,aux7 output.w64
SoX를 살펴보고 PipeWire를 직접 지원하는지 살펴봤는데 안타깝게도 그렇지 않은 것 같습니다. 하지만 PulseAudio는 실제로 모든 채널을 볼 수 있기 때문에 여기서 SoX와 FFmpeg가 실패하는 이유를 이해할 수 없습니다.
어떤 아이디어가 있나요?