【问题标题】:Remove/control clicking sound using PyAudio as an oscillator使用 PyAudio 作为振荡器删除/控制点击声音
【发布时间】:2017-02-12 19:34:09
【问题描述】:

运行时,音高之间会发出咔哒声。我不太介意咔哒声——它很有节奏感。那就是……

  • 我希望能够在我不想要这种咔哒声时消除它。
  • 更好的是,能够控制点击声音会很好 以某种方式 - 音量等。

我已经看过这个帖子,但还没有弄清楚如何将它应用于我的问题: How to remove pops from concatented sound data in PyAudio

有什么想法吗?感谢您的宝贵时间!

import numpy
import pyaudio
import math
import random


def sine(frequency, length, rate):
    length = int(length * rate)
    factor = float(frequency) * (math.pi * 2) / rate
    waveform = numpy.sin(numpy.arange(length) * factor)
    return waveform


def play_tone(stream, frequency, length, rate=44100):
    chunks = []
    chunks.append(sine(frequency, length, rate))

    chunk = numpy.concatenate(chunks) * .25

    stream.write(chunk.astype(numpy.float32).tostring())


def bassline():
        frequency = 300
        for i in range(1000000):
            play_tone(stream, frequency, .15)
            change = random.choice([-75, -75, -10, 10, 2, 3, 100, -125])
            print (frequency)
            if frequency < 0:
                frequency = random.choice([100, 200, 250, 300])
            else:
                frequency = frequency + change 

if __name__ == '__main__':
    p = pyaudio.PyAudio()
    stream = p.open(format=pyaudio.paFloat32,
                    channels=1, rate=44100, output=4)

bassline()

/编辑

我已经绘制了音调,看起来不连续性在于每个音调的开始和结束阶段之间的关系。

First tone

Second tone

任何想法如何解决这个问题?

【问题讨论】:

  • 您应该尝试绘制生成的波形。通过这种方式,您可能会看到导致点击的不连续性。
  • 既然你现在知道了问题的原因,也知道它与 PyAudio 或 PortAudio 没有任何关系,你应该放弃这个问题,问一个描述你实际问题的新问题。您应该尝试将示例代码减少到相关部分。您还应该考虑在dsp.stackexchange.com 提问,因为这实际上是一个 DSP 问题。

标签: python audio signal-processing pyaudio portaudio


【解决方案1】:

从两个波形图像中可以看出,当您在频率之间切换时,由于波形幅度的快速变化,您会听到咔哒声。为了解决这个问题,您需要在更改频率时保持波形的相位。我认为最简单的方法是添加一个变量,该变量记录每次正弦调用后波形周期中的最后一个位置。结束位置可以用作下一个正弦调用的开始位置。

类似:

phase_start = phase_position
phase_end = phase_start + length
waveform = numpy.sin(numpy.arange(phase_start, phase_end) * factor)
phase_position = phase_end

注意:我认为这是最简单的答案,但我建议使用您引用的问题中的信息。您应该以弧度保持播放正弦波的相位。 How to remove pops from concatented sound data in PyAudio

【讨论】:

    【解决方案2】:

    谢谢EhzMatthias

    最后,我通过在几百毫秒的过程中淡入和淡出每个音调来解决这个问题。这也是控制点击声音的好方法。 fade0 越近,点击的声音越大。

    import math
    import numpy
    import pyaudio
    
    
    def sine(frequency, length, rate):
        length = int(length * rate)
        factor = (float(frequency) * (math.pi * 2) / rate)
        return numpy.sin(numpy.arange(length) * factor)
    
    
    def play_tone(stream, frequency, length, rate=44100):
        chunks = [sine(frequency, length, rate)]
    
        chunk = numpy.concatenate(chunks) * 0.25
    
        fade = 200.
    
        fade_in = numpy.arange(0., 1., 1/fade)
        fade_out = numpy.arange(1., 0., -1/fade)
    
        chunk[:fade] = numpy.multiply(chunk[:fade], fade_in)
        chunk[-fade:] = numpy.multiply(chunk[-fade:], fade_out)
    
        stream.write(chunk.astype(numpy.float32).tostring())
    
    
    def test():
        test_freqs = [50, 100, 200, 400, 800, 1200, 2000, 3200]
    
        for i in range(2):
            for freq in test_freqs:
                play_tone(stream, freq, 1)
    
    
    if __name__ == '__main__':
        p = pyaudio.PyAudio()
        stream = p.open(format=pyaudio.paFloat32,
                        channels=1, rate=44100, output=1)
    
    
    test()
    

    【讨论】:

      【解决方案3】:

      点击是由于一个频率的结束波相位与以下频率的起始波相位不同。请参阅下面的两个图像:检查第一波的图表显示结束相位值约为 -0.96。第二幅图显示了下一个频率,从大约 0.85 的幅度开始。如果您不相应地移动每个新波,您会在频率之间听到明显的咔嗒声。事实证明,有一个非常简单的解决方案。使用 numpy.arcsin() 计算并存储所需的相移,以保持波和谐运行:

      wave_delta_arcsin = 0.0
      
      def sine(frequency, length):
          global wave_delta_arcsin
          length = int(length * rate)
          factor = (math.pi * 2) * float(frequency) / rate
          wave = numpy.sin(numpy.arange(length) * factor + wave_delta_arcsin)
          wave_delta_arcsin = numpy.arcsin(wave[-1])
          return wave
      

      【讨论】:

        猜你喜欢
        • 2021-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-12
        • 1970-01-01
        相关资源
        最近更新 更多