我已经创建了一个读取wavfile的wavform并将其打印出来的代码。 (阅读我在代码中的注释)
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp = fopen("file.wav","rb");
fseek(fp,40,SEEK_SET); // moves pointer to Subchunk2Size. Read http://soundfile.sapp.org/doc/WaveFormat/
int length;
fread(&length,sizeof(int),1,fp); // stores the length of the waveform to "length"
printf("%d\n", length);
short *data;
data = malloc(length*sizeof(short)); // allocate a memory with the size length*sizeof(short)
fseek(fp,44,SEEK_SET); // moves pointer to byte 44 where data begins. again http://soundfile.sapp.org/doc/WaveFormat/
fread(data,sizeof(short),length,fp);
for (int k=0; k<length; k++){
printf("data at %d is %d\n", k, data[k]);
}
free(data);
return 0;
}
尽管它可以读取单声道wavfile(单通道)。它无法读取2个通道(左右通道。)
[我的知识:单声道wav文件中的1个样本包含2个字节,立体声声道wavfile中的1个样本包含4个字节(左声道2个字节,右声道2个字节。
示例:例如:24 17 1E F3
[如果这是一个单声道wav文件,它将被视为两个样本并打印出5924
和-3298
(注意:这是小尾数,F3 1E是http://soundfile.sapp.org/doc/WaveFormat/中所述的2的补码)
如果这是立体声通道wav文件,它将被视为1个样本,打印为:
Sample 1 Left channel: 5924
Sample 1 Right channel: -3298
因此24 17
是左边的样本,右边的1E F3
是样本。这是我对http://soundfile.sapp.org/doc/WaveFormat/]的解释
我正在寻找一个答案,该答案将把左声道置于short Left[]
,将右声道置于short Right[]
我已经创建了一个读取wavfile的wavform并将其打印出来的代码。 (请阅读代码中的注释)#include
几次折腾后,我认为我终于对了(阅读我的评论)。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
short * stereoChannel;
short * leftChannel;
short * rightChannel;
char Subchunk2[4];
int move = 0;
short channel = 1;
int val = 50000;
int main(){
FILE *fp = fopen("bin.wav","rb");
if (!fp){
printf("Couldn't open file!\n");
return 0;
}
while (1){
fseek(fp,36+move,SEEK_SET);
fread(Subchunk2,4*sizeof(char),1,fp);
if (!strcmp(Subchunk2,"data")){
break;
}
move++;
}
fseek(fp,22,SEEK_SET);
fread(&channel,sizeof(short),1,fp);
fseek(fp,36+move+4,SEEK_SET);
int num;
fread(&num,sizeof(int),1,fp);
stereoChannel = malloc(num*sizeof(short));
fseek(fp,4,SEEK_CUR);
fread(stereoChannel,sizeof(short),num,fp);
if (channel == 2){
val=0;
printf("wavfile in stereo\n");
leftChannel = malloc(num*sizeof(short)/2);
rightChannel = malloc(num*sizeof(short)/2);
int channelpoint = 0;
for (int inc=0;inc<num/2;inc++){
leftChannel[channelpoint] = stereoChannel[inc*2];
rightChannel[channelpoint] = stereoChannel[(inc*2)+1];
channelpoint++;
}
for (int k=0; k<50000; k++){
printf("stereo sample %d L: %d R: %d \n",k,leftChannel[k],rightChannel[k]);
}
free(rightChannel);
free(leftChannel);
}
for (int k=0; k<val; k++){ // If this is stereo, it would print nothing because val was set to 0
printf("mono sample %d is %d\n", k, stereoChannel[k]);
}
free(stereoChannel);
return 0;
}
打印:
...
stereo sample 49981 L: 8039 R: 6943
stereo sample 49982 L: 9277 R: 10518
stereo sample 49983 L: 13398 R: 16936
stereo sample 49984 L: 13305 R: 15692
stereo sample 49985 L: 2715 R: 9778
stereo sample 49986 L: -5680 R: 5595
stereo sample 49987 L: -3632 R: 3921
...
while loop
的说明。此代码检查data
标记,因为并非每个wavfile数据标记都从偏移量36开始。(也许我应该添加一个函数来检查文件是否为wavfile,因为如果没有它,它将永远循环并可能导致分段错误。)
给我您的想法。