#include "wav_writer.h" #include #include #include #include #include namespace { void write_u32(std::ofstream& f, uint32_t v) { char b[4] = {static_cast(v & 0xff), static_cast((v >> 8) & 0xff), static_cast((v >> 16) & 0xff), static_cast((v >> 24) & 0xff)}; f.write(b, 4); } void write_u16(std::ofstream& f, uint16_t v) { char b[2] = {static_cast(v & 0xff), static_cast((v >> 8) & 0xff)}; f.write(b, 2); } } // namespace void write_wav(const std::string& path, const std::vector& waveform, int sample_rate) { std::ofstream f(path, std::ios::binary); if (!f) { throw std::runtime_error("failed to open " + path); } const uint32_t data_bytes = static_cast(waveform.size() * 2); f.write("RIFF", 4); write_u32(f, 36 + data_bytes); f.write("WAVE", 4); f.write("fmt ", 4); write_u32(f, 16); // PCM chunk size write_u16(f, 1); // PCM format write_u16(f, 1); // mono write_u32(f, static_cast(sample_rate)); write_u32(f, static_cast(sample_rate * 2)); // byte rate write_u16(f, 2); // block align write_u16(f, 16); // bits per sample f.write("data", 4); write_u32(f, data_bytes); for (float v : waveform) { v = std::min(1.0f, std::max(-1.0f, v)); write_u16(f, static_cast( static_cast(std::lround(v * 32767.0f)))); } if (!f) { throw std::runtime_error("failed while writing " + path); } }