我想用C编写以下小脚本:
`%% getting the spectgrum
clear, clc ;
fileName ='M0.raw'
[x,fs] = audioread(fileName);
[xPSD,f] = pwelch(x,hanning(8192),0,8192*4 ,fs);
plot(f,10*log10(abs(xPSD)));
xlim([0 22e3]);
absxPSD = abs(xPSD);
save('absXPSD.txt','absxPSD','-ascii');
save('xPSD.txt','xPSD','-ascii');
save('xValues.txt','x','-ascii');
save('frequency.txt','f','-ascii');`
没有详细说明,我在获取正确结果时遇到了问题,当我检查时,我发现我读到的数据是错误的,这里读取原始文件的样本与Matalb读取的内容进行比较:
#include <stdio.h>
#include <stdlib.h>
int main (){
FILE* inp =NULL;
FILE* oup =NULL;
double value =0;
inp = fopen("M0.raw","r");
oup = fopen("checks.txt","w+");
更新
在LoPiTaL的回答之后,我试图使用fseek
fseek (inp,352,SEEK_SET);// that didn't help getting the right result !!
if( inp == NULL || oup==NULL){
printf(" error at file opning \n");
return -1;
}
while (!(feof(inp))){
fread(&value,sizeof(double),1,inp);
printf(" %f \n ",value);
fprintf(oup,"%f\n",value);
}
fclose(inp);
fclose(oup);
return 0;
}
我得到的结果是:
-28083683309813134333858080554409220100578902032859386180468433149049781495379346137536863936326139303879846829175766826833343673613788446579155215033623707200818670767132304934425064429529496303287641688697019947073799877821581901737052884168025721481955133510652655692037990001524306465271815108431928360960.000000
0.000000
0.000000
0.000000
0.000000
0.000000
-20701636078248669570005757343846586744027511881225108933223144646890577802102653022204406730988428912367583701134782419138464527797567258583836429190479797597328678189654150340845........................................................................
我的目标是获得这些价值:
-1.0162354e-02
-9.3688965e-03
-7.5073242e-03
-1.9531250e-03
3.7231445e-03
1.3549805e-02
2.3223877e-02
3.2867432e-02
4.4830322e-02
5.5114746e-02
6.7291260e-02
7.7636719e-02
8.8562012e-02
9.5794678e-02
1.0055542e-01
1.0415649e-01
1.0351563e-01
1.0235596e-01
9.8785400e-02
9.1796875e-02
8.3648682e-02
7.1594238e-02
音频文件是单声道是16位分辨率,任何想法怎么解决这个?谢谢你的帮助
答案 0 :(得分:2)
对于初学者,您必须以二进制模式打开文件。否则,您将获得文本模式,例如,可以进行行结尾的翻译。二进制数据不太好。
二进制模式:
inp = fopen("M0.raw", "rb");
^
|
muy
importante
答案 1 :(得分:1)
当然,您无法按原样读取音频文件,并希望数据符合您的预期。
忽略任何编码的音频文件,当然在阅读之前你必须解码它,让我们专注于RAW音频文件:
RAW音频文件通常是WAV文件。 WAV文件在文件开头有一个.RIFF标题,显然你在阅读音频数据之前必须忽略它。
http://en.wikipedia.org/wiki/Resource_Interchange_File_Format
删除RIFF标题后,数据就会启动。 如您所述,数据编码为16位分辨率。 16位分辨率意味着0x0000是0.0而0xFFFF是1.0,并且数据的大小只有两个字节! 所以你必须一次读取两个字节(即带有符号的短路),然后转换到0到1的范围:
signed short ss;
double value;
FILE* inp =NULL;
inp = fopen("M0.raw","rb"); //As stated in other answer, use binary mode!
fseek (inp,44,SEEK_SET); // Only 44 bytes!!
//We already have discarded the header here....
while (fread(&ss, sizeof(signed short) ,1 , inp) == 1){
//Now we have to convert from signed short to double:
value=((double)ss)/(unsigned)0xFFFF;
//Print the results:
printf(" %f \n ",value);
fprintf(oup,"%f\n",value);
}
当然,功能&#34; audioread&#34;来自Matlab已经为你做了所有这些,所以你不必关心编码,如你的例子中,你的特定数据是16位,但如果你使用任何其他文件,它可能是8, 16,24或32,即使是WAV文件,也可以是差分或编码(有关更多信息,请参阅RIFF标题)。