Merge pull request #110 from tesselode/fixes
[wdl/wdl-ol.git] / WDL / wavwrite.h
blobac1cd8fa66f6bdded87ff87f8b8ffac7a72fb140
1 /*
2 WDL - wavwrite.h
3 Copyright (C) 2005 and later, Cockos Incorporated
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
26 This file provides a simple class for writing basic 16 or 24 bit PCM WAV files.
31 #ifndef _WAVWRITE_H_
32 #define _WAVWRITE_H_
35 #include <stdio.h>
36 #include "pcmfmtcvt.h"
37 #include "wdlstring.h"
39 class WaveWriter
41 public:
42 // appending doesnt check sample types
43 WaveWriter()
45 m_fp=0;
46 m_bps=0;
47 m_srate=0;
48 m_nch=0;
51 WaveWriter(const char *filename, int bps, int nch, int srate, int allow_append=1)
53 m_fp=0;
54 m_bps=0;
55 m_srate=0;
56 m_nch=0;
57 Open(filename,bps,nch,srate,allow_append);
61 int Open(const char *filename, int bps, int nch, int srate, int allow_append=1)
63 m_fn.Set(filename);
64 m_fp=0;
65 if (allow_append)
67 m_fp=fopen(filename,"r+b");
68 if (m_fp)
70 fseek(m_fp,0,SEEK_END);
71 int pos=ftell(m_fp);
72 if (pos < 44)
74 char buf[44]={0,};
75 fwrite(buf,1,44-pos,m_fp);
79 if (!m_fp)
81 m_fp=fopen(filename,"wb");
82 if (!m_fp) return 0;
84 char tbuf[44];
85 fwrite(tbuf,1,44,m_fp); // room for header
87 m_bps=bps;
88 m_nch=nch>1?2:1;
89 m_srate=srate;
91 return !!m_fp;
94 ~WaveWriter()
96 if (m_fp)
98 int bytelen=ftell(m_fp)-44;
99 fseek(m_fp,0,SEEK_SET);
101 // write header
102 fwrite("RIFF",1,4,m_fp);
103 int riff_size=bytelen+44-8;
104 int x;
105 for (x = 0; x < 32; x += 8)
107 unsigned char c=(riff_size>>x)&255;
108 fwrite(&c,1,1,m_fp);
110 fwrite("WAVEfmt \x10\0\0\0",1,12,m_fp);
111 fwrite("\1\0",1,2,m_fp); // PCM
113 for (x = 0; x < 16; x += 8) // nch
115 char c=(m_nch>>x)&255;
116 fwrite(&c,1,1,m_fp);
118 for (x = 0; x < 32; x += 8) // srate
120 char c=(m_srate>>x)&255;
121 fwrite(&c,1,1,m_fp);
123 for (x = 0; x < 32; x += 8) // bytes_per_sec
125 char c=((m_nch * (m_bps/8) * m_srate)>>x)&255;
126 fwrite(&c,1,1,m_fp);
128 int blockalign=m_nch * (m_bps/8);
129 for (x = 0; x < 16; x += 8) // block alignment
131 char c=(blockalign>>x)&255;
132 fwrite(&c,1,1,m_fp);
134 for (x = 0; x < 16; x += 8) // bits/sample
136 char c=((m_bps&~7)>>x)&255;
137 fwrite(&c,1,1,m_fp);
139 fwrite("data",1,4,m_fp);
140 for (x = 0; x < 32; x += 8) // size
142 char c=((bytelen)>>x)&255;
143 fwrite(&c,1,1,m_fp);
146 fclose(m_fp);
147 m_fp=0;
151 const char *GetFileName() { return m_fn.Get(); }
153 int Status() { return !!m_fp; }
155 int BytesWritten()
157 if (m_fp) return ftell(m_fp)-44;
158 return 0;
161 void WriteRaw(void *buf, int len)
163 if (m_fp) fwrite(buf,1,len,m_fp);
166 void WriteFloats(float *samples, int nsamples)
168 if (!m_fp) return;
170 if (m_bps == 16)
172 while (nsamples-->0)
174 short a;
175 float_TO_INT16(a,*samples);
176 unsigned char c=a&0xff;
177 fwrite(&c,1,1,m_fp);
178 c=a>>8;
179 fwrite(&c,1,1,m_fp);
180 samples++;
183 else if (m_bps == 24)
185 while (nsamples-->0)
187 unsigned char a[3];
188 float_to_i24(samples,a);
189 fwrite(a,1,3,m_fp);
190 samples++;
195 void WriteDoubles(double *samples, int nsamples)
197 if (!m_fp) return;
199 if (m_bps == 16)
201 while (nsamples-->0)
203 short a;
204 double_TO_INT16(a,*samples);
205 unsigned char c=a&0xff;
206 fwrite(&c,1,1,m_fp);
207 c=a>>8;
208 fwrite(&c,1,1,m_fp);
209 samples++;
212 else if (m_bps == 24)
214 while (nsamples-->0)
216 unsigned char a[3];
217 double_to_i24(samples,a);
218 fwrite(a,1,3,m_fp);
219 samples++;
224 void WriteFloatsNI(float **samples, int offs, int nsamples, int nchsrc=0)
226 if (!m_fp) return;
228 if (nchsrc < 1) nchsrc=m_nch;
230 float *tmpptrs[2]={samples[0]+offs,m_nch>1?(nchsrc>1?samples[1]+offs:samples[0]+offs):NULL};
232 if (m_bps == 16)
234 while (nsamples-->0)
236 int ch;
237 for (ch = 0; ch < m_nch; ch ++)
239 short a;
240 float_TO_INT16(a,tmpptrs[ch][0]);
241 unsigned char c=a&0xff;
242 fwrite(&c,1,1,m_fp);
243 c=a>>8;
244 fwrite(&c,1,1,m_fp);
245 tmpptrs[ch]++;
249 else if (m_bps == 24)
251 while (nsamples-->0)
253 int ch;
254 for (ch = 0; ch < m_nch; ch ++)
256 unsigned char a[3];
257 float_to_i24(tmpptrs[ch],a);
258 fwrite(a,1,3,m_fp);
259 tmpptrs[ch]++;
265 void WriteDoublesNI(double **samples, int offs, int nsamples, int nchsrc=0)
267 if (!m_fp) return;
269 if (nchsrc < 1) nchsrc=m_nch;
271 double *tmpptrs[2]={samples[0]+offs,m_nch>1?(nchsrc>1?samples[1]+offs:samples[0]+offs):NULL};
273 if (m_bps == 16)
275 while (nsamples-->0)
277 int ch;
278 for (ch = 0; ch < m_nch; ch ++)
280 short a;
281 double_TO_INT16(a,tmpptrs[ch][0]);
282 unsigned char c=a&0xff;
283 fwrite(&c,1,1,m_fp);
284 c=a>>8;
285 fwrite(&c,1,1,m_fp);
286 tmpptrs[ch]++;
290 else if (m_bps == 24)
292 while (nsamples-->0)
294 int ch;
295 for (ch = 0; ch < m_nch; ch ++)
297 unsigned char a[3];
298 double_to_i24(tmpptrs[ch],a);
299 fwrite(a,1,3,m_fp);
300 tmpptrs[ch]++;
307 int get_nch() { return m_nch; }
308 int get_srate() { return m_srate; }
309 int get_bps() { return m_bps; }
311 private:
312 WDL_String m_fn;
313 FILE *m_fp;
314 int m_bps,m_nch,m_srate;
318 #endif//_WAVWRITE_H_