2017-02-12 61 views
2

運行時,音高之間會有一聲卡嗒聲。我不介意咔嗒聲太多 - 它令人愉快有節奏。這就是說...刪除/控制使用PyAudio作爲振盪器的點擊聲音

  • 我希望能夠擺脫這種點擊聲音,當我不想要它。
  • 更重要的是,這將是很好能夠控制在某種程度上咔嗒聲 - 音量等

我看到這個線程,但還沒有想出如何把它應用到我的問題: 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() 

/EDIT

我繪製的色調,它看起來像的不連續性是在開始和每個音的結束階段之間的關係。

First tone

Second tone

任何想法如何解決這個問題?

+0

您應該嘗試繪製生成的波形。通過這種方式,您可能會看到導致點擊的不連續點。 – Matthias

+0

由於您現在知道問題的原因,並且知道它與PyAudio或PortAudio沒有任何關係,因此您應該放棄此問題並請求描述您實際問題的新問題。您應該嘗試將示例代碼減少到相關部分。你也應該考慮在http://dsp.stackexchange.com/上詢問,因爲它實際上是一個DSP問題。 – Matthias

回答

1

正如在兩幅波形圖中所看到的那樣,當您在頻率之間切換時,由於波形振幅的快速變化,您會看到卡嗒聲。爲了解決這個問題,您需要在更改頻率時保持波形的相位。我認爲最簡單的方法是在每次正弦調用後添加一個記錄波形週期中最後一個位置的變量。結束位置可用作下一次正弦呼叫的起始位置。

喜歡的東西:

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

Pitch shift maintaining cycle position

注:我認爲這是一個可以工作的最簡單的答案,但我會建議使用在你提到的問題的信息。您應該以弧度保持播放的正弦波的相位。 How to remove pops from concatented sound data in PyAudio

1

謝謝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()