3 * This program is distributed under the GNU General Public License, version 2.
4 * A copy of this license is included with this source.
6 * Copyright 2002, Michael Smith <msmith@xiph.org>
12 * This code was hacked off of the carcass of oggdec.c, from
13 * the vorbistools-1.2.0 package, and is copyrighted as above,
14 * with the modifications made by me,
15 * (c) Copyright Stephen M. Cameron, 2008,
16 * (and of course also released under the GNU General Public License, version 2.)
26 #if !defined(__APPLE__)
27 /* Apple gets what it needs for malloc from stdlib.h */
31 #include <vorbis/vorbisfile.h>
33 #define DEFINE_OGG_TO_PCM_GLOBALS
34 #include "ogg_to_pcm.h"
36 static const int bits = 16;
38 /* Reads an ogg vorbis file, infile, and dumps the data into
39 a big buffer, *pcmbuffer (which it allocates via malloc)
40 and returns the number of samples in *nsamples, and the
41 samplesize in *samplesize. and etc.
43 int ogg_to_pcm(char *infile, int16_t **pcmbuffer,
44 int *samplesize, int *sample_rate, int *nchannels,
50 unsigned char *bufferptr;
51 int link, ret, chainsallowed = 0, bs = 0;
53 /* how to do this portably at compile time? */
54 const uint32_t dummy = 0x01020304;
55 const unsigned char *endian = (unsigned char *) &dummy;
57 in = fopen(infile, "r");
59 fprintf(stderr, "%s:%d ERROR: Failed to open '%s' for read: '%s'\n",
60 __FILE__, __LINE__, infile, strerror(errno));
63 if (ov_open(in, &vf, NULL, 0) < 0) {
64 fprintf(stderr, "%s:%d: ERROR: Failed to open '%s' as vorbis\n",
65 __FILE__, __LINE__, infile);
69 if (!ov_seekable(&vf)) {
70 fprintf(stderr, "%s:%d: %s is not seekable.\n",
71 __FILE__, __LINE__, infile);
76 *nchannels = ov_info(&vf,0)->channels;
77 *sample_rate = ov_info(&vf,0)->rate;
79 for (link = 0; link < ov_streams(&vf); link++) {
80 if (ov_info(&vf, link)->channels == *nchannels &&
81 ov_info(&vf, link)->rate == *sample_rate) {
87 *nsamples = ov_pcm_total(&vf, -1);
89 *nsamples = ov_pcm_total(&vf, 0);
91 *pcmbuffer = (void *) malloc(sizeof(int16_t) * *nsamples * *nchannels);
92 memset(*pcmbuffer, 0, sizeof(int16_t) * *nsamples * *nchannels);
93 if (*pcmbuffer == NULL) {
94 fprintf(stderr, "%s:%d: Failed to allocate memory for '%s'\n",
95 __FILE__, __LINE__, infile);
99 bufferptr = (unsigned char *) *pcmbuffer;
101 while ((ret = ov_read(&vf, buf, sizeof(buf), endian[0] == 0x01, bits/8, 1, &bs)) != 0) {
103 vorbis_info *vi = ov_info(&vf, -1);
104 if (*nchannels != vi->channels || *sample_rate != vi->rate) {
105 fprintf(stderr, "%s:%d: Logical bitstreams with changing "
106 "parameters are not supported\n",
113 fprintf(stderr, "%s:%d: Warning: hole in data (%d)\n",
114 __FILE__, __LINE__, ret);
118 /* copy the data to the pcmbuffer. */
119 memcpy(bufferptr, buf, ret);
123 /* ov_clear closes the file, so don't fclose here, even though we fopen()ed.
124 * libvorbis is weird that way.