我是初学的android程序员。 (我的母语不是英语,所以我的英语很差。)
我想制作应用程序,获取频率录制的人声并显示“C3”或“G#4”等音符......
所以,我想检测人声频率,但实在太难了。
我尝试使用FFT,它检测钢琴(或吉他)声音相当不错(某些部分,超过八度,它没有检测到低频钢琴(或吉他)声音。),但它无法检测到人声。
(我使用钢琴程序使用普通midi)
我发现了很多信息,但我无法理解。
大多数人都说使用音高检测算法和链接只是维基。
请详细告诉我音高检测算法。
(实际上我想要示例代码:(
或
有什么想法使用我的应用程序吗?
这是我的源代码:
public void Frequency(double[] array) {
int sampleSize = array.length;
double[] win = window.generate(sampleSize);
// signals for fft input
double[] signals = new double[sampleSize];
for (int i = 0; i < sampleSize; i++) {
signals[i] = array[i] * win[i];
}
double[] fftArray = new double[sampleSize * 2];
for (int i = 0; i < sampleSize - 1; i++) {
fftArray[2 * i] = signals[i];
fftArray[2 * i + 1] = 0;
}
FFT.complexForward(fftArray);
getFrequency(fftArray);
}
private void getFrequency(double[] array) {
// ========== Value ========== //
int RATE = sampleRate;
int CHUNK_SIZE_IN_SAMPLES = RECORDER_BUFFER_SIZE;
int MIN_FREQUENCY = 50; // HZ
int MAX_FREQUENCY = 2000; // HZ
int min_frequency_fft = Math.round(MIN_FREQUENCY * CHUNK_SIZE_IN_SAMPLES / RATE);
int max_frequency_fft = Math.round(MAX_FREQUENCY * CHUNK_SIZE_IN_SAMPLES / RATE);
// ============================ //
double best_frequency = min_frequency_fft;
double best_amplitude = 0;
for (int i = min_frequency_fft; i <= max_frequency_fft; i++) {
double current_frequency = i * 1.0 * RATE / CHUNK_SIZE_IN_SAMPLES;
double current_amplitude = Math.pow(array[i * 2], 2) + Math.pow(array[i * 2 + 1], 2);
double normalized_amplitude = current_amplitude * Math.pow(MIN_FREQUENCY * MAX_FREQUENCY, 0.5) / current_frequency;
if (normalized_amplitude > best_amplitude) {
best_frequency = current_frequency;
best_amplitude = normalized_amplitude;
}
}
FrequencyArray[FrequencyArrayIndex] = best_frequency;
FrequencyArrayIndex++;
}
我指的是:http://code.google.com/p/android-guitar-tuner/
使用 Jtransforms
答案 0 :(得分:0)
关于音高检测的维基百科页面链接到解释自相关的另一个维基百科页面:http://en.m.wikipedia.org/wiki/Autocorrelation#section_3,这是您可以尝试的众多音高估算方法之一。
运行您发布的示例代码可以显示FFT峰值频率估计在音阶检测和许多常见倾斜声音的估计方面非常差。