我已经在互联网上搜索了几天以找到以下问题的解决方案。
在我的程序中,我将两个 16 位 .wav 文件中的数据块读取到声音缓冲区(类型为 的数组short
)中,我在堆上为其分配内存。将数据转换double
为 fftw 函数并进行处理,然后按比例缩小并short
转换为在将输出文件写入磁盘之前放入集合缓冲区。通过这种方式,我减少了访问硬盘的次数,因为我正在读取几块数据(即在文件中移动)并且不想在每次迭代中写入磁盘。
这是我正在做的事情:
short* sound_buffer_zero;
short* sound_buffer_one;
short* collection_buffer_one;
sound_buffer_zero = (short *) fftw_malloc(sizeof(short) * BUFFERSIZE);
sound_buffer_one = (short *) fftw_malloc(sizeof(short) * BUFFERSIZE);
collection_buffer_one = (short *) fftw_malloc(sizeof(short) * COLLECTIONLENGTH);
// read BUFFERSIZE samples from file into sound_buffer
inFileZero.read((char*)sound_buffer_zero, sizeof(short)*BUFFERSIZE);
inFileOne.read((char*)sound_buffer_one, sizeof(short)*BUFFERSIZE);
// typecast the short int values of sound_buffer into double values
// and write them to in_
for(int p = 0; p < BUFFERSIZE; ++p) {
*(in_zero + p) = (double)*(sound_buffer_zero + p);
*(in_one + p) = (double)*(sound_buffer_one + p);
}
// cross correlation in the frequency domain
// FFT on input zero (output is f_zero)
fftw_execute(p_zero);
// FFT on input one (output is f_one)
fftw_execute(p_one);
// complex multiplication (output is almost_one, also array of type double)
fastCplxConjProd(almost_one, f_zero, f_one, COMPLEXLENGTH);
// IFFT on almost_one (output is out_one, array of double)
fftw_execute(pi_one);
// finalize the output array (sort the parts correctly, output is final_one, array of double)
// last half without first value becomes first half of final array
for(int i = ARRAYLENGTH/2 + 1; i < ARRAYLENGTH; ++i) {
*(final_one + i - (ARRAYLENGTH/2 + 1)) = *(out_one + i);
}
// first half becomes second half of final array
for(int i = 0; i < ARRAYLENGTH/2; ++i) {
*(final_one + i + (ARRAYLENGTH/2 - 1)) = *(out_one + i);
}
short* scaling_vector;
scaling_vector = (short *) fftw_malloc(sizeof(short) * ARRAYLENGTH-1);
// fill the scaling_vector with the numbers from 1, 2, 3, ..., BUFFERSIZE, ..., 3, 2, 1
for(short i = 0; i < BUFFERSIZE; ++i) {
*(scaling_vector + i) = i + 1;
if(i + BUFFERSIZE > ARRAYLENGTH-1) break;
*(scaling_vector + i + BUFFERSIZE) = BUFFERSIZE - i - 1;
}
// scale values in relation to their position in the output array
// to values suitable for short int for storage
for(int i = 0; i < ARRAYLENGTH-1; ++i) {
*(final_one + i) = *(final_one + i) * SCALEFACTOR; // #define SCALEFACTOR SHRT_MAX/pow(2,42)
*(final_one + i) = *(final_one + i) / *(scaling_vector + i);
}
// transform the double values of final_ into rounded short int values
// and write them to the collection buffer
for(int p = 0; p < ARRAYLENGTH-1; ++p) {
*(collection_buffer_one + collectioncount*(ARRAYLENGTH) + p) = (short)round(*(final_one + p));
}
// write collection_buffer to disk
outFileOne.write((char*)collection_buffer_one, sizeof(short)*collectioncount*(ARRAYLENGTH));
在互相关中计算的值具有类型double
并且具有正号或负号。通过缩小它们,符号不会改变。但是当我将它们转换short
为到达 collection_array 的数字时,它们都是正数。
该数组被声明为short
,而不是unsigned short
,并且在缩放后值处于short
可以容纳的范围内(您必须相信我,因为我不想发布所有代码以保持帖子可读)。我不关心小数部分的截断,我不需要进一步计算,但符号应该保持不变。
这是输入和输出值的一个小示例(显示的是数组中的前 10 个值):
input: 157
input: 4058
input: -1526
input: 1444
input: -774
input: -1507
input: -1615
input: -1895
input: -987
input: -1729
// converted to double
as double: 157
as double: 4058
as double: -1526
as double: 1444
as double: -774
as double: -1507
as double: -1615
as double: -1895
as double: -987
as double: -1729
// after the computations
after scaling: -2.99445
after scaling: -42.6612
after scaling: -57.0962
after scaling: 41.0415
after scaling: -18.3168
after scaling: 43.5853
after scaling: -14.3663
after scaling: -3.58456
after scaling: -46.3902
after scaling: 16.0804
// in the collection array and before writing to disk
collection [short(round*(final_one))]: 3
collection [short(round*(final_one))]: 43
collection [short(round*(final_one))]: 57
collection [short(round*(final_one))]: 41
collection [short(round*(final_one))]: 18
collection [short(round*(final_one))]: 44
collection [short(round*(final_one))]: 14
collection [short(round*(final_one))]: 4
collection [short(round*(final_one))]: 46
collection [short(round*(final_one))]: 16
我的问题是,为什么没有保留标志?我错过了一些内部转换吗?我没有在其他帖子中找到我的问题的答案。如果我错过了,请告诉我,如果我为您遗漏了重要信息。谢谢你的帮助!
干杯,芒果
这是测试输出的代码:
//contents of sound_buffer (input from file):
// test output
for(int i = 0; i < 10; ++i) {
cout << "input: " << *(sound_buffer_zero + i) << endl;
}
// content of in_ after converting to double
// test output
for(int i = 0; i < 10; ++i) {
cout << "as double: " << *(in_zero + i) << endl;
}
// contents of final_ after the scaling
// test output
for(int i = 0; i < 10; ++i) {
cout << "after scaling: " << *(final_one + i) << endl;
}
// contents of collection_buffer after converting to short
// test output
for(int i = 0; i < 10; ++i) {
cout << "collection [short(round*(final_one))]: " << *(collection_buffer_one + i) << endl;
}
感谢aleguna,我发现这些符号在以下计算中消失了。我完全错过了我所做的那一步final_one = fabs(final_one)
。我已经把它放在了一个测试中,完全忘记了它。
谢谢大家的评论和回答。事实证明,我只是愚蠢。对不起。