#include "stdafx.h" #include "WAV.h" namespace Assets { WAVFormat::WAVFormat() : FrameRate(44100), ChannelsCount(1), BitsPerSample(16), DataEncoding(WAVEncoding::PCM16), DataSize(0) { } // The maximum size of a WAV header constexpr static uint32_t MaximumHeaderSize = 0x100; // Helper routine to build a WAV header, internal const static uint32_t BuildWAVHeader(uint8_t* Buffer, const WAVFormat& Format) { uint32_t Offset = 4; // RIFF *(uint32_t*)Buffer = 0x46464952; // Calculate format buffer size based on encoding uint32_t WAVHeaderSize = 0; uint32_t WAVfmtSize = 0; switch (Format.DataEncoding) { case WAVEncoding::PCM16: case WAVEncoding::FLOAT32: WAVHeaderSize = 36; WAVfmtSize = 16; break; // TODO: Support other encoding formats... } // BufferSize *(uint32_t*)(Buffer + Offset) = Format.DataSize + WAVHeaderSize; Offset += sizeof(uint32_t); // 'WAVfmt ' *(uint64_t*)(Buffer + Offset) = 0x20746D6645564157; Offset += sizeof(uint64_t); // WAVfmtSize *(uint32_t*)(Buffer + Offset) = WAVfmtSize; Offset += sizeof(uint32_t); // Encoding *(uint16_t*)(Buffer + Offset) = (uint16_t)Format.DataEncoding; Offset += sizeof(uint16_t); // Channels *(uint16_t*)(Buffer + Offset) = (uint16_t)Format.ChannelsCount; Offset += sizeof(uint16_t); // FrameRate *(uint32_t*)(Buffer + Offset) = Format.FrameRate; Offset += sizeof(uint32_t); // AverageBps *(uint32_t*)(Buffer + Offset) = (Format.FrameRate * (Format.ChannelsCount * (Format.BitsPerSample / 8))); Offset += sizeof(uint32_t); // BlockAlign *(uint16_t*)(Buffer + Offset) = (uint16_t)(Format.ChannelsCount * (Format.BitsPerSample / 8)); Offset += sizeof(uint16_t); // BitsPerSample *(uint16_t*)(Buffer + Offset) = (uint16_t)Format.BitsPerSample; Offset += sizeof(uint16_t); // 'data' *(uint32_t*)(Buffer + Offset) = 0x61746164; Offset += sizeof(uint32_t); // DataSize *(uint32_t*)(Buffer + Offset) = Format.DataSize; Offset += sizeof(uint32_t); // TODO: Some formats require extra data here... MSADPCM/IMA return Offset; } void WAV::WriteWAVHeader(const std::unique_ptr& Stream, const WAVFormat& Format) { uint8_t Header[MaximumHeaderSize]; auto HeaderSize = BuildWAVHeader(Header, Format); Stream->Write(Header, 0, HeaderSize); } void WAV::WriteWAVHeader(IO::Stream* Stream, const WAVFormat& Format) { uint8_t Header[MaximumHeaderSize]; auto HeaderSize = BuildWAVHeader(Header, Format); Stream->Write(Header, 0, HeaderSize); } void WAV::WriteWAVHeader(uint8_t* Buffer, const WAVFormat& Format, uint32_t& ResultSize) { uint8_t Header[MaximumHeaderSize]; auto HeaderSize = BuildWAVHeader(Header, Format); std::memcpy(Buffer, Header, HeaderSize); ResultSize = HeaderSize; } }