分离PCM16LE双声道音频

PCM16LE中左右声道是间隔存储的。16表示采样位数是16bit,LE表示Litter Endian,小端模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int pcm16leSplit(const char * url){
FILE *fp=fopen("","wb+");
FILE *fp1=fopen("","wb+");
FILE *fp2=fopen(url,"rb+");

unsigned char *temp=(unsigned char *)malloc(4);

while(!feof(fp2)){
fread(temp,1,4,fp2);

fwrite(temp,1,2,fp);
fwrite(temp+2,1,2,fp1);
}
free(temp);
fclose(fp);
fclose(fp1);
fclose(fp2);

return 0;
}

左声道音量减半

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int pcm16leCutLeft(char *url){
FILE *fp=fopen("","wb+");
FILE *fp2=fopen(url,"rb+");

unsigned char *temp=(unsigned char *)malloc(4);

while(!feof(fp2)){
fread(temp,1,4,fp2);

short *sh=(short *)temp;
*sh=(*sh)/2;

fwrite(temp,1,2,fp);
fwrite(temp+2,1,2,fp);
}
free(temp);
fclose(fp);
fclose(fp2);

return 0;
}

PCM16LE2PCM8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//将-32768~32767转换为0~255
int pcm16le2pcm8(char *url){
FILE *fp=fopen("","wb+");
FILE *fp2=fopen(url,"rb+");

unsigned char *temp=(unsigned char *)malloc(4);
while(!feof(fp2)){
fread(temp,1,4,fp2);

char pcm8;
pcm8= (*(short*)temp)>>256+128;
fwrite(&pcm8,1,1,fp);

pcm8= (*(short*)(temp+2)>>256+128;
fwrite(&pcm8,1,1,fp);
}
free(temp);
fclose(fp);
fclose(fp2);

return 0;
}

PCM16LE2WAVE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
WAVE是微软上常见的音频格式,具体为在PCM前加了一个文件头
WAVE_HEADER
WAVE_FMT
WAVE_DATA
PCM数据
;
typedef struct WAVE_HEADER{
char fccID[4];
unsigned long dwSize;
char fccType[4];
}WAVE_HEADER;

typedef struct WAVE_FMT{
char fccID[4];
unsigned long dwSize;
unsigned short wFormatTag;
unsigned short wChannels;
unsigned long dwSamplesPerSec;
unsigned long dwAvgBytesPerSec;
unsigned short wBlockAlign;
unsigned short uiBitsPerSample;
}WAVE_FMT;

typedef struct WAVE_DATA{
char fccID[4];
unsigned long dwSize;
}WAVE_DATA;

int pcm16le2wave(const char *pcmUrl,int channels,int sample_rate/*44100*/,const char * waveUrl){
int bits=16;
unsigned short m_pcmData;
WAVE_HEADER pcmHEADER;
WAVE_FMT pcmFMT;
WAVE_DATA pcmDATA;
FILE *fp=fopen(pcmUrl,"rb+");
FILE *fp2=fopen(waveUrl,"wb+");

memcpy(pcmHEADER.fccID,"RIFF",strlen("RIFF"));
memcpy(pcmHEADER.fccType,"WAVE",strlen("WAVE"));
fseek(fp2,sizeof(WAVE_HEADER),1);

pcmFMT.dwSamplesPerSec=sample_rate;
pcmFMT.dwAvgBytesPerSec=pcmFMT.dwSamplesPerSec*sizeof(m_pcmData);
pcmFMT.uiBitsPerSample=bits;
memcpy(pcmFMT.fccID,"fmt ",strlen("fmt "));
pcmFMT.dwSize=16;
pcmFMT.wBlockAlign=2;
pcmFMT.wChannels=channels;
pcmFMT.wFormatTag=1;

fwrite(&pcmFMT,sizeof(WAVE_FMT),1,fp2);

memcpy(pcmDATA.fccID,"data",strlen("data"));
pcmDATA.dwSize=0;
fseek(fp2,sizeof(WAVE_DATA),SEEK_CUR);

fread(&m_pcmData,sizeof(unsigned short),1,fp);
while(!feof(fp)){
pcmDATA.dwSize+=2;
fwrite(&m_pcmData,sizeof(unsigned short),1,fp2);
fread(&m_pcmData,sizeof(unsigned short),1,fp);
}

pcmHEADER.dwSize=44+pcmDATA.dwSize;//44没说是啥 应该是文件头

rewind(fp2);
fwrite(&pcmHEADER,sizeof(WAVE_HEADER),1,fp2);
fseek(fp2,sizeof(WAVE_FMT),SEEK_CUR);
fwrite(&pcmDATA,sizeof(WAVE_DATA),1,fp2);

fclose(fp);
fclose(fp2);

return 0;
}