summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXANTRONIX Development2022-01-02 16:35:52 -0500
committerXANTRONIX Development2022-01-02 16:35:52 -0500
commitb39a63d4d49819bc4e94e82515539e53369f4196 (patch)
tree2308f4521cc2c232ba12191e02410161232e648a
parenta37783ef4efca7b469c43cb7935278ec7de7f773 (diff)
downloadxas-b39a63d4d49819bc4e94e82515539e53369f4196.tar.gz
xas-b39a63d4d49819bc4e94e82515539e53369f4196.tar.bz2
xas-b39a63d4d49819bc4e94e82515539e53369f4196.zip
Initial commit of src/riff.c
-rw-r--r--include/xas/riff.h47
-rw-r--r--src/riff.c121
2 files changed, 168 insertions, 0 deletions
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 <stdint.h>
+#include <sys/types.h>
+
+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 <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <xas/riff.h>
+
+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;
+}