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