chiark / gitweb /
debian/control: db4.8 is obsolete in wheezy.
[disorder] / server / decode-ogg.c
CommitLineData
8d399b30
RK
1/*
2 * This file is part of DisOrder
8a886602 3 * Copyright (C) 2007-2011 Richard Kettlewell
8d399b30
RK
4 *
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.
9 *
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.
14 *
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/>.
17 */
1a164e63 18/** @file server/decode-ogg.c
8d399b30
RK
19 * @brief General-purpose decoder for use by speaker process
20 */
21#include "decode.h"
22
23#include <vorbis/vorbisfile.h>
24
25static size_t ogg_read_func(void *ptr, size_t size, size_t nmemb, void *datasource) {
26 struct hreader *h = datasource;
27
28 int n = hreader_read(h, ptr, size * nmemb);
29 if(n < 0) n = 0;
30 return n / size;
31}
32
33static int ogg_seek_func(void *datasource, ogg_int64_t offset, int whence) {
34 struct hreader *h = datasource;
35
36 return hreader_seek(h, offset, whence) < 0 ? -1 : 0;
37}
38
39static int ogg_close_func(void attribute((unused)) *datasource) {
40 return 0;
41}
42
43static long ogg_tell_func(void *datasource) {
44 struct hreader *h = datasource;
45
46 return hreader_seek(h, 0, SEEK_CUR);
47}
48
49static const ov_callbacks ogg_callbacks = {
50 ogg_read_func,
51 ogg_seek_func,
52 ogg_close_func,
53 ogg_tell_func,
54};
55
56/** @brief OGG decoder */
57void decode_ogg(void) {
58 struct hreader ogginput[1];
59 OggVorbis_File vf[1];
60 int err;
61 long n;
62 int bitstream;
63 vorbis_info *vi;
64
65 hreader_init(path, ogginput);
66 /* There doesn't seem to be any standard function for mapping the error codes
67 * to strings l-( */
68 if((err = ov_open_callbacks(ogginput, vf, 0/*initial*/, 0/*ibytes*/,
69 ogg_callbacks)))
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))) {
75 if(n < 0)
76 disorder_fatal(0, "ov_read %s: %ld", path, n);
77 if(bitstream > 0)
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);
82 }
83}
84
85/*
86Local Variables:
87c-basic-offset:2
88comment-column:40
89fill-column:79
90indent-tabs-mode:nil
91End:
92*/