diff options
author | XANTRONIX Development | 2022-01-15 01:04:48 -0500 |
---|---|---|
committer | XANTRONIX Development | 2022-01-15 01:04:48 -0500 |
commit | 10743527b811423032adb38a7dafe00f5b69443e (patch) | |
tree | 053653220f60d6179124c84faf580e1639753ceb | |
parent | 031451c6287a344566c96b49274f92e9a44c6196 (diff) | |
download | xas-10743527b811423032adb38a7dafe00f5b69443e.tar.gz xas-10743527b811423032adb38a7dafe00f5b69443e.tar.bz2 xas-10743527b811423032adb38a7dafe00f5b69443e.zip |
~Getting there, sweetie.~
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | include/xas/audio.h | 76 | ||||
-rw-r--r-- | include/xas/riff.h | 2 | ||||
-rw-r--r-- | src/riff.c | 65 |
4 files changed, 127 insertions, 18 deletions
@@ -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 <stdint.h> +#include <sys/types.h> + +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, @@ -1,3 +1,4 @@ +#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> @@ -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; |