ascii-chat 0.11.33
Video chat in your terminal
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)
 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 implementation for audio debugging.

Definition in file wav_writer.c.

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