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-ogg.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
);