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: | 
 
    