File size: 1,620 Bytes
de996a0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #include "wav_writer.h"
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <fstream>
#include <stdexcept>
namespace {
void write_le32(std::ofstream& f, uint32_t v) {
char b[4] = {static_cast<char>(v & 0xff), static_cast<char>((v >> 8) & 0xff),
static_cast<char>((v >> 16) & 0xff), static_cast<char>((v >> 24) & 0xff)};
f.write(b, 4);
}
void write_le16(std::ofstream& f, uint16_t v) {
char b[2] = {static_cast<char>(v & 0xff), static_cast<char>((v >> 8) & 0xff)};
f.write(b, 2);
}
} // namespace
void write_wav_stereo(const std::string& path, const std::vector<float>& waveform,
int sample_rate) {
if (waveform.empty()) {
throw std::runtime_error("empty waveform");
}
const uint32_t samples = static_cast<uint32_t>(waveform.size());
const uint32_t data_bytes = samples * sizeof(int16_t);
std::ofstream f(path, std::ios::binary);
if (!f) {
throw std::runtime_error("failed to open " + path);
}
f.write("RIFF", 4);
write_le32(f, 36 + data_bytes);
f.write("WAVE", 4);
f.write("fmt ", 4);
write_le32(f, 16);
write_le16(f, 1);
write_le16(f, 2); // 双声道
write_le32(f, static_cast<uint32_t>(sample_rate));
write_le32(f, static_cast<uint32_t>(sample_rate) * 2 * 2);
write_le16(f, 4);
write_le16(f, 16);
f.write("data", 4);
write_le32(f, data_bytes);
for (float v : waveform) {
v = std::max(-1.0f, std::min(1.0f, v));
write_le16(f, static_cast<uint16_t>(static_cast<int16_t>(std::round(v * 32767.0f))));
}
}
|