2017-05-09 283 views
0

我寫了一小段Python代碼(其中大部分是我從SO本身複製而來的),如果我的持續時間是0.1,但如果我的持續時間是0.05,我聽到一些點擊聲音。不知道爲什麼會這樣。在python中生成正弦音頻時產生噪音

我需要播放持續時間較短的頻率更高的數字,但是這種情況下的聲音完全混亂了。附上以下代碼:

import numpy as np 
import sounddevice as sd 

def playArray(pts, time): 

    samplerate = 44100.0 
    sd.default.samplerate = samplerate 
    volume = 10000 
    count = len(pts) 

    samples = np.arange(samplerate * time)/samplerate 

    wave = [] 
    for freq in pts: 
     wavelet = volume * np.sin(2 * np.pi * freq * samples) 
     wave = np.concatenate([wave, wavelet]) 

    wav_wave = np.array(wave, dtype=np.int16) 
    sd.play(wav_wave, blocking=True) 

pts = np.arange(300, 1500, 10) 
playArray(pts, 0.1) 
+1

你應該繪製你的波形圖,然後你會很快看到什麼是錯的。你串聯正弦音調,完全忽略它們的相位。這肯定會出錯。即使您要調整階段,如果頻率發生快速變化,仍然可能會聽到瑕疵。如果你需要正弦掃描,你可以試試[scipy.signal.chirp()](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.chirp.html)。還有一些其他庫提供類似的信號。 – Matthias

+0

您的音頻持續時間是0.1分鐘還是0.1秒? –

+0

@Anil_M它的秒 –

回答

1

基於@Matthias評論我更改了我的代碼,將相位納入採樣。

下面是更新後的代碼:

import numpy as np 
import sounddevice as sd 
import math 

def playArray(pts, time): 

    samplerate = 44100.0 
    sd.default.samplerate = samplerate 
    volume = 10000 
    total = len(pts) 
    count = 0 
    phase = 0.0 
    samples = np.zeros(math.ceil(samplerate * time * total), dtype = np.float) 

    for i, val in enumerate(samples): 
     freq = pts[count] 
     freqRads = 2 * np.pi * freq/samplerate 
     phase = phase + freqRads 
     sampleValue = volume * np.sin(phase) 
     samples[i] = sampleValue 
     if (i > 0 and i % (samplerate * time) == 0): 
      count = count + 1 

    wav_wave = np.array(samples, dtype=np.int16) 
    sd.play(wav_wave, blocking=True) 
0

如果你需要的是創造持續時間短的正弦波音,你可能想看看pydub

可以使用pydub.generators模塊具有類來創建不同的波形,例如sinesquarepulsesawtooth等並用的代碼量最少。

而且您可以創建波形數毫秒的持續時間。

這是一個工作示例,可創建正弦波持續0.05秒(50毫秒)。音頻段的

from pydub import AudioSegment 
from pydub.generators import Sine 
from pydub.playback import play 

frequency = 2000 #in Hz 

#create sine wave of given freq 
sine_wave = Sine(frequency, sample_rate=44100, bit_depth=16) 

#Convert waveform to audio_segment for playback and export 
#duation is in millisec 
sine_segment = sine_wave.to_audio_segment(duration=50.0) 

#Play audio segment 
play(sine_segment) 

#save/export audio_segment 
sine_segment.export("out_sine.wav", format="wav") 

長度可使用

#Duration in seconds 
>>> sine_segment.duration_seconds 
0.05 

#Duration in milliseconds 
>>> len(sine_segment) 
50 
>>> 

更多發生器模塊here上找到。
希望這會有所幫助。