diff options
| author | XANTRONIX Development | 2022-01-02 16:35:52 -0500 | 
|---|---|---|
| committer | XANTRONIX Development | 2022-01-02 16:35:52 -0500 | 
| commit | b39a63d4d49819bc4e94e82515539e53369f4196 (patch) | |
| tree | 2308f4521cc2c232ba12191e02410161232e648a | |
| parent | a37783ef4efca7b469c43cb7935278ec7de7f773 (diff) | |
| download | xas-b39a63d4d49819bc4e94e82515539e53369f4196.tar.gz xas-b39a63d4d49819bc4e94e82515539e53369f4196.tar.bz2 xas-b39a63d4d49819bc4e94e82515539e53369f4196.zip | |
Initial commit of src/riff.c
| -rw-r--r-- | include/xas/riff.h | 47 | ||||
| -rw-r--r-- | src/riff.c | 121 | 
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; +} | 
 
    