Tôi đã thực hiện một thuật toán phát hiện cao độ bằng HPS và tôi đang gặp vấn đề. Tôi là người mới bắt đầu xử lý tín hiệu và trang web này đã giúp tôi trước đây, vì vậy tôi mặc dù tôi nên hỏi.
Đối với các nốt cao hơn ( eg. >C6:1046.50hz
) Tôi bắt đầu nhận dữ liệu rác từ HPS. Cao độ càng cao, tôi càng nhận được nhiều rác (bởi rác tôi có nghĩa là các tần số không phải là lỗi quãng tám cũng như sóng hài và khoảng 1Hz-20Hz)
Những gì tôi đã quan sát theo kinh nghiệm:
kết quả là tồi tệ nhất đối với các nốt cao hơn, nếu mức cơ bản cao hơn A6 hoặc hơn, tôi chỉ nhận được dữ liệu rác.
FFT hoạt động tốt ngay cả đối với âm vực rất cao, (ý tôi là, đỉnh của nó thể hiện cơ bản hoặc một trong những sóng hài của nó, nhưng không phải rác)
nếu tôi giảm số lượng sóng hài tôi xem xét cho HPS, rác sẽ giảm đi, nhưng điều đó làm cho việc phân biệt giữa cơ bản và sóng hài khó hơn.
Đây là thuật toán của tôi:
->raw buffer -> hann window, 16384 samples, 50% overlap -> zero padding -> FFT -> HPS
Bất kỳ trợ giúp được đánh giá cao!
CẬP NHẬT 1: Vì vậy, có một vài điều nữa tôi muốn thêm:
- Tốc độ mẫu tôi đang ghi là 44100 Hz
- Tôi đã quan sát thấy rằng hành vi này hầu như không thể nhìn thấy trên một cây đàn guitar, nhưng rất rõ ràng trên một cây đàn piano kỹ thuật số (cho cùng một nốt nhạc được chơi)
Đây là thuật toán hps của tôi, có lẽ ai đó có kinh nghiệm lớn hơn có thể phát hiện ra một vấn đề.
int hps(float* spectrum, int spectrumSize, int harmonics) { int i, j, maxSearchIndex, maxBin; maxSearchIndex = spectrumSize/harmonics; maxBin = 1; for (j=1; j<=maxSearchIndex; j++) { for (i=1; i<=harmonics; i++) { spectrum[j] *= spectrum[j*i]; } if (spectrum[j] > spectrum[maxBin]) { maxBin = j; } } // Fixing octave too high errors int correctMaxBin = 1; int maxsearch = maxBin * 3 / 4; for (i=2; i<maxsearch; i++) { if (spectrum[i] > spectrum[correctMaxBin]) { correctMaxBin = i; } } if (abs(correctMaxBin * 2 - maxBin) < 4) { if (spectrum[correctMaxBin]/spectrum[maxBin] > 0.2) { maxBin = correctMaxBin; } } return maxBin; }