From 67fed6580a18ec18cb649172907f986fbc2e60c0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 8 Apr 2009 14:36:39 +0930 Subject: [PATCH] Module from smcameron@yahoo.com: - Deleted test/ dir, since it was a noop. --- ccan/ogg_to_pcm/_info.c | 43 ++++++++++++ ccan/ogg_to_pcm/ogg_to_pcm.c | 129 +++++++++++++++++++++++++++++++++++ ccan/ogg_to_pcm/ogg_to_pcm.h | 38 +++++++++++ 3 files changed, 210 insertions(+) create mode 100644 ccan/ogg_to_pcm/_info.c create mode 100644 ccan/ogg_to_pcm/ogg_to_pcm.c create mode 100644 ccan/ogg_to_pcm/ogg_to_pcm.h diff --git a/ccan/ogg_to_pcm/_info.c b/ccan/ogg_to_pcm/_info.c new file mode 100644 index 00000000..bf023c8b --- /dev/null +++ b/ccan/ogg_to_pcm/_info.c @@ -0,0 +1,43 @@ +#include +#include +#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 + * #include + * + * 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 index 00000000..a9148b05 --- /dev/null +++ b/ccan/ogg_to_pcm/ogg_to_pcm.c @@ -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 + * + */ + +/* + * + * 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 +#include +#include +#include +#include +#include +#if !defined(__APPLE__) +/* Apple gets what it needs for malloc from stdlib.h */ +#include +#endif + +#include + +#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 index 00000000..6c1b4a23 --- /dev/null +++ b/ccan/ogg_to_pcm/ogg_to_pcm.h @@ -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 + * + */ + +/* + * + * 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 -- 2.39.2