music_buffer_vorbis.cpp.patch.cpp
1 |
diff -r 4ea92975a277 code/nel/src/sound/driver/music_buffer_vorbis.cpp
|
---|---|
2 |
--- a/code/nel/src/sound/driver/music_buffer_vorbis.cpp Tue Feb 01 18:56:55 2011 +0100 |
3 |
+++ b/code/nel/src/sound/driver/music_buffer_vorbis.cpp Tue Feb 08 16:45:41 2011 +0100 |
4 |
@@ -1,214 +1,222 @@ |
5 |
-// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
6 |
-// Copyright (C) 2010 Winch Gate Property Limited
|
7 |
-//
|
8 |
-// This program is free software: you can redistribute it and/or modify
|
9 |
-// it under the terms of the GNU Affero General Public License as
|
10 |
-// published by the Free Software Foundation, either version 3 of the
|
11 |
-// License, or (at your option) any later version.
|
12 |
-//
|
13 |
-// This program is distributed in the hope that it will be useful,
|
14 |
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16 |
-// GNU Affero General Public License for more details.
|
17 |
-//
|
18 |
-// You should have received a copy of the GNU Affero General Public License
|
19 |
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20 |
- |
21 |
-#include "stdsound_lowlevel.h" |
22 |
- |
23 |
-// Project includes
|
24 |
-#include "nel/sound/driver/music_buffer_vorbis.h" |
25 |
- |
26 |
-using namespace std; |
27 |
-using namespace NLMISC; |
28 |
- |
29 |
-namespace NLSOUND
|
30 |
-{ |
31 |
- |
32 |
-size_t vorbisReadFunc(void *ptr, size_t size, size_t nmemb, void *datasource) |
33 |
-{ |
34 |
- CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; |
35 |
- NLMISC::IStream *stream = music_buffer_vorbis->getStream(); |
36 |
- nlassert(stream->isReading()); |
37 |
- sint32 length = (sint32)(size * nmemb); |
38 |
- if (length > music_buffer_vorbis->getStreamSize() - stream->getPos())
|
39 |
- length = music_buffer_vorbis->getStreamSize() - stream->getPos(); |
40 |
- stream->serialBuffer((uint8 *)ptr, length); |
41 |
- return length;
|
42 |
-} |
43 |
- |
44 |
-int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence) |
45 |
-{ |
46 |
- if (whence == SEEK_CUR && offset == 0) |
47 |
- { |
48 |
- // nlwarning(NLSOUND_XAUDIO2_PREFIX "This seek call doesn't do a damn thing, wtf.");
|
49 |
- return 0; // ooookkaaaaaayyy |
50 |
- } |
51 |
- |
52 |
- CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; |
53 |
- |
54 |
- NLMISC::IStream::TSeekOrigin origin; |
55 |
- switch (whence)
|
56 |
- { |
57 |
- case SEEK_SET:
|
58 |
- origin = NLMISC::IStream::begin; |
59 |
- break;
|
60 |
- case SEEK_CUR:
|
61 |
- origin = NLMISC::IStream::current; |
62 |
- break;
|
63 |
- case SEEK_END:
|
64 |
- origin = NLMISC::IStream::end; |
65 |
- break;
|
66 |
- default:
|
67 |
- // nlwarning(NLSOUND_XAUDIO2_PREFIX "Seeking to fake origin.");
|
68 |
- return -1; |
69 |
- } |
70 |
- |
71 |
- if (music_buffer_vorbis->getStream()->seek(SEEK_SET ? music_buffer_vorbis->getStreamOffset() + (sint32)offset : (sint32)offset, origin)) return 0; |
72 |
- else return -1; |
73 |
-} |
74 |
- |
75 |
-//int vorbisCloseFunc(void *datasource)
|
76 |
-//{
|
77 |
-// //CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource;
|
78 |
-//}
|
79 |
- |
80 |
-long vorbisTellFunc(void *datasource) |
81 |
-{ |
82 |
- CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; |
83 |
- return (long)(music_buffer_vorbis->getStream()->getPos() - music_buffer_vorbis->getStreamOffset()); |
84 |
-} |
85 |
- |
86 |
-static ov_callbacks OV_CALLBACKS_NLMISC_STREAM = {
|
87 |
- (size_t (*)(void *, size_t, size_t, void *)) vorbisReadFunc, |
88 |
- (int (*)(void *, ogg_int64_t, int)) vorbisSeekFunc, |
89 |
- (int (*)(void *)) NULL, //vorbisCloseFunc, |
90 |
- (long (*)(void *)) vorbisTellFunc |
91 |
-}; |
92 |
- |
93 |
-CMusicBufferVorbis::CMusicBufferVorbis(NLMISC::IStream *stream, bool loop)
|
94 |
-: _Stream(stream), _Loop(loop), _IsMusicEnded(false)
|
95 |
-{ |
96 |
- _StreamOffset = stream->getPos(); |
97 |
- stream->seek(0, NLMISC::IStream::end);
|
98 |
- _StreamSize = stream->getPos(); |
99 |
- stream->seek(_StreamOffset, NLMISC::IStream::begin); |
100 |
- ov_open_callbacks(this, &_OggVorbisFile, NULL, 0, OV_CALLBACKS_NLMISC_STREAM); |
101 |
-} |
102 |
- |
103 |
-CMusicBufferVorbis::~CMusicBufferVorbis() |
104 |
-{ |
105 |
- ov_clear(&_OggVorbisFile); |
106 |
-} |
107 |
- |
108 |
-/// Get information on a music file (only artist and title at the moment).
|
109 |
-bool CMusicBufferVorbis::getInfo(NLMISC::IStream *stream, std::string &artist, std::string &title) |
110 |
-{ |
111 |
- CMusicBufferVorbis mbv(stream, false); // just opens and closes the oggvorbisfile thing :) |
112 |
- vorbis_comment *vc = ov_comment(&mbv._OggVorbisFile, -1);
|
113 |
- char *title_c = vorbis_comment_query(vc, "title", 0); |
114 |
- if (title_c) title = title_c; else title.clear(); |
115 |
- char *artist_c = vorbis_comment_query(vc, "artist", 0); |
116 |
- if (artist_c) artist = artist_c; else artist.clear(); |
117 |
- return true; |
118 |
-} |
119 |
- |
120 |
-uint32 CMusicBufferVorbis::getRequiredBytes() |
121 |
-{ |
122 |
- return 0; // no minimum requirement of bytes to buffer out |
123 |
-} |
124 |
- |
125 |
-uint32 CMusicBufferVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) |
126 |
-{ |
127 |
- sint current_section = 0; // ??? |
128 |
- if (_IsMusicEnded) return 0; |
129 |
- nlassert(minimum <= maximum); // can't have this..
|
130 |
- uint32 bytes_read = 0;
|
131 |
- do
|
132 |
- { |
133 |
- // signed 16-bit or unsigned 8-bit little-endian samples
|
134 |
- sint br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read,
|
135 |
- 0, // Specifies big or little endian byte packing. 0 for little endian, 1 for b ig endian. Typical value is 0. |
136 |
- getBitsPerSample() == 8 ? 1 : 2, |
137 |
- getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1. |
138 |
- ¤t_section); |
139 |
- // nlinfo(NLSOUND_XAUDIO2_PREFIX "current_section: %i", current_section);
|
140 |
- if (br > 0) |
141 |
- { |
142 |
- bytes_read += (uint32)br; |
143 |
- } |
144 |
- else if (br == 0) // EOF |
145 |
- { |
146 |
- if (_Loop)
|
147 |
- { |
148 |
- ov_pcm_seek(&_OggVorbisFile, 0);
|
149 |
- //_Stream->seek(0, NLMISC::IStream::begin);
|
150 |
- } |
151 |
- else
|
152 |
- { |
153 |
- _IsMusicEnded = true;
|
154 |
- break;
|
155 |
- } |
156 |
- } |
157 |
- else
|
158 |
- { |
159 |
- // error
|
160 |
- switch(br)
|
161 |
- { |
162 |
- case OV_HOLE:
|
163 |
- nlwarning("ov_read returned OV_HOLE");
|
164 |
- break;
|
165 |
- |
166 |
- case OV_EINVAL:
|
167 |
- nlwarning("ov_read returned OV_EINVAL");
|
168 |
- break;
|
169 |
- |
170 |
- case OV_EBADLINK:
|
171 |
- nlwarning("ov_read returned OV_EBADLINK");
|
172 |
- break;
|
173 |
- |
174 |
- default:
|
175 |
- nlwarning("ov_read returned %d", br);
|
176 |
- } |
177 |
- |
178 |
- return 0; |
179 |
- } |
180 |
- } while (bytes_read < minimum);
|
181 |
- return bytes_read;
|
182 |
-} |
183 |
- |
184 |
-uint8 CMusicBufferVorbis::getChannels() |
185 |
-{ |
186 |
- vorbis_info *vi = ov_info(&_OggVorbisFile, -1);
|
187 |
- return (uint8)vi->channels;
|
188 |
-} |
189 |
- |
190 |
-uint32 CMusicBufferVorbis::getSamplesPerSec() |
191 |
-{ |
192 |
- vorbis_info *vi = ov_info(&_OggVorbisFile, -1);
|
193 |
- return vi->rate;
|
194 |
-} |
195 |
- |
196 |
-uint8 CMusicBufferVorbis::getBitsPerSample() |
197 |
-{ |
198 |
- return 16; |
199 |
-} |
200 |
- |
201 |
-bool CMusicBufferVorbis::isMusicEnded()
|
202 |
-{ |
203 |
- return _IsMusicEnded;
|
204 |
-} |
205 |
- |
206 |
-float CMusicBufferVorbis::getLength()
|
207 |
-{ |
208 |
- return (float)ov_time_total(&_OggVorbisFile, -1); |
209 |
-} |
210 |
- |
211 |
-uint CMusicBufferVorbis::getUncompressedSize() |
212 |
-{ |
213 |
- return (uint)ov_pcm_total(&_OggVorbisFile, -1) * (getBitsPerSample() / 2) * getChannels(); |
214 |
-} |
215 |
- |
216 |
-} /* namespace NLSOUND */
|
217 |
- |
218 |
-/* end of file */
|
219 |
+// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
220 |
+// Copyright (C) 2010 Winch Gate Property Limited
|
221 |
+//
|
222 |
+// This program is free software: you can redistribute it and/or modify
|
223 |
+// it under the terms of the GNU Affero General Public License as
|
224 |
+// published by the Free Software Foundation, either version 3 of the
|
225 |
+// License, or (at your option) any later version.
|
226 |
+//
|
227 |
+// This program is distributed in the hope that it will be useful,
|
228 |
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
229 |
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
230 |
+// GNU Affero General Public License for more details.
|
231 |
+//
|
232 |
+// You should have received a copy of the GNU Affero General Public License
|
233 |
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
234 |
+ |
235 |
+#include "stdsound_lowlevel.h" |
236 |
+ |
237 |
+// Project includes
|
238 |
+#include "nel/sound/driver/music_buffer_vorbis.h" |
239 |
+ |
240 |
+using namespace std; |
241 |
+using namespace NLMISC; |
242 |
+ |
243 |
+namespace NLSOUND
|
244 |
+{ |
245 |
+ |
246 |
+size_t vorbisReadFunc(void *ptr, size_t size, size_t nmemb, void *datasource) |
247 |
+{ |
248 |
+ CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; |
249 |
+ NLMISC::IStream *stream = music_buffer_vorbis->getStream(); |
250 |
+ nlassert(stream->isReading()); |
251 |
+ sint32 length = (sint32)(size * nmemb); |
252 |
+ if (length > music_buffer_vorbis->getStreamSize() - stream->getPos())
|
253 |
+ length = music_buffer_vorbis->getStreamSize() - stream->getPos(); |
254 |
+ stream->serialBuffer((uint8 *)ptr, length); |
255 |
+ return length;
|
256 |
+} |
257 |
+ |
258 |
+int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence) |
259 |
+{ |
260 |
+ if (whence == SEEK_CUR && offset == 0) |
261 |
+ { |
262 |
+ // nlwarning(NLSOUND_XAUDIO2_PREFIX "This seek call doesn't do a damn thing, wtf.");
|
263 |
+ return 0; // ooookkaaaaaayyy |
264 |
+ } |
265 |
+ |
266 |
+ CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; |
267 |
+ |
268 |
+ NLMISC::IStream::TSeekOrigin origin; |
269 |
+ switch (whence)
|
270 |
+ { |
271 |
+ case SEEK_SET:
|
272 |
+ origin = NLMISC::IStream::begin; |
273 |
+ break;
|
274 |
+ case SEEK_CUR:
|
275 |
+ origin = NLMISC::IStream::current; |
276 |
+ break;
|
277 |
+ case SEEK_END:
|
278 |
+ origin = NLMISC::IStream::end; |
279 |
+ break;
|
280 |
+ default:
|
281 |
+ // nlwarning(NLSOUND_XAUDIO2_PREFIX "Seeking to fake origin.");
|
282 |
+ return -1; |
283 |
+ } |
284 |
+ |
285 |
+ if (music_buffer_vorbis->getStream()->seek(SEEK_SET ? music_buffer_vorbis->getStreamOffset() + (sint32)offset : (sint32)offset, origin)) return 0; |
286 |
+ else return -1; |
287 |
+} |
288 |
+ |
289 |
+//int vorbisCloseFunc(void *datasource)
|
290 |
+//{
|
291 |
+// //CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource;
|
292 |
+//}
|
293 |
+ |
294 |
+long vorbisTellFunc(void *datasource) |
295 |
+{ |
296 |
+ CMusicBufferVorbis *music_buffer_vorbis = (CMusicBufferVorbis *)datasource; |
297 |
+ return (long)(music_buffer_vorbis->getStream()->getPos() - music_buffer_vorbis->getStreamOffset()); |
298 |
+} |
299 |
+ |
300 |
+static ov_callbacks OV_CALLBACKS_NLMISC_STREAM = {
|
301 |
+ (size_t (*)(void *, size_t, size_t, void *)) vorbisReadFunc, |
302 |
+ (int (*)(void *, ogg_int64_t, int)) vorbisSeekFunc, |
303 |
+ (int (*)(void *)) NULL, //vorbisCloseFunc, |
304 |
+ (long (*)(void *)) vorbisTellFunc |
305 |
+}; |
306 |
+ |
307 |
+CMusicBufferVorbis::CMusicBufferVorbis(NLMISC::IStream *stream, bool loop)
|
308 |
+: _Stream(stream), _Loop(loop), _IsMusicEnded(false)
|
309 |
+{ |
310 |
+ _StreamOffset = stream->getPos(); |
311 |
+ stream->seek(0, NLMISC::IStream::end);
|
312 |
+ _StreamSize = stream->getPos(); |
313 |
+ stream->seek(_StreamOffset, NLMISC::IStream::begin); |
314 |
+ ov_open_callbacks(this, &_OggVorbisFile, NULL, 0, OV_CALLBACKS_NLMISC_STREAM); |
315 |
+} |
316 |
+ |
317 |
+CMusicBufferVorbis::~CMusicBufferVorbis() |
318 |
+{ |
319 |
+ ov_clear(&_OggVorbisFile); |
320 |
+} |
321 |
+ |
322 |
+/// Get information on a music file (only artist and title at the moment).
|
323 |
+bool CMusicBufferVorbis::getInfo(NLMISC::IStream *stream, std::string &artist, std::string &title) |
324 |
+{ |
325 |
+ CMusicBufferVorbis mbv(stream, false); // just opens and closes the oggvorbisfile thing :) |
326 |
+ vorbis_comment *vc = ov_comment(&mbv._OggVorbisFile, -1);
|
327 |
+ char *title_c = vorbis_comment_query(vc, "title", 0); |
328 |
+ if (title_c) title = title_c; else title.clear(); |
329 |
+ char *artist_c = vorbis_comment_query(vc, "artist", 0); |
330 |
+ if (artist_c) artist = artist_c; else artist.clear(); |
331 |
+ return true; |
332 |
+} |
333 |
+ |
334 |
+uint32 CMusicBufferVorbis::getRequiredBytes() |
335 |
+{ |
336 |
+ return 0; // no minimum requirement of bytes to buffer out |
337 |
+} |
338 |
+ |
339 |
+uint32 CMusicBufferVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 maximum) |
340 |
+{ |
341 |
+ sint current_section = 0; // ??? |
342 |
+ if (_IsMusicEnded) return 0; |
343 |
+ nlassert(minimum <= maximum); // can't have this..
|
344 |
+ uint32 bytes_read = 0;
|
345 |
+ do
|
346 |
+ { |
347 |
+ // signed 16-bit or unsigned 8-bit little-endian samples
|
348 |
+#ifdef NL_BIG_ENDIAN
|
349 |
+ sint br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read,
|
350 |
+ 1, // Specifies big or little endian byte packing. 0 for little endian, 1 for b ig endian. Typical value is 0. |
351 |
+ getBitsPerSample() == 8 ? 1 : 2, |
352 |
+ getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1. |
353 |
+ ¤t_section); |
354 |
+#else
|
355 |
+ sint br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read,
|
356 |
+ 0, // Specifies big or little endian byte packing. 0 for little endian, 1 for b ig endian. Typical value is 0. |
357 |
+ getBitsPerSample() == 8 ? 1 : 2, |
358 |
+ getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1. |
359 |
+ ¤t_section); |
360 |
+#endif
|
361 |
+ // nlinfo(NLSOUND_XAUDIO2_PREFIX "current_section: %i", current_section);
|
362 |
+ if (br > 0) |
363 |
+ { |
364 |
+ bytes_read += (uint32)br; |
365 |
+ } |
366 |
+ else if (br == 0) // EOF |
367 |
+ { |
368 |
+ if (_Loop)
|
369 |
+ { |
370 |
+ ov_pcm_seek(&_OggVorbisFile, 0);
|
371 |
+ //_Stream->seek(0, NLMISC::IStream::begin);
|
372 |
+ } |
373 |
+ else
|
374 |
+ { |
375 |
+ _IsMusicEnded = true;
|
376 |
+ break;
|
377 |
+ } |
378 |
+ } |
379 |
+ else
|
380 |
+ { |
381 |
+ // error
|
382 |
+ switch(br)
|
383 |
+ { |
384 |
+ case OV_HOLE:
|
385 |
+ nlwarning("ov_read returned OV_HOLE");
|
386 |
+ break;
|
387 |
+ |
388 |
+ case OV_EINVAL:
|
389 |
+ nlwarning("ov_read returned OV_EINVAL");
|
390 |
+ break;
|
391 |
+ |
392 |
+ case OV_EBADLINK:
|
393 |
+ nlwarning("ov_read returned OV_EBADLINK");
|
394 |
+ break;
|
395 |
+ |
396 |
+ default:
|
397 |
+ nlwarning("ov_read returned %d", br);
|
398 |
+ } |
399 |
+ |
400 |
+ return 0; |
401 |
+ } |
402 |
+ } while (bytes_read < minimum);
|
403 |
+ return bytes_read;
|
404 |
+} |
405 |
+ |
406 |
+uint8 CMusicBufferVorbis::getChannels() |
407 |
+{ |
408 |
+ vorbis_info *vi = ov_info(&_OggVorbisFile, -1);
|
409 |
+ return (uint8)vi->channels;
|
410 |
+} |
411 |
+ |
412 |
+uint32 CMusicBufferVorbis::getSamplesPerSec() |
413 |
+{ |
414 |
+ vorbis_info *vi = ov_info(&_OggVorbisFile, -1);
|
415 |
+ return vi->rate;
|
416 |
+} |
417 |
+ |
418 |
+uint8 CMusicBufferVorbis::getBitsPerSample() |
419 |
+{ |
420 |
+ return 16; |
421 |
+} |
422 |
+ |
423 |
+bool CMusicBufferVorbis::isMusicEnded()
|
424 |
+{ |
425 |
+ return _IsMusicEnded;
|
426 |
+} |
427 |
+ |
428 |
+float CMusicBufferVorbis::getLength()
|
429 |
+{ |
430 |
+ return (float)ov_time_total(&_OggVorbisFile, -1); |
431 |
+} |
432 |
+ |
433 |
+uint CMusicBufferVorbis::getUncompressedSize() |
434 |
+{ |
435 |
+ return (uint)ov_pcm_total(&_OggVorbisFile, -1) * (getBitsPerSample() / 2) * getChannels(); |
436 |
+} |
437 |
+ |
438 |
+} /* namespace NLSOUND */
|
439 |
+ |
440 |
+/* end of file */
|