Skip to content

Instantly share code, notes, and snippets.

@ITotalJustice
Last active November 29, 2022 20:54
Show Gist options
  • Select an option

  • Save ITotalJustice/56e4cc9408261e2abd7b60af5ffaeb8e to your computer and use it in GitHub Desktop.

Select an option

Save ITotalJustice/56e4cc9408261e2abd7b60af5ffaeb8e to your computer and use it in GitHub Desktop.
simple wav writer to a buffer
#pragma once
#include <cstdint>
#include <cstring>
#include <vector>
template<typename T>
struct WavWriter
{
void init()
{
buffer.clear();
buffer.resize(44 / sizeof(T));
}
void add(const std::vector<T>& data)
{
buffer.reserve(buffer.size() + data.size());
buffer.insert(buffer.end(), data.begin(), data.end());
}
void flush(uint16_t channels, uint32_t freq)
{
uint8_t wav_header[44] = {};
const char* ChunkID = "RIFF";
const char* Format = "WAVE";
const char* Subchunk1ID = "fmt ";
const char* Subchunk2ID = "data";
const uint32_t NumSamples = (buffer.size() - 44 / sizeof(T));
const uint32_t Subchunk1Size = 16;
const uint16_t AudioFormat = 1;
const uint16_t NumChannels = channels;
const uint32_t SampleRate = freq;
const uint16_t BitsPerSample = sizeof(T) * 8;
const uint32_t ByteRate = SampleRate * NumChannels * BitsPerSample / 8;
const uint32_t BlockAlign = NumChannels * BitsPerSample / 8;
const uint32_t Subchunk2Size = NumSamples * BitsPerSample / 8;
const uint32_t ChunkSize = 4 + (8 + Subchunk1Size) + (8 + Subchunk2Size);
const auto w16 = [](uint8_t* data, uint16_t value)
{
data[0] = value >> 0;
data[1] = value >> 8;
};
const auto w32 = [](uint8_t* data, uint32_t value)
{
data[0] = value >> 0;
data[1] = value >> 8;
data[2] = value >> 16;
data[3] = value >> 24;
};
memcpy(wav_header + 0, ChunkID, 4);
memcpy(wav_header + 8, Format, 4);
memcpy(wav_header + 12, Subchunk1ID, 4);
memcpy(wav_header + 36, Subchunk2ID, 4);
w32(wav_header + 4, ChunkSize);
w32(wav_header + 16, Subchunk1Size);
w16(wav_header + 20, AudioFormat);
w16(wav_header + 22, NumChannels);
w32(wav_header + 24, SampleRate);
w32(wav_header + 28, ByteRate);
w16(wav_header + 32, BlockAlign);
w16(wav_header + 34, BitsPerSample);
w32(wav_header + 40, Subchunk2Size);
memcpy(buffer.data(), wav_header, sizeof(wav_header));
}
std::vector<T> buffer;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment