~ubuntu-branches/ubuntu/raring/scummvm/raring

« back to all changes in this revision

Viewing changes to sound/decoders/mp3.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Moritz Muehlenhoff
  • Date: 2011-05-25 19:02:23 UTC
  • mto: (21.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20110525190223-fiqm0oaec714xk31
Tags: upstream-1.3.0
ImportĀ upstreamĀ versionĀ 1.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ScummVM - Graphic Adventure Engine
2
 
 *
3
 
 * ScummVM is the legal property of its developers, whose names
4
 
 * are too numerous to list here. Please refer to the COPYRIGHT
5
 
 * file distributed with this source distribution.
6
 
 *
7
 
 * This program 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 2
10
 
 * of the License, or (at your option) any later version.
11
 
 
12
 
 * This program 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 this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
 
 *
21
 
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-2-1/sound/decoders/mp3.cpp $
22
 
 * $Id: mp3.cpp 52272 2010-08-22 12:04:44Z lordhoto $
23
 
 *
24
 
 */
25
 
 
26
 
#include "sound/decoders/mp3.h"
27
 
 
28
 
#ifdef USE_MAD
29
 
 
30
 
#include "common/debug.h"
31
 
#include "common/stream.h"
32
 
#include "common/util.h"
33
 
 
34
 
#include "sound/audiocd.h"
35
 
#include "sound/audiostream.h"
36
 
 
37
 
#include <mad.h>
38
 
 
39
 
#if defined(__PSP__)
40
 
        #include "backends/platform/psp/mp3.h"
41
 
#endif
42
 
namespace Audio {
43
 
 
44
 
 
45
 
#pragma mark -
46
 
#pragma mark --- MP3 (MAD) stream ---
47
 
#pragma mark -
48
 
 
49
 
 
50
 
class MP3Stream : public SeekableAudioStream {
51
 
protected:
52
 
        enum State {
53
 
                MP3_STATE_INIT, // Need to init the decoder
54
 
                MP3_STATE_READY,        // ready for processing data
55
 
                MP3_STATE_EOS           // end of data reached (may need to loop)
56
 
        };
57
 
 
58
 
        Common::SeekableReadStream *_inStream;
59
 
        DisposeAfterUse::Flag _disposeAfterUse;
60
 
 
61
 
        uint _posInFrame;
62
 
        State _state;
63
 
 
64
 
        Timestamp _length;
65
 
        mad_timer_t _totalTime;
66
 
 
67
 
        mad_stream _stream;
68
 
        mad_frame _frame;
69
 
        mad_synth _synth;
70
 
 
71
 
        enum {
72
 
                BUFFER_SIZE = 5 * 8192
73
 
        };
74
 
 
75
 
        // This buffer contains a slab of input data
76
 
        byte _buf[BUFFER_SIZE + MAD_BUFFER_GUARD];
77
 
 
78
 
public:
79
 
        MP3Stream(Common::SeekableReadStream *inStream,
80
 
                       DisposeAfterUse::Flag dispose);
81
 
        ~MP3Stream();
82
 
 
83
 
        int readBuffer(int16 *buffer, const int numSamples);
84
 
 
85
 
        bool endOfData() const          { return _state == MP3_STATE_EOS; }
86
 
        bool isStereo() const           { return MAD_NCHANNELS(&_frame.header) == 2; }
87
 
        int getRate() const                     { return _frame.header.samplerate; }
88
 
 
89
 
        bool seek(const Timestamp &where);
90
 
        Timestamp getLength() const { return _length; }
91
 
protected:
92
 
        void decodeMP3Data();
93
 
        void readMP3Data();
94
 
 
95
 
        void initStream();
96
 
        void readHeader();
97
 
        void deinitStream();
98
 
};
99
 
 
100
 
MP3Stream::MP3Stream(Common::SeekableReadStream *inStream, DisposeAfterUse::Flag dispose) :
101
 
        _inStream(inStream),
102
 
        _disposeAfterUse(dispose),
103
 
        _posInFrame(0),
104
 
        _state(MP3_STATE_INIT),
105
 
        _length(0, 1000),
106
 
        _totalTime(mad_timer_zero) {
107
 
 
108
 
        // The MAD_BUFFER_GUARD must always contain zeros (the reason
109
 
        // for this is that the Layer III Huffman decoder of libMAD
110
 
        // may read a few bytes beyond the end of the input buffer).
111
 
        memset(_buf + BUFFER_SIZE, 0, MAD_BUFFER_GUARD);
112
 
 
113
 
        // Calculate the length of the stream
114
 
        initStream();
115
 
 
116
 
        while (_state != MP3_STATE_EOS)
117
 
                readHeader();
118
 
 
119
 
        // To rule out any invalid sample rate to be encountered here, say in case the
120
 
        // MP3 stream is invalid, we just check the MAD error code here.
121
 
        // We need to assure this, since else we might trigger an assertion in Timestamp
122
 
        // (When getRate() returns 0 or a negative number to be precise).
123
 
        // Note that we allow "MAD_ERROR_BUFLEN" as error code here, since according
124
 
        // to mad.h it is also set on EOF.
125
 
        if ((_stream.error == MAD_ERROR_NONE || _stream.error == MAD_ERROR_BUFLEN) && getRate() > 0)
126
 
                _length = Timestamp(mad_timer_count(_totalTime, MAD_UNITS_MILLISECONDS), getRate());
127
 
 
128
 
        deinitStream();
129
 
 
130
 
        // Reinit stream
131
 
        _state = MP3_STATE_INIT;
132
 
 
133
 
        // Decode the first chunk of data. This is necessary so that _frame
134
 
        // is setup and isStereo() and getRate() return correct results.
135
 
        decodeMP3Data();
136
 
}
137
 
 
138
 
MP3Stream::~MP3Stream() {
139
 
        deinitStream();
140
 
 
141
 
        if (_disposeAfterUse == DisposeAfterUse::YES)
142
 
                delete _inStream;
143
 
}
144
 
 
145
 
void MP3Stream::decodeMP3Data() {
146
 
        do {
147
 
                if (_state == MP3_STATE_INIT)
148
 
                        initStream();
149
 
 
150
 
                if (_state == MP3_STATE_EOS)
151
 
                        return;
152
 
 
153
 
                // If necessary, load more data into the stream decoder
154
 
                if (_stream.error == MAD_ERROR_BUFLEN)
155
 
                        readMP3Data();
156
 
 
157
 
                while (_state == MP3_STATE_READY) {
158
 
                        _stream.error = MAD_ERROR_NONE;
159
 
 
160
 
                        // Decode the next frame
161
 
                        if (mad_frame_decode(&_frame, &_stream) == -1) {
162
 
                                if (_stream.error == MAD_ERROR_BUFLEN) {
163
 
                                        break; // Read more data
164
 
                                } else if (MAD_RECOVERABLE(_stream.error)) {
165
 
                                        // Note: we will occasionally see MAD_ERROR_BADDATAPTR errors here.
166
 
                                        // These are normal and expected (caused by our frame skipping (i.e. "seeking")
167
 
                                        // code above).
168
 
                                        debug(6, "MP3Stream: Recoverable error in mad_frame_decode (%s)", mad_stream_errorstr(&_stream));
169
 
                                        continue;
170
 
                                } else {
171
 
                                        warning("MP3Stream: Unrecoverable error in mad_frame_decode (%s)", mad_stream_errorstr(&_stream));
172
 
                                        break;
173
 
                                }
174
 
                        }
175
 
 
176
 
                        // Synthesize PCM data
177
 
                        mad_synth_frame(&_synth, &_frame);
178
 
                        _posInFrame = 0;
179
 
                        break;
180
 
                }
181
 
        } while (_state != MP3_STATE_EOS && _stream.error == MAD_ERROR_BUFLEN);
182
 
 
183
 
        if (_stream.error != MAD_ERROR_NONE)
184
 
                _state = MP3_STATE_EOS;
185
 
}
186
 
 
187
 
void MP3Stream::readMP3Data() {
188
 
        uint32 remaining = 0;
189
 
 
190
 
        // Give up immediately if we already used up all data in the stream
191
 
        if (_inStream->eos()) {
192
 
                _state = MP3_STATE_EOS;
193
 
                return;
194
 
        }
195
 
 
196
 
        if (_stream.next_frame) {
197
 
                // If there is still data in the MAD stream, we need to preserve it.
198
 
                // Note that we use memmove, as we are reusing the same buffer,
199
 
                // and hence the data regions we copy from and to may overlap.
200
 
                remaining = _stream.bufend - _stream.next_frame;
201
 
                assert(remaining < BUFFER_SIZE);        // Paranoia check
202
 
                memmove(_buf, _stream.next_frame, remaining);
203
 
        }
204
 
 
205
 
        // Try to read the next block
206
 
        uint32 size = _inStream->read(_buf + remaining, BUFFER_SIZE - remaining);
207
 
        if (size <= 0) {
208
 
                _state = MP3_STATE_EOS;
209
 
                return;
210
 
        }
211
 
 
212
 
        // Feed the data we just read into the stream decoder
213
 
        _stream.error = MAD_ERROR_NONE;
214
 
        mad_stream_buffer(&_stream, _buf, size + remaining);
215
 
}
216
 
 
217
 
bool MP3Stream::seek(const Timestamp &where) {
218
 
        if (where == _length) {
219
 
                _state = MP3_STATE_EOS;
220
 
                return true;
221
 
        } else if (where > _length) {
222
 
                return false;
223
 
        }
224
 
 
225
 
        const uint32 time = where.msecs();
226
 
 
227
 
        mad_timer_t destination;
228
 
        mad_timer_set(&destination, time / 1000, time % 1000, 1000);
229
 
 
230
 
        if (_state != MP3_STATE_READY || mad_timer_compare(destination, _totalTime) < 0)
231
 
                initStream();
232
 
 
233
 
        while (mad_timer_compare(destination, _totalTime) > 0 && _state != MP3_STATE_EOS)
234
 
                readHeader();
235
 
 
236
 
        decodeMP3Data();
237
 
 
238
 
        return (_state != MP3_STATE_EOS);
239
 
}
240
 
 
241
 
void MP3Stream::initStream() {
242
 
        if (_state != MP3_STATE_INIT)
243
 
                deinitStream();
244
 
 
245
 
        // Init MAD
246
 
        mad_stream_init(&_stream);
247
 
        mad_frame_init(&_frame);
248
 
        mad_synth_init(&_synth);
249
 
 
250
 
        // Reset the stream data
251
 
        _inStream->seek(0, SEEK_SET);
252
 
        _totalTime = mad_timer_zero;
253
 
        _posInFrame = 0;
254
 
 
255
 
        // Update state
256
 
        _state = MP3_STATE_READY;
257
 
 
258
 
        // Read the first few sample bytes
259
 
        readMP3Data();
260
 
}
261
 
 
262
 
void MP3Stream::readHeader() {
263
 
        if (_state != MP3_STATE_READY)
264
 
                return;
265
 
 
266
 
        // If necessary, load more data into the stream decoder
267
 
        if (_stream.error == MAD_ERROR_BUFLEN)
268
 
                readMP3Data();
269
 
 
270
 
        while (_state != MP3_STATE_EOS) {
271
 
                _stream.error = MAD_ERROR_NONE;
272
 
 
273
 
                // Decode the next header. Note: mad_frame_decode would do this for us, too.
274
 
                // However, for seeking we don't want to decode the full frame (else it would
275
 
                // be far too slow). Hence we perform this explicitly in a separate step.
276
 
                if (mad_header_decode(&_frame.header, &_stream) == -1) {
277
 
                        if (_stream.error == MAD_ERROR_BUFLEN) {
278
 
                                readMP3Data();  // Read more data
279
 
                                continue;
280
 
                        } else if (MAD_RECOVERABLE(_stream.error)) {
281
 
                                debug(6, "MP3Stream: Recoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
282
 
                                continue;
283
 
                        } else {
284
 
                                warning("MP3Stream: Unrecoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
285
 
                                break;
286
 
                        }
287
 
                }
288
 
 
289
 
                // Sum up the total playback time so far
290
 
                mad_timer_add(&_totalTime, _frame.header.duration);
291
 
                break;
292
 
        }
293
 
 
294
 
        if (_stream.error != MAD_ERROR_NONE)
295
 
                _state = MP3_STATE_EOS;
296
 
}
297
 
 
298
 
void MP3Stream::deinitStream() {
299
 
        if (_state == MP3_STATE_INIT)
300
 
                return;
301
 
 
302
 
        // Deinit MAD
303
 
        mad_synth_finish(&_synth);
304
 
        mad_frame_finish(&_frame);
305
 
        mad_stream_finish(&_stream);
306
 
 
307
 
        _state = MP3_STATE_EOS;
308
 
}
309
 
 
310
 
static inline int scale_sample(mad_fixed_t sample) {
311
 
        // round
312
 
        sample += (1L << (MAD_F_FRACBITS - 16));
313
 
 
314
 
        // clip
315
 
        if (sample > MAD_F_ONE - 1)
316
 
                sample = MAD_F_ONE - 1;
317
 
        else if (sample < -MAD_F_ONE)
318
 
                sample = -MAD_F_ONE;
319
 
 
320
 
        // quantize and scale to not saturate when mixing a lot of channels
321
 
        return sample >> (MAD_F_FRACBITS + 1 - 16);
322
 
}
323
 
 
324
 
int MP3Stream::readBuffer(int16 *buffer, const int numSamples) {
325
 
        int samples = 0;
326
 
        // Keep going as long as we have input available
327
 
        while (samples < numSamples && _state != MP3_STATE_EOS) {
328
 
                const int len = MIN(numSamples, samples + (int)(_synth.pcm.length - _posInFrame) * MAD_NCHANNELS(&_frame.header));
329
 
                while (samples < len) {
330
 
                        *buffer++ = (int16)scale_sample(_synth.pcm.samples[0][_posInFrame]);
331
 
                        samples++;
332
 
                        if (MAD_NCHANNELS(&_frame.header) == 2) {
333
 
                                *buffer++ = (int16)scale_sample(_synth.pcm.samples[1][_posInFrame]);
334
 
                                samples++;
335
 
                        }
336
 
                        _posInFrame++;
337
 
                }
338
 
                if (_posInFrame >= _synth.pcm.length) {
339
 
                        // We used up all PCM data in the current frame -- read & decode more
340
 
                        decodeMP3Data();
341
 
                }
342
 
        }
343
 
        return samples;
344
 
}
345
 
 
346
 
 
347
 
#pragma mark -
348
 
#pragma mark --- MP3 factory functions ---
349
 
#pragma mark -
350
 
 
351
 
SeekableAudioStream *makeMP3Stream(
352
 
        Common::SeekableReadStream *stream,
353
 
        DisposeAfterUse::Flag disposeAfterUse) {
354
 
 
355
 
#if defined(__PSP__)
356
 
        SeekableAudioStream *s = 0;
357
 
 
358
 
        if (Mp3PspStream::isOkToCreateStream())
359
 
                s = new Mp3PspStream(stream, disposeAfterUse);
360
 
 
361
 
        if (!s) // go to regular MAD mp3 stream if ME fails
362
 
                s = new MP3Stream(stream, disposeAfterUse);
363
 
#else
364
 
        SeekableAudioStream *s = new MP3Stream(stream, disposeAfterUse);
365
 
#endif
366
 
        if (s && s->endOfData()) {
367
 
                delete s;
368
 
                return 0;
369
 
        } else {
370
 
                return s;
371
 
        }
372
 
}
373
 
 
374
 
} // End of namespace Audio
375
 
 
376
 
#endif // #ifdef USE_MAD