#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <string_view>
namespace Chanell
{
const unsigned short mono = 1;
const unsigned short stereo = 2;
};
struct WavHeader
{
// WAV-формат начинается с RIFF-заголовка:
// Содержит символы "RIFF" в ASCII кодировке
// (0x52494646 в big-endian представлении)
char chunkId[4];
// 36 + subchunk2Size, или более точно:
// 4 + (8 + subchunk1Size) + (8 + subchunk2Size)
// Это оставшийся размер цепочки, начиная с этой позиции.
// Иначе говоря, это размер файла - 8, то есть,
// исключены поля chunkId и chunkSize.
unsigned long chunkSize;
// Содержит символы "WAVE"
// (0x57415645 в big-endian представлении)
char format[4];
// Формат "WAVE" состоит из двух подцепочек: "fmt " и "data":
// Подцепочка "fmt " описывает формат звуковых данных:
// Содержит символы "fmt "
// (0x666d7420 в big-endian представлении)
char subchunk1Id[4];
// 16 для формата PCM.
// Это оставшийся размер подцепочки, начиная с этой позиции.
unsigned long subchunk1Size;
// Аудио формат, полный список можно получить здесь http://a...content-available-to-author-only...g.ru/wav_formats.txt
// Для PCM = 1 (то есть, Линейное квантование).
// Значения, отличающиеся от 1, обозначают некоторый формат сжатия.
unsigned short audioFormat;
// Количество каналов. Моно = 1, Стерео = 2 и т.д.
unsigned short numChannels;
// Частота дискретизации. 8000 Гц, 44100 Гц и т.д.
unsigned long sampleRate;
// sampleRate * numChannels * bitsPerSample/8
unsigned long byteRate;
// numChannels * bitsPerSample/8
// Количество байт для одного сэмпла, включая все каналы.
unsigned short blockAlign;
// Так называемая "глубиная" или точность звучания. 8 бит, 16 бит и т.д.
unsigned short bitsPerSample;
// Подцепочка "data" содержит аудио-данные и их размер.
// Содержит символы "data"
// (0x64617461 в big-endian представлении)
char subchunk2Id[4];
// numSamples * numChannels * bitsPerSample/8
// Количество байт в области данных.
unsigned long subchunk2Size;
public:
WavHeader(int channels, unsigned long frequency, unsigned short depth, unsigned long data)
{
memcpy(chunkId, "RIFF", 4);
memcpy(format, "WAVE", 4);
memcpy(subchunk1Id, "fmt ", 4);
memcpy(subchunk2Id, "data", 4);
subchunk1Size = 16;
audioFormat = 1;
numChannels = channels;
sampleRate = frequency;
bitsPerSample = depth;
byteRate = sampleRate * numChannels * bitsPerSample / 8;
blockAlign = numChannels * bitsPerSample / 8;
subchunk2Size = data * numChannels * bitsPerSample / 8;
chunkSize = subchunk2Size + 36;
}
// Далее следуют непосредственно Wav данные.
};
class WavWriter
{
public:
FILE* file;
WavWriter(WavHeader& head, const char* path)
{
file = fopen(path, "w");
char* p = (char*)&head;
for (int i = 0; i < sizeof(WavHeader); i++)
{
putc(*(p++), file);
}
}
void write(char* pointer, unsigned long size)
{
for (int i = 0; i < size; i++)
{
putc(*(pointer++), file);
}
}
void writeByte(char byte)
{
putc(byte, file);
}
};