xoreos  0.0.5
vorbis.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 /* Based on ScummVM (<http://scummvm.org>) code, which is released
26  * under the terms of version 2 or later of the GNU General Public
27  * License.
28  *
29  * The original copyright note in ScummVM reads as follows:
30  *
31  * ScummVM is the legal property of its developers, whose names
32  * are too numerous to list here. Please refer to the COPYRIGHT
33  * file distributed with this source distribution.
34  *
35  * This program is free software; you can redistribute it and/or
36  * modify it under the terms of the GNU General Public License
37  * as published by the Free Software Foundation; either version 2
38  * of the License, or (at your option) any later version.
39  *
40  * This program is distributed in the hope that it will be useful,
41  * but WITHOUT ANY WARRANTY; without even the implied warranty of
42  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43  * GNU General Public License for more details.
44  *
45  * You should have received a copy of the GNU General Public License
46  * along with this program; if not, write to the Free Software
47  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
48  */
49 
50 #include <cassert>
51 #include <cstring>
52 #include <queue>
53 
54 #include <vorbis/vorbisfile.h>
55 
56 #include "src/common/scopedptr.h"
58 #include "src/common/mutex.h"
59 #include "src/common/util.h"
60 #include "src/common/readstream.h"
61 
62 #include "src/sound/audiostream.h"
63 
65 
66 namespace Sound {
67 
68 // These are wrapper functions to allow using a SeekableReadStream object to
69 // provide data to the OggVorbis_File object.
70 
71 static size_t read_stream_wrap(void *ptr, size_t size, size_t nmemb, void *dataSource) {
72  Common::SeekableReadStream *stream = static_cast<Common::SeekableReadStream *>(dataSource);
73 
74  size_t result = stream->read(ptr, size * nmemb);
75 
76  return result / size;
77 }
78 
79 static int seek_stream_wrap(void *dataSource, ogg_int64_t offset, int whence) {
81  switch (whence) {
82  case SEEK_SET:
84  break;
85  case SEEK_CUR:
87  break;
88  case SEEK_END:
90  break;
91  default:
92  assert(false);
93  break;
94  }
95 
96  Common::SeekableReadStream *stream = static_cast<Common::SeekableReadStream *>(dataSource);
97  stream->seek((ptrdiff_t)offset, seekOrigin);
98  return stream->pos();
99 }
100 
101 static int close_stream_wrap(void *UNUSED(dataSource)) {
102  // Do nothing -- we leave it up to the VorbisStream to free memory as appropriate.
103  return 0;
104 }
105 
106 static long tell_stream_wrap(void *dataSource) {
107  Common::SeekableReadStream *stream = static_cast<Common::SeekableReadStream *>(dataSource);
108  return stream->pos();
109 }
110 
111 static ov_callbacks g_stream_wrap = {
113 };
114 
116 protected:
118 
119  bool _isStereo;
120  int _rate;
121 
122  OggVorbis_File _ovFile;
123 
124  int16 _buffer[4096];
126  const int16 *_pos;
127 
129 
130 public:
131  // startTime / duration are in milliseconds
132  VorbisStream(Common::SeekableReadStream *inStream, bool dispose);
133  ~VorbisStream();
134 
135  size_t readBuffer(int16 *buffer, const size_t numSamples);
136 
137  bool endOfData() const { return _pos >= _bufferEnd; }
138  int getChannels() const { return _isStereo ? 2 : 1; }
139  int getRate() const { return _rate; }
140  uint64 getLength() const { return _length; }
141 
142  bool rewind();
143 
144 protected:
145  bool refill();
146 };
147 
149  _inStream(inStream, dispose),
150  _bufferEnd(_buffer + ARRAYSIZE(_buffer)),
151  _length(kInvalidLength) {
152 
153  int res = ov_open_callbacks(inStream, &_ovFile, 0, 0, g_stream_wrap);
154  if (res < 0) {
155  warning("Could not create Vorbis stream (%d)", res);
156  _pos = _bufferEnd;
157  return;
158  }
159 
160  ogg_int64_t total = ov_pcm_total(&_ovFile, -1);
161  if (total >= 0)
162  _length = (uint64) total;
163 
164  // Read in initial data
165  if (!refill())
166  return;
167 
168  // Setup some header information
169  _isStereo = ov_info(&_ovFile, -1)->channels >= 2;
170  _rate = ov_info(&_ovFile, -1)->rate;
171 }
172 
174  ov_clear(&_ovFile);
175 }
176 
177 size_t VorbisStream::readBuffer(int16 *buffer, const size_t numSamples) {
178  size_t samples = 0;
179  while (samples < numSamples && _pos < _bufferEnd) {
180  const size_t len = MIN<size_t>(numSamples - samples, _bufferEnd - _pos);
181  std::memcpy(buffer, _pos, len * 2);
182 
183  buffer += len;
184  _pos += len;
185  samples += len;
186 
187  if (_pos >= _bufferEnd) {
188  if (!refill())
189  break;
190  }
191  }
192  return samples;
193 }
194 
196  if (ov_pcm_seek(&_ovFile, 0) != 0)
197  return false;
198 
199  return refill();
200 }
201 
203  // Read the samples
204  size_t len_left = sizeof(_buffer);
205  char *read_pos = reinterpret_cast<char *>(_buffer);
206 
207  while (len_left > 0) {
208  long result;
209 
210 #if USE_TREMOR
211  // Tremor ov_read() always returns data as signed 16 bit interleaved PCM
212  // in host byte order. As such, it does not take arguments to request
213  // specific signedness, byte order or bit depth as in Vorbisfile.
214  result = ov_read(&_ovFile, read_pos, len_left,
215  0);
216 #else
217 #ifdef XOREOS_BIG_ENDIAN
218  result = ov_read(&_ovFile, read_pos, len_left,
219  1, // big endian
220  2, // 16 bit
221  1, // signed
222  0);
223 #else
224  result = ov_read(&_ovFile, read_pos, len_left,
225  0, // little endian
226  2, // 16 bit
227  1, // signed
228  0);
229 #endif
230 #endif
231  if (result == OV_HOLE) {
232  // Possibly recoverable, just warn about it
233  warning("Corrupted data in Vorbis file");
234  } else if (result == 0) {
235  //warning("End of file while reading from Vorbis file");
236  //_pos = _bufferEnd;
237  //return false;
238  break;
239  } else if (result < 0) {
240  warning("Error reading from Vorbis stream (%d)", int(result));
241  _pos = _bufferEnd;
242  // Don't delete it yet, that causes problems in
243  // the CD player emulation code.
244  return false;
245  } else {
246  len_left -= result;
247  read_pos += result;
248  }
249  }
250 
251  _pos = _buffer;
252  _bufferEnd = reinterpret_cast<int16 *>(read_pos);
253 
254  return true;
255 }
256 
258 public:
261 
264 
265  // AudioStream API
266  int getChannels() const { return _vorbisInfo.channels; }
267  int getRate() const { return _vorbisInfo.rate; }
268  size_t readBuffer(int16 *buffer, const size_t numSamples);
269  bool endOfData() const;
270  bool endOfStream() const;
271 
272  // PacketizedAudioStream API
274  void finish();
275  bool isFinished() const;
276 
277 private:
278  // Vorbis decode state
279  vorbis_info _vorbisInfo;
280  vorbis_dsp_state _dspState;
281  vorbis_block _block;
282  vorbis_comment _comment;
283  ogg_packet _packet;
284  bool _init;
285 
287  std::queue<Common::SeekableReadStream *> _queue;
288  bool _finished;
289  bool _hasData;
290 };
291 
293  _finished = false;
294  _init = false;
295  _hasData = false;
296  vorbis_info_init(&_vorbisInfo);
297  vorbis_comment_init(&_comment);
298  memset(&_packet, 0, sizeof(_packet));
299 }
300 
302  if (_init) {
303  vorbis_block_clear(&_block);
304  vorbis_dsp_clear(&_dspState);
305  }
306 
307  vorbis_info_clear(&_vorbisInfo);
308  vorbis_comment_clear(&_comment);
309 
310  // Remove anything from the queue
311  while (!_queue.empty()) {
312  delete _queue.front();
313  _queue.pop();
314  }
315 }
316 
318  if (stream.size() < 3)
319  return false;
320 
321  byte initialBytes[3];
322  stream.read(initialBytes, sizeof(initialBytes));
323 
324  size_t headerSizes[3];
325  Common::ScopedArray<byte> headers[3];
326 
327  if (stream.size() >= 6 && READ_BE_UINT16(initialBytes) == 30) {
328  stream.seek(0);
329 
330  for (int i = 0; i < 3; i++) {
331  headerSizes[i] = stream.readUint16BE();
332 
333  if (headerSizes[i] + stream.pos() > stream.size()) {
334  warning("Vorbis header size invalid");
335  return false;
336  }
337 
338  headers[i].reset(new byte[headerSizes[i]]);
339  stream.read(headers[i].get(), headerSizes[i]);
340  }
341  } else if (initialBytes[0] == 2 && stream.size() < 0x7FFFFE00) {
342  stream.seek(1);
343  uint32 offset = 1;
344 
345  for (int i = 0; i < 2; i++) {
346  headerSizes[i] = 0;
347 
348  while (stream.pos() < stream.size()) {
349  byte length = stream.readByte();
350  headerSizes[i] += length;
351  offset++;
352 
353  if (length != 0xFF)
354  break;
355  }
356 
357  if (offset >= (uint32)stream.size()) {
358  warning("Vorbis header sizes damaged");
359  return false;
360  }
361  }
362 
363  headerSizes[2] = stream.size() - (headerSizes[0] + headerSizes[1] + offset);
364  stream.seek(offset);
365 
366  for (int i = 0; i < 3; i++) {
367  headers[i].reset(new byte[headerSizes[i]]);
368  stream.read(headers[i].get(), headerSizes[i]);
369  }
370  } else {
371  warning("Invalid vorbis initial header length: %d", initialBytes[0]);
372  return false;
373  }
374 
375  for (int i = 0; i < 3; i++) {
376  _packet.b_o_s = (i == 0);
377  _packet.bytes = headerSizes[i];
378  _packet.packet = headers[i].get();
379 
380  if (vorbis_synthesis_headerin(&_vorbisInfo, &_comment, &_packet) < 0) {
381  warning("Vorbis header %d is damaged", i);
382  return false;
383  }
384  }
385 
386  // Begin decode
387  vorbis_synthesis_init(&_dspState, &_vorbisInfo);
388  vorbis_block_init(&_dspState, &_block);
389  _init = true;
390 
391  return true;
392 }
393 
395  int headerSizes[3];
396  Common::ScopedArray<byte> headers[3];
397 
398 #define READ_WHOLE_STREAM(x) \
399  do { \
400  Common::SeekableReadStream &packet = packet##x; \
401  headerSizes[x - 1] = packet.size(); \
402  headers[x - 1].reset(new byte[headerSizes[x - 1]]); \
403  packet.read(headers[x - 1].get(), headerSizes[x - 1]); \
404  } while (0)
405 
409 
410 #undef READ_WHOLE_STREAM
411 
412  for (int i = 0; i < 3; i++) {
413  _packet.b_o_s = (i == 0);
414  _packet.bytes = headerSizes[i];
415  _packet.packet = headers[i].get();
416 
417  if (vorbis_synthesis_headerin(&_vorbisInfo, &_comment, &_packet) < 0) {
418  warning("Vorbis header %d is damaged", i);
419  return false;
420  }
421  }
422 
423  // Begin decode
424  vorbis_synthesis_init(&_dspState, &_vorbisInfo);
425  vorbis_block_init(&_dspState, &_block);
426  _init = true;
427 
428  return true;
429 }
430 
431 size_t PacketizedVorbisStream::readBuffer(int16 *buffer, const size_t numSamples) {
432  assert(_init);
433 
434  size_t samples = 0;
435  while (samples < numSamples) {
436 #ifdef USE_TREMOR
437  ogg_int32_t **pcm;
438 #else
439  float **pcm;
440 #endif
441  int decSamples = vorbis_synthesis_pcmout(&_dspState, &pcm);
442  if (decSamples <= 0) {
443  // No more samples
445  _hasData = false;
446 
447  // If the queue is empty, we can do nothing else
448  if (_queue.empty())
449  return samples;
450 
451  // Feed the next packet into the beast
453  _queue.pop();
454  Common::ScopedArray<byte> data(new byte[stream->size()]);
455  stream->read(data.get(), stream->size());
456 
457  // Synthesize!
458  _packet.packet = data.get();
459  _packet.bytes = stream->size();
460  if (vorbis_synthesis(&_block, &_packet) == 0) {
461  vorbis_synthesis_blockin(&_dspState, &_block);
462  _hasData = true;
463  } else {
464  warning("Failed to synthesize from vorbis packet");
465  }
466 
467  // Retry pcmout
468  continue;
469  }
470 
471  // See how many samples we can decode
472  decSamples = MIN<int>((numSamples - samples) / getChannels(), decSamples);
473 
474 #ifdef USE_TREMOR
475  for (int i = 0; i < decSamples; i++)
476  for (int j = 0; j < getChannels(); j++)
477  buffer[samples++] = (int16)(pcm[j][i] / 32768);
478 #else
479  for (int i = 0; i < decSamples; i++)
480  for (int j = 0; j < getChannels(); j++)
481  buffer[samples++] = CLIP<int>(floor(pcm[j][i] * 32767.0f + 0.5), -32768, 32767);
482 #endif
483 
484  vorbis_synthesis_read(&_dspState, decSamples);
485  }
486 
487  return samples;
488 }
489 
492  return !_hasData && _queue.empty();
493 }
494 
497  return _finished && endOfData();
498 }
499 
502  assert(!_finished);
503  _queue.push(packet);
504 }
505 
508  _finished = true;
509 }
510 
513  return _finished;
514 }
515 
517  Common::ScopedPtr<RewindableAudioStream> s(new VorbisStream(stream, disposeAfterUse));
518  if (s && s->endOfData())
519  return 0;
520 
521  return s.release();
522 }
523 
526  if (!stream->parseExtraData(extraData))
527  return 0;
528 
529  return stream.release();
530 }
531 
534  if (!stream->parseExtraData(packet1, packet2, packet3))
535  return 0;
536 
537  return stream.release();
538 }
539 
540 } // End of namespace Sound
static ov_callbacks g_stream_wrap
Definition: vorbis.cpp:111
static long tell_stream_wrap(void *dataSource)
Definition: vorbis.cpp:106
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
void reset(PointerType o=0)
Resets the pointer with the new value.
Definition: scopedptr.h:87
static size_t read_stream_wrap(void *ptr, size_t size, size_t nmemb, void *dataSource)
Definition: vorbis.cpp:71
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
Definition: scopedptr.h:103
uint64_t uint64
Definition: types.h:206
uint64 getLength() const
Estimate the total number of samples per channel in this stream.
Definition: vorbis.cpp:140
#define READ_WHOLE_STREAM(x)
vorbis_dsp_state _dspState
Definition: vorbis.cpp:280
static int close_stream_wrap(void *dataSource)
Definition: vorbis.cpp:101
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
Definition: util.h:131
PacketizedAudioStream * makePacketizedVorbisStream(Common::SeekableReadStream &extraData)
Create a new PacketizedAudioStream capable of decoding vorbis audio data.
Definition: vorbis.cpp:524
bool isFinished() const
Is the stream marked as finished?
Definition: vorbis.cpp:511
const int16 * _pos
Definition: vorbis.cpp:126
int16_t int16
Definition: types.h:201
Seek from the end of the stream.
Definition: readstream.h:271
int16 _buffer[4096]
Definition: vorbis.cpp:124
A simple scoped smart pointer template.
Definition: game.h:37
const int16 * _bufferEnd
Definition: vorbis.cpp:125
Origin
The position a seeking offset takes as a base.
Definition: readstream.h:268
int getRate() const
Sample rate of the stream.
Definition: vorbis.cpp:139
int getChannels() const
Return the number channels in this stream.
Definition: vorbis.cpp:138
A rewindable audio stream.
Definition: audiostream.h:125
A mutex.
Definition: mutex.h:40
#define UNUSED(x)
Definition: system.h:170
static int seek_stream_wrap(void *dataSource, ogg_int64_t offset, int whence)
Definition: vorbis.cpp:79
Utility templates and functions.
std::queue< Common::SeekableReadStream * > _queue
Definition: vorbis.cpp:287
uint16 readUint16BE()
Read an unsigned 16-bit word stored in big endian (MSB first) order from the stream and return it...
Definition: readstream.h:155
int getRate() const
Sample rate of the stream.
Definition: vorbis.cpp:267
An AudioStream designed to work in terms of packets.
Definition: audiostream.h:271
bool rewind()
Rewinds the stream to its start.
Definition: vorbis.cpp:195
size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
Definition: vorbis.cpp:431
virtual size_t read(void *dataPtr, size_t dataSize)=0
Read data from the stream.
RewindableAudioStream * makeVorbisStream(Common::SeekableReadStream *stream, bool disposeAfterUse)
Create a new RewindableAudioStream from the Ogg Vorbis data in the given stream.
Definition: vorbis.cpp:516
void queuePacket(Common::SeekableReadStream *packet)
Queue the next packet to be decoded.
Definition: vorbis.cpp:500
void warning(const char *s,...)
Definition: util.cpp:33
virtual size_t size() const =0
Obtains the total size of the stream, measured in bytes.
Basic reading stream interfaces.
virtual size_t pos() const =0
Obtains the current value of the stream position indicator of the stream.
VorbisStream(Common::SeekableReadStream *inStream, bool dispose)
Definition: vorbis.cpp:148
Convenience class that locks a mutex on creation and unlocks it on destruction.
Definition: mutex.h:71
Seek from the current position of the stream.
Definition: readstream.h:270
Thread mutex classes.
Common::DisposablePtr< Common::SeekableReadStream > _inStream
Definition: vorbis.cpp:117
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
A smart pointer with a deletion flag.
OggVorbis_File _ovFile
Definition: vorbis.cpp:122
Decoding Ogg Vorbis.
uint32_t uint32
Definition: types.h:204
bool parseExtraData(Common::SeekableReadStream &stream)
Definition: vorbis.cpp:317
bool endOfData() const
End of data reached? If this returns true, it means that at this time there is no data available in t...
Definition: vorbis.cpp:490
size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
Definition: vorbis.cpp:177
void finish()
Mark this stream as finished.
Definition: vorbis.cpp:506
int getChannels() const
Return the number channels in this stream.
Definition: vorbis.cpp:266
bool endOfStream() const
End of stream reached? If this returns true, it means that all data in this stream is used up and no ...
Definition: vorbis.cpp:495
bool endOfData() const
End of data reached? If this returns true, it means that at this time there is no data available in t...
Definition: vorbis.cpp:137
Seek from the begin of the stream.
Definition: readstream.h:269
Interface for a seekable & readable data stream.
Definition: readstream.h:265
Streaming audio.
byte readByte()
Read an unsigned byte from the stream and return it.
Definition: readstream.h:92
uint8 byte
Definition: types.h:209