commit f5d1284c5a39bc5fff33639a9f2c5c1432ac7cf1
parent cf3f42e4dbf1c81603d84bc9fcf3c3c2c0f8f7bd
Author: sin <sin@2f30.org>
Date: Fri, 26 Dec 2014 16:48:11 +0000
Add vorbis decoder
Diffstat:
4 files changed, 93 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile
@@ -5,9 +5,9 @@ MANPREFIX = $(PREFIX)/man
CFLAGS = -I/usr/local/include -g
LDFLAGS = -L /usr/local/lib
-LDLIBS = -lsndfile -lmpg123 -lsndio
+LDLIBS = -lsndfile -lmpg123 -lsndio -logg -lvorbis -lvorbisfile
-OBJ = sndio.o cmd.o mp3.o wav.o playlist.o sad.o tokenizer.o decoder.o
+OBJ = sndio.o cmd.o mp3.o wav.o vorbis.o playlist.o sad.o tokenizer.o decoder.o
BIN = sad
all: $(BIN)
@@ -19,6 +19,7 @@ sndio.o: sad.h
cmd.o: sad.h
wav.o: sad.h
mp3.o: sad.h
+vorbis.o: sad.h
playlist.o: sad.h
sad.o: sad.h
tokenizer.o: sad.h
diff --git a/decoder.c b/decoder.c
@@ -12,8 +12,9 @@ static struct {
char *ext;
Decoder *decoder;
} Decodermap[] = {
- { ".wav", &wavdecoder },
- { ".mp3", &mp3decoder },
+ { ".wav", &wavdecoder },
+ { ".mp3", &mp3decoder },
+ { ".ogg", &vorbisdecoder },
};
int
diff --git a/sad.h b/sad.h
@@ -69,6 +69,9 @@ extern Decoder wavdecoder;
/* mp3.c */
extern Decoder mp3decoder;
+/* vorbis.c */
+extern Decoder vorbisdecoder;
+
/* sndio.c */
extern Output sndiooutput;
diff --git a/vorbis.c b/vorbis.c
@@ -0,0 +1,84 @@
+#include <sys/select.h>
+
+#include <err.h>
+#include <limits.h>
+#include <stdio.h>
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
+
+#include "sad.h"
+
+static FILE *fp;
+static OggVorbis_File vf;
+static int cursect;
+
+static int
+vorbisinit(void)
+{
+ return 0;
+}
+
+static int
+vorbisopen(const char *name)
+{
+ int r;
+
+ fp = fopen(name, "r");
+ if (!fp) {
+ warn("fopen %s", name);
+ return -1;
+ }
+
+ cursect = 0;
+ r = ov_open_callbacks(fp, &vf, NULL, 0, OV_CALLBACKS_NOCLOSE);
+ if (r < 0) {
+ warnx("ov_open_callbacks: failed");
+ return -1;
+ }
+
+ /* TODO: pull out params from file */
+ return output->open(16, 44100, 2);
+}
+
+static int
+vorbisdecode(void *buf, int nbytes)
+{
+ int r;
+
+ r = ov_read(&vf, buf, nbytes, 0, 2, 1, &cursect);
+ if (r < 0) {
+ warnx("ov_read: failed");
+ return -1;
+ } else if (r == 0)
+ return r;
+ return r;
+}
+
+static int
+vorbisclose(void)
+{
+ int r;
+
+ if (fp) {
+ fclose(fp);
+ fp = NULL;
+ }
+ if (ov_clear(&vf) < 0)
+ r = -1;
+ if (output->close() < 0)
+ r = -1;
+ return r;
+}
+
+static void
+vorbisexit(void)
+{
+}
+
+Decoder vorbisdecoder = {
+ .init = vorbisinit,
+ .open = vorbisopen,
+ .decode = vorbisdecode,
+ .close = vorbisclose,
+ .exit = vorbisexit
+};