1 // WAVWriter.cpp: .wav audio writer
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "WAVWriter.h"
22 #include <cstring> // for strncpy
23 #include <boost/cstdint.hpp>
24 #include <fstream> // for composition (file_stream)
27 #include "GnashException.h" // for SoundException
28 #include "log.h" // will import boost::format too
33 namespace { // anonymous
35 // Header of a wave file
36 // http://ftp.iptel.org/pub/sems/doc/full/current/wav__hdr_8c-source.html
38 char rID
[4]; // 'RIFF'
40 char wID
[4]; // 'WAVE'
41 char fId
[4]; // 'fmt '
42 boost::uint32_t pcm_header_len
; // varies...
43 boost::int16_t wFormatTag
;
44 boost::int16_t nChannels
; // 1,2 for stereo data is (l,r) pairs
45 boost::uint32_t nSamplesPerSec
;
46 boost::uint32_t nAvgBytesPerSec
;
47 boost::int16_t nBlockAlign
;
48 boost::int16_t nBitsPerSample
;
52 // http://ftp.iptel.org/pub/sems/doc/full/current/wav__hdr_8c-source.html
54 char dId
[4]; // 'data' or 'fact'
58 } // end of anonymous namespace
61 WAVWriter::WAVWriter(const std::string
& wavefile
)
63 file_stream
.open(wavefile
.c_str());
64 if (file_stream
.fail()) {
65 boost::format fmt
= boost::format(_("Unable to write file %1%"))
67 throw SoundException(fmt
.str());
70 write_wave_header(file_stream
);
71 std::cout
<< "# Created 44100 16Mhz stereo wave file:\n" <<
72 "AUDIOFILE=" << wavefile
<< std::endl
;
77 WAVWriter::~WAVWriter()
79 if (file_stream
) file_stream
.close();
84 WAVWriter::pushSamples(boost::int16_t* from
, unsigned int nSamples
)
86 // NOTE: if muted, the samples will be silent already
87 boost::uint8_t* stream
= reinterpret_cast<boost::uint8_t*>(from
);
88 unsigned int len
= nSamples
*2;
89 file_stream
.write((char*) stream
, len
);
95 WAVWriter::write_wave_header(std::ofstream
& outfile
)
98 // allocate wav header
103 std::strncpy(wav
.rID
, "RIFF", 4);
104 std::strncpy(wav
.wID
, "WAVE", 4);
105 std::strncpy(wav
.fId
, "fmt ", 4);
107 wav
.nBitsPerSample
= 16;
108 wav
.nSamplesPerSec
= 44100;
109 wav
.nAvgBytesPerSec
= 44100;
110 wav
.nAvgBytesPerSec
*= wav
.nBitsPerSample
/ 8;
111 wav
.nAvgBytesPerSec
*= 2;
114 wav
.pcm_header_len
= 16;
116 wav
.rLen
= sizeof(WAV_HDR
) + sizeof(CHUNK_HDR
);
117 wav
.nBlockAlign
= 2 * wav
.nBitsPerSample
/ 8;
119 // setup chunk header
120 std::strncpy(chk
.dId
, "data", 4);
123 /* write riff/wav header */
124 outfile
.write((char *)&wav
, sizeof(WAV_HDR
));
126 /* write chunk header */
127 outfile
.write((char *)&chk
, sizeof(CHUNK_HDR
));
132 } // gnash.sound namespace