#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> *(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> *(uint32_t*)(Buffer + Offset) = Format.DataSize + WAVHeaderSize; Offset += sizeof(uint32_t); // 'WAVfmt ' <uint64_t> *(uint64_t*)(Buffer + Offset) = 0x20746D6645564157; Offset += sizeof(uint64_t); // WAVfmtSize <uint32_t> *(uint32_t*)(Buffer + Offset) = WAVfmtSize; Offset += sizeof(uint32_t); // Encoding <uint16_t> *(uint16_t*)(Buffer + Offset) = (uint16_t)Format.DataEncoding; Offset += sizeof(uint16_t); // Channels <uint16_t> *(uint16_t*)(Buffer + Offset) = (uint16_t)Format.ChannelsCount; Offset += sizeof(uint16_t); // FrameRate <uint32_t> *(uint32_t*)(Buffer + Offset) = Format.FrameRate; Offset += sizeof(uint32_t); // AverageBps <uint32_t> *(uint32_t*)(Buffer + Offset) = (Format.FrameRate * (Format.ChannelsCount * (Format.BitsPerSample / 8))); Offset += sizeof(uint32_t); // BlockAlign <uint16_t> *(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> *(uint32_t*)(Buffer + Offset) = 0x61746164; Offset += sizeof(uint32_t); // DataSize <uint32_t> *(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<IO::Stream>& 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; } }