summaryrefslogtreecommitdiffstats
path: root/src/read-vorbis.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2008-05-26 22:00:19 +0000
committerLennart Poettering <lennart@poettering.net>2008-05-26 22:00:19 +0000
commitd7fd6a45e50475cddf0b8bad8baab01b33cf3c1f (patch)
tree4f210adb96478280df083b6d4802053f93b59192 /src/read-vorbis.c
parent48178a5e2813546b61706d1f97fab761934a97f0 (diff)
move sources to src/ subdir
git-svn-id: file:///home/lennart/svn/public/libcanberra/trunk@12 01b60673-d06a-42c0-afdd-89cb8e0f78ac
Diffstat (limited to 'src/read-vorbis.c')
-rw-r--r--src/read-vorbis.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/read-vorbis.c b/src/read-vorbis.c
new file mode 100644
index 0000000..717f851
--- /dev/null
+++ b/src/read-vorbis.c
@@ -0,0 +1,148 @@
+/* $Id$ */
+
+/***
+ This file is part of libcanberra.
+
+ Copyright 2008 Lennart Poettering
+
+ libcanberra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 2.1 of the
+ License, or (at your option) any later version.
+
+ libcanberra is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with libcanberra. If not, If not, see
+ <http://www.gnu.org/licenses/>.
+***/
+
+#include "read-vorbis.h"
+
+#define FILE_SIZE_MAX (64U*1024U*1024U)
+
+struct ca_vorbis {
+ OggVorbis_File ovf;
+};
+
+static int convert_error(int or) {
+ switch (or) {
+ case OV_NOSEEK:
+ case OV_BADPACKET:
+ case OV_BADLINK:
+ case OV_FAULT:
+ case OV_EREAD:
+ case OV_HOLE:
+ return CA_ERROR_IO;
+
+ case OV_EIMPL:
+ case OV_EVERSION:
+ case OV_ENOTAUDIO
+ return CA_ERROR_NOT_SUPPORTED;
+
+ case OV_ENOTVORBIS:
+ case OV_EBADHEADER:
+ case OV_EOF:
+ return CA_ERROR_CORRUPT;
+
+ case OV_EINVAL:
+ return CA_ERROR_INVALID;
+
+ default:
+ return CA_ERROR_INTERNAL;
+ }
+}
+
+int ca_vorbis_open(ca_vorbis **_v, FILE *f) {
+ int ret, or;
+ ca_vorbis *v;
+ int64_t n;
+
+ ca_return_val_if_fail(_v, CA_ERROR_INVALID);
+ ca_return_val_if_fail(f, CA_ERROR_INVALID);
+
+ if (!(v = ca_new(ca_vorbis, 1)))
+ return CA_ERROR_OOM;
+
+ if ((or = ov_open(f, &v->ovf, NULL, 0)) < 0) {
+ ret = convert_error(or);
+ goto fail;
+ }
+
+ if ((n = ov_pcm_total(&ovf, -1)) < 0) {
+ ret = convert_error(or);
+ ov_clear(&v->ovf);
+ goto fail;
+ }
+
+ if (n * sizeof(int16_t) > FILE_SIZE_MAX) {
+ ret = CA_ERROR_TOOBIG;
+ ov_clear(&v->ovf);
+ goto fail;
+ }
+
+ *_v = v;
+
+ return CA_SUCCESS;
+
+fail:
+
+ ca_free(v);
+ return ret;
+}
+
+void ca_vorbis_close(ca_vorbis *v) {
+ ca_assert(v);
+
+ ov_clear(&v->ovf);
+ ca_free(v);
+}
+
+unsigned ca_vorbis_get_nchannels(ca_vorbis *v) {
+ vorbis_info *vi;
+ ca_assert(v);
+
+ ca_assert_se(vi = ov_info(&vf, -1));
+
+ return vi->channels;
+}
+
+unsigned ca_vorbis_get_rate(ca_vorbis *v) {
+ vorbis_info *vi;
+ ca_assert(v);
+
+ ca_assert_se(vi = ov_info(&vf, -1));
+
+ return (unsigned) vi->rate;
+}
+
+int ca_vorbis_read_int16ne(ca_vorbis *v, int16_t *d, unsigned *n){
+ long r;
+ int section;
+
+ ca_return_val_if_fail(w, CA_ERROR_INVALID);
+ ca_return_val_if_fail(d, CA_ERROR_INVALID);
+ ca_return_val_if_fail(n, CA_ERROR_INVALID);
+ ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID);
+
+ r = ov_read(&v->ovf, d, *n * sizeof(float),
+#ifdef WORDS_BIGENDIAN
+ 1,
+#else
+ 0,
+#endif
+ 2, 1, &section);
+
+ if (r < 0)
+ return convert_error(or);
+
+ /* We only read the first section */
+ if (section != 0)
+ return 0;
+
+ *n = (unsigned) r;
+ return CA_SUCCESS;
+}