2022-05-21 19:58:09 +02:00

110 lines
2.9 KiB
C++

#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;
}
}