#include "sound/wav.h" #include #include static void write_u16(FILE *f, uint16_t v) { uint8_t b[2]; b[0] = (uint8_t)(v & 0xff); b[1] = (uint8_t)((v >> 8) & 0xff); fwrite(b, 1, 2, f); } static void write_u32(FILE *f, uint32_t v) { uint8_t b[4]; b[0] = (uint8_t)(v & 0xff); b[1] = (uint8_t)((v >> 8) & 0xff); b[2] = (uint8_t)((v >> 16) & 0xff); b[3] = (uint8_t)((v >> 24) & 0xff); fwrite(b, 1, 4, f); } int wave_open(wav_t *wav, const char *filename, uint32_t sample_rate) { wav->file = fopen(filename, "wb"); if (!wav->file) return 0; wav->sample_rate = sample_rate; wav->samples_written = 0; /* RIFF header */ fwrite((uint8_t[]){'R','I','F','F'}, 1, 4, wav->file); write_u32(wav->file, 0); // Placeholder for file size fwrite((uint8_t[]){'W','A','V','E'}, 1, 4, wav->file); /* fmt chunk */ fwrite((uint8_t[]){'f','m','t',' '}, 1, 4, wav->file); write_u32(wav->file, 16); // PCM chunk size write_u16(wav->file, 1); // Audio format (1 = PCM) write_u16(wav->file, 1); // Channels (1 = mono) write_u32(wav->file, sample_rate); // Sample rate write_u32(wav->file, sample_rate * 2); // Byte rate (sr * block_align) write_u16(wav->file, 2); // Block align (mono 16-bit = 2) write_u16(wav->file, 16); // Bits per sample /* data chunk */ fwrite((uint8_t[]){'d','a','t','a'}, 1, 4, wav->file); write_u32(wav->file, 0); // Placeholder for data size return 1; } void wave_write_sample(wav_t *wav, int16_t sample) { write_u16(wav->file, (uint16_t)sample); wav->samples_written++; } void wave_close(wav_t *wav) { uint32_t data_size = wav->samples_written * 2; uint32_t file_size = 36 + data_size; /* Patch RIFF size */ fseek(wav->file, 4, SEEK_SET); write_u32(wav->file, file_size); /* Patch data chunk size */ fseek(wav->file, 40, SEEK_SET); write_u32(wav->file, data_size); fclose(wav->file); }