Ошибка вычисления высоты тона с помощью метода автокорреляции - PullRequest
0 голосов
/ 13 сентября 2018
  • Цель: расчет высоты тона
  • Проблема: рассчитанный шаг не соответствует ожидаемому. Например, выход составляет ок. «D3», однако ожидаемый результат - «C5».

  • Источник звука: https://freewavesamples.com/1980s-casio-celesta-c5

Исходный код

library("tuneR")
library("seewave")

#0: Acquisition of sample sound
snd_smpl = readWave(paste("~/Music/sample/1980s-Casio-Celesta-C5.wav"), 
                                    from = 0, to = 1, units = "seconds")
dur_smpl = duration(snd_smpl)
len_smpl = length(snd_smpl)

#1 : Pre-Processing Stage

#1.1 : Application of Hanning Window
n = 1:len_smpl
han_win = 0.5-0.5*cos(2*pi*n/(len_smpl-1))
wind_sig = han_win*snd_smpl@left

#2.1 : Auto-Correlation Calculation
rev_wind_sig = rev(wind_sig)    #Reversing the windowed signal

acorr_1 = convolve(wind_sig, rev_wind_sig, type = "open")
# Obtaining the 2nd half of the correlation, to simplify calculation
n = 2*len_smpl-1 
acorr_2 = (1/len_smpl)*acorr_1[len_smpl:n]

#2.2 : Note Calculation
min_index = which.min(acorr_2)
print(min_index)
fs = 44100              
fo = fs/min_index #To obtain fundamental frequency

print(fo)
print(notenames(noteFromFF(fo)))

выход

> print(min_index)
[1] 37
> fs = 44100                
> fo = fs/min_index 
> print(fo)
[1] 1191.892
> print(notenames(noteFromFF(fo)))
[1] "d'''"

Весь расчет выполняется в Временной области . В настоящее время я использую автокорреляцию в качестве основы, чтобы больше узнать о Pitch Detection & Analysis. Я попытался проанализировать выборку с помощью «Audacity», и в результате получил «C5». Следовательно, мне интересно, где на самом деле проблема. Можете ли вы помочь мне найти его?

Также есть несколько, но важных сомнений:

  1. Насколько маленьким должно быть мое окно анализа (20 мс, 1 с, ..)?
  2. Будет ли усиление алгоритма автокорреляции с AMDF и другими подобными алгоритмами делать этот модуль Pitch Detection более надежным?

1 Ответ

0 голосов
/ 13 сентября 2018

Весь этот анализ кажется неправильным.Вы не должны использовать управление окнами в анализе временной области.

Приложено краткое решение на языке Python;Вы можете использовать его в качестве псевдокода

from soundfile import read
from glob import glob
from scipy.signal import correlate, find_peaks
from matplotlib.pyplot import plot, show, xlim, title, xlabel
import numpy as np
%matplotlib inline

name = glob('*wav')[0]
samples, fs = read(name)

corr = correlate(samples, samples)
corr = corr[corr.size / 2:]
time = np.arange(corr.size) / float(fs)
ind = find_peaks(corr[time < 0.002])[0]

plot(time, corr)
plot(time[ind], corr[ind], '*')
xlim([0, 0.005])
title('Frequency = {} Hz'.format(1 / time[ind][0]))
xlabel('Time [Sec]')
show()

enter image description here

...