Actually call on_reset callback
[lsnes.git] / src / video / sox.cpp
blobc0406b075894de66eff18d1425296f48e1422c30
1 #include "video/sox.hpp"
2 #include "library/serialization.hpp"
4 #include <iostream>
6 namespace
8 void write_double(uint8_t* buf, double v)
10 unsigned mag = 1023;
11 while(v >= 2) {
12 mag++;
13 v /= 2;
15 while(v < 1) {
16 mag--;
17 v *= 2;
19 uint64_t v2 = mag;
20 v -= 1;
21 for(unsigned i = 0; i < 52; i++) {
22 v *= 2;
23 v2 = 2 * v2 + ((v >= 1) ? 1 : 0);
24 if(v >= 1)
25 v -= 1;
27 serialization::u64l(buf, v2);
31 sox_dumper::sox_dumper(const std::string& filename, double samplerate, uint32_t channels)
33 sox_file.open(filename.c_str(), std::ios::out | std::ios::binary);
34 if(!sox_file)
35 throw std::runtime_error("Can't open sox file for output");
36 try {
37 uint8_t buffer[32] = {0};
38 serialization::u64l(buffer, 0x1C586F532E); //Magic and header size.
39 write_double(buffer + 16, samplerate);
40 serialization::u32l(buffer + 24, channels);
41 sox_file.write(reinterpret_cast<char*>(buffer), 32);
42 if(!sox_file)
43 throw std::runtime_error("Can't write audio header");
44 samplebuffer.resize(channels);
45 databuf.resize(channels << 2);
46 samples_dumped = 0;
47 } catch(...) {
48 sox_file.close();
49 throw;
53 sox_dumper::~sox_dumper() throw()
55 try {
56 close();
57 } catch(...) {
61 void sox_dumper::close()
63 sox_file.seekp(8, std::ios::beg);
64 uint8_t buffer[8];
65 uint64_t raw_samples = samples_dumped * samplebuffer.size();
66 serialization::u64l(buffer, raw_samples);
67 sox_file.write(reinterpret_cast<char*>(buffer), 8);
68 if(!sox_file)
69 throw std::runtime_error("Can't fixup audio header");
70 sox_file.close();
73 void sox_dumper::internal_dump_sample()
75 for(size_t i = 0; i < samplebuffer.size(); ++i)
76 serialization::u32l(&databuf[4 * i], static_cast<uint32_t>(samplebuffer[i]));
77 sox_file.write(&databuf[0], databuf.size());
78 if(!sox_file)
79 throw std::runtime_error("Failed to dump sample");
80 samples_dumped++;