comparison engine/core/loaders/native/audio_loaders/sounddecoder_ogg.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children 90005975cdbb
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 /***************************************************************************
2 * Copyright (C) 2005-2008 by the FIFE team *
3 * http://www.fifengine.de *
4 * This file is part of FIFE. *
5 * *
6 * FIFE is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 // Standard C++ library includes
23
24 // Platform specific includes
25
26 // 3rd party library includes
27
28 // FIFE includes
29 // These includes are split up in two parts, separated by one empty line
30 // First block: files included from the FIFE root src directory
31 // Second block: files included from the same folder
32 #include "util/log/logger.h"
33 #include "util/base/exception.h"
34
35 #include "sounddecoder_ogg.h"
36
37 namespace FIFE {
38 static Logger _log(LM_AUDIO);
39
40 /* OggVorbis Callback functions
41 */
42 namespace OGG_cb {
43 static size_t read(void *ptr, size_t size, size_t nmemb, void *datasource) {
44 RawData* rdp = reinterpret_cast<RawData*>(datasource);
45 size_t restlen = rdp->getDataLength()-rdp->getCurrentIndex();
46 size_t len = (restlen<=size*nmemb)?restlen:size*nmemb;
47 if (len) {
48 rdp->readInto(reinterpret_cast<uint8_t *>(ptr), len);
49 }
50 return len;
51 }
52
53 static int seek(void *datasource, ogg_int64_t offset, int whence) {
54 RawData* rdp = reinterpret_cast<RawData*>(datasource);
55 switch (whence) {
56 case SEEK_SET:
57 (*rdp).setIndex(offset);
58 return 0;
59 case SEEK_CUR:
60 (*rdp).moveIndex(offset);
61 return 0;
62 case SEEK_END:
63 (*rdp).setIndex( (*rdp).getDataLength() -1 + offset);
64 return 0;
65 }
66 return -1;
67 }
68
69 static int close(void *datasource) { return 0; }
70
71 static long tell(void *datasource) {
72 RawData* rdp = reinterpret_cast<RawData*>(datasource);
73 return (*rdp).getCurrentIndex();
74 }
75 }
76
77 SoundDecoderOgg::SoundDecoderOgg(RawData* rdp) : m_file(rdp) {
78
79 ov_callbacks ocb = {
80 OGG_cb::read, OGG_cb::seek, OGG_cb::close, OGG_cb::tell
81 };
82
83 if (0 > ov_open_callbacks(m_file.get(), &m_ovf, 0, 0, ocb)) {
84 throw InvalidFormat("Error opening OggVorbis file");
85 }
86
87
88 vorbis_info *vi = ov_info(&m_ovf, -1);
89 if (!vi) {
90 throw InvalidFormat("Error fetching OggVorbis info");
91 }
92
93 if (!ov_seekable(&m_ovf)) {
94 throw InvalidFormat("OggVorbis file has to be seekable");
95 }
96
97 m_isstereo = vi->channels == 2;
98 m_samplerate = vi->rate;
99 m_is8bit = false;
100 m_declength = (m_isstereo ? 2 : 1) * 2 * ov_pcm_total(&m_ovf, -1);
101 m_datasize = 0;
102 m_data = NULL;
103 }
104
105 bool SoundDecoderOgg::decode(unsigned long length) {
106 int stream = 0;
107 int ret = 0;
108
109 // release buffer and allocate new memory
110 releaseBuffer();
111 m_data = new char[length];
112
113 // decode the stream
114 m_datasize = 0;
115 do {
116 ret = ov_read(&m_ovf, m_data + m_datasize,
117 length-m_datasize, 0, 2, 1, &stream);
118 if (ret > 0) {
119 m_datasize += ret;
120 }
121
122 } while (length-m_datasize > 0 && ret > 0);
123
124 return m_datasize == 0;
125 }
126
127 bool SoundDecoderOgg::setCursor(unsigned long pos) {
128
129 if (ov_pcm_seek(&m_ovf, pos / ((m_isstereo ? 2 : 1) * 2)) == 0) {
130 return true;
131 }
132 return false;
133 }
134 }