ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

flac.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 // Disable symbol overrides for FILE as that is used in FLAC headers
00024 #define FORBIDDEN_SYMBOL_EXCEPTION_FILE
00025 
00026 #include "audio/decoders/flac.h"
00027 
00028 #ifdef USE_FLAC
00029 
00030 #include "common/debug.h"
00031 #include "common/stream.h"
00032 #include "common/textconsole.h"
00033 #include "common/util.h"
00034 
00035 #include "audio/audiostream.h"
00036 
00037 #define FLAC__NO_DLL // that MS-magic gave me headaches - just link the library you like
00038 #include <FLAC/export.h>
00039 
00040 
00041 // check if we have FLAC >= 1.1.3; LEGACY_FLAC code can be removed once FLAC-1.1.3 propagates everywhere
00042 #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT < 8
00043 #define LEGACY_FLAC
00044 #else
00045 #undef LEGACY_FLAC
00046 #endif
00047 
00048 
00049 #ifdef LEGACY_FLAC
00050 
00051 // Before FLAC 1.1.3, we needed to use the stream decoder API.
00052 #include <FLAC/seekable_stream_decoder.h>
00053 typedef uint FLAC_size_t;
00054 
00055 #else
00056 
00057 // With FLAC 1.1.3, the stream decoder API was merged into the regular
00058 // stream API. In order to stay compatible with older FLAC versions, we
00059 // simply add some typedefs and #ifdefs to map between the old and new API.
00060 // We use the typedefs (instead of only #defines) in order to somewhat
00061 // improve the readability of the code.
00062 
00063 #include <FLAC/stream_decoder.h>
00064 typedef size_t FLAC_size_t;
00065 // Add aliases for the old names
00066 typedef FLAC__StreamDecoderState FLAC__SeekableStreamDecoderState;
00067 typedef FLAC__StreamDecoderReadStatus FLAC__SeekableStreamDecoderReadStatus;
00068 typedef FLAC__StreamDecoderSeekStatus FLAC__SeekableStreamDecoderSeekStatus;
00069 typedef FLAC__StreamDecoderTellStatus FLAC__SeekableStreamDecoderTellStatus;
00070 typedef FLAC__StreamDecoderLengthStatus FLAC__SeekableStreamDecoderLengthStatus;
00071 typedef FLAC__StreamDecoder FLAC__SeekableStreamDecoder;
00072 
00073 #endif
00074 
00075 
00076 namespace Audio {
00077 
00078 #pragma mark -
00079 #pragma mark --- FLAC stream ---
00080 #pragma mark -
00081 
00082 static const uint MAX_OUTPUT_CHANNELS = 2;
00083 
00084 
00085 class FLACStream : public SeekableAudioStream {
00086 protected:
00087     Common::SeekableReadStream *_inStream;
00088     bool _disposeAfterUse;
00089 
00090     ::FLAC__SeekableStreamDecoder *_decoder;
00091 
00093     FLAC__StreamMetadata_StreamInfo _streaminfo;
00094 
00096     FLAC__uint64 _lastSample;
00097 
00099     Timestamp _length;
00100 
00102     bool _lastSampleWritten;
00103 
00104     typedef int16 SampleType;
00105     enum { BUFTYPE_BITS = 16 };
00106 
00107     enum {
00108         // Maximal buffer size. According to the FLAC format specification, the  block size is
00109         // a 16 bit value (in fact it seems the maximal block size is 32768, but we play it safe).
00110         BUFFER_SIZE = 65536
00111     };
00112 
00113     struct {
00114         SampleType bufData[BUFFER_SIZE];
00115         SampleType *bufReadPos;
00116         uint bufFill;
00117     } _sampleCache;
00118 
00119     SampleType *_outBuffer;
00120     uint _requestedSamples;
00121 
00122     typedef void (*PFCONVERTBUFFERS)(SampleType*, const FLAC__int32*[], uint, const uint, const uint8);
00123     PFCONVERTBUFFERS _methodConvertBuffers;
00124 
00125 
00126 public:
00127     FLACStream(Common::SeekableReadStream *inStream, bool dispose);
00128     virtual ~FLACStream();
00129 
00130     int readBuffer(int16 *buffer, const int numSamples);
00131 
00132     bool isStereo() const { return _streaminfo.channels >= 2; }
00133     int getRate() const { return _streaminfo.sample_rate; }
00134     bool endOfData() const {
00135         // End of data is reached if there either is no valid stream data available,
00136         // or if we reached the last sample and completely emptied the sample cache.
00137         return _streaminfo.channels == 0 || (_lastSampleWritten && _sampleCache.bufFill == 0);
00138     }
00139 
00140     bool seek(const Timestamp &where);
00141     Timestamp getLength() const { return _length; }
00142 
00143     bool isStreamDecoderReady() const { return getStreamDecoderState() == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; }
00144 protected:
00145     uint getChannels() const { return MIN<uint>(_streaminfo.channels, MAX_OUTPUT_CHANNELS); }
00146 
00147     bool allocateBuffer(uint minSamples);
00148 
00149     inline FLAC__StreamDecoderState getStreamDecoderState() const;
00150 
00151     inline bool processSingleBlock();
00152     inline bool processUntilEndOfMetadata();
00153     bool seekAbsolute(FLAC__uint64 sample);
00154 
00155     inline ::FLAC__SeekableStreamDecoderReadStatus callbackRead(FLAC__byte buffer[], FLAC_size_t *bytes);
00156     inline ::FLAC__SeekableStreamDecoderSeekStatus callbackSeek(FLAC__uint64 absoluteByteOffset);
00157     inline ::FLAC__SeekableStreamDecoderTellStatus callbackTell(FLAC__uint64 *absoluteByteOffset);
00158     inline ::FLAC__SeekableStreamDecoderLengthStatus callbackLength(FLAC__uint64 *streamLength);
00159     inline bool callbackEOF();
00160     inline ::FLAC__StreamDecoderWriteStatus callbackWrite(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
00161     inline void callbackMetadata(const ::FLAC__StreamMetadata *metadata);
00162     inline void callbackError(::FLAC__StreamDecoderErrorStatus status);
00163 
00164 private:
00165     static ::FLAC__SeekableStreamDecoderReadStatus callWrapRead(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], FLAC_size_t *bytes, void *clientData);
00166     static ::FLAC__SeekableStreamDecoderSeekStatus callWrapSeek(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absoluteByteOffset, void *clientData);
00167     static ::FLAC__SeekableStreamDecoderTellStatus callWrapTell(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absoluteByteOffset, void *clientData);
00168     static ::FLAC__SeekableStreamDecoderLengthStatus callWrapLength(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *streamLength, void *clientData);
00169     static FLAC__bool callWrapEOF(const ::FLAC__SeekableStreamDecoder *decoder, void *clientData);
00170     static ::FLAC__StreamDecoderWriteStatus callWrapWrite(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *clientData);
00171     static void callWrapMetadata(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *clientData);
00172     static void callWrapError(const ::FLAC__SeekableStreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *clientData);
00173 
00174     void setBestConvertBufferMethod();
00175     static void convertBuffersGeneric(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits);
00176     static void convertBuffersStereoNS(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits);
00177     static void convertBuffersStereo8Bit(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits);
00178     static void convertBuffersMonoNS(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits);
00179     static void convertBuffersMono8Bit(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits);
00180 };
00181 
00182 FLACStream::FLACStream(Common::SeekableReadStream *inStream, bool dispose)
00183 #ifdef LEGACY_FLAC
00184             :   _decoder(::FLAC__seekable_stream_decoder_new()),
00185 #else
00186             :   _decoder(::FLAC__stream_decoder_new()),
00187 #endif
00188         _inStream(inStream),
00189         _disposeAfterUse(dispose),
00190         _length(0, 1000), _lastSample(0),
00191         _outBuffer(NULL), _requestedSamples(0), _lastSampleWritten(false),
00192         _methodConvertBuffers(&FLACStream::convertBuffersGeneric)
00193 {
00194     assert(_inStream);
00195     memset(&_streaminfo, 0, sizeof(_streaminfo));
00196 
00197     _sampleCache.bufReadPos = NULL;
00198     _sampleCache.bufFill = 0;
00199 
00200     _methodConvertBuffers = &FLACStream::convertBuffersGeneric;
00201 
00202     bool success;
00203 #ifdef LEGACY_FLAC
00204     ::FLAC__seekable_stream_decoder_set_read_callback(_decoder, &FLACStream::callWrapRead);
00205     ::FLAC__seekable_stream_decoder_set_seek_callback(_decoder, &FLACStream::callWrapSeek);
00206     ::FLAC__seekable_stream_decoder_set_tell_callback(_decoder, &FLACStream::callWrapTell);
00207     ::FLAC__seekable_stream_decoder_set_length_callback(_decoder, &FLACStream::callWrapLength);
00208     ::FLAC__seekable_stream_decoder_set_eof_callback(_decoder, &FLACStream::callWrapEOF);
00209     ::FLAC__seekable_stream_decoder_set_write_callback(_decoder, &FLACStream::callWrapWrite);
00210     ::FLAC__seekable_stream_decoder_set_metadata_callback(_decoder, &FLACStream::callWrapMetadata);
00211     ::FLAC__seekable_stream_decoder_set_error_callback(_decoder, &FLACStream::callWrapError);
00212     ::FLAC__seekable_stream_decoder_set_client_data(_decoder, (void *)this);
00213 
00214     success = (::FLAC__seekable_stream_decoder_init(_decoder) == FLAC__SEEKABLE_STREAM_DECODER_OK);
00215 #else
00216     success = (::FLAC__stream_decoder_init_stream(
00217         _decoder,
00218         &FLACStream::callWrapRead,
00219         &FLACStream::callWrapSeek,
00220         &FLACStream::callWrapTell,
00221         &FLACStream::callWrapLength,
00222         &FLACStream::callWrapEOF,
00223         &FLACStream::callWrapWrite,
00224         &FLACStream::callWrapMetadata,
00225         &FLACStream::callWrapError,
00226         (void *)this
00227     ) == FLAC__STREAM_DECODER_INIT_STATUS_OK);
00228 #endif
00229     if (success) {
00230         if (processUntilEndOfMetadata() && _streaminfo.channels > 0) {
00231             _lastSample = _streaminfo.total_samples + 1;
00232             _length = Timestamp(0, _lastSample - 1, getRate());
00233             return; // no error occurred
00234         }
00235     }
00236 
00237     warning("FLACStream: could not create audio stream");
00238 }
00239 
00240 FLACStream::~FLACStream() {
00241     if (_decoder != NULL) {
00242 #ifdef LEGACY_FLAC
00243         (void) ::FLAC__seekable_stream_decoder_finish(_decoder);
00244         ::FLAC__seekable_stream_decoder_delete(_decoder);
00245 #else
00246         (void) ::FLAC__stream_decoder_finish(_decoder);
00247         ::FLAC__stream_decoder_delete(_decoder);
00248 #endif
00249     }
00250     if (_disposeAfterUse)
00251         delete _inStream;
00252 }
00253 
00254 inline FLAC__StreamDecoderState FLACStream::getStreamDecoderState() const {
00255     assert(_decoder != NULL);
00256 #ifdef LEGACY_FLAC
00257     return ::FLAC__seekable_stream_decoder_get_stream_decoder_state(_decoder);
00258 #else
00259     return ::FLAC__stream_decoder_get_state(_decoder);
00260 #endif
00261 }
00262 
00263 inline bool FLACStream::processSingleBlock() {
00264     assert(_decoder != NULL);
00265 #ifdef LEGACY_FLAC
00266     return 0 != ::FLAC__seekable_stream_decoder_process_single(_decoder);
00267 #else
00268     return 0 != ::FLAC__stream_decoder_process_single(_decoder);
00269 #endif
00270 }
00271 
00272 inline bool FLACStream::processUntilEndOfMetadata() {
00273     assert(_decoder != NULL);
00274 #ifdef LEGACY_FLAC
00275     return 0 != ::FLAC__seekable_stream_decoder_process_until_end_of_metadata(_decoder);
00276 #else
00277     return 0 != ::FLAC__stream_decoder_process_until_end_of_metadata(_decoder);
00278 #endif
00279 }
00280 
00281 bool FLACStream::seekAbsolute(FLAC__uint64 sample) {
00282     assert(_decoder != NULL);
00283 #ifdef LEGACY_FLAC
00284     const bool result = (0 != ::FLAC__seekable_stream_decoder_seek_absolute(_decoder, sample));
00285 #else
00286     const bool result = (0 != ::FLAC__stream_decoder_seek_absolute(_decoder, sample));
00287 #endif
00288     if (result) {
00289         _lastSampleWritten = (_lastSample != 0 && sample >= _lastSample); // only set if we are SURE
00290     }
00291     return result;
00292 }
00293 
00294 bool FLACStream::seek(const Timestamp &where) {
00295     _sampleCache.bufFill = 0;
00296     _sampleCache.bufReadPos = NULL;
00297     // FLAC uses the sample pair number, thus we always use "false" for the isStereo parameter
00298     // of the convertTimeToStreamPos helper.
00299     return seekAbsolute((FLAC__uint64)convertTimeToStreamPos(where, getRate(), false).totalNumberOfFrames());
00300 }
00301 
00302 int FLACStream::readBuffer(int16 *buffer, const int numSamples) {
00303     const uint numChannels = getChannels();
00304 
00305     if (numChannels == 0) {
00306         warning("FLACStream: Stream not successfully initialized, cant playback");
00307         return -1; // streaminfo wasnt read!
00308     }
00309 
00310     assert(numSamples % numChannels == 0); // must be multiple of channels!
00311     assert(buffer != NULL);
00312     assert(_outBuffer == NULL);
00313     assert(_requestedSamples == 0);
00314 
00315     _outBuffer = buffer;
00316     _requestedSamples = numSamples;
00317 
00318     // If there is still data in our buffer from the last time around,
00319     // copy that first.
00320     if (_sampleCache.bufFill > 0) {
00321         assert(_sampleCache.bufReadPos >= _sampleCache.bufData);
00322         assert(_sampleCache.bufFill % numChannels == 0);
00323 
00324         const uint copySamples = MIN((uint)numSamples, _sampleCache.bufFill);
00325         memcpy(buffer, _sampleCache.bufReadPos, copySamples*sizeof(buffer[0]));
00326 
00327         _outBuffer = buffer + copySamples;
00328         _requestedSamples = numSamples - copySamples;
00329         _sampleCache.bufReadPos += copySamples;
00330         _sampleCache.bufFill -= copySamples;
00331     }
00332 
00333     bool decoderOk = true;
00334 
00335     FLAC__StreamDecoderState state = getStreamDecoderState();
00336 
00337     // Keep poking FLAC to process more samples until we completely satisfied the request
00338     // respectively until we run out of data.
00339     while (!_lastSampleWritten && _requestedSamples > 0 && state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) {
00340         assert(_sampleCache.bufFill == 0);
00341         assert(_requestedSamples % numChannels == 0);
00342         processSingleBlock();
00343         state = getStreamDecoderState();
00344 
00345         if (state == FLAC__STREAM_DECODER_END_OF_STREAM)
00346             _lastSampleWritten = true;
00347     }
00348 
00349     // Error handling
00350     switch (state) {
00351     case FLAC__STREAM_DECODER_END_OF_STREAM:
00352         _lastSampleWritten = true;
00353         break;
00354     case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
00355         break;
00356     default:
00357         decoderOk = false;
00358         warning("FLACStream: An error occurred while decoding. DecoderState is: %s",
00359             FLAC__StreamDecoderStateString[getStreamDecoderState()]);
00360     }
00361 
00362     // Compute how many samples we actually produced
00363     const int samples = (int)(_outBuffer - buffer);
00364     assert(samples % numChannels == 0);
00365 
00366     _outBuffer = NULL; // basically unnecessary, only for the purpose of the asserts
00367     _requestedSamples = 0; // basically unnecessary, only for the purpose of the asserts
00368 
00369     return decoderOk ? samples : -1;
00370 }
00371 
00372 inline ::FLAC__SeekableStreamDecoderReadStatus FLACStream::callbackRead(FLAC__byte buffer[], FLAC_size_t *bytes) {
00373     if (*bytes == 0) {
00374 #ifdef LEGACY_FLAC
00375         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
00376 #else
00377         return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
00378 #endif
00379     }
00380 
00381     const uint32 bytesRead = _inStream->read(buffer, *bytes);
00382 
00383     if (bytesRead == 0) {
00384 #ifdef LEGACY_FLAC
00385         return _inStream->eos() ? FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK : FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
00386 #else
00387         return _inStream->eos() ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_ABORT;
00388 #endif
00389     }
00390 
00391     *bytes = static_cast<uint>(bytesRead);
00392 #ifdef LEGACY_FLAC
00393     return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
00394 #else
00395     return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
00396 #endif
00397 }
00398 
00399 void FLACStream::setBestConvertBufferMethod() {
00400     PFCONVERTBUFFERS tempMethod = &FLACStream::convertBuffersGeneric;
00401 
00402     const uint numChannels = getChannels();
00403     const uint8 numBits = (uint8)_streaminfo.bits_per_sample;
00404 
00405     assert(numChannels >= 1);
00406     assert(numBits >= 4 && numBits <=32);
00407 
00408     if (numChannels == 1) {
00409         if (numBits == 8)
00410             tempMethod = &FLACStream::convertBuffersMono8Bit;
00411         if (numBits == BUFTYPE_BITS)
00412             tempMethod = &FLACStream::convertBuffersMonoNS;
00413     } else if (numChannels == 2) {
00414         if (numBits == 8)
00415             tempMethod = &FLACStream::convertBuffersStereo8Bit;
00416         if (numBits == BUFTYPE_BITS)
00417             tempMethod = &FLACStream::convertBuffersStereoNS;
00418     } /* else ... */
00419 
00420     _methodConvertBuffers = tempMethod;
00421 }
00422 
00423 // 1 channel, no scaling
00424 void FLACStream::convertBuffersMonoNS(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits) {
00425     assert(numChannels == 1);
00426     assert(numBits == BUFTYPE_BITS);
00427 
00428     FLAC__int32 const* inChannel1 = inChannels[0];
00429 
00430     while (numSamples >= 4) {
00431         bufDestination[0] = static_cast<SampleType>(inChannel1[0]);
00432         bufDestination[1] = static_cast<SampleType>(inChannel1[1]);
00433         bufDestination[2] = static_cast<SampleType>(inChannel1[2]);
00434         bufDestination[3] = static_cast<SampleType>(inChannel1[3]);
00435         bufDestination += 4;
00436         inChannel1 += 4;
00437         numSamples -= 4;
00438     }
00439 
00440     for (; numSamples > 0; --numSamples) {
00441         *bufDestination++ = static_cast<SampleType>(*inChannel1++);
00442     }
00443 
00444     inChannels[0] = inChannel1;
00445     assert(numSamples == 0); // dint copy too many samples
00446 }
00447 
00448 // 1 channel, scaling from 8Bit
00449 void FLACStream::convertBuffersMono8Bit(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits) {
00450     assert(numChannels == 1);
00451     assert(numBits == 8);
00452     assert(8 < BUFTYPE_BITS);
00453 
00454     FLAC__int32 const* inChannel1 = inChannels[0];
00455 
00456     while (numSamples >= 4) {
00457         bufDestination[0] = static_cast<SampleType>(inChannel1[0]) << (BUFTYPE_BITS - 8);
00458         bufDestination[1] = static_cast<SampleType>(inChannel1[1]) << (BUFTYPE_BITS - 8);
00459         bufDestination[2] = static_cast<SampleType>(inChannel1[2]) << (BUFTYPE_BITS - 8);
00460         bufDestination[3] = static_cast<SampleType>(inChannel1[3]) << (BUFTYPE_BITS - 8);
00461         bufDestination += 4;
00462         inChannel1 += 4;
00463         numSamples -= 4;
00464     }
00465 
00466     for (; numSamples > 0; --numSamples) {
00467         *bufDestination++ = static_cast<SampleType>(*inChannel1++) << (BUFTYPE_BITS - 8);
00468     }
00469 
00470     inChannels[0] = inChannel1;
00471     assert(numSamples == 0); // dint copy too many samples
00472 }
00473 
00474 // 2 channels, no scaling
00475 void FLACStream::convertBuffersStereoNS(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits) {
00476     assert(numChannels == 2);
00477     assert(numBits == BUFTYPE_BITS);
00478     assert(numSamples % 2 == 0); // must be integral multiply of channels
00479 
00480 
00481     FLAC__int32 const* inChannel1 = inChannels[0];  // Left Channel
00482     FLAC__int32 const* inChannel2 = inChannels[1];  // Right Channel
00483 
00484     while (numSamples >= 2*2) {
00485         bufDestination[0] = static_cast<SampleType>(inChannel1[0]);
00486         bufDestination[1] = static_cast<SampleType>(inChannel2[0]);
00487         bufDestination[2] = static_cast<SampleType>(inChannel1[1]);
00488         bufDestination[3] = static_cast<SampleType>(inChannel2[1]);
00489         bufDestination += 2 * 2;
00490         inChannel1 += 2;
00491         inChannel2 += 2;
00492         numSamples -= 2 * 2;
00493     }
00494 
00495     while (numSamples > 0) {
00496         bufDestination[0] = static_cast<SampleType>(*inChannel1++);
00497         bufDestination[1] = static_cast<SampleType>(*inChannel2++);
00498         bufDestination += 2;
00499         numSamples -= 2;
00500     }
00501 
00502     inChannels[0] = inChannel1;
00503     inChannels[1] = inChannel2;
00504     assert(numSamples == 0); // dint copy too many samples
00505 }
00506 
00507 // 2 channels, scaling from 8Bit
00508 void FLACStream::convertBuffersStereo8Bit(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits) {
00509     assert(numChannels == 2);
00510     assert(numBits == 8);
00511     assert(numSamples % 2 == 0); // must be integral multiply of channels
00512     assert(8 < BUFTYPE_BITS);
00513 
00514     FLAC__int32 const* inChannel1 = inChannels[0];  // Left Channel
00515     FLAC__int32 const* inChannel2 = inChannels[1];  // Right Channel
00516 
00517     while (numSamples >= 2*2) {
00518         bufDestination[0] = static_cast<SampleType>(inChannel1[0]) << (BUFTYPE_BITS - 8);
00519         bufDestination[1] = static_cast<SampleType>(inChannel2[0]) << (BUFTYPE_BITS - 8);
00520         bufDestination[2] = static_cast<SampleType>(inChannel1[1]) << (BUFTYPE_BITS - 8);
00521         bufDestination[3] = static_cast<SampleType>(inChannel2[1]) << (BUFTYPE_BITS - 8);
00522         bufDestination += 2 * 2;
00523         inChannel1 += 2;
00524         inChannel2 += 2;
00525         numSamples -= 2 * 2;
00526     }
00527 
00528     while (numSamples > 0) {
00529         bufDestination[0] = static_cast<SampleType>(*inChannel1++) << (BUFTYPE_BITS - 8);
00530         bufDestination[1] = static_cast<SampleType>(*inChannel2++) << (BUFTYPE_BITS - 8);
00531         bufDestination += 2;
00532         numSamples -= 2;
00533     }
00534 
00535     inChannels[0] = inChannel1;
00536     inChannels[1] = inChannel2;
00537     assert(numSamples == 0); // dint copy too many samples
00538 }
00539 
00540 // all Purpose-conversion - slowest of em all
00541 void FLACStream::convertBuffersGeneric(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits) {
00542     assert(numSamples % numChannels == 0); // must be integral multiply of channels
00543 
00544     if (numBits < BUFTYPE_BITS) {
00545         const uint8 kPower = (uint8)(BUFTYPE_BITS - numBits);
00546 
00547         for (; numSamples > 0; numSamples -= numChannels) {
00548             for (uint i = 0; i < numChannels; ++i)
00549                 *bufDestination++ = static_cast<SampleType>(*(inChannels[i]++)) << kPower;
00550         }
00551     } else if (numBits > BUFTYPE_BITS) {
00552         const uint8 kPower = (uint8)(numBits - BUFTYPE_BITS);
00553 
00554         for (; numSamples > 0; numSamples -= numChannels) {
00555             for (uint i = 0; i < numChannels; ++i)
00556                 *bufDestination++ = static_cast<SampleType>(*(inChannels[i]++) >> kPower);
00557         }
00558     } else {
00559         for (; numSamples > 0; numSamples -= numChannels) {
00560             for (uint i = 0; i < numChannels; ++i)
00561                 *bufDestination++ = static_cast<SampleType>(*(inChannels[i]++));
00562         }
00563     }
00564 
00565     assert(numSamples == 0); // dint copy too many samples
00566 }
00567 
00568 inline ::FLAC__StreamDecoderWriteStatus FLACStream::callbackWrite(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) {
00569     assert(frame->header.channels == _streaminfo.channels);
00570     assert(frame->header.sample_rate == _streaminfo.sample_rate);
00571     assert(frame->header.bits_per_sample == _streaminfo.bits_per_sample);
00572     assert(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER || _streaminfo.min_blocksize == _streaminfo.max_blocksize);
00573 
00574     // We require that either the sample cache is empty, or that no samples were requested
00575     assert(_sampleCache.bufFill == 0 || _requestedSamples == 0);
00576 
00577     uint numSamples = frame->header.blocksize;
00578     const uint numChannels = getChannels();
00579     const uint8 numBits = (uint8)_streaminfo.bits_per_sample;
00580 
00581     assert(_requestedSamples % numChannels == 0); // must be integral multiply of channels
00582 
00583     const FLAC__uint64 firstSampleNumber = (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER) ?
00584         frame->header.number.sample_number : (static_cast<FLAC__uint64>(frame->header.number.frame_number)) * _streaminfo.max_blocksize;
00585 
00586     // Check whether we are about to reach beyond the last sample we are supposed to play.
00587     if (_lastSample != 0 && firstSampleNumber + numSamples >= _lastSample) {
00588         numSamples = (uint)(firstSampleNumber >= _lastSample ? 0 : _lastSample - firstSampleNumber);
00589         _lastSampleWritten = true;
00590     }
00591 
00592     // The value in _requestedSamples counts raw samples, so if there are more than one
00593     // channel, we have to multiply the number of available sample "pairs" by numChannels
00594     numSamples *= numChannels;
00595 
00596     const FLAC__int32 *inChannels[MAX_OUTPUT_CHANNELS];
00597     for (uint i = 0; i < numChannels; ++i)
00598         inChannels[i] = buffer[i];
00599 
00600     // write the incoming samples directly into the buffer provided to us by the mixer
00601     if (_requestedSamples > 0) {
00602         assert(_requestedSamples % numChannels == 0);
00603         assert(_outBuffer != NULL);
00604 
00605         // Copy & convert the available samples (limited both by how many we have available, and
00606         // by how many are actually needed).
00607         const uint copySamples = MIN(_requestedSamples, numSamples);
00608         (*_methodConvertBuffers)(_outBuffer, inChannels, copySamples, numChannels, numBits);
00609 
00610         _requestedSamples -= copySamples;
00611         numSamples -= copySamples;
00612         _outBuffer += copySamples;
00613     }
00614 
00615     // Write all remaining samples (i.e. those which didn't fit into the mixer buffer)
00616     // into the sample cache.
00617     if (_sampleCache.bufFill == 0)
00618         _sampleCache.bufReadPos = _sampleCache.bufData;
00619     const uint cacheSpace = (_sampleCache.bufData + BUFFER_SIZE) - (_sampleCache.bufReadPos + _sampleCache.bufFill);
00620     assert(numSamples <= cacheSpace);
00621     (*_methodConvertBuffers)(_sampleCache.bufReadPos + _sampleCache.bufFill, inChannels, numSamples, numChannels, numBits);
00622 
00623     _sampleCache.bufFill += numSamples;
00624 
00625     return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
00626 }
00627 
00628 inline ::FLAC__SeekableStreamDecoderSeekStatus FLACStream::callbackSeek(FLAC__uint64 absoluteByteOffset) {
00629     _inStream->seek(absoluteByteOffset, SEEK_SET);
00630     const bool result = (absoluteByteOffset == (FLAC__uint64)_inStream->pos());
00631 
00632 #ifdef LEGACY_FLAC
00633     return result ? FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK : FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
00634 #else
00635     return result ? FLAC__STREAM_DECODER_SEEK_STATUS_OK : FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
00636 #endif
00637 }
00638 
00639 inline ::FLAC__SeekableStreamDecoderTellStatus FLACStream::callbackTell(FLAC__uint64 *absoluteByteOffset) {
00640     *absoluteByteOffset = static_cast<FLAC__uint64>(_inStream->pos());
00641 #ifdef LEGACY_FLAC
00642     return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
00643 #else
00644     return FLAC__STREAM_DECODER_TELL_STATUS_OK;
00645 #endif
00646 }
00647 
00648 inline ::FLAC__SeekableStreamDecoderLengthStatus FLACStream::callbackLength(FLAC__uint64 *streamLength) {
00649     *streamLength = static_cast<FLAC__uint64>(_inStream->size());
00650 #ifdef LEGACY_FLAC
00651     return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
00652 #else
00653     return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
00654 #endif
00655 }
00656 
00657 inline bool FLACStream::callbackEOF() {
00658     return _inStream->eos();
00659 }
00660 
00661 
00662 inline void FLACStream::callbackMetadata(const ::FLAC__StreamMetadata *metadata) {
00663     assert(_decoder != NULL);
00664     assert(metadata->type == FLAC__METADATA_TYPE_STREAMINFO); // others arent really interesting
00665 
00666     _streaminfo = metadata->data.stream_info;
00667     setBestConvertBufferMethod(); // should be set after getting stream-information. FLAC always parses the info first
00668 }
00669 inline void FLACStream::callbackError(::FLAC__StreamDecoderErrorStatus status) {
00670     // some of these are non-critical-Errors
00671     debug(1, "FLACStream: An error occurred while decoding. DecoderState is: %s",
00672             FLAC__StreamDecoderErrorStatusString[status]);
00673 }
00674 
00675 /* Static Callback Wrappers */
00676 ::FLAC__SeekableStreamDecoderReadStatus FLACStream::callWrapRead(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], FLAC_size_t *bytes, void *clientData) {
00677     FLACStream *instance = (FLACStream *)clientData;
00678     assert(0 != instance);
00679     return instance->callbackRead(buffer, bytes);
00680 }
00681 
00682 ::FLAC__SeekableStreamDecoderSeekStatus FLACStream::callWrapSeek(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absoluteByteOffset, void *clientData) {
00683     FLACStream *instance = (FLACStream *)clientData;
00684     assert(0 != instance);
00685     return instance->callbackSeek(absoluteByteOffset);
00686 }
00687 
00688 ::FLAC__SeekableStreamDecoderTellStatus FLACStream::callWrapTell(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absoluteByteOffset, void *clientData) {
00689     FLACStream *instance = (FLACStream *)clientData;
00690     assert(0 != instance);
00691     return instance->callbackTell(absoluteByteOffset);
00692 }
00693 
00694 ::FLAC__SeekableStreamDecoderLengthStatus FLACStream::callWrapLength(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *streamLength, void *clientData) {
00695     FLACStream *instance = (FLACStream *)clientData;
00696     assert(0 != instance);
00697     return instance->callbackLength(streamLength);
00698 }
00699 
00700 FLAC__bool FLACStream::callWrapEOF(const ::FLAC__SeekableStreamDecoder *decoder, void *clientData) {
00701     FLACStream *instance = (FLACStream *)clientData;
00702     assert(0 != instance);
00703     return instance->callbackEOF();
00704 }
00705 
00706 ::FLAC__StreamDecoderWriteStatus FLACStream::callWrapWrite(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *clientData) {
00707     FLACStream *instance = (FLACStream *)clientData;
00708     assert(0 != instance);
00709     return instance->callbackWrite(frame, buffer);
00710 }
00711 
00712 void FLACStream::callWrapMetadata(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *clientData) {
00713     FLACStream *instance = (FLACStream *)clientData;
00714     assert(0 != instance);
00715     instance->callbackMetadata(metadata);
00716 }
00717 
00718 void FLACStream::callWrapError(const ::FLAC__SeekableStreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *clientData) {
00719     FLACStream *instance = (FLACStream *)clientData;
00720     assert(0 != instance);
00721     instance->callbackError(status);
00722 }
00723 
00724 
00725 #pragma mark -
00726 #pragma mark --- FLAC factory functions ---
00727 #pragma mark -
00728 
00729 SeekableAudioStream *makeFLACStream(
00730     Common::SeekableReadStream *stream,
00731     DisposeAfterUse::Flag disposeAfterUse) {
00732     SeekableAudioStream *s = new FLACStream(stream, disposeAfterUse);
00733     if (s && s->endOfData()) {
00734         delete s;
00735         return 0;
00736     } else {
00737         return s;
00738     }
00739 }
00740 
00741 } // End of namespace Audio
00742 
00743 #endif // #ifdef USE_FLAC


Generated on Sat Feb 16 2019 05:00:51 for ResidualVM by doxygen 1.7.1
curved edge   curved edge