summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--include/xas/audio.h76
-rw-r--r--include/xas/riff.h2
-rw-r--r--src/riff.c65
4 files changed, 127 insertions, 18 deletions
diff --git a/Makefile b/Makefile
index e476f4e..dcbc342 100644
--- a/Makefile
+++ b/Makefile
@@ -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,
diff --git a/src/riff.c b/src/riff.c
index edacce4..3a4933f 100644
--- a/src/riff.c
+++ b/src/riff.c
@@ -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;