You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyAudio无法识别Focusrite 18i20多通道输入问题求助

问题:Focusrite 18i20 8通道音频接口3-8通道无声排查

环境配置

  • Python版本:3.11.4
  • PyAudio版本:0.2.11
  • Torch版本:2.1.1+cu118

问题描述

已通过DAW确认Focusrite 18i20的8个麦克风通道均有音频输入,但Python脚本仅能将1、2通道的音频实时播放到笔记本立体声耳机接口,3-8通道完全无声。同时测试脚本录制的8通道WAV文件,在RX10/Pro Tools中打开后3-8通道仅显示静音。采用阻塞模式而非回调模式。

音频流设置代码

if read_from_file == True:
    wf = wave.open(audio_path, 'rb')
    stream = paudio.open(
        format=paudio.get_format_from_width(wf.getsampwidth()),
        channels=output_format, rate=wf.getframerate(), output=True)
elif read_from_file == False:
    istream = paudio.open(format=format_audio, channels=channels, rate=sr,
                          input=True, frames_per_buffer=input_chunk,
                          input_device_index=input_device)
    stream = paudio.open(format=pyaudio.paInt16, channels=2, rate=sr,
                         frames_per_buffer=input_chunk, output=True)

实时流播放代码

while len(data) > 0 and time.time() < end_time:
    if channels == 8:
        numpy_data = np.frombuffer(data, dtype=np.int16)
        stereo_data = mix_down_to_stereo(numpy_data)
        if normalize == False:
            data = stereo_data.astype(np.int16).tobytes()
        else:
            processed_data = compress_and_normalize(stereo_data,
                                                    threshold=-0.1, ratio=4.0,
                                                    normalize_scale=0.5)
            scaled_data = np.int16(processed_data * 32767)
            data = scaled_data.tobytes()
    stream.write(data)
    if read_from_file == True:
        data = wf.readframes(chunk)
    elif read_from_file == False:
        data = istream.read(input_chunk)

关闭音频流代码

if read_from_file == True:
    wf.close()
stream.close()
paudio.terminate()

测试录制脚本代码

import pyaudio
import wave

FORMAT = pyaudio.paInt16
CHANNELS = 8
RATE = 48000
CHUNK = 1024
RECORD_SECONDS = 5
FILENAME = "test_recording.wav"

audio = pyaudio.PyAudio()

# Start Recording
stream = audio.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True,
                    frames_per_buffer=CHUNK)
frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

# Stop Recording
stream.stop_stream()
stream.close()
audio.terminate()

# Save the recorded data as a WAV file
wf = wave.open(FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(audio.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

问题分析与解决方案

1. PyAudio对多通道的支持

PyAudio本身支持多通道输入输出,但实际能否获取所有通道数据,取决于音频硬件的驱动是否正确暴露这些通道给底层依赖的PortAudio库。

2. 3-8通道无声的核心原因

(1)输入设备通道映射问题

Focusrite 18i20这类专业音频接口,默认可能不会将所有通道都映射为系统默认输入设备的可用通道。即使脚本指定了channels=8,PyAudio可能实际只获取到前2通道的数据——因为PortAudio未正确识别接口的全部8个输入通道,或系统音频设置未启用这些通道。

(2)测试脚本的WAV文件格式问题

标准WAV文件的多通道存储分交错式和非交错式,PyAudio返回的多通道数据是交错式(每个采样帧按通道1→通道2→...→通道8循环存储),而部分DAW(如Pro Tools)对多通道WAV格式要求更严格,需要非交错式存储或特定通道标记才能识别全部通道。

(3)实时播放的通道处理逻辑

实时播放代码的输出流是channels=2的立体声,若mix_down_to_stereo函数未正确处理8通道的交错数据,会仅提取前2通道内容,导致3-8通道音频被丢弃。

3. 解决方案

(1)确认输入设备的通道可用性

运行以下代码,检查Focusrite设备的输入通道数是否被正确识别:

import pyaudio

pa = pyaudio.PyAudio()
for i in range(pa.get_device_count()):
    dev_info = pa.get_device_info_by_index(i)
    print(f"设备索引: {i}")
    print(f"设备名称: {dev_info['name']}")
    print(f"支持的输入通道数: {dev_info['maxInputChannels']}")
    print(f"支持的输出通道数: {dev_info['maxOutputChannels']}")
    print("-"*30)
pa.terminate()

若maxInputChannels不是8,需调整系统设置:

  • Windows:打开「声音设置」→「更多声音设置」→ 找到Focusrite设备→「属性」→「高级」,确认启用所有输入通道。
  • macOS:打开「音频MIDI设置」→ 找到Focusrite设备→ 点击「配置输入」,启用8个输入通道。

(2)修复测试脚本的WAV写入逻辑

使用scipy.io.wavfile替代标准wave模块,更好处理多通道数据:

import pyaudio
import numpy as np
from scipy.io import wavfile

FORMAT = pyaudio.paInt16
CHANNELS = 8
RATE = 48000
CHUNK = 1024
RECORD_SECONDS = 5
FILENAME = "test_recording.wav"

audio = pyaudio.PyAudio()
stream = audio.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True,
                    frames_per_buffer=CHUNK)

frames = []
for _ in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

stream.stop_stream()
stream.close()
audio.terminate()

# 将字节数据转换为numpy数组并重塑为(采样数, 通道数)格式
audio_data = np.frombuffer(b''.join(frames), dtype=np.int16)
audio_data = audio_data.reshape(-1, CHANNELS)
# 写入WAV文件
wavfile.write(FILENAME, RATE, audio_data)

(3)修复实时播放的通道混音逻辑

确保mix_down_to_stereo正确处理8通道交错数据:

def mix_down_to_stereo(interleaved_data):
    # 将交错数据重塑为(帧数量, 8通道)
    multi_channel = interleaved_data.reshape(-1, 8)
    # 自定义3-8通道到立体声的混音规则(可调整权重)
    left = (multi_channel[:,0] + multi_channel[:,2] + multi_channel[:,4] + multi_channel[:,6]) / 4
    right = (multi_channel[:,1] + multi_channel[:,3] + multi_channel[:,5] + multi_channel[:,7]) / 4
    # 重新生成立体声交错数据
    stereo_interleaved = np.column_stack((left, right)).flatten()
    return stereo_interleaved

内容的提问来源于stack exchange,提问作者Strigi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:33:20