2 * This file is part of DisOrder
3 * Copyright (C) 2007-2010 Richard Kettlewell
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 /** @file server/decode.c
19 * @brief General-purpose decoder for use by speaker process
23 #include <vorbis/vorbisfile.h>
25 static size_t ogg_read_func(void *ptr, size_t size, size_t nmemb, void *datasource) {
26 struct hreader *h = datasource;
28 int n = hreader_read(h, ptr, size * nmemb);
33 static int ogg_seek_func(void *datasource, ogg_int64_t offset, int whence) {
34 struct hreader *h = datasource;
36 return hreader_seek(h, offset, whence) < 0 ? -1 : 0;
39 static int ogg_close_func(void attribute((unused)) *datasource) {
43 static long ogg_tell_func(void *datasource) {
44 struct hreader *h = datasource;
46 return hreader_seek(h, 0, SEEK_CUR);
49 static const ov_callbacks ogg_callbacks = {
56 /** @brief OGG decoder */
57 void decode_ogg(void) {
58 struct hreader ogginput[1];
65 hreader_init(path, ogginput);
66 /* There doesn't seem to be any standard function for mapping the error codes
68 if((err = ov_open_callbacks(ogginput, vf, 0/*initial*/, 0/*ibytes*/,
70 disorder_fatal(0, "ov_open_callbacks %s: %d", path, err);
71 if(!(vi = ov_info(vf, 0/*link*/)))
72 disorder_fatal(0, "ov_info %s: failed", path);
73 while((n = ov_read(vf, input_buffer, sizeof input_buffer, 1/*bigendianp*/,
74 2/*bytes/word*/, 1/*signed*/, &bitstream))) {
76 disorder_fatal(0, "ov_read %s: %ld", path, n);
78 disorder_fatal(0, "only single-bitstream ogg files are supported");
79 output_header(vi->rate, vi->channels, 16/*bits*/, n, ENDIAN_BIG);
80 if(fwrite(input_buffer, 1, n, outputfp) < (size_t)n)
81 disorder_fatal(errno, "decoding %s: writing sample data", path);