ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
wav_writer.c
Go to the documentation of this file.
1
7#include <ascii-chat/common.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)
19typedef struct {
20 char riff[4];
22 char wave[4];
24
38
42typedef struct {
43 char data[4];
46#pragma pack(pop)
47
48wav_writer_t *wav_writer_open(const char *filepath, int sample_rate, int channels) {
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}
93
94int wav_writer_write(wav_writer_t *writer, const float *samples, int num_samples) {
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}
111
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}
137
139 const char *env = SAFE_GETENV("ASCIICHAT_DUMP_AUDIO");
140 return env && (strcmp(env, "1") == 0 || strcmp(env, "true") == 0);
141}
⚙️ Common definitions, error codes, macros, and types shared throughout the application
unsigned short uint16_t
Definition common.h:57
unsigned int uint32_t
Definition common.h:58
#define SAFE_FREE(ptr)
Definition common.h:376
#define SAFE_MALLOC(size, cast)
Definition common.h:264
#define SAFE_GETENV(name)
Definition common.h:434
FILE * platform_fopen(const char *name, const char *filename, const char *mode)
Safe file open stream (fopen replacement)
Cross-platform string operations.
WAV data chunk header preceding audio samples.
Definition wav_writer.c:42
char data[4]
"data" chunk identifier
Definition wav_writer.c:43
uint32_t data_size
Size of data section in bytes.
Definition wav_writer.c:44
WAV format chunk describing audio format parameters.
Definition wav_writer.c:28
char fmt[4]
"fmt " chunk identifier
Definition wav_writer.c:29
uint16_t num_channels
Number of channels (1 = mono, 2 = stereo)
Definition wav_writer.c:32
uint32_t byte_rate
Bytes per second (sample_rate * num_channels * bytes_per_sample)
Definition wav_writer.c:34
uint16_t audio_format
Audio format (3 = IEEE float)
Definition wav_writer.c:31
uint16_t bits_per_sample
Bits per sample (32 for float)
Definition wav_writer.c:36
uint32_t chunk_size
Chunk size (16 for PCM)
Definition wav_writer.c:30
uint32_t sample_rate
Sample rate in Hz (e.g., 44100)
Definition wav_writer.c:33
uint16_t block_align
Block alignment (num_channels * bytes_per_sample)
Definition wav_writer.c:35
WAV RIFF header (first 12 bytes of WAV file)
Definition wav_writer.c:19
uint32_t file_size
File size - 8 bytes.
Definition wav_writer.c:21
char riff[4]
"RIFF" identifier
Definition wav_writer.c:20
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:138
wav_writer_t * wav_writer_open(const char *filepath, int sample_rate, int channels)
Open WAV file for writing.
Definition wav_writer.c:48
int wav_writer_write(wav_writer_t *writer, const float *samples, int num_samples)
Write audio samples to WAV file.
Definition wav_writer.c:94
void wav_writer_close(wav_writer_t *writer)
Close WAV file and finalize header.
Definition wav_writer.c:112
Simple WAV file writer for audio debugging.