xoreos  0.0.5
mp3.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 
53 #include <mad.h>
54 
55 #include "src/common/scopedptr.h"
57 #include "src/common/util.h"
58 #include "src/common/readstream.h"
59 
60 #include "src/sound/audiostream.h"
61 
62 #include "src/sound/decoders/mp3.h"
63 
64 namespace Sound {
65 
66 static const mad_timer_t timer_zero = {0, 0};
67 
69 protected:
70  enum State {
71  MP3_STATE_INIT, // Need to init the decoder
72  MP3_STATE_READY, // ready for processing data
73  MP3_STATE_EOS // end of data reached (may need to loop)
74  };
75 
77 
78  size_t _posInFrame;
80 
81  mad_timer_t _totalTime;
82 
83  mad_stream _stream;
84  mad_frame _frame;
85  mad_synth _synth;
86 
89 
91  int _channels;
92 
93  enum {
94  BUFFER_SIZE = 5 * 8192
95  };
96 
97  // This buffer contains a slab of input data
98  byte _buf[BUFFER_SIZE + MAD_BUFFER_GUARD];
99 
100 public:
102  bool dispose);
103  ~MP3Stream();
104 
105  size_t readBuffer(int16 *buffer, const size_t numSamples);
106 
107  bool endOfData() const { return _state == MP3_STATE_EOS; }
108  int getChannels() const { return _channels; }
109  int getRate() const { return _sampleRate; }
110  uint64 getLength() const { return _length; }
111 
112  bool rewind();
113 
114 protected:
115  void decodeMP3Data();
116  void readMP3Data();
117 
118  void initStream();
119  void readHeader();
120  void deinitStream();
121 };
122 
124  _inStream(inStream, dispose),
125  _posInFrame(0),
126  _state(MP3_STATE_INIT),
127  _totalTime(timer_zero),
128  _length(kInvalidLength),
129  _samples(0) {
130 
131  // The MAD_BUFFER_GUARD must always contain zeros (the reason
132  // for this is that the Layer III Huffman decoder of libMAD
133  // may read a few bytes beyond the end of the input buffer).
134  std::memset(_buf + BUFFER_SIZE, 0, MAD_BUFFER_GUARD);
135 
136  // Calculate the length of the stream
137  initStream();
138 
139  while (_state != MP3_STATE_EOS)
140  readHeader();
141 
142  _length = _samples;
143 
144  deinitStream();
145 
146  // Reinit stream
148 
149  // Decode the first chunk of data. This is necessary so that _frame is
150  // set up, and the number of channels and the sample rate can be queried.
151  decodeMP3Data();
152 
153  _sampleRate = _frame.header.samplerate;
154  _channels = MAD_NCHANNELS(&_frame.header);
155 }
156 
158  deinitStream();
159 }
160 
162  do {
163  if (_state == MP3_STATE_INIT)
164  initStream();
165 
166  if (_state == MP3_STATE_EOS)
167  return;
168 
169  // If necessary, load more data into the stream decoder
170  if (_stream.error == MAD_ERROR_BUFLEN)
171  readMP3Data();
172 
173  while (_state == MP3_STATE_READY) {
174  _stream.error = MAD_ERROR_NONE;
175 
176  // Decode the next frame
177  if (mad_frame_decode(&_frame, &_stream) == -1) {
178  if (_stream.error == MAD_ERROR_BUFLEN) {
179  break; // Read more data
180  } else if (MAD_RECOVERABLE(_stream.error)) {
181  // Note: we will occasionally see MAD_ERROR_BADDATAPTR errors here.
182  // These are normal and expected (caused by our frame skipping (i.e. "seeking")
183  // code above).
184  // status("MP3Stream: Recoverable error in mad_frame_decode (%s)", mad_stream_errorstr(&_stream));
185  continue;
186  } else {
187  warning("MP3Stream: Unrecoverable error in mad_frame_decode (%s)", mad_stream_errorstr(&_stream));
188  break;
189  }
190  }
191 
192  // Synthesize PCM data
193  mad_synth_frame(&_synth, &_frame);
194  _posInFrame = 0;
195  break;
196  }
197  } while (_state != MP3_STATE_EOS && _stream.error == MAD_ERROR_BUFLEN);
198 
199  if (_stream.error != MAD_ERROR_NONE)
201 }
202 
204  size_t remaining = 0;
205 
206  // Give up immediately if we already used up all data in the stream
207  if (_inStream->eos()) {
209  return;
210  }
211 
212  if (_stream.next_frame) {
213  // If there is still data in the MAD stream, we need to preserve it.
214  // Note that we use memmove, as we are reusing the same buffer,
215  // and hence the data regions we copy from and to may overlap.
216  remaining = _stream.bufend - _stream.next_frame;
217  assert(remaining < BUFFER_SIZE); // Paranoia check
218  memmove(_buf, _stream.next_frame, remaining);
219  }
220 
221  // Try to read the next block
222  size_t size = _inStream->read(_buf + remaining, BUFFER_SIZE - remaining);
223  if (size <= 0) {
225  return;
226  }
227 
228  // Feed the data we just read into the stream decoder
229  _stream.error = MAD_ERROR_NONE;
230  mad_stream_buffer(&_stream, _buf, size + remaining);
231 }
232 
234  mad_timer_t destination;
235  mad_timer_set(&destination, 0, 0, 1000);
236 
237  if (_state != MP3_STATE_READY || mad_timer_compare(destination, _totalTime) < 0)
238  initStream();
239 
240  while (mad_timer_compare(destination, _totalTime) > 0 && _state != MP3_STATE_EOS)
241  readHeader();
242 
243  return (_state != MP3_STATE_EOS);
244 }
245 
247  if (_state != MP3_STATE_INIT)
248  deinitStream();
249 
250  // Init MAD
251  mad_stream_init(&_stream);
252  mad_frame_init(&_frame);
253  mad_synth_init(&_synth);
254 
255  // Reset the stream data
256  _inStream->seek(0);
258  _samples = 0;
259  _posInFrame = 0;
260 
261  // Update state
263 
264  // Read the first few sample bytes
265  readMP3Data();
266 }
267 
269  if (_state != MP3_STATE_READY)
270  return;
271 
272  // If necessary, load more data into the stream decoder
273  if (_stream.error == MAD_ERROR_BUFLEN)
274  readMP3Data();
275 
276  while (_state != MP3_STATE_EOS) {
277  _stream.error = MAD_ERROR_NONE;
278 
279  // Decode the next header. Note: mad_frame_decode would do this for us, too.
280  // However, for seeking we don't want to decode the full frame (else it would
281  // be far too slow). Hence we perform this explicitly in a separate step.
282  if (mad_header_decode(&_frame.header, &_stream) == -1) {
283  if (_stream.error == MAD_ERROR_BUFLEN) {
284  readMP3Data(); // Read more data
285  continue;
286  } else if (MAD_RECOVERABLE(_stream.error)) {
287  //status("MP3Stream: Recoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
288  continue;
289  } else {
290  warning("MP3Stream: Unrecoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
291  break;
292  }
293  }
294 
295  // Sum up the total playback time so far
296  mad_timer_add(&_totalTime, _frame.header.duration);
297  _samples += 32 * MAD_NSBSAMPLES(&_frame.header);
298  break;
299  }
300 
301  if (_stream.error != MAD_ERROR_NONE)
303 }
304 
306  if (_state == MP3_STATE_INIT)
307  return;
308 
309  // Deinit MAD
310  mad_synth_finish(&_synth);
311  mad_frame_finish(&_frame);
312  mad_stream_finish(&_stream);
313 
315 }
316 
317 static inline int scale_sample(mad_fixed_t sample) {
318  // round
319  sample += (1L << (MAD_F_FRACBITS - 16));
320 
321  // clip
322  if (sample > MAD_F_ONE - 1)
323  sample = MAD_F_ONE - 1;
324  else if (sample < -MAD_F_ONE)
325  sample = -MAD_F_ONE;
326 
327  // quantize and scale to not saturate when mixing a lot of channels
328  return sample >> (MAD_F_FRACBITS + 1 - 16);
329 }
330 
331 size_t MP3Stream::readBuffer(int16 *buffer, const size_t numSamples) {
332  size_t samples = 0;
333  // Keep going as long as we have input available
334  while (samples < numSamples && _state != MP3_STATE_EOS) {
335  const size_t len = MIN<size_t>(numSamples, samples + (int)(_synth.pcm.length - _posInFrame) * MAD_NCHANNELS(&_frame.header));
336  while (samples < len) {
337  *buffer++ = (int16)scale_sample(_synth.pcm.samples[0][_posInFrame]);
338  samples++;
339  if (MAD_NCHANNELS(&_frame.header) == 2) {
340  *buffer++ = (int16)scale_sample(_synth.pcm.samples[1][_posInFrame]);
341  samples++;
342  }
343  _posInFrame++;
344  }
345  if (_posInFrame >= _synth.pcm.length) {
346  // We used up all PCM data in the current frame -- read & decode more
347  decodeMP3Data();
348  }
349  }
350  return samples;
351 }
352 
354  Common::ScopedPtr<RewindableAudioStream> s(new MP3Stream(stream, disposeAfterUse));
355  if (s && s->endOfData())
356  return 0;
357 
358  return s.release();
359 }
360 
361 } // End of namespace Sound
mad_frame _frame
Definition: mp3.cpp:84
void readMP3Data()
Definition: mp3.cpp:203
void initStream()
Definition: mp3.cpp:246
Common::DisposablePtr< Common::SeekableReadStream > _inStream
Definition: mp3.cpp:76
uint64 getLength() const
Estimate the total number of samples per channel in this stream.
Definition: mp3.cpp:110
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
Definition: scopedptr.h:103
uint64_t uint64
Definition: types.h:206
int _channels
Definition: mp3.cpp:91
static const mad_timer_t timer_zero
Definition: mp3.cpp:66
int16_t int16
Definition: types.h:201
int getChannels() const
Return the number channels in this stream.
Definition: mp3.cpp:108
A simple scoped smart pointer template.
uint64 _samples
Definition: mp3.cpp:88
Definition: game.h:37
size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
Definition: mp3.cpp:331
A rewindable audio stream.
Definition: audiostream.h:125
Utility templates and functions.
bool rewind()
Rewinds the stream to its start.
Definition: mp3.cpp:233
mad_synth _synth
Definition: mp3.cpp:85
State _state
Definition: mp3.cpp:79
static int scale_sample(mad_fixed_t sample)
Definition: mp3.cpp:317
void deinitStream()
Definition: mp3.cpp:305
A scoped plain pointer, allowing pointer-y access and normal deletion.
Definition: scopedptr.h:120
size_t _posInFrame
Definition: mp3.cpp:78
void warning(const char *s,...)
Definition: util.cpp:33
Basic reading stream interfaces.
int getRate() const
Sample rate of the stream.
Definition: mp3.cpp:109
mad_timer_t _totalTime
Definition: mp3.cpp:81
A smart pointer with a deletion flag.
void decodeMP3Data()
Definition: mp3.cpp:161
byte _buf[BUFFER_SIZE+MAD_BUFFER_GUARD]
Definition: mp3.cpp:98
uint64 _length
Definition: mp3.cpp:87
MP3Stream(Common::SeekableReadStream *inStream, bool dispose)
Definition: mp3.cpp:123
int _sampleRate
Definition: mp3.cpp:90
mad_stream _stream
Definition: mp3.cpp:83
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: mp3.cpp:107
Decoding MP3 (MPEG-1 Audio Layer 3).
RewindableAudioStream * makeMP3Stream(Common::SeekableReadStream *stream, bool disposeAfterUse)
Create a new SeekableAudioStream from the MP3 data in the given stream.
Definition: mp3.cpp:353
void readHeader()
Definition: mp3.cpp:268
Interface for a seekable & readable data stream.
Definition: readstream.h:265
Streaming audio.
uint8 byte
Definition: types.h:209