ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
wav_writer.h File Reference

Simple WAV file writer for audio debugging. More...

Go to the source code of this file.

Data Structures

struct  wav_writer_t
 File handle and sample counters needed to finalize a WAV recording. More...

Functions

wav_writer_t * wav_writer_open (const char *filepath, int sample_rate, int channels)
 Open WAV file for writing.
int wav_writer_write (wav_writer_t *writer, const float *samples, int num_samples)
 Write audio samples to WAV file.
void wav_writer_close (wav_writer_t *writer)
 Close WAV file and finalize header.
bool wav_dump_enabled (void)
 Check if audio dumping is enabled via environment.

Detailed Description

Simple WAV file writer for audio debugging.

Provides utilities to dump audio buffers to WAV files for debugging. Enable with environment variable: ASCIICHAT_DUMP_AUDIO=1

Definition in file wav_writer.h.

Function Documentation

◆ wav_dump_enabled()

bool wav_dump_enabled ( void )

Check if audio dumping is enabled via environment.

Returns
true if ASCIICHAT_DUMP_AUDIO=1

Definition at line 142 of file wav_writer.c.

142 {
143 const char *env = SAFE_GETENV("ASCIICHAT_DUMP_AUDIO");
144 return env && (strcmp(env, "1") == 0 || strcmp(env, "true") == 0);
145}
#define SAFE_GETENV(name)
Definition common.h:449

References SAFE_GETENV.

Referenced by audio_analysis_init(), audio_client_init(), and client_audio_pipeline_create().

◆ wav_writer_close()

void wav_writer_close ( wav_writer_t * writer)

Close WAV file and finalize header.

Parameters
writerWAV writer context

Definition at line 116 of file wav_writer.c.

116 {
117 if (!writer) {
118 return;
119 }
120
121 if (writer->file) {
122 // Update file size and data size in header
123 uint32_t data_size = (uint32_t)(writer->samples_written * sizeof(float));
124 uint32_t file_size = data_size + 36; // 36 = header size without RIFF chunk
125
126 // Seek to file size field (offset 4)
127 fseek(writer->file, 4, SEEK_SET);
128 fwrite(&file_size, sizeof(uint32_t), 1, writer->file);
129
130 // Seek to data size field (offset 40)
131 fseek(writer->file, 40, SEEK_SET);
132 fwrite(&data_size, sizeof(uint32_t), 1, writer->file);
133
134 // Flush all buffered data to ensure headers are written before closing
135 fflush(writer->file);
136 fclose(writer->file);
137 }
138
139 SAFE_FREE(writer);
140}
unsigned int uint32_t
Definition common.h:62
#define SAFE_FREE(ptr)
Definition common.h:377
FILE * file
Definition wav_writer.h:29
size_t samples_written
Definition wav_writer.h:30

References wav_writer_t::file, SAFE_FREE, and wav_writer_t::samples_written.

Referenced by audio_analysis_destroy(), audio_cleanup(), audio_client_init(), and client_audio_pipeline_destroy().

◆ wav_writer_open()

wav_writer_t * wav_writer_open ( const char * filepath,
int sample_rate,
int channels )

Open WAV file for writing.

Parameters
filepathPath to WAV file to create
sample_rateSample rate (e.g., 44100)
channelsNumber of channels (1=mono, 2=stereo)
Returns
WAV writer context or NULL on error

Definition at line 52 of file wav_writer.c.

52 {
53 if (!filepath || sample_rate <= 0 || channels <= 0 || channels > 2) {
54 return NULL;
55 }
56
58 if (!writer) {
59 return NULL;
60 }
61
62 writer->file = platform_fopen("file_stream", filepath, "wb");
63 if (!writer->file) {
64 SAFE_FREE(writer);
65 return NULL;
66 }
67
68 writer->samples_written = 0;
69 writer->sample_rate = sample_rate;
70 writer->channels = channels;
71
72 // Write WAV header (we'll update sizes when closing)
73 wav_riff_header_t riff = {.riff = {'R', 'I', 'F', 'F'},
74 .file_size = 0, // Will update on close
75 .wave = {'W', 'A', 'V', 'E'}};
76
77 wav_fmt_chunk_t fmt = {.fmt = {'f', 'm', 't', ' '},
78 .chunk_size = 16,
79 .audio_format = 3, // IEEE float
80 .num_channels = (uint16_t)channels,
81 .sample_rate = (uint32_t)sample_rate,
82 .byte_rate = (uint32_t)(sample_rate * channels * sizeof(float)),
83 .block_align = (uint16_t)(channels * sizeof(float)),
84 .bits_per_sample = 32};
85
86 wav_data_header_t data = {
87 .data = {'d', 'a', 't', 'a'},
88 .data_size = 0 // Will update on close
89 };
90
91 fwrite(&riff, sizeof(riff), 1, writer->file);
92 fwrite(&fmt, sizeof(fmt), 1, writer->file);
93 fwrite(&data, sizeof(data), 1, writer->file);
94
95 return writer;
96}
unsigned short uint16_t
Definition common.h:61
#define SAFE_MALLOC(size, cast)
Definition common.h:265
Packed data chunk header giving the byte count of the following samples.
Definition wav_writer.c:46
Packed fmt chunk describing PCM/float encoding, channels, rate, and sample width.
Definition wav_writer.c:32
Packed RIFF/WAVE container header written before the format and data chunks.
Definition wav_writer.c:23
File handle and sample counters needed to finalize a WAV recording.
Definition wav_writer.h:28

References wav_writer_t::channels, wav_writer_t::file, SAFE_FREE, SAFE_MALLOC, wav_writer_t::sample_rate, and wav_writer_t::samples_written.

Referenced by audio_analysis_init(), audio_client_init(), and client_audio_pipeline_create().

◆ wav_writer_write()

int wav_writer_write ( wav_writer_t * writer,
const float * samples,
int num_samples )

Write audio samples to WAV file.

Parameters
writerWAV writer context
samplesFloat samples in range [-1.0, 1.0]
num_samplesNumber of samples to write
Returns
0 on success, -1 on error

Definition at line 98 of file wav_writer.c.

98 {
99 if (!writer || !writer->file || !samples || num_samples <= 0) {
100 return -1;
101 }
102
103 size_t written = fwrite(samples, sizeof(float), num_samples, writer->file);
104 if (written != (size_t)num_samples) {
105 return -1;
106 }
107
108 writer->samples_written += num_samples;
109
110 // Flush immediately to ensure data is written to disk (critical for real-time analysis)
111 fflush(writer->file);
112
113 return 0;
114}

References wav_writer_t::file, and wav_writer_t::samples_written.

Referenced by audio_analysis_track_received_sample(), audio_analysis_track_sent_sample(), audio_process_received_samples(), and client_audio_pipeline_process_duplex().