我有多个 USB 音频接口,每个接口都有 10 个、18 个甚至 32 个输入通道。主要用于将乐队的每种乐器录制到单独的轨道中。
我以原始 wav 格式(s32le @48kHz)录制,这意味着如果我录制所有通道,我需要大量的存储空间。因此,我只需要录制我真正想要录制的频道。我发现使用 SoX 可以实现这一点,通过使用标志指定我需要的通道数量-c
并使用remix
“效果”来选择要记录的通道。
这个小小的概念证明向我表明它确实有效:
$ 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
顺便说一句,使用 PipeWirepw-record
实用程序直接录音效果很好:
$ 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 在这里失败
有任何想法吗?