ascii-chat 0.11.33
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
 WAV file writer context. 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 138 of file wav_writer.c.

138 {
139 const char *env = SAFE_GETENV("ASCIICHAT_DUMP_AUDIO");
140 return env && (strcmp(env, "1") == 0 || strcmp(env, "true") == 0);
141}
#define SAFE_GETENV(name)
Definition common.h:434

References SAFE_GETENV.

Referenced by audio_analysis_init(), and audio_client_init().

◆ wav_writer_close()

void wav_writer_close ( wav_writer_t *  writer)

Close WAV file and finalize header.

Parameters
writerWAV writer context

Definition at line 112 of file wav_writer.c.

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

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 48 of file wav_writer.c.

48 {
49 if (!filepath || sample_rate <= 0 || channels <= 0 || channels > 2) {
50 return NULL;
51 }
52
54 if (!writer) {
55 return NULL;
56 }
57
58 writer->file = platform_fopen("file_stream", filepath, "wb");
59 if (!writer->file) {
60 SAFE_FREE(writer);
61 return NULL;
62 }
63
64 writer->samples_written = 0;
65 writer->sample_rate = sample_rate;
66 writer->channels = channels;
67
68 // Write WAV header (we'll update sizes when closing)
69 wav_riff_header_t riff = {.riff = {'R', 'I', 'F', 'F'},
70 .file_size = 0, // Will update on close
71 .wave = {'W', 'A', 'V', 'E'}};
72
73 wav_fmt_chunk_t fmt = {.fmt = {'f', 'm', 't', ' '},
74 .chunk_size = 16,
75 .audio_format = 3, // IEEE float
76 .num_channels = (uint16_t)channels,
77 .sample_rate = (uint32_t)sample_rate,
78 .byte_rate = (uint32_t)(sample_rate * channels * sizeof(float)),
79 .block_align = (uint16_t)(channels * sizeof(float)),
80 .bits_per_sample = 32};
81
82 wav_data_header_t data = {
83 .data = {'d', 'a', 't', 'a'},
84 .data_size = 0 // Will update on close
85 };
86
87 fwrite(&riff, sizeof(riff), 1, writer->file);
88 fwrite(&fmt, sizeof(fmt), 1, writer->file);
89 fwrite(&data, sizeof(data), 1, writer->file);
90
91 return writer;
92}
unsigned short uint16_t
Definition common.h:57
#define SAFE_MALLOC(size, cast)
Definition common.h:264
FILE * platform_fopen(const char *name, const char *filename, const char *mode)
Safe file open stream (fopen replacement)
WAV data chunk header preceding audio samples.
Definition wav_writer.c:42
char data[4]
"data" chunk identifier
Definition wav_writer.c:43
WAV format chunk describing audio format parameters.
Definition wav_writer.c:28
char fmt[4]
"fmt " chunk identifier
Definition wav_writer.c:29
WAV RIFF header (first 12 bytes of WAV file)
Definition wav_writer.c:19
char riff[4]
"RIFF" identifier
Definition wav_writer.c:20
WAV file writer context.
Definition wav_writer.h:23

References wav_writer_t::channels, wav_data_header_t::data, wav_writer_t::file, wav_fmt_chunk_t::fmt, platform_fopen(), wav_riff_header_t::riff, 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 94 of file wav_writer.c.

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

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().