From 10743527b811423032adb38a7dafe00f5b69443e Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sat, 15 Jan 2022 01:04:48 -0500 Subject: ~Getting there, sweetie.~ --- Makefile | 2 ++ include/xas/audio.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/xas/riff.h | 2 +- src/riff.c | 65 +++++++++++++++++++++++++++++++++------------ 4 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 include/xas/audio.h diff --git a/Makefile b/Makefile index e476f4e..dcbc342 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,10 @@ all: $(MAKE) -C src all + $(MAKE) -C examples all install: $(MAKE) -C src install clean: $(MAKE) -C src clean + $(MAKE) -C examples clean diff --git a/include/xas/audio.h b/include/xas/audio.h new file mode 100644 index 0000000..4ffc430 --- /dev/null +++ b/include/xas/audio.h @@ -0,0 +1,76 @@ +#ifndef _XAS_AUDIO_H +#define _XAS_AUDIO_H + +#include +#include + +enum xas_audio_stream_type { + XAS_AUDIO_STREAM_SINK, + XAS_AUDIO_STREAM_SOURCE +}; + +typedef struct _xas_audio_stream xas_audio_stream; + +typedef int (*xas_audio_drain)(void *ctx, + void *samples, + size_t count, + xas_audio_stream *stream); + +typedef ssize_t (*xas_audio_fill)(void *ctx, + void *samples, + size_t count, + xas_audio_stream *stream); + +typedef void (*xas_audio_cleanup)(void *ctx, + xas_audio_stream *stream); + +struct _xas_audio_stream { + enum xas_audio_stream_type type; + + size_t sample_size, + sample_rate, + channels; + + size_t buffer_size, + buffer_count; + + union { + void *callback; + xas_audio_drain drain; + xas_audio_fill fill; + }; + + xas_audio_cleanup cleanup; + + void *ctx; +}; + +xas_audio_stream *xas_audio_stream_new_sink(xas_audio_drain drain, + xas_audio_cleanup cleanup, + void *ctx, + size_t sample_size, + size_t sample_rate, + size_t channels, + size_t buffer_size); + +xas_audio_stream *xas_audio_stream_new_source(xas_audio_fill fill, + xas_audio_cleanup cleanup, + void *ctx, + size_t sample_size, + size_t sample_rate, + size_t channels, + size_t buffer_size); + +void xas_audio_stream_destroy(xas_audio_stream *stream); + +ssize_t xas_audio_stream_write(xas_audio_stream *stream, + void *samples, + size_t count); + +ssize_t xas_audio_stream_read(xas_audio_stream *stream, + void *samples, + size_t count); + +int xas_audio_stream_flush(xas_audio_stream *stream); + +#endif /* _XAS_AUDIO_H */ diff --git a/include/xas/riff.h b/include/xas/riff.h index bf438cc..07ed0f2 100644 --- a/include/xas/riff.h +++ b/include/xas/riff.h @@ -39,7 +39,7 @@ typedef struct _xas_riff_wave_header { typedef struct _xas_riff xas_riff; -xas_audio_stream *xas_riff_open_file(const char *path, +xas_audio_stream *xas_riff_file_open(const char *path, size_t sample_size, size_t sample_rate, size_t channels, diff --git a/src/riff.c b/src/riff.c index edacce4..3a4933f 100644 --- a/src/riff.c +++ b/src/riff.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,6 +9,10 @@ struct _xas_riff { int fd; size_t size; + + size_t sample_size, + sample_rate, + channels; }; static int header_write(xas_riff *riff) { @@ -30,11 +35,11 @@ static int header_write(xas_riff *riff) { }, .type = XAS_RIFF_WAVE_DEFAULT_TYPE, - .channels = 1, - .sample_rate = 44100, - .byte_rate = 176400 / 2, - .sample_size = 2, - .sample_size_bits = 16 + .channels = riff->channels, + .sample_rate = riff->sample_rate, + .byte_rate = riff->channels * riff->sample_size * riff->sample_rate, + .sample_size = riff->sample_size, + .sample_size_bits = riff->sample_size << 3 }, { @@ -43,6 +48,11 @@ static int header_write(xas_riff *riff) { } }; + printf("channels %zu sample size %zu sample rate %zu\n", + riff->channels, + riff->sample_size, + riff->sample_rate); + if (lseek(riff->fd, 0, SEEK_SET) < 0) { goto error_io; } @@ -80,6 +90,9 @@ static xas_riff *file_open(const char *path, } riff->size = 0; + riff->sample_size = sample_size; + riff->sample_rate = sample_rate; + riff->channels = channels; if (flags & (O_CREAT | O_TRUNC)) { if (header_write(riff) < 0) { @@ -99,7 +112,7 @@ error_malloc_riff: return NULL; } -static int file_close(xas_riff *riff) { +static void file_close(xas_riff *riff, xas_audio_stream *stream) { if (lseek(riff->fd, 0, SEEK_SET) < 0) { goto error_io; } @@ -110,31 +123,47 @@ static int file_close(xas_riff *riff) { (void)close(riff->fd); - return 0; - error_header_write: error_io: - return -1; + return; } static int audio_drain(xas_riff *riff, void *samples, size_t count, xas_audio_stream *stream) { - size_t wrlen = count * stream->sample_size - * stream->channels; + size_t len = count * stream->sample_size + * stream->channels; + + ssize_t wrlen; + + if ((wrlen = write(riff->fd, samples, len)) < 0) { + goto error_write; + } + + return wrlen / stream->sample_size / stream->channels; - return write(riff->fd, samples, wrlen); +error_write: + return -1; } static ssize_t audio_fill(xas_riff *riff, void *samples, size_t count, xas_audio_stream *stream) { - ssize_t len = count * stream->sample_size - * stream->channels; + size_t len = count * stream->sample_size + * stream->channels; + + ssize_t rdlen; + + if ((rdlen = read(riff->fd, samples, len)) < 0) { + goto error_read; + } - return read(riff->fd, samples, len); + return rdlen / stream->sample_size / stream->channels; + +error_read: + return -1; } xas_audio_stream *xas_riff_file_open(const char *path, @@ -146,15 +175,16 @@ xas_audio_stream *xas_riff_file_open(const char *path, xas_riff *riff; if ((riff = file_open(path, - channels, sample_size, sample_rate, + channels, flags)) == NULL) { goto error_file_open; } if (flags & (O_RDWR | O_WRONLY)) { if ((stream = xas_audio_stream_new_sink((xas_audio_drain)audio_drain, + (xas_audio_cleanup)file_close, riff, sample_size, sample_rate, @@ -164,6 +194,7 @@ xas_audio_stream *xas_riff_file_open(const char *path, } } else { if ((stream = xas_audio_stream_new_source((xas_audio_fill)audio_fill, + (xas_audio_cleanup)file_close, riff, sample_size, sample_rate, @@ -176,7 +207,7 @@ xas_audio_stream *xas_riff_file_open(const char *path, return stream; error_audio_stream_new_sink: - file_close(riff); + file_close(riff, NULL); error_file_open: return NULL; -- cgit v1.2.3