기타로 연주 된 B3 음의 피치를 감지하려고합니다. 오디오는 here입니다. 당신이 볼 수 있듯이 단일 기타 음을위한 고조파 스펙트럼 파이톤
, 기본 피치는 B3 노트에 해당하는 250Hz에서 관한 것이라고 볼 수 있습니다 :
이
은 스펙트로 그램이다.또한 고조파가 많아서 here에서 HPS를 사용하기로했습니다. 나는 피치를 검출하는이 코드를 사용하고 있습니다 :
def freq_from_hps(signal, fs):
"""Estimate frequency using harmonic product spectrum
Low frequency noise piles up and overwhelms the desired peaks
"""
N = len(signal)
signal -= mean(signal) # Remove DC offset
# Compute Fourier transform of windowed signal
windowed = signal * kaiser(N, 100)
# Get spectrum
X = log(abs(rfft(windowed)))
# Downsample sum logs of spectra instead of multiplying
hps = copy(X)
for h in arange(2, 9): # TODO: choose a smarter upper limit
dec = decimate(X, h)
hps[:len(dec)] += dec
# Find the peak and interpolate to get a more accurate peak
i_peak = argmax(hps[:len(dec)])
i_interp = parabolic(hps, i_peak)[0]
# Convert to equivalent frequency
return fs * i_interp/N # Hz
내 샘플링 속도는 그러나 40000입니다 대신 250Hz에서 (B3 노트)에 가까운 결과, 내가 0.66Hz를 얻고을 얻는. 이것이 어떻게 가능한지?
같은 레포에서 자동 상관법을 사용해 보았지만 10000Hz와 같은 나쁜 결과가 나옵니다.
대답 덕분에 신호의 저주파수를 제거하기 위해 필터를 적용해야한다는 것을 이해합니다. 어떻게해야합니까? 이를 수행하는 방법이 여러 가지가 있으며 권장되는 방법은 무엇입니까?
상태 업데이트 : 대답에 의해 제안 된
하이 패스 필터가 작동된다. 내 오디오 신호에 응답 기능을 적용하면 약 245Hz가 올바르게 표시됩니다. 그러나 전체 신호를 필터링하고 싶습니다. 노트가 신호 중간에 있거나 신호에 두 개 이상의 노트가 포함되어있을 수 있습니다 (솔루션의 시작 감지는 알고 있지만 왜 이것이 작동하지 않는지 궁금합니다). 그래서 filtered_audio
을 반환하는 코드를 편집했습니다.
노이즈가 올바르게 제거 되었더라도 문제가 발생합니다 (스크린 샷 참조). 결과적으로 0.05가됩니다.
당신이 루프백을 수행 한 또 다른 알려진 주파수 소스를 가지고 : 여기
이 작업을 수행하는 코드는?- 다른 사람들은 OS, 드라이버에 따라 원하는 샘플 속도를 얻는 데 어려움을 겪었습니다. – f5r5e5d피치 알고리즘이 스펙트로 그램을 보지 못하기 때문에 전체 클립의 피치를 계산하려고하면 말도 안됩니다. 스펙트로 그램은 시간 경과에 따른 파워 스펙트럼을 나타내지 만 알고리즘은 전체 신호의 평균 파워 스펙트럼에서만 작동합니다. 필자가 의미하는 바를 알기 위해서는 전체 신호의 스펙트럼을보고 단지 노트의 스펙트럼 (0-1 초)과 비교하십시오. 클립에서 여러 음표의 가능성을 해결하려면 새로운 질문을해야한다고 생각합니다. – Michael
감사합니다. 당신 말이 맞습니다. 나는 신호를 여러 개의 신호 (모든 음을 연주 할 때마다 10-15 프레임 중 하나의 세그먼트)로 분할 한 다음 각 신호에 대해 HPS를 수행해야한다고 생각했습니다. 논리적 인 접근이라고 생각하십니까? – pk1914