简体   繁体   English

Python实时音频混合

[英]Python real time audio mixing

I'm using scapy and pyaudio to play a short length of sine wave every time a packet is sent or received, with the frequency of the sound indicating the sender address. 每次发送或接收数据包时,我都使用scapy和pyaudio播放较短长度的正弦波,声音的频率表示发送者的地址。

sniff(prn = makeSound)

In this code, the makeSound function takes a packet, dissects it, and plays a sound based on the sender address. 在此代码中, makeSound函数获取一个数据包,对其进行解剖,然后根据发送者地址播放声音。

As far as I know, pyaudio has either blocking or callback mode. 据我所知,pyaudio具有阻塞或回调模式。 In neither of these modes can I play multiple sounds simultaneously. 在这两种模式下,我都不能同时播放多个声音。

I need a way to start a note, and have it immediately start being mixed into the audio stream, regardless of how many sine waves are already in the process of being played. 我需要一种开始音符的方法,并使其立即开始被混合到音频流中,而不管正在播放多少正弦波。

You need to perform the mixing yourself. 您需要自己进行混合。 See the following example-program on how to mix several voices into one single-channel output. 请参阅以下示例程序,了解如何将几种声音混合到一个单通道输出中。

 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM