如何以编程方式控制声卡?

时间:2015-09-03 10:16:55

标签: python audio pyaudio soundcard

我正在使用Saffire Pro 40声卡在Mac上玩pyaudio。 目前我插入了两个输入,我想以编程方式控制第二个输入通道的电平。 (使用声卡的混音控制软件可以正常工作)。

我一直在浏览pyaudio文档,但到目前为止还没有发现任何关于此问题的内容。基本上以混合控制软件的方式(以通道方式控制每个通道的音量)的最简单方法是什么? (Python API会很好,但不是必需的)

为了简化:看起来可以手动从我想要控制的通道中读取流,使用numpy缩放它们,将它们写为输出,但我希望有一种方法可以简单地发送一个规范化的值每个频道控制它。

所以不要这样:

stream1 = pyaudioInstance.open( format             = FORMAT,
                                channels           = CHANNELS,
                                rate               = RATE,
                                input              = True,
                                output             = True,
                                input_device_index = 0,
                                frames_per_buffer  = CHUNK
                                )
stream2 = pyaudioInstance.open( format             = FORMAT,
                                channels           = CHANNELS,
                                rate               = RATE,
                                input              = True,
                                input_device_index = 1,
                                frames_per_buffer  = CHUNK
                                )

while processingAudio:
    # manually fetch each channel
    data1In = stream1.read(CHUNK)
    data2In = stream2.read(CHUNK)
    # convert to numpy to easy scale the arrays
    decodeddata1 = numpy.fromstring(data1In, numpy.int16)
    decodeddata2 = numpy.fromstring(data2In, numpy.int16)
    newdata = (decodeddata1 * 0.5 + decodeddata2* 0.1).astype(numpy.int16)
    # finally write the processed data
    stream1.write(result.tostring())

这有点误导,但我需要在同一输入设备索引中混合使用不同的通道。然而,我希望是这样的:

someSoundCardAPI.channels[0].setVolume(0.2)

看看Channel Maps example感觉更接近我所追求的。目前我发现API的host_api_specific部分有点令人困惑,我希望有人已经有一些成功使用它的经验。

我正在使用OSX 10.10

1 个答案:

答案 0 :(得分:1)

我对OSX没有任何经验,所以我不知道,但通常你可以使用AppleScript远程控制所有内容。 例如,请参阅this question。 但是,它没有说明如何单独控制单个通道的音量。

可能你应该问那里......

关于劣质解决方法,您可以使用python-sounddevice创建一个小的(未经测试的)Python脚本:

import sounddevice as sd

def callback(indata, outdata, *stuff):
    outdata[:] = indata * [1, 0.5]

with sd.Stream(channels=2, callback=callback):
    input()

此脚本将一直运行,直到您按<Return>,这将减少第二个频道的音量。