ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
wav_writer.c
Go to the documentation of this file.
1
6#include "audio/wav_writer.h"
7#include "common.h"
8#include "platform/string.h"
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <stdint.h>
13
14// WAV file header structures
15#pragma pack(push, 1)
16typedef struct {
17 char riff[4]; // "RIFF"
18 uint32_t file_size; // File size - 8
19 char wave[4]; // "WAVE"
21
22typedef struct {
23 char fmt[4]; // "fmt "
24 uint32_t chunk_size; // 16 for PCM
25 uint16_t audio_format; // 3 = IEEE float
26 uint16_t num_channels; // 1 = mono, 2 = stereo
27 uint32_t sample_rate; // 44100, etc.
28 uint32_t byte_rate; // sample_rate * num_channels * bytes_per_sample
29 uint16_t block_align; // num_channels * bytes_per_sample
30 uint16_t bits_per_sample; // 32 for float
32
33typedef struct {
34 char data[4]; // "data"
35 uint32_t data_size; // Size of data section
37#pragma pack(pop)
38
39wav_writer_t *wav_writer_open(const char *filepath, int sample_rate, int channels) {
40 if (!filepath || sample_rate <= 0 || channels <= 0 || channels > 2) {
41 return NULL;
42 }
43
45 if (!writer) {
46 return NULL;
47 }
48
49 writer->file = fopen(filepath, "wb");
50 if (!writer->file) {
51 SAFE_FREE(writer);
52 return NULL;
53 }
54
55 writer->samples_written = 0;
56 writer->sample_rate = sample_rate;
57 writer->channels = channels;
58
59 // Write WAV header (we'll update sizes when closing)
60 wav_riff_header_t riff = {.riff = {'R', 'I', 'F', 'F'},
61 .file_size = 0, // Will update on close
62 .wave = {'W', 'A', 'V', 'E'}};
63
64 wav_fmt_chunk_t fmt = {.fmt = {'f', 'm', 't', ' '},
65 .chunk_size = 16,
66 .audio_format = 3, // IEEE float
67 .num_channels = (uint16_t)channels,
68 .sample_rate = (uint32_t)sample_rate,
69 .byte_rate = (uint32_t)(sample_rate * channels * sizeof(float)),
70 .block_align = (uint16_t)(channels * sizeof(float)),
71 .bits_per_sample = 32};
72
73 wav_data_header_t data = {
74 .data = {'d', 'a', 't', 'a'},
75 .data_size = 0 // Will update on close
76 };
77
78 fwrite(&riff, sizeof(riff), 1, writer->file);
79 fwrite(&fmt, sizeof(fmt), 1, writer->file);
80 fwrite(&data, sizeof(data), 1, writer->file);
81
82 return writer;
83}
84
85int wav_writer_write(wav_writer_t *writer, const float *samples, int num_samples) {
86 if (!writer || !writer->file || !samples || num_samples <= 0) {
87 return -1;
88 }
89
90 size_t written = fwrite(samples, sizeof(float), num_samples, writer->file);
91 if (written != (size_t)num_samples) {
92 return -1;
93 }
94
95 writer->samples_written += num_samples;
96 return 0;
97}
98
100 if (!writer) {
101 return;
102 }
103
104 if (writer->file) {
105 // Update file size and data size in header
106 uint32_t data_size = (uint32_t)(writer->samples_written * sizeof(float));
107 uint32_t file_size = data_size + 36; // 36 = header size without RIFF chunk
108
109 // Seek to file size field (offset 4)
110 fseek(writer->file, 4, SEEK_SET);
111 fwrite(&file_size, sizeof(uint32_t), 1, writer->file);
112
113 // Seek to data size field (offset 40)
114 fseek(writer->file, 40, SEEK_SET);
115 fwrite(&data_size, sizeof(uint32_t), 1, writer->file);
116
117 fclose(writer->file);
118 }
119
120 SAFE_FREE(writer);
121}
122
124 const char *env = SAFE_GETENV("ASCIICHAT_DUMP_AUDIO");
125 return env && (strcmp(env, "1") == 0 || strcmp(env, "true") == 0);
126}
unsigned short uint16_t
Definition common.h:57
unsigned int uint32_t
Definition common.h:58
#define SAFE_FREE(ptr)
Definition common.h:320
#define SAFE_MALLOC(size, cast)
Definition common.h:208
#define SAFE_GETENV(name)
Definition common.h:378
Platform-independent safe string functions.
uint32_t data_size
Definition wav_writer.c:35
uint16_t num_channels
Definition wav_writer.c:26
uint32_t byte_rate
Definition wav_writer.c:28
uint16_t audio_format
Definition wav_writer.c:25
uint16_t bits_per_sample
Definition wav_writer.c:30
uint32_t chunk_size
Definition wav_writer.c:24
uint32_t sample_rate
Definition wav_writer.c:27
uint16_t block_align
Definition wav_writer.c:29
uint32_t file_size
Definition wav_writer.c:18
WAV file writer context.
Definition wav_writer.h:23
FILE * file
Definition wav_writer.h:24
size_t samples_written
Definition wav_writer.h:25
🔤 String Manipulation and Shell Escaping Utilities
bool wav_dump_enabled(void)
Check if audio dumping is enabled via environment.
Definition wav_writer.c:123
wav_writer_t * wav_writer_open(const char *filepath, int sample_rate, int channels)
Open WAV file for writing.
Definition wav_writer.c:39
int wav_writer_write(wav_writer_t *writer, const float *samples, int num_samples)
Write audio samples to WAV file.
Definition wav_writer.c:85
void wav_writer_close(wav_writer_t *writer)
Close WAV file and finalize header.
Definition wav_writer.c:99
Simple WAV file writer for audio debugging.