编辑:已解决!我认为我的wav值导入奇怪,但它现在完美无缺
我正在尝试在预先录制的信号上实现自相关,以确定其频率。我正在使用“自相关维基百科”页面中的“高效计算”下的蛮力定义'。该代码最终将用作实时自动调谐设备的一部分,因此输入数据是某人唱歌的幅度值。数据的采样率为44100Hz。
据我了解,计算的最终值将是最大值,即每个样本乘以每个其他样本并加在一起的点。我的输出应该类似于 - i.stack.imgur.com/Q1Mm7.png
但是看起来像这样(当我在Excel中绘制数据时):
My autocorrelation signal - 1800 samples
我的代码如下所示。它需要一个包含一定数量样本的文件('值'),用户选择一个采样率(在任何时候执行自相关的样本数),然后执行自相关到达输入文件的末尾。
int i, j, k = 0; //Integers for loop counts
unsigned int N; //Number of samples
int main()
{
//Opens file
FILE *amp;
amp = fopen("Vocal1_Wav_Amplitude.txt", "r");
//Returns error if file cannot be read
if (amp == NULL)
{
printf("Error Reading File\n");
getchar();
exit(0);
}
//Count the number of lines in the file
int c;
int values = 0;
while ((c = fgetc(amp)) != EOF) {
if (c == '\n')
values++;
}
//Creates array the size of the number of lines in the file for storing calculations
float* autocor = new float[values]();
//Imports values from file into array
float * array = new float[values];
ifstream inData;
inData.open("Vocal1_Wav_Amplitude.txt");
for (int i = 0; i < values; i++) {
inData >> array[i];
}inData.close();
//User enters sample rate
cout << "Enter sample rate (number of samples for each calculation) : ";
cin >> N;
int measurements = values / N; //number of times to repeat the autocorrelation on the signal
//Performs autocorrelation on the input data
for (k = 0; k < measurements; ++k) {
for (size_t i = k * N; i < ((k + 1)*(N - 1)) + k; ++i) {
autocor[i] = 0;
for (size_t j = k * N; j <= i; ++j) {
const size_t idxA = j
, idxR = ((k + 1)*N) - (i - j) - 1;
autocor[i] += array[idxA] * array[idxR];
}
}
}
//Saves autocorrelation calculations to a new file
FILE *fp = fopen("test.txt", "w");
if (fp == NULL)
{
printf("Error Reading File\n");
getchar();
exit(0);
}
for (i = 0; i < values; ++i) {
fprintf(fp, "%f\n", autocor[i]);
}
printf ("Press enter to close...");
_getch();
return 0;
}
我认为我的主要问题是这段代码:
for (k = 0; k < measurements; ++k) {
for (size_t i = k * N; i < ((k + 1)*(N - 1)) + k; ++i) {
autocor[i] = 0;
for (size_t j = k * N; j <= i; ++j) {
const size_t idxA = j
, idxR = ((k + 1)*N) - (i - j) - 1;
autocor[i] += array[idxA] * array[idxR];
}
}
}
当每个样本移位时,它应该取信号并将其乘以其倒数,然后将所有单独的乘法加在一起。但是,如果是这种情况,那么我应该得到最终值的最大值。谁能看到这个代码的任何问题?我之前已经在这里问了2次才能使它工作,看起来它是完美的,直到我真正去绘制数据或尝试从中确定频率。