langpackedit: sorting fixes, 0.015 -- from 8f06f769
[wdl.git] / WDL / wavwrite.h
blob44f956205055473e0d3123ab03e6c02ca7b7d80e
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"
38 #include "win32_utf8.h"
40 class WaveWriter
42 public:
43 // appending doesnt check sample types
44 WaveWriter()
46 m_fp=0;
47 m_bps=0;
48 m_srate=0;
49 m_nch=0;
52 WaveWriter(const char *filename, int bps, int nch, int srate, int allow_append=1)
54 m_fp=0;
55 m_bps=0;
56 m_srate=0;
57 m_nch=0;
58 Open(filename,bps,nch,srate,allow_append);
62 int Open(const char *filename, int bps, int nch, int srate, int allow_append=1)
64 m_fn.Set(filename);
65 m_fp=0;
66 if (allow_append)
68 m_fp=fopen(filename,"r+b");
69 if (m_fp)
71 fseek(m_fp,0,SEEK_END);
72 int pos=ftell(m_fp);
73 if (pos < 44)
75 char buf[44]={0,};
76 fwrite(buf,1,44-pos,m_fp);
80 if (!m_fp)
82 m_fp=fopen(filename,"wb");
83 if (!m_fp) return 0;
85 char tbuf[44];
86 fwrite(tbuf,1,44,m_fp); // room for header
88 m_bps=bps;
89 m_nch=nch>1?2:1;
90 m_srate=srate;
92 return !!m_fp;
95 ~WaveWriter()
97 if (m_fp)
99 int bytelen=ftell(m_fp)-44;
100 fseek(m_fp,0,SEEK_SET);
102 // write header
103 fwrite("RIFF",1,4,m_fp);
104 int riff_size=bytelen+44-8;
105 int x;
106 for (x = 0; x < 32; x += 8)
108 unsigned char c=(riff_size>>x)&255;
109 fwrite(&c,1,1,m_fp);
111 fwrite("WAVEfmt \x10\0\0\0",1,12,m_fp);
112 fwrite("\1\0",1,2,m_fp); // PCM
114 for (x = 0; x < 16; x += 8) // nch
116 char c=(m_nch>>x)&255;
117 fwrite(&c,1,1,m_fp);
119 for (x = 0; x < 32; x += 8) // srate
121 char c=(m_srate>>x)&255;
122 fwrite(&c,1,1,m_fp);
124 for (x = 0; x < 32; x += 8) // bytes_per_sec
126 char c=((m_nch * (m_bps/8) * m_srate)>>x)&255;
127 fwrite(&c,1,1,m_fp);
129 int blockalign=m_nch * (m_bps/8);
130 for (x = 0; x < 16; x += 8) // block alignment
132 char c=(blockalign>>x)&255;
133 fwrite(&c,1,1,m_fp);
135 for (x = 0; x < 16; x += 8) // bits/sample
137 char c=((m_bps&~7)>>x)&255;
138 fwrite(&c,1,1,m_fp);
140 fwrite("data",1,4,m_fp);
141 for (x = 0; x < 32; x += 8) // size
143 char c=((bytelen)>>x)&255;
144 fwrite(&c,1,1,m_fp);
147 fclose(m_fp);
148 m_fp=0;
152 const char *GetFileName() { return m_fn.Get(); }
154 int Status() { return !!m_fp; }
156 int BytesWritten()
158 if (m_fp) return ftell(m_fp)-44;
159 return 0;
162 void WriteRaw(void *buf, int len)
164 if (m_fp) fwrite(buf,1,len,m_fp);
167 void WriteFloats(float *samples, int nsamples)
169 if (!m_fp) return;
171 if (m_bps == 16)
173 while (nsamples-->0)
175 short a;
176 float_TO_INT16(a,*samples);
177 unsigned char c=a&0xff;
178 fwrite(&c,1,1,m_fp);
179 c=a>>8;
180 fwrite(&c,1,1,m_fp);
181 samples++;
184 else if (m_bps == 24)
186 while (nsamples-->0)
188 unsigned char a[3];
189 float_to_i24(samples,a);
190 fwrite(a,1,3,m_fp);
191 samples++;
196 void WriteDoubles(double *samples, int nsamples)
198 if (!m_fp) return;
200 if (m_bps == 16)
202 while (nsamples-->0)
204 short a;
205 double_TO_INT16(a,*samples);
206 unsigned char c=a&0xff;
207 fwrite(&c,1,1,m_fp);
208 c=a>>8;
209 fwrite(&c,1,1,m_fp);
210 samples++;
213 else if (m_bps == 24)
215 while (nsamples-->0)
217 unsigned char a[3];
218 double_to_i24(samples,a);
219 fwrite(a,1,3,m_fp);
220 samples++;
225 void WriteFloatsNI(float **samples, int offs, int nsamples, int nchsrc=0)
227 if (!m_fp) return;
229 if (nchsrc < 1) nchsrc=m_nch;
231 float *tmpptrs[2]={samples[0]+offs,m_nch>1?(nchsrc>1?samples[1]+offs:samples[0]+offs):NULL};
233 if (m_bps == 16)
235 while (nsamples-->0)
237 int ch;
238 for (ch = 0; ch < m_nch; ch ++)
240 short a;
241 float_TO_INT16(a,tmpptrs[ch][0]);
242 unsigned char c=a&0xff;
243 fwrite(&c,1,1,m_fp);
244 c=a>>8;
245 fwrite(&c,1,1,m_fp);
246 tmpptrs[ch]++;
250 else if (m_bps == 24)
252 while (nsamples-->0)
254 int ch;
255 for (ch = 0; ch < m_nch; ch ++)
257 unsigned char a[3];
258 float_to_i24(tmpptrs[ch],a);
259 fwrite(a,1,3,m_fp);
260 tmpptrs[ch]++;
266 void WriteDoublesNI(double **samples, int offs, int nsamples, int nchsrc=0)
268 if (!m_fp) return;
270 if (nchsrc < 1) nchsrc=m_nch;
272 double *tmpptrs[2]={samples[0]+offs,m_nch>1?(nchsrc>1?samples[1]+offs:samples[0]+offs):NULL};
274 if (m_bps == 16)
276 while (nsamples-->0)
278 int ch;
279 for (ch = 0; ch < m_nch; ch ++)
281 short a;
282 double_TO_INT16(a,tmpptrs[ch][0]);
283 unsigned char c=a&0xff;
284 fwrite(&c,1,1,m_fp);
285 c=a>>8;
286 fwrite(&c,1,1,m_fp);
287 tmpptrs[ch]++;
291 else if (m_bps == 24)
293 while (nsamples-->0)
295 int ch;
296 for (ch = 0; ch < m_nch; ch ++)
298 unsigned char a[3];
299 double_to_i24(tmpptrs[ch],a);
300 fwrite(a,1,3,m_fp);
301 tmpptrs[ch]++;
308 int get_nch() { return m_nch; }
309 int get_srate() { return m_srate; }
310 int get_bps() { return m_bps; }
312 private:
313 WDL_String m_fn;
314 FILE *m_fp;
315 int m_bps,m_nch,m_srate;
319 #endif//_WAVWRITE_H_