1 #include "sound_io.h"
2 
in_8(FILE * wavfile,double ** sound,int32_t samplecount,int32_t channels)3 void in_8(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
4 {
5 	int32_t i, ic;
6 	uint8_t byte;
7 
8 	#ifdef DEBUG
9 	printf("in_8...\n");
10 	#endif
11 
12 	for (i=0; i<samplecount; i++)
13 		for (ic=0;ic<channels;ic++)
14 		{
15 			fread(&byte, 1, 1, wavfile);
16 			sound[ic][i] = (double) byte/128.0 - 1.0;
17 		}
18 }
19 
out_8(FILE * wavfile,double ** sound,int32_t samplecount,int32_t channels)20 void out_8(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
21 {
22 	int32_t i, ic;
23 	double val;
24 	uint8_t byte;
25 
26 	#ifdef DEBUG
27 	printf("out_8...\n");
28 	#endif
29 
30 	for (i=0; i<samplecount; i++)
31 		for (ic=0;ic<channels;ic++)
32 		{
33 			val = roundoff((sound[ic][i]+1.0)*128.0);
34 			if (val>255)
35 				val=255;
36 			if (val<0)
37 				val=0;
38 
39 			byte = (uint8_t) val;
40 
41 			fwrite(&byte, sizeof(uint8_t), 1, wavfile);
42 		}
43 }
44 
in_16(FILE * wavfile,double ** sound,int32_t samplecount,int32_t channels)45 void in_16(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
46 {
47 	int32_t i, ic;
48 
49 	#ifdef DEBUG
50 	printf("in_16...\n");
51 	#endif
52 
53 	for (i=0; i<samplecount; i++)
54 		for (ic=0; ic<channels; ic++)
55 			sound[ic][i]=(double) ((int16_t) fread_le_short(wavfile))/32768.0;
56 }
57 
out_16(FILE * wavfile,double ** sound,int32_t samplecount,int32_t channels)58 void out_16(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
59 {
60 	int32_t i, ic;
61 	double val;
62 
63 	#ifdef DEBUG
64 	printf("out_16...\n");
65 	#endif
66 
67 	for (i=0; i<samplecount; i++)
68 		for (ic=0;ic<channels;ic++)
69 		{
70 			val=roundoff(sound[ic][i]*32768.0);
71 			if (val>32767.0)
72 				val=32767.0;
73 			if (val<-32768.0)
74 				val=-32768.0;
75 
76 			fwrite_le_short((int16_t) val, wavfile);
77 		}
78 }
79 
in_32(FILE * wavfile,double ** sound,int32_t samplecount,int32_t channels)80 void in_32(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
81 {
82 	int32_t i, ic;
83 	float val;
84 
85 	#ifdef DEBUG
86 	printf("in_32...\n");
87 	#endif
88 
89 	for (i=0;i<samplecount;i++)
90 		for (ic=0;ic<channels;ic++)
91 		{
92 			*(uint32_t *) &val = fread_le_word(wavfile);
93 			sound[ic][i] = (double) val;
94 		}
95 }
96 
out_32(FILE * wavfile,double ** sound,int32_t samplecount,int32_t channels)97 void out_32(FILE *wavfile, double **sound, int32_t samplecount, int32_t channels)
98 {
99 	int32_t i, ic;
100 	float val;
101 
102 	#ifdef DEBUG
103 	printf("out_32...\n");
104 	#endif
105 
106 	for (i=0; i<samplecount; i++)
107 		for (ic=0;ic<channels;ic++)
108 		{
109 			val = (float) sound[ic][i];
110 			fwrite_le_word(*(uint32_t *) &val, wavfile);
111 		}
112 }
113 
wav_in(FILE * wavfile,int32_t * channels,int32_t * samplecount,int32_t * samplerate)114 double **wav_in(FILE *wavfile, int32_t *channels, int32_t *samplecount, int32_t *samplerate)
115 {
116 	int32_t i, ic;
117 	double **sound;
118 	int32_t tag[13];
119 
120 	#ifdef DEBUG
121 	printf("wav_in...\n");
122 	#endif
123 
124 	for (i=0; i<13; i++)					// tag reading
125 	{
126 		tag[i]=0;
127 
128 		if ((i==5) || (i==6) || (i==9) || (i==10))
129 			tag[i] = fread_le_short(wavfile);
130 		else
131 			tag[i] = fread_le_word(wavfile);
132 	}
133 
134 	//********File format checking********
135 
136 	if (tag[0]!=1179011410 || tag[2]!=1163280727)
137 	{
138 		fprintf(stderr, "This file is not in WAVE format\n");
139 		win_return();
140 		exit(EXIT_FAILURE);
141 	}
142 
143 	if (tag[3]!=544501094 || tag[4]!=16 || tag[11]!=1635017060)
144 	{
145 		fprintf(stderr, "This WAVE file format is not currently supported\n");
146 		win_return();
147 		exit(EXIT_FAILURE);
148 	}
149 	//--------File format checking--------
150 
151 	*channels = tag[6];
152 
153 	*samplecount = tag[12]/(tag[10]/8) / *channels;
154 	*samplerate = tag[7];
155 
156 	sound = malloc (*channels * sizeof(double *));	// allocate sound
157 	for (ic=0; ic < *channels; ic++)
158 		sound[ic] = malloc (*samplecount * sizeof(double));
159 
160 	//********Data loading********
161 
162 	if (tag[10]==8)
163 		in_8(wavfile, sound, *samplecount, *channels);
164 	if (tag[10]==16)
165 		in_16(wavfile, sound, *samplecount, *channels);
166 	if (tag[10]==32)
167 		in_32(wavfile, sound, *samplecount, *channels);
168 	//--------Data loading--------
169 
170 	fclose(wavfile);
171 	return sound;
172 }
173 
wav_out(FILE * wavfile,double ** sound,int32_t channels,int32_t samplecount,int32_t samplerate,int32_t format_param)174 void wav_out(FILE *wavfile, double **sound, int32_t channels, int32_t samplecount, int32_t samplerate, int32_t format_param)
175 {
176 	int32_t i;
177 	int32_t tag[] = {1179011410, 0, 1163280727, 544501094, 16, 1, 1, 0, 0, 0, 0, 1635017060, 0, 0};
178 
179 	#ifdef DEBUG
180 	printf("wav_out...\n");
181 	#endif
182 
183 	//********WAV tags generation********
184 
185 	tag[12] = samplecount*(format_param/8)*channels;
186 	tag[1] = tag[12]+36;
187 	tag[7] = samplerate;
188 	tag[8] = samplerate*format_param/8;
189 	tag[9] = format_param/8;
190 	tag[6] = channels;
191 	tag[10] = format_param;
192 
193 	if ((format_param==8) || (format_param==16))
194 		tag[5]=1;
195 	if (format_param==32)
196 		tag[5]=3;
197 	//--------WAV tags generation--------
198 
199 	for (i=0; i<13; i++)					// tag writing
200 		if ((i==5) || (i==6) || (i==9) || (i==10))
201 			fwrite_le_short(tag[i], wavfile);
202 		else
203 			fwrite_le_word(tag[i], wavfile);
204 
205 	if (format_param==8)
206 		out_8(wavfile, sound, samplecount, channels);
207 	if (format_param==16)
208 		out_16(wavfile, sound, samplecount, channels);
209 	if (format_param==32)
210 		out_32(wavfile, sound, samplecount, channels);
211 
212 	fclose(wavfile);
213 }
214 
wav_out_param()215 int32_t wav_out_param()
216 {
217 	int32_t bps;
218 
219 	do
220 	{
221 		printf("Bits per sample (8/16/32) [16] : ");
222 		bps=getfloat();
223 		if (bps==0 || bps<-2147483647)	// The -2147483647 check is used for the sake of compatibility with C90
224 			bps = 16;
225 	}
226 	while (bps!=8 && bps!=16 && bps!=32);
227 
228 	return bps;
229 }
230