2015-01-28 6 views
0

두 개의 430Hz와 450Hz 사이에서 진동하여 비브라토를 만들고, 목록에 16 비트 샘플을 저장하려고합니다. wav. 그러나 가청 주파수는 전체 클립에서 진동 범위를 증가시키는 것으로 보입니다. 아무도 이유를 아나요?비브라토 사인파 생성

편집 : 재 작성 코드/간결 더 명확하게하기

# vibrato.py 

maxamp = 2**15 - 1 # max signed short 
wav = [] 
(t, dt) = (0, 1/44100) 
while t < 6.0: 
    f = 440 + 10 * math.sin(2 * math.pi * 6 * t) 
    samp = maxamp * math.sin(2 * math.pi * f * t) 
    wav.append(samp) 
    t += dt 

-

업데이트 : 응답이 NumPy와를 사용하기 때문에, 나는 일반 python3 내 코드를 업데이트합니다

# vibrato.py 

maxamp = 2**15 - 1 # max signed short 
wav = [] 
(t, dt) = (0, 1/44100) 
phase = 0 
while t < 6.0: 
    f = 440 + 10 * math.sin(2 * math.pi * 6 * t) 
    phase += 2 * math.pi * f * t 
    samp = maxamp * math.sin(phase) 
    wav.append(samp) 
    t += dt 

답변

2

문제는 묵시적 위상 변화와 관련이 있습니다. 주파수가 변하는 것과 함께 진행됩니다. 요컨대, 타임 라인의 각 지점에 대한 응답을 계산할 때 진동의 위상이 각 주파수마다 다를 것이라는 점에 유의해야합니다 (모든 시작점을 제외하고 모두 동일 함). 따라서 주파수 간 이동은 여러 단계로 이동하는 것과 같습니다. 두 개의 별개의 주파수 사이를 이동하는 경우 주파수 변경을 기반으로 전체 신호 위상을 조정하여 이후에이를에 맞게 수정할 수 있습니다. 나는 이것을 in another answer으로 설명 했으므로 여기서 다시 설명하지는 않겠지 만 문제를 강조하는 초기 플롯과 문제를 해결하는 방법을 보여줍니다. 여기서 중요한 점은 좋은 진단 플롯의 중요성이며, 이에 대한 올바른 플롯은 스펙트로 그램입니다. (처음 들어 본으로) 주파수 진동의 폭이 증가하고 있음을

import numpy as np 

dt = 1./44100 
time = np.arange(0., 6., dt) 
frequency = 440. - 10*np.sin(2*math.pi*time*1.) # a 1Hz oscillation 
waveform = np.sin(2*math.pi*time*frequency) 

Pxx, freqs, bins, im = plt.specgram(waveform, NFFT=4*1024, Fs=44100, noverlap=90, cmap=plt.cm.gist_heat) 
plt.show() 

enter image description here

참고 :

다음은 예입니다. 위의 링크 된 보정을 적용하면 제공 : 의도했던 것과 매우 가까운

dt = 1./defaults['framerate'] 
time = np.arange(0., 6., dt) 
frequency = 440. - 10*np.sin(2*math.pi*time*1.) # a 1Hz oscillation 
phase_correction = np.add.accumulate(time*np.concatenate((np.zeros(1), 2*np.pi*(frequency[:-1]-frequency[1:])))) 
waveform = np.sin(2*math.pi*time*frequency + phase_correction) 

enter image description here , 나는 희망한다.

각 시간 단계 (OP와 마찬가지로)를 반복하면서 실제 모델에 더 가깝게 반복되는 맥락에서 더 잘 이해할 수있는 또 다른 방법은 각 단계에서 위상을 추적하는 것입니다. 이전 단계의 진폭과 위상을 모두 고려한 새 진폭을 결정하고이를 새로운 주파수와 결합합니다. 나는 이것을 순수 파이썬으로 돌릴 수있는 인내심을 가지고 있지 않지만, numpy에서는 그 해결책이 이렇게 생겼고 유사한 결과를 얻었습니다.

dt = 1./44100 
time = np.arange(0., 6., dt) 
f = 440. - 10*np.sin(2*math.pi*time*1.) # a 1Hz oscillation 
delta_phase = 2 * math.pi * f * dt 
phase = np.cumsum(delta_phase) # add up the phase differences along timeline (same as np.add.accumulate) 
wav = np.sin(phase) 
+0

나는 내 게시물을 명확하게 편집했습니다. 나는 파형을보기 위해 대담함을 사용하고 있었지만 실제로는 도움이되지 않았습니다. 왜냐하면 우리는 파도의 실제 값이 아닌 파도가 압축되는 속도를보고 있기 때문입니다. 나는 주파수를 정의하는 초기 사인파가 잘 작동한다는 것을 알고 있으므로 개념적 문제라고 생각합니다. 내 함수의 파생물을 가져 와서 내 샘플 함수가 Ω (t)로 바뀌므로 내 함수가 사인 곡선으로 만 변하지 않는다는 것을 알 수있었습니다. – twinlakes

+0

@twinlakes : 당신이 무슨 뜻인지 알았는데 이전 대답이 잘못되었습니다. 나는 그것을 완전히 다시 작성했습니다, 그리고 지금 그것이 정확하다고 생각합니다. 덕분에 – tom10

+0

. 방금 구현했고 작동했습니다. – twinlakes