diff options
| author | XANTRONIX Development | 2022-02-02 00:12:09 -0500 | 
|---|---|---|
| committer | XANTRONIX Development | 2022-02-02 00:12:09 -0500 | 
| commit | 37566c51d0e80fbf3837b6527c501727521e92cd (patch) | |
| tree | c8af3ea836c2b91c41bd02145d4f769ed219be15 /src | |
| parent | 45a040e8d17da6550dd389725bc7c482ba99f6ab (diff) | |
| download | xas-37566c51d0e80fbf3837b6527c501727521e92cd.tar.gz xas-37566c51d0e80fbf3837b6527c501727521e92cd.tar.bz2 xas-37566c51d0e80fbf3837b6527c501727521e92cd.zip | |
nailed it
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio.c | 78 | 
1 files changed, 49 insertions, 29 deletions
| diff --git a/src/audio.c b/src/audio.c index 8853164..10f7a34 100644 --- a/src/audio.c +++ b/src/audio.c @@ -106,50 +106,70 @@ static inline void *ptr(xas_audio_stream *stream, void *buf, size_t index) {  ssize_t xas_audio_stream_write(xas_audio_stream *stream,                                   void *samples,                                   size_t count) { -    size_t left  = count, -           index = 0; +    size_t index_i = 0; -    if (stream->buffer_count > 0) { -        size_t remainder = stream->buffer_size - stream->buffer_count; +    if (stream->buffer_count + count > stream->buffer_size) { +        /* +         * If the number of samples offered, plus the number of items currently +         * in the buffer exceeds the buffer size, fill the buffer to capacity +         * and flush it. +         */ +        size_t remaining = stream->buffer_size - stream->buffer_count;          memcpy(ptr(stream, stream + 1, stream->buffer_count), -               ptr(stream, samples, 0), -               stream->sample_size * stream->channels * remainder); +               ptr(stream, samples,    index_i), +               remaining * stream->sample_size * stream->channels); -        stream->buffer_count += remainder; - -        if (stream_flush(stream) < 0) { -            goto error_stream_flush; -        } - -        left  -= remainder; -        index += remainder; -    } - -    while (left > stream->buffer_size) {          if (stream->drain(stream->ctx, -                          ptr(stream, samples, index), +                          ptr(stream, stream + 1, 0),                            stream->buffer_size,                            stream) < 0) {              goto error_stream_drain;          } -        left  -= stream->buffer_size; -        index += stream->buffer_size; -    } +        index_i += remaining; -    memcpy(ptr(stream, stream + 1, 0), -           ptr(stream, samples, index), -           stream->sample_size * stream->channels * left); - -    stream->buffer_count = left; +        stream->buffer_count = 0; +    } -    index += left; +    /* +     * While there are still samples to buffer or flush... +     */ +    while (index_i < count) { +        size_t remaining = count - index_i; + +        if (remaining >= stream->buffer_size) { +            /* +             * If the number of samples remaining is greater than the target +             * buffer size, then drain directly from the source buffer to the +             * output an amount equal to the buffer size. +             */ +            if (stream->drain(stream->ctx, +                              ptr(stream, samples, index_i), +                              stream->buffer_size, +                              stream) < 0) { +                goto error_stream_drain; +            } + +            index_i += stream->buffer_size; +        } else { +            /* +             * Enough of the input has been drained that it can be copied to +             * the target buffer. +             */ +            memcpy(ptr(stream, stream + 1, stream->buffer_count), +                   ptr(stream, samples,    index_i), +                   remaining * stream->sample_size * stream->channels); + +            index_i += remaining; + +            stream->buffer_count += remaining; +        } +    } -    return index; +    return 0;  error_stream_drain: -error_stream_flush:      return -1;  } | 
 
    