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.
36 #include "pcmfmtcvt.h"
37 #include "wdlstring.h"
42 // appending doesnt check sample types
51 WaveWriter(const char *filename
, int bps
, int nch
, int srate
, int allow_append
=1)
57 Open(filename
,bps
,nch
,srate
,allow_append
);
61 int Open(const char *filename
, int bps
, int nch
, int srate
, int allow_append
=1)
67 m_fp
=fopen(filename
,"r+b");
70 fseek(m_fp
,0,SEEK_END
);
75 fwrite(buf
,1,44-pos
,m_fp
);
81 m_fp
=fopen(filename
,"wb");
85 fwrite(tbuf
,1,44,m_fp
); // room for header
98 int bytelen
=ftell(m_fp
)-44;
99 fseek(m_fp
,0,SEEK_SET
);
102 fwrite("RIFF",1,4,m_fp
);
103 int riff_size
=bytelen
+44-8;
105 for (x
= 0; x
< 32; x
+= 8)
107 unsigned char c
=(riff_size
>>x
)&255;
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;
118 for (x
= 0; x
< 32; x
+= 8) // srate
120 char c
=(m_srate
>>x
)&255;
123 for (x
= 0; x
< 32; x
+= 8) // bytes_per_sec
125 char c
=((m_nch
* (m_bps
/8) * m_srate
)>>x
)&255;
128 int blockalign
=m_nch
* (m_bps
/8);
129 for (x
= 0; x
< 16; x
+= 8) // block alignment
131 char c
=(blockalign
>>x
)&255;
134 for (x
= 0; x
< 16; x
+= 8) // bits/sample
136 char c
=((m_bps
&~7)>>x
)&255;
139 fwrite("data",1,4,m_fp
);
140 for (x
= 0; x
< 32; x
+= 8) // size
142 char c
=((bytelen
)>>x
)&255;
151 const char *GetFileName() { return m_fn
.Get(); }
153 int Status() { return !!m_fp
; }
157 if (m_fp
) return ftell(m_fp
)-44;
161 void WriteRaw(void *buf
, int len
)
163 if (m_fp
) fwrite(buf
,1,len
,m_fp
);
166 void WriteFloats(float *samples
, int nsamples
)
175 float_TO_INT16(a
,*samples
);
176 unsigned char c
=a
&0xff;
183 else if (m_bps
== 24)
188 float_to_i24(samples
,a
);
195 void WriteDoubles(double *samples
, int nsamples
)
204 double_TO_INT16(a
,*samples
);
205 unsigned char c
=a
&0xff;
212 else if (m_bps
== 24)
217 double_to_i24(samples
,a
);
224 void WriteFloatsNI(float **samples
, int offs
, int nsamples
, int nchsrc
=0)
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
};
237 for (ch
= 0; ch
< m_nch
; ch
++)
240 float_TO_INT16(a
,tmpptrs
[ch
][0]);
241 unsigned char c
=a
&0xff;
249 else if (m_bps
== 24)
254 for (ch
= 0; ch
< m_nch
; ch
++)
257 float_to_i24(tmpptrs
[ch
],a
);
265 void WriteDoublesNI(double **samples
, int offs
, int nsamples
, int nchsrc
=0)
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
};
278 for (ch
= 0; ch
< m_nch
; ch
++)
281 double_TO_INT16(a
,tmpptrs
[ch
][0]);
282 unsigned char c
=a
&0xff;
290 else if (m_bps
== 24)
295 for (ch
= 0; ch
< m_nch
; ch
++)
298 double_to_i24(tmpptrs
[ch
],a
);
307 int get_nch() { return m_nch
; }
308 int get_srate() { return m_srate
; }
309 int get_bps() { return m_bps
; }
314 int m_bps
,m_nch
,m_srate
;