Python 实时混音
Python real time audio mixing
每次发送或接收数据包时,我都使用 scapy 和 pyaudio 播放一小段正弦波,声音的频率指示发件人地址。
sniff(prn = makeSound)
在此代码中,makeSound
函数获取一个数据包,对其进行分解,并根据发件人地址播放声音。
据我所知,pyaudio有阻塞模式和回调模式。在这两种模式下我都不能同时播放多个声音。
我需要一种方法来开始一个音符,并立即开始将其混合到音频流中,而不管正在播放的过程中已经有多少正弦波。
您需要自己进行混音。请参阅以下示例程序,了解如何将多种声音混合到一个单通道输出中。
import struct
import math
import pyaudio
from itertools import count
pa = pyaudio.PyAudio()
FORMAT = pyaudio.paFloat32
CHANNELS = 1
RATE = 44100
OUTPUT_BLOCK_TIME = 0.05
OUTPUT_FRAMES_PER_BLOCK = int(RATE*OUTPUT_BLOCK_TIME)
def sine_gen():
time = 0
format = "%df" % OUTPUT_FRAMES_PER_BLOCK
voices = []
voices.append(lambda sampletime: math.sin(sampletime * math.pi * 2 * 440.0))
for frame in count():
block = []
for i in xrange(OUTPUT_FRAMES_PER_BLOCK):
sampletime = time + (float(i) / OUTPUT_FRAMES_PER_BLOCK) * OUTPUT_BLOCK_TIME
sample = sum(voice(sampletime) for voice in voices) / len(voices)
block.append(sample)
yield struct.pack(format, *block)
time += OUTPUT_BLOCK_TIME
if frame == 20:
voices.append(
lambda sampletime: math.sin(sampletime * math.pi * 2 * 880.0)
)
stream = pa.open(format=FORMAT,
channels=CHANNELS, rate=RATE, output=1)
for i, block in enumerate(sine_gen()):
stream.write(block)
每次发送或接收数据包时,我都使用 scapy 和 pyaudio 播放一小段正弦波,声音的频率指示发件人地址。
sniff(prn = makeSound)
在此代码中,makeSound
函数获取一个数据包,对其进行分解,并根据发件人地址播放声音。
据我所知,pyaudio有阻塞模式和回调模式。在这两种模式下我都不能同时播放多个声音。
我需要一种方法来开始一个音符,并立即开始将其混合到音频流中,而不管正在播放的过程中已经有多少正弦波。
您需要自己进行混音。请参阅以下示例程序,了解如何将多种声音混合到一个单通道输出中。
import struct
import math
import pyaudio
from itertools import count
pa = pyaudio.PyAudio()
FORMAT = pyaudio.paFloat32
CHANNELS = 1
RATE = 44100
OUTPUT_BLOCK_TIME = 0.05
OUTPUT_FRAMES_PER_BLOCK = int(RATE*OUTPUT_BLOCK_TIME)
def sine_gen():
time = 0
format = "%df" % OUTPUT_FRAMES_PER_BLOCK
voices = []
voices.append(lambda sampletime: math.sin(sampletime * math.pi * 2 * 440.0))
for frame in count():
block = []
for i in xrange(OUTPUT_FRAMES_PER_BLOCK):
sampletime = time + (float(i) / OUTPUT_FRAMES_PER_BLOCK) * OUTPUT_BLOCK_TIME
sample = sum(voice(sampletime) for voice in voices) / len(voices)
block.append(sample)
yield struct.pack(format, *block)
time += OUTPUT_BLOCK_TIME
if frame == 20:
voices.append(
lambda sampletime: math.sin(sampletime * math.pi * 2 * 880.0)
)
stream = pa.open(format=FORMAT,
channels=CHANNELS, rate=RATE, output=1)
for i, block in enumerate(sine_gen()):
stream.write(block)