#include #include #include #include static int header_write(xas_riff *riff) { xas_riff_wave_header header = { .riff = { { .id = "RIFF", .size = sizeof(xas_riff_wave_chunk) + sizeof(xas_riff_chunk) + riff->size }, .type = "WAVE" }, .wave = { { .id = "fmt ", .size = 16 }, .type = 1, .channels = 1, .sample_rate = 44100, .byte_rate = 176400 / 2, .sample_size = 2, .sample_size_bits = 16 }, { .id = "data", .size = riff->size } }; if (lseek(riff->fd, 0, SEEK_SET) < 0) { goto error_io; } if (write(riff->fd, &header, sizeof(header)) < 0) { goto error_io; } if (lseek(riff->fd, 0, SEEK_END) < 0) { goto error_io; } return 0; error_io: return -1; } xas_riff *xas_riff_open_file(const char *path, int flags) { xas_riff *riff; if ((riff = malloc(sizeof(*riff))) == NULL) { goto error_malloc_riff; } riff->fd = (flags & O_CREAT)? open(path, flags, 0644): open(path, flags); if (riff->fd < 0) { goto error_open; } riff->size = 0; if (header_write(riff) < 0) { goto error_header_write; } return riff; error_header_write: (void)close(riff->fd); error_open: free(riff); error_malloc_riff: return NULL; } int xas_riff_close(xas_riff *riff) { if (lseek(riff->fd, 0, SEEK_SET) < 0) { goto error_io; } if (header_write(riff) < 0) { goto error_header_write; } (void)close(riff->fd); return 0; error_header_write: error_io: return -1; } ssize_t xas_riff_write(xas_riff *riff, void *data, size_t len) { ssize_t wrlen; if ((wrlen = write(riff->fd, data, len)) < 0) { goto error_write; } riff->size += wrlen; return wrlen; error_write: return -1; }