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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-#include "stdsound_lowlevel.h"
|
22
|
-
|
23
|
-
|
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
|
-
|
49
|
- return 0;
|
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
|
-
|
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
|
-
|
76
|
-
|
77
|
-
|
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,
|
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
|
-
|
109
|
-bool CMusicBufferVorbis::getInfo(NLMISC::IStream *stream, std::string &artist, std::string &title)
|
110
|
-{
|
111
|
- CMusicBufferVorbis mbv(stream, false);
|
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;
|
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);
|
130
|
- uint32 bytes_read = 0;
|
131
|
- do
|
132
|
- {
|
133
|
-
|
134
|
- sint br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read,
|
135
|
- 0,
|
136
|
- getBitsPerSample() == 8 ? 1 : 2,
|
137
|
- getBitsPerSample() == 8 ? 0 : 1,
|
138
|
- ¤t_section);
|
139
|
-
|
140
|
- if (br > 0)
|
141
|
- {
|
142
|
- bytes_read += (uint32)br;
|
143
|
- }
|
144
|
- else if (br == 0)
|
145
|
- {
|
146
|
- if (_Loop)
|
147
|
- {
|
148
|
- ov_pcm_seek(&_OggVorbisFile, 0);
|
149
|
-
|
150
|
- }
|
151
|
- else
|
152
|
- {
|
153
|
- _IsMusicEnded = true;
|
154
|
- break;
|
155
|
- }
|
156
|
- }
|
157
|
- else
|
158
|
- {
|
159
|
-
|
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
|
-}
|
217
|
-
|
218
|
-
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
|
230
|
+
|
231
|
+
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+#include "stdsound_lowlevel.h"
|
236
|
+
|
237
|
+
|
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
|
+
|
263
|
+ return 0;
|
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
|
+
|
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
|
+
|
290
|
+
|
291
|
+
|
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,
|
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
|
+
|
323
|
+bool CMusicBufferVorbis::getInfo(NLMISC::IStream *stream, std::string &artist, std::string &title)
|
324
|
+{
|
325
|
+ CMusicBufferVorbis mbv(stream, false);
|
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;
|
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);
|
344
|
+ uint32 bytes_read = 0;
|
345
|
+ do
|
346
|
+ {
|
347
|
+
|
348
|
+#ifdef NL_BIG_ENDIAN
|
349
|
+ sint br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read,
|
350
|
+ 1,
|
351
|
+ getBitsPerSample() == 8 ? 1 : 2,
|
352
|
+ getBitsPerSample() == 8 ? 0 : 1,
|
353
|
+ ¤t_section);
|
354
|
+#else
|
355
|
+ sint br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read,
|
356
|
+ 0,
|
357
|
+ getBitsPerSample() == 8 ? 1 : 2,
|
358
|
+ getBitsPerSample() == 8 ? 0 : 1,
|
359
|
+ ¤t_section);
|
360
|
+#endif
|
361
|
+
|
362
|
+ if (br > 0)
|
363
|
+ {
|
364
|
+ bytes_read += (uint32)br;
|
365
|
+ }
|
366
|
+ else if (br == 0)
|
367
|
+ {
|
368
|
+ if (_Loop)
|
369
|
+ {
|
370
|
+ ov_pcm_seek(&_OggVorbisFile, 0);
|
371
|
+
|
372
|
+ }
|
373
|
+ else
|
374
|
+ {
|
375
|
+ _IsMusicEnded = true;
|
376
|
+ break;
|
377
|
+ }
|
378
|
+ }
|
379
|
+ else
|
380
|
+ {
|
381
|
+
|
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
|
+}
|
439
|
+
|
440
|
+
|