1 #define RIFF_MAGIC 0x46464952
2 #define WAVE_MAGIC 0x45564157
3 #define FMT_MAGIC 0x20746d66
4 #define DATA_MAGIC 0x61746164
6 #include "output-drv.hpp"
13 static void write_little32(unsigned char* to
, uint32_t value
)
15 to
[0] = (value
) & 0xFF;
16 to
[1] = (value
>> 8) & 0xFF;
17 to
[2] = (value
>> 16) & 0xFF;
18 to
[3] = (value
>> 24) & 0xFF;
21 static void write_little16(unsigned char* to
, uint16_t value
)
23 to
[0] = (value
) & 0xFF;
24 to
[1] = (value
>> 8) & 0xFF;
27 void write_wav_header(FILE* out
, uint32_t rate
, uint64_t samples
)
29 unsigned char header
[44];
32 size2
= (uint32_t)(samples
<< 2);
34 write_little32(header
+ 0, RIFF_MAGIC
); //Main RIFF header magic
35 write_little32(header
+ 4, size1
); //RIFF payload size.
36 write_little32(header
+ 8, WAVE_MAGIC
); //This is WAVE data.
37 write_little32(header
+ 12, FMT_MAGIC
); //Format data.
38 write_little32(header
+ 16, 16); //16 bytes of format data
39 write_little16(header
+ 20, 1); //PCM encoded.
40 write_little16(header
+ 22, 2); //Stereo
41 write_little32(header
+ 24, rate
); //Sample rate.
42 write_little32(header
+ 28, rate
<< 2); //Data rate.
43 write_little16(header
+ 32, 4); //4 bytes per sample.
44 write_little16(header
+ 34, 16); //16 bits per sample and channel.
45 write_little32(header
+ 36, DATA_MAGIC
); //Actual data.
46 write_little32(header
+ 40, size2
); //Data size.
47 if(fseek(out
, 0, SEEK_SET
) < 0 || fwrite(header
, 1, 44, out
) < 44)
48 throw std::runtime_error("Failed to write WAV header");
51 class output_driver_wav
: public output_driver
54 output_driver_wav(const std::string
& filename
)
57 out
= fopen(filename
.c_str(), "wb");
59 throw std::runtime_error("WAV driver does not support output to stdout");
61 throw std::runtime_error("Unable to open output file");
62 write_wav_header(out
, 0, 0);
63 set_audio_callback
<output_driver_wav
>(*this, &output_driver_wav::audio_callback
);
68 write_wav_header(out
, rate
, samples
);
74 rate
= get_audio_settings().get_rate();
78 void audio_callback(short left
, short right
)
81 rawdata
[1] = ((unsigned short)left
>> 8) & 0xFF;
82 rawdata
[0] = ((unsigned short)left
) & 0xFF;
83 rawdata
[3] = ((unsigned short)right
>> 8) & 0xFF;
84 rawdata
[2] = ((unsigned short)right
) & 0xFF;
85 if(fwrite(rawdata
, 1, 4, out
) < 4)
86 throw std::runtime_error("Error writing sample to file");
96 class output_driver_wav_factory
: output_driver_factory
99 output_driver_wav_factory()
100 : output_driver_factory("wav")
104 output_driver
& make(const std::string
& type
, const std::string
& name
, const std::string
& parameters
)
107 throw std::runtime_error("wav output does not take parameters");
108 return *new output_driver_wav(name
);