【问题标题】:Python real time audio mixingPython 实时混音
【发布时间】:2015-08-22 15:38:21
【问题描述】:

每次发送或接收数据包时,我都会使用 scapy 和 pyaudio 播放一小段正弦波,声音的频率指示发件人地址。

sniff(prn = makeSound)

在此代码中,makeSound 函数获取一个数据包,对其进行剖析,并根据发送者地址播放声音。

据我所知,pyaudio 有阻塞或回调模式。在这两种模式下,我都不能同时播放多个声音。

我需要一种方法来开始一个音符,并让它立即开始混合到音频流中,不管有多少正弦波已经在播放。

【问题讨论】:

  • 你不能在不同的线程中触发它们吗?
  • 对于这样的事情,手动线程似乎有点矫枉过正。是否有一些示例代码显示我将如何做到这一点?
  • 如果线程看起来工作量太大,那么 Timer() 怎么样
  • 糟糕!我认为这是 wxpython 特有的!
  • 我最终做的是使用os.system('play --no-show-progress --null --channels 1 synth %s sine %f &' % ( 0.1, srcHz))。最后的“&”允许外壳是非阻塞的。这当然非常笨拙,但它确实有效。根据 Rolf of Saxony 的建议,我可能会将其升级为 in-python 线程。

标签: python scapy pyaudio


【解决方案1】:

您需要自己进行混音。请参阅以下示例程序,了解如何将多个声音混合到一个单通道输出中。

 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)

【讨论】:

    猜你喜欢
    • 2012-04-26
    • 2016-02-08
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    相关资源
    最近更新 更多