我想爲iPhone構建一個吉他調音器應用程序。我的目標是找到吉他弦所產生的聲音的基本頻率。我已經使用Apple提供的aurioTouch示例中的一些代碼來計算頻譜,並且我找到了幅度最高的頻率。它對純音(僅具有一個頻率的音)起作用很好,但對於來自吉他弦的聲音它會產生錯誤的結果。我讀過這是因爲吉他弦產生的泛音可能比基本弦的幅度更大。我怎樣才能找到基本的頻率,所以它適用於吉他弦? C/C++/Obj-C中是否有開放源代碼庫用於聲音分析(或信號處理)?如何找到吉他絃音的基本頻率?
回答
您可以使用信號的自相關,它是DFT幅度平方的逆變換。如果以44100樣本/秒進行採樣,那麼82.4Hz基波約爲535個樣本,而1479.98Hz約爲30個樣本。尋找該範圍內的峯值正滯後(例如從28到560)。確保你的窗口至少有兩個最長基本時期,這裏是1070個樣本。對於兩個2048樣本緩衝區的下一個功能。爲了獲得更好的頻率分辨率和更少的偏差估計,可以使用更長的緩衝區,但不要太長以至於信號不再近似靜止。下面是在Python一個例子:
from pylab import *
import wave
fs = 44100.0 # sample rate
K = 3 # number of windows
L = 8192 # 1st pass window overlap, 50%
M = 16384 # 1st pass window length
N = 32768 # 1st pass DFT lenth: acyclic correlation
# load a sample of guitar playing an open string 6
# with a fundamental frequency of 82.4 Hz (in theory),
# but this sample is actually at about 81.97 Hz
g = fromstring(wave.open('dist_gtr_6.wav').readframes(-1),
dtype='int16')
g = g/float64(max(abs(g))) # normalize to +/- 1.0
mi = len(g)/4 # start index
def welch(x, w, L, N):
# Welch's method
M = len(w)
K = (len(x) - L)/(M - L)
Xsq = zeros(N/2+1) # len(N-point rfft) = N/2+1
for k in range(K):
m = k * (M - L)
xt = w * x[m:m+M]
# use rfft for efficiency (assumes x is real-valued)
Xsq = Xsq + abs(rfft(xt, N)) ** 2
Xsq = Xsq/K
Wsq = abs(rfft(w, N)) ** 2
bias = irfft(Wsq) # for unbiasing Rxx and Sxx
p = dot(x,x)/len(x) # avg power, used as a check
return Xsq, bias, p
# first pass: acyclic autocorrelation
x = g[mi:mi + K*M - (K-1)*L] # len(x) = 32768
w = hamming(M) # hamming[m] = 0.54 - 0.46*cos(2*pi*m/M)
# reduces the side lobes in DFT
Xsq, bias, p = welch(x, w, L, N)
Rxx = irfft(Xsq) # acyclic autocorrelation
Rxx = Rxx/bias # unbias (bias is tapered)
mp = argmax(Rxx[28:561]) + 28 # index of 1st peak in 28 to 560
# 2nd pass: cyclic autocorrelation
N = M = L - (L % mp) # window an integer number of periods
# shortened to ~8192 for stationarity
x = g[mi:mi+K*M] # data for K windows
w = ones(M); L = 0 # rectangular, non-overlaping
Xsq, bias, p = welch(x, w, L, N)
Rxx = irfft(Xsq) # cyclic autocorrelation
Rxx = Rxx/bias # unbias (bias is constant)
mp = argmax(Rxx[28:561]) + 28 # index of 1st peak in 28 to 560
Sxx = Xsq/bias[0]
Sxx[1:-1] = 2 * Sxx[1:-1] # fold the freq axis
Sxx = Sxx/N # normalize S for avg power
n0 = N/mp
np = argmax(Sxx[n0-2:n0+3]) + n0-2 # bin of the nearest peak power
# check
print "\nAverage Power"
print " p:", p
print "Rxx:", Rxx[0] # should equal dot product, p
print "Sxx:", sum(Sxx), '\n' # should equal Rxx[0]
figure().subplots_adjust(hspace=0.5)
subplot2grid((2,1), (0,0))
title('Autocorrelation, R$_{xx}$'); xlabel('Lags')
mr = r_[:3 * mp]
plot(Rxx[mr]); plot(mp, Rxx[mp], 'ro')
xticks(mp/2 * r_[1:6])
grid(); axis('tight'); ylim(1.25*min(Rxx), 1.25*max(Rxx))
subplot2grid((2,1), (1,0))
title('Power Spectral Density, S$_{xx}$'); xlabel('Frequency (Hz)')
fr = r_[:5 * np]; f = fs * fr/N;
vlines(f, 0, Sxx[fr], colors='b', linewidth=2)
xticks((fs * np/N * r_[1:5]).round(3))
grid(); axis('tight'); ylim(0,1.25*max(Sxx[fr]))
show()
輸出:
Average Power
p: 0.0410611012542
Rxx: 0.0410611012542
Sxx: 0.0410611012542
峯值滯後是538,這是五百三十八分之四萬四千百= 81.97赫茲。第一遍非循環DFT顯示了在箱61處的基波,其爲82.10 +/- 0.67Hz。第二遍使用的窗口長度爲538 * 15 = 8070,所以DFT頻率包括字符串的基本週期和諧波。這使得無偏循環自相關能夠用於具有較少諧波擴展的改進的PSD估計(即,相關性可以週期性地圍繞窗口)。
編輯:更新爲使用韋爾奇方法來估計自相關。重疊窗口補償了漢明窗口。我還計算了海明窗的錐形偏差以去除自相關。
編輯:添加了循環相關的第2遍以清除功率譜密度。此通道使用3個不重疊的矩形窗口,長度爲538 * 15 = 8070(足夠短,幾乎靜止不動)。循環相關的偏差是一個常數,而不是漢明窗的錐形偏差。
找到一個和絃中的音樂節奏要比估計一次播放的單個字符串或音符的節奏困難得多。和絃中的多個音符的泛音可能都是重疊和交錯的。並且所有普通和絃的音符本身可以處於一個或多個不存在的低音音符的泛音頻率。
對於單音符,自相關是一些吉他調音器常用的技巧。但是對於自相關,你必須意識到一些潛在的八度不確定性,因爲吉他可能會產生不和諧和衰減的泛音,因此從音調週期到音高週期不完全匹配。 Cepstrum和Harmonic Product Spectrum是另外兩種基音估計方法,根據吉他和音符的不同,它們可能會有也可能不會有不同的問題。
RAPT似乎是一種公開的算法,用於更可靠的基音估計。陰是另一個。另外目標C是ANSI C的一個超集。因此,您可以使用您在Objective C應用程序中爲音高估計找到的任何C DSP例程。
- 1. 從音頻樣本中識別單個吉他和絃
- 2. 通過原始音頻再現吉他弦與和聲
- 3. 如何用Flash的聲音合成器模擬吉他弦/和絃?
- 4. 吉他和絃檢測
- 5. 如何連續改變正弦聲音的頻率?
- 6. 用於吉他琴絃的FFT音高檢測
- 7. c基本頻率+語音檢測#
- 8. 吉他和絃識別算法?
- 9. 如何使用步長查找正弦表中的音頻? STM32
- 10. 如何使用Skype4Com找到麥克風音頻的採樣率?
- 11. 安卓音頻FFT顯示基本頻率
- 12. 如何在pcm流(c#)中找到音頻功率(db)
- 13. 正弦信號的計算頻率,C++
- 14. 查找麥克風中正弦波的頻率
- 15. 如何找到音頻暫停或完成在jquery,Html5音頻
- 16. 處理中的和絃音頻播放
- 17. 轉換音頻流頻率
- 18. 所有音頻頻率
- 19. Google主頁使用的是什麼技術(吉他弦)
- 20. iOS視頻播放器w /添加了音頻通道,可以播放吉他
- 21. 如何在iphone中錄製語音時查找頻率?
- 22. html5音頻。如何獲得比特率
- 23. 如何從DTMF音低頻率
- 24. 通過倒譜法的基本頻率
- 25. 隨着時間的推移改變音樂頻率讓它聽起來像吉他?
- 26. 是否有Android庫來識別吉他和絃?
- 27. 在電路顯示器上顯示吉他和絃
- 28. 使用PHP創建圖像以顯示吉他和絃
- 29. 如何在C/C++或Java中生成真正的低音吉他聲音?
- 30. YouTube視頻中的音頻比特率?
我不是一個音樂家,但如果你想要做一個調音器,爲什麼你需要找出一個和絃?一次調整一個字符串不是更容易嗎? – mtrw 2011-02-18 22:30:13
@mtrw這是拼寫錯誤......它應該是「繩索」,而不是「和絃」......我很抱歉誤會 – Mircea 2011-02-19 12:28:36
所以編輯它來修復錯誤!並使用術語「字符串」來避免任何進一步的混淆。 – Clifford 2011-02-20 08:33:24