fix: deep-copy audio buffers and add mutex to prevent race conditions in autosave

Co-authored-by: aider (deepseek/deepseek-coder) <aider@aider.chat>
This commit is contained in:
Loic Coenen
2026-05-04 12:14:15 +00:00
parent 99bd840fbe
commit e17e40e28f
2 changed files with 47 additions and 2 deletions

View File

@@ -3,6 +3,9 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <pthread.h>
static pthread_mutex_t wav_io_mutex = PTHREAD_MUTEX_INITIALIZER;
// WAV file header structures (little-endian)
typedef struct {
@@ -55,8 +58,13 @@ static uint32_t read_le32(const unsigned char *buf) {
int save_wav_float(const char *filename, const float *buffer, size_t num_samples, unsigned int sample_rate) {
if (!filename || !buffer || num_samples == 0) return -1;
pthread_mutex_lock(&wav_io_mutex);
FILE *f = fopen(filename, "wb");
if (!f) return -1;
if (!f) {
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
// Calculate sizes
uint32_t data_size = (uint32_t)(num_samples * sizeof(float));
@@ -85,24 +93,32 @@ int save_wav_float(const char *filename, const float *buffer, size_t num_samples
fwrite(buffer, sizeof(float), num_samples, f);
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return 0;
}
int load_wav_float(const char *filename, float **buffer, size_t *num_samples, unsigned int *sample_rate) {
if (!filename || !buffer || !num_samples || !sample_rate) return -1;
pthread_mutex_lock(&wav_io_mutex);
FILE *f = fopen(filename, "rb");
if (!f) return -1;
if (!f) {
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
// Read RIFF header
unsigned char header[12];
if (fread(header, 1, 12, f) != 12) {
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
if (memcmp(header, "RIFF", 4) != 0 || memcmp(header + 8, "WAVE", 4) != 0) {
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
@@ -143,6 +159,7 @@ int load_wav_float(const char *filename, float **buffer, size_t *num_samples, un
data_buffer = (float *)calloc(num_frames, sizeof(float));
if (!data_buffer) {
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
@@ -154,12 +171,14 @@ int load_wav_float(const char *filename, float **buffer, size_t *num_samples, un
if (!temp) {
free(data_buffer);
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
if (fread(temp, 1, read_size, f) != read_size) {
free(temp);
free(data_buffer);
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
// Mix to mono if stereo
@@ -183,12 +202,14 @@ int load_wav_float(const char *filename, float **buffer, size_t *num_samples, un
if (!temp) {
free(data_buffer);
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
if (fread(temp, 1, read_size, f) != read_size) {
free(temp);
free(data_buffer);
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
// Convert to float and mix to mono
@@ -210,6 +231,7 @@ int load_wav_float(const char *filename, float **buffer, size_t *num_samples, un
// Unsupported format
free(data_buffer);
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}
@@ -217,6 +239,7 @@ int load_wav_float(const char *filename, float **buffer, size_t *num_samples, un
*num_samples = num_frames;
*sample_rate = sample_rate_val;
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return 0;
} else {
// Skip unknown chunk
@@ -227,5 +250,6 @@ int load_wav_float(const char *filename, float **buffer, size_t *num_samples, un
// If we get here, we didn't find data
if (data_buffer) free(data_buffer);
fclose(f);
pthread_mutex_unlock(&wav_io_mutex);
return -1;
}