Module from smcameron@yahoo.com:
authorRusty Russell <rusty@rustcorp.com.au>
Wed, 8 Apr 2009 05:06:39 +0000 (14:36 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Wed, 8 Apr 2009 05:06:39 +0000 (14:36 +0930)
- Deleted test/ dir, since it was a noop.

ccan/ogg_to_pcm/_info.c [new file with mode: 0644]
ccan/ogg_to_pcm/ogg_to_pcm.c [new file with mode: 0644]
ccan/ogg_to_pcm/ogg_to_pcm.h [new file with mode: 0644]

diff --git a/ccan/ogg_to_pcm/_info.c b/ccan/ogg_to_pcm/_info.c
new file mode 100644 (file)
index 0000000..bf023c8
--- /dev/null
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <string.h>
+#include "config.h"
+
+/**
+ * ogg_to_pcm - decode ogg vorbis audio files to PCM data using libvorbis 
+ *
+ * ogg_to_pcm implements a single function using libvorbis to decode
+ * signed 16 bit ogg audio data to signed 16 bit PCM data.
+ *
+ * Example:
+ *     #include <stdint.h>
+ *     #include <ogg_to_pcm.h>
+ *
+ *     int main(int argc, char *argv[]) 
+ *     {
+ *             int16_t *pcmbuffer;
+ *             int rc, sample_size, sample_rate, channels, nsamples;
+ *
+ *             rc = ogg_to_pcm("mysound.ogg", &pcmbuffer,
+ *                     &sample_size, &sample_rate, &channels, &nsamples);
+ *             if (rc != 0)
+ *                     return -1;
+ *             return 0;
+ *     }
+ *
+ * Licence: LGPL (2 or any later version)
+ *
+ */
+int main(int argc, char *argv[])
+{
+       if (argc != 2)
+               return 1;
+
+       if (strcmp(argv[1], "depends") == 0)
+               return 0;
+
+       if (strcmp(argv[1], "libs") == 0) {
+               printf("vorbisfile\n");
+               return 0;
+       }
+       return 1;
+}
diff --git a/ccan/ogg_to_pcm/ogg_to_pcm.c b/ccan/ogg_to_pcm/ogg_to_pcm.c
new file mode 100644 (file)
index 0000000..a9148b0
--- /dev/null
@@ -0,0 +1,129 @@
+/* OggDec
+ *
+ * This program is distributed under the GNU General Public License, version 2.
+ * A copy of this license is included with this source.
+ *
+ * Copyright 2002, Michael Smith <msmith@xiph.org>
+ *
+ */
+
+/*
+ *
+ * This code was hacked off of the carcass of oggdec.c, from
+ * the vorbistools-1.2.0 package, and is copyrighted as above,
+ * with the modifications made by me,
+ * (c) Copyright Stephen M. Cameron, 2008,
+ * (and of course also released under the GNU General Public License, version 2.)
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#if !defined(__APPLE__)
+/* Apple gets what it needs for malloc from stdlib.h */
+#include <malloc.h>
+#endif
+
+#include <vorbis/vorbisfile.h>
+
+#define DEFINE_OGG_TO_PCM_GLOBALS
+#include "ogg_to_pcm.h"
+
+static const int bits = 16;
+
+/* Reads an ogg vorbis file, infile, and dumps the data into
+   a big buffer, *pcmbuffer (which it allocates via malloc)
+   and returns the number of samples in *nsamples, and the
+   samplesize in *samplesize. and etc.
+*/
+int ogg_to_pcm(char *infile, int16_t **pcmbuffer,
+       int *samplesize, int *sample_rate, int *nchannels,
+       uint64_t *nsamples)
+{
+       FILE *in;
+       OggVorbis_File vf;
+       char buf[8192];
+       unsigned char *bufferptr;
+       int link, ret, chainsallowed = 0, bs = 0;
+
+       /* how to do this portably at compile time? */
+       const uint32_t dummy = 0x01020304;
+       const unsigned char *endian = (unsigned char *) &dummy;
+
+       in = fopen(infile, "r");
+       if (in == NULL) {
+               fprintf(stderr, "%s:%d ERROR: Failed to open '%s' for read: '%s'\n",
+                       __FILE__, __LINE__, infile, strerror(errno));
+               return -1;
+       }
+       if (ov_open(in, &vf, NULL, 0) < 0) {
+               fprintf(stderr, "%s:%d: ERROR: Failed to open '%s' as vorbis\n",
+                       __FILE__, __LINE__, infile);
+               fclose(in);
+               return -1;
+       }
+       if (!ov_seekable(&vf)) {
+               fprintf(stderr, "%s:%d: %s is not seekable.\n",
+                       __FILE__, __LINE__, infile);
+               fclose(in);
+               return -1;
+       }
+
+       *nchannels = ov_info(&vf,0)->channels;
+       *sample_rate = ov_info(&vf,0)->rate;
+
+       for (link = 0; link < ov_streams(&vf); link++) {
+               if (ov_info(&vf, link)->channels == *nchannels &&
+                   ov_info(&vf, link)->rate == *sample_rate) {
+                       chainsallowed = 1;
+               }
+       }
+
+       if (chainsallowed)
+               *nsamples = ov_pcm_total(&vf, -1);
+       else
+               *nsamples = ov_pcm_total(&vf, 0);
+
+       *pcmbuffer = (void *) malloc(sizeof(int16_t) * *nsamples * *nchannels);
+       memset(*pcmbuffer, 0, sizeof(int16_t) * *nsamples * *nchannels);
+       if (*pcmbuffer == NULL) {
+               fprintf(stderr, "%s:%d: Failed to allocate memory for '%s'\n",
+                       __FILE__, __LINE__, infile);
+               fclose(in);
+               return -1;
+       }
+       bufferptr = (unsigned char *) *pcmbuffer;
+
+       while ((ret = ov_read(&vf, buf, sizeof(buf), endian[0] == 0x01, bits/8, 1, &bs)) != 0) {
+               if (bs != 0) {
+                       vorbis_info *vi = ov_info(&vf, -1);
+                       if (*nchannels != vi->channels || *sample_rate != vi->rate) {
+                               fprintf(stderr, "%s:%d: Logical bitstreams with changing "
+                                       "parameters are not supported\n",
+                                       __FILE__, __LINE__);
+                               break;
+                       }
+               }
+
+               if(ret < 0 ) {
+                       fprintf(stderr, "%s:%d: Warning: hole in data (%d)\n",
+                               __FILE__, __LINE__, ret);
+                       continue;
+               }
+
+               /* copy the data to the pcmbuffer. */
+               memcpy(bufferptr, buf, ret);
+               bufferptr += ret;
+       }
+
+       /* ov_clear closes the file, so don't fclose here, even though we fopen()ed.
+        * libvorbis is weird that way.
+        */
+       ov_clear(&vf);
+
+       return 0;
+}
diff --git a/ccan/ogg_to_pcm/ogg_to_pcm.h b/ccan/ogg_to_pcm/ogg_to_pcm.h
new file mode 100644 (file)
index 0000000..6c1b4a2
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef __OGG_TO_PCM_H__
+#define __OGG_TO_PCM_H__
+#ifdef DEFINE_OGG_TO_PCM_GLOBALS
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+/* OggDec
+ *
+ * This program is distributed under the GNU General Public License, version 2.
+ * A copy of this license is included with this source.
+ *
+ * Copyright 2002, Michael Smith <msmith@xiph.org>
+ *
+ */
+
+/*
+ *
+ * This code was hacked off of the carcass of oggdec.c, from
+ * the vorbistools-1.2.0 package, and is copyrighted as above,
+ * with the modifications made by me,
+ * (c) Copyright Stephen M. Cameron, 2008,
+ * (and of course also released under the GNU General Public License, version 2.)
+ *
+ */
+
+/* ogg_to_pcm() reads an ogg vorbis audio file, infile, and
+ * dumps the data into a big buffer, *pcmbuffer (which it
+ * allocates via malloc) and returns the number of samples
+ * in *nsamples, and the samplesize in *samplesize. and etc.
+ */
+GLOBAL int ogg_to_pcm(char *infile, int16_t **pcmbuffer,
+       int *samplesize, int *sample_rate, int *nchannels,
+       uint64_t *nsamples);
+
+#undef GLOBAL
+#endif