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

aac.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 #include "audio/decoders/aac.h"
00024 
00025 #ifdef USE_FAAD
00026 
00027 #include "common/debug.h"
00028 #include "common/memstream.h"
00029 #include "common/stream.h"
00030 #include "common/textconsole.h"
00031 #include "common/util.h"
00032 
00033 #include "audio/audiostream.h"
00034 #include "audio/decoders/codec.h"
00035 #include "audio/decoders/raw.h"
00036 
00037 #include <neaacdec.h>
00038 
00039 namespace Audio {
00040 
00041 class AACDecoder : public Codec {
00042 public:
00043     AACDecoder(Common::SeekableReadStream *extraData,
00044               DisposeAfterUse::Flag disposeExtraData);
00045     ~AACDecoder();
00046 
00047     AudioStream *decodeFrame(Common::SeekableReadStream &stream);
00048 
00049 private:
00050     NeAACDecHandle _handle;
00051     byte _channels;
00052     unsigned long _rate;
00053 };
00054 
00055 AACDecoder::AACDecoder(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) {
00056     // Open the library
00057     _handle = NeAACDecOpen();
00058 
00059     // Configure the library to our needs
00060     NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(_handle);
00061     conf->outputFormat = FAAD_FMT_16BIT; // We only support 16bit audio
00062     conf->downMatrix = 1;                // Convert from 5.1 to stereo if required
00063     NeAACDecSetConfiguration(_handle, conf);
00064 
00065     // Copy the extra data to a buffer
00066     extraData->seek(0);
00067     byte *extraDataBuf = new byte[extraData->size()];
00068     extraData->read(extraDataBuf, extraData->size());
00069 
00070     // Initialize with our extra data
00071     // NOTE: This code assumes the extra data is coming from an MPEG-4 file!
00072     int err = NeAACDecInit2(_handle, extraDataBuf, extraData->size(), &_rate, &_channels);
00073     delete[] extraDataBuf;
00074 
00075     if (err < 0)
00076         error("Could not initialize AAC decoder: %s", NeAACDecGetErrorMessage(err));
00077 
00078     if (disposeExtraData == DisposeAfterUse::YES)
00079         delete extraData;
00080 }
00081 
00082 AACDecoder::~AACDecoder() {
00083     NeAACDecClose(_handle);
00084 }
00085 
00086 AudioStream *AACDecoder::decodeFrame(Common::SeekableReadStream &stream) {
00087     // read everything into a buffer
00088     uint32 inBufferPos = 0;
00089     uint32 inBufferSize = stream.size();
00090     byte *inBuffer = new byte[inBufferSize];
00091     stream.read(inBuffer, inBufferSize);
00092 
00093     QueuingAudioStream *audioStream = makeQueuingAudioStream(_rate, _channels == 2);
00094 
00095     // Decode until we have enough samples (or there's no more left)
00096     while (inBufferPos < inBufferSize) {
00097         NeAACDecFrameInfo frameInfo;
00098         void *decodedSamples = NeAACDecDecode(_handle, &frameInfo, inBuffer + inBufferPos, inBufferSize - inBufferPos);
00099 
00100         if (frameInfo.error != 0)
00101             error("Failed to decode AAC frame: %s", NeAACDecGetErrorMessage(frameInfo.error));
00102 
00103         byte *buffer = (byte *)malloc(frameInfo.samples * 2);
00104         memcpy(buffer, decodedSamples, frameInfo.samples * 2);
00105 
00106         byte flags = FLAG_16BITS;
00107 
00108         if (_channels == 2)
00109             flags |= FLAG_STEREO;
00110 
00111 #ifdef SCUMM_LITTLE_ENDIAN
00112         flags |= FLAG_LITTLE_ENDIAN;
00113 #endif
00114 
00115         audioStream->queueBuffer(buffer, frameInfo.samples * 2, DisposeAfterUse::YES, flags);
00116 
00117         inBufferPos += frameInfo.bytesconsumed;
00118     }
00119 
00120     audioStream->finish();
00121     return audioStream;
00122 }
00123 
00124 // Factory function
00125 Codec *makeAACDecoder(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) {
00126     return new AACDecoder(extraData, disposeExtraData);
00127 }
00128 
00129 } // End of namespace Audio
00130 
00131 #endif // #ifdef USE_FAAD


Generated on Sat Feb 23 2019 05:00:56 for ResidualVM by doxygen 1.7.1
curved edge   curved edge