From f20a98aa7a2f418167d884df4da243986ba601ec Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Tue, 1 Feb 2022 14:27:04 -0500 Subject: Implement xas_riff_open_fd() Implement xas_riff_open_fd() to allow readonly access to a PCM stream beginning with a valid RIFF header --- src/riff.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'src') diff --git a/src/riff.c b/src/riff.c index d3ddee7..f5c1c23 100644 --- a/src/riff.c +++ b/src/riff.c @@ -8,6 +8,7 @@ #include struct _xas_riff { + const char *file; int fd; size_t size; @@ -85,6 +86,7 @@ static xas_riff *new_file(const char *path, goto error_open; } + riff->file = path; riff->size = 0; riff->sample_size = sample_size; riff->sample_rate = sample_rate; @@ -184,6 +186,48 @@ error_invalid_header_main_id: return -1; } +static xas_riff *open_fd(int fd) { + xas_riff *riff; + xas_riff_wave_header header; + + ssize_t readlen; + + if ((riff = malloc(sizeof(*riff))) == NULL) { + goto error_malloc_riff; + } + + riff->file = NULL; + riff->fd = fd; + riff->size = 0; + riff->sample_size = 0; + riff->sample_rate = 0; + riff->channels = 0; + + if ((readlen = read(fd, &header, sizeof(header))) < 0) { + goto error_read; + } + + if (readlen != sizeof(header)) { + errno= EINVAL; + + goto error_wave_header_short; + } + + if (wave_header_parse(riff, &header) < 0) { + goto error_wave_header_parse; + } + + return riff; + +error_wave_header_parse: +error_wave_header_short: +error_read: + free(riff); + +error_malloc_riff: + return NULL; +} + static xas_riff *open_file(const char *path, int flags) { xas_riff *riff; xas_riff_wave_header header; @@ -200,6 +244,7 @@ static xas_riff *open_file(const char *path, int flags) { goto error_open; } + riff->file = path; riff->size = 0; riff->sample_size = 0; riff->sample_rate = 0; @@ -381,3 +426,30 @@ error_audio_stream_new_sink: error_open_file: return NULL; } + +xas_audio_stream *xas_riff_open_fd(int fd) { + xas_audio_stream *stream; + xas_riff *riff; + + if ((riff = open_fd(fd)) == NULL) { + goto error_open_fd; + } + + if ((stream = xas_audio_stream_new_source((xas_audio_fill)audio_fill, + (xas_audio_cleanup)close_file, + riff, + riff->sample_size, + riff->sample_rate, + riff->channels, + 4096)) == NULL) { + goto error_audio_stream_new_sink; + } + + return stream; + +error_audio_stream_new_sink: + free(riff); + +error_open_fd: + return NULL; +} -- cgit v1.2.3