-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpcm2wav.cpp
159 lines (136 loc) · 3.63 KB
/
pcm2wav.cpp
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <stdio.h>
#include <string.h>
//#include <inttypes.h>
#include "pcm2wav.h"
//define wav head 44byte
static struct RIFFHEAD //12byte
{
char riff[4];
int32_t length;
char wave[4];
} headr;
/*
static struct CHUNK
{
char name[4];
int32_t size;
} headc;
*/
static struct WAVEFMT/*format*/ //24byte
{
char fmt[4]; /* "fmt " */
int32_t fmtsize; /*0x10*/
int16_t tag; /*format tag. 1=PCM*/
int16_t channel; /*1*/
int32_t smplrate;
int32_t bytescnd; /*average bytes per second*/
int16_t align; /*block alignment, in bytes*/
int16_t nbits; /*specific to PCM format*/
}headf;
/*static struct WAVEFACT //12byte
{
char fact[4];
char temp[8];
}headfact;*/
static struct WAVEDATA /*data*/ //8byte
{
char data[4]; /* "data" */
int32_t datasize; //data size,based on the pcapfile
}headw;
void pcm2wav(const char *file, const unsigned char *buffer, int32_t size, int16_t channel, int32_t smplrate, int32_t bytescnd,int16_t align, int16_t nbits)
{
FILE *fp;
int32_t wsize,sz=0;
fp = fopen(file, "wb");
//fp = fopen("input.pcm","wb");
if(fp == NULL)
{
printf("Can't open %s for writing.", file);
return;
}
/*header*///write the wav head into pcmfile
strncpy(headr.riff,"RIFF",4);
//write_i32_le (&headr.length, 4+sizeof(struct WAVEFMT)+sizeof(struct WAVEDATA)+size);
write_i32_le (&headr.length,size+44-8);
strncpy(headr.wave,"WAVE",4);
fwrite(&headr,sizeof(struct RIFFHEAD),1,fp);
strncpy(headf.fmt, "fmt ",4);
write_i32_le (&headf.fmtsize, sizeof(struct WAVEFMT)-8);
write_i16_le (&headf.tag, 1);
write_i16_le (&headf.channel, channel);
write_i32_le (&headf.smplrate, smplrate); //samplerate:8KHZ or 16KHZ
write_i32_le (&headf.bytescnd, bytescnd); // nbit*1000
write_i16_le (&headf.align, align); //nbit/8
write_i16_le (&headf.nbits, nbits); //nbit
fwrite(&headf,sizeof(struct WAVEFMT),1,fp);
//strncpy(headfact.fact,"fact",4);
// strncpy(headfact.temp,"",8);
// fwrite(&headf,sizeof(struct WAVEFACT),1,fp);
strncpy(headw.data,"data",4);
write_i32_le (&headw.datasize, size );
fwrite(&headw,sizeof(struct WAVEDATA),1,fp);
for(wsize=0;wsize<size;wsize+=sz)
{
sz= (size-wsize>MEMORYCACHE)? MEMORYCACHE:(size-wsize);
if(fwrite((buffer+(wsize)),(size_t)sz,1,fp)!=1)
{
printf("%s: write error!", file);
return;
}
}
fclose(fp);
}
/*
* write_i16_le
* Write a little-endian 16-bit signed integer to memory area
* pointed to by <ptr>.
*/
void write_i16_le (void *ptr, int16_t val)
{
((uint8_t *) ptr)[0] = val;
((uint8_t *) ptr)[1] = val >> 8;
}
/*
* write_i32_le
* Write a little-endian 32-bit signed integer to memory area
* pointed to by <ptr>.
*/
void write_i32_le (void *ptr, int32_t val)
{
((uint8_t *) ptr)[0] = val;
((uint8_t *) ptr)[1] = val >> 8;
((uint8_t *) ptr)[2] = val >> 16;
((uint8_t *) ptr)[3] = val >> 24;
}
/*
* peek_i16_le
* Read a little-endian 16-bit signed integer from memory area
* pointed to by <ptr>.
*/
int16_t peek_i16_le (const void *ptr)
{
return ((const uint8_t *) ptr)[0]
| (((const uint8_t *) ptr)[1] << 8);
}
/*
* peek_u16_le
* Read a little-endian 16-bit unsigned integer from memory area
* pointed to by <ptr>.
*/
uint16_t peek_u16_le (const void *ptr)
{
return ((const uint8_t *) ptr)[0]
| (((const uint8_t *) ptr)[1] << 8);
}
/*
* peek_i32_le
* Read a little-endian 32-bit signed integer from memory area
* pointed to by <ptr>.
*/
int32_t peek_i32_le (const void *ptr)
{
return ((const uint8_t *) ptr)[0]
| ((uint16_t) ((const uint8_t *) ptr)[1] << 8)
| ((int32_t) ((const uint8_t *) ptr)[2] << 16)
| ((int32_t) ((const uint8_t *) ptr)[3] << 24);
}