diff options
author | XANTRONIX Development | 2022-01-15 10:30:20 -0500 |
---|---|---|
committer | XANTRONIX Development | 2022-01-15 10:30:20 -0500 |
commit | 712c1bafab413143b1edcd868a736f0fe6f026b9 (patch) | |
tree | 04a5954ece0a7cc9118b18149cd82734bcec89c0 | |
parent | 10743527b811423032adb38a7dafe00f5b69443e (diff) | |
download | xas-712c1bafab413143b1edcd868a736f0fe6f026b9.tar.gz xas-712c1bafab413143b1edcd868a736f0fe6f026b9.tar.bz2 xas-712c1bafab413143b1edcd868a736f0fe6f026b9.zip |
still not quite there, but close
-rw-r--r-- | include/xas/riff.h | 7 | ||||
-rw-r--r-- | src/audio.c | 145 | ||||
-rw-r--r-- | src/riff.c | 8 |
3 files changed, 156 insertions, 4 deletions
diff --git a/include/xas/riff.h b/include/xas/riff.h index 07ed0f2..4e600da 100644 --- a/include/xas/riff.h +++ b/include/xas/riff.h @@ -8,6 +8,9 @@ #define XAS_RIFF_WAVE_DEFAULT_TYPE 1 +#pragma pack(1) +#pragma pack(push) + typedef struct _xas_riff_chunk { char id[4]; uint32_t size; @@ -18,7 +21,7 @@ typedef struct _xas_riff_main_chunk { char type[4]; } xas_riff_main_chunk; -typedef struct _xas_riff_wave_format_chunk { +typedef struct _xas_riff_wave_chunk { xas_riff_chunk header; uint16_t type, @@ -39,6 +42,8 @@ typedef struct _xas_riff_wave_header { typedef struct _xas_riff xas_riff; +#pragma pack(pop) + xas_audio_stream *xas_riff_file_open(const char *path, size_t sample_size, size_t sample_rate, diff --git a/src/audio.c b/src/audio.c new file mode 100644 index 0000000..8922698 --- /dev/null +++ b/src/audio.c @@ -0,0 +1,145 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <xas/audio.h> + +static xas_audio_stream *stream_new(enum xas_audio_stream_type type, + void *callback, + xas_audio_cleanup cleanup, + void *ctx, + size_t sample_size, + size_t sample_rate, + size_t channels, + size_t buffer_size) { + xas_audio_stream *stream; + + size_t total = sizeof(xas_audio_stream) + + sample_size * channels * buffer_size; + + if ((stream = malloc(total)) == NULL) { + goto error_malloc_stream; + } + + stream->type = type; + stream->sample_size = sample_size; + stream->sample_rate = sample_rate; + stream->channels = channels; + stream->buffer_size = buffer_size; + stream->buffer_count = 0; + stream->callback = callback; + stream->cleanup = cleanup; + stream->ctx = ctx; + + return stream; + +error_malloc_stream: + return NULL; +} + +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) { + return stream_new(XAS_AUDIO_STREAM_SINK, + drain, + cleanup, + ctx, + sample_size, + sample_rate, + channels, + 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) { + return stream_new(XAS_AUDIO_STREAM_SOURCE, + fill, + cleanup, + ctx, + sample_size, + sample_rate, + channels, + buffer_size); +} + +void xas_audio_stream_destroy(xas_audio_stream *stream) { + if (stream->cleanup) { + stream->cleanup(stream->ctx, stream); + } + + free(stream); +} + +static inline int stream_flush(xas_audio_stream *stream) { + printf("Flushing stream\n"); + if (stream->buffer_count == 0) { + return 0; + } + + if (stream->drain(stream->ctx, + stream + 1, + stream->buffer_count, + stream) < 0) { + goto error_stream_drain; + } + + stream->buffer_count = 0; + + return 0; + +error_stream_drain: + return -1; +} + +ssize_t xas_audio_stream_write(xas_audio_stream *stream, + void *samples, + size_t count) { + size_t total = stream->buffer_count + count, + offset = stream->sample_size * stream->channels * stream->buffer_count; + + if (total > stream->buffer_size) { + if (stream_flush(stream) < 0) { + goto error_stream_flush; + } + } + + memcpy((uint8_t *)(stream + 1) + offset, + samples, + stream->sample_size * stream->channels * count); + + stream->buffer_count += count; + + return count; + +error_stream_flush: + return -1; +} + +ssize_t xas_audio_stream_read(xas_audio_stream *stream, + void *samples, + size_t count) { + return stream->fill(stream->ctx, + samples, + count, + stream); +} + +int xas_audio_stream_flush(xas_audio_stream *stream) { + if (stream->type == XAS_AUDIO_STREAM_SINK) { + return stream_flush(stream); + } + + errno = EINVAL; + + return -1; +} @@ -20,8 +20,8 @@ static int header_write(xas_riff *riff) { .riff = { { .id = "RIFF", - .size = sizeof(xas_riff_wave_chunk) - + sizeof(xas_riff_chunk) + .size = sizeof(xas_riff_main_chunk) + + sizeof(xas_riff_wave_chunk) + riff->size }, @@ -89,7 +89,7 @@ static xas_riff *file_open(const char *path, goto error_open; } - riff->size = 0; + riff->size = 0; riff->sample_size = sample_size; riff->sample_rate = sample_rate; riff->channels = channels; @@ -141,6 +141,8 @@ static int audio_drain(xas_riff *riff, goto error_write; } + riff->size += wrlen; + return wrlen / stream->sample_size / stream->channels; error_write: |