From b39a63d4d49819bc4e94e82515539e53369f4196 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sun, 2 Jan 2022 16:35:52 -0500 Subject: Initial commit of src/riff.c --- include/xas/riff.h | 47 +++++++++++++++++++++ src/riff.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 include/xas/riff.h create mode 100644 src/riff.c diff --git a/include/xas/riff.h b/include/xas/riff.h new file mode 100644 index 0000000..6dc2d8d --- /dev/null +++ b/include/xas/riff.h @@ -0,0 +1,47 @@ +#ifndef _XAS_RIFF_H +#define _XAS_RIFF_H + +#include +#include + +typedef struct _xas_riff_chunk { + char id[4]; + uint32_t size; +} xas_riff_chunk; + +typedef struct _xas_riff_main_chunk { + xas_riff_chunk header; + char type[4]; +} xas_riff_main_chunk; + +typedef struct _xas_riff_wave_format_chunk { + xas_riff_chunk header; + + uint16_t type, + channels; + + uint32_t sample_rate, + byte_rate; + + uint16_t sample_size, + sample_size_bits; +} xas_riff_wave_chunk; + +typedef struct _xas_riff_wave_header { + xas_riff_main_chunk riff; + xas_riff_wave_chunk wave; + xas_riff_chunk data; +} xas_riff_wave_header; + +typedef struct _xas_riff { + int fd; + size_t size; +} xas_riff; + +xas_riff *xas_riff_open_file(const char *path, int flags); + +int xas_riff_close(xas_riff *riff); + +ssize_t xas_riff_write(xas_riff *riff, void *data, size_t len); + +#endif /* _XAS_RIFF_H */ diff --git a/src/riff.c b/src/riff.c new file mode 100644 index 0000000..1cf2f85 --- /dev/null +++ b/src/riff.c @@ -0,0 +1,121 @@ +#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; +} -- cgit v1.2.3