ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
wav_writer.c File Reference

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

Go to the source code of this file.

Data Structures

struct  wav_riff_header_t
 WAV RIFF header (first 12 bytes of WAV file) More...
 
struct  wav_fmt_chunk_t
 WAV format chunk describing audio format parameters. More...
 
struct  wav_data_header_t
 WAV data chunk header preceding audio samples. More...
 

Functions

wav_writer_t * wav_writer_open (const char *filepath, int sample_rate, int channels)
 
int wav_writer_write (wav_writer_t *writer, const float *samples, int num_samples)
 
void wav_writer_close (wav_writer_t *writer)
 
bool wav_dump_enabled (void)
 

Detailed Description

Simple WAV file writer implementation for audio debugging.

Definition in file wav_writer.c.

Function Documentation

◆ wav_dump_enabled()

bool wav_dump_enabled ( void  )

Definition at line 139 of file wav_writer.c.

139 {
140 const char *env = SAFE_GETENV("ASCIICHAT_DUMP_AUDIO");
141 return env && (strcmp(env, "1") == 0 || strcmp(env, "true") == 0);
142}

Referenced by audio_analysis_init(), and audio_client_init().

◆ wav_writer_close()

void wav_writer_close ( wav_writer_t *  writer)

Definition at line 113 of file wav_writer.c.

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

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 
)

Definition at line 49 of file wav_writer.c.

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

References wav_data_header_t::data, wav_fmt_chunk_t::fmt, platform_fopen(), and wav_riff_header_t::riff.

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 
)

Definition at line 95 of file wav_writer.c.

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

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