nice refactors, now way cleaner to work with!
This commit is contained in:
71
src/sound/wav.c
Normal file
71
src/sound/wav.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "sound/wav.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user