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

iss.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
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 "engines/stark/formats/iss.h"
00024 
00025 #include "audio/decoders/adpcm_intern.h"
00026 #include "audio/decoders/raw.h"
00027 #include "common/substream.h"
00028 
00029 namespace Stark {
00030 namespace Formats {
00031 
00035 class ISSADPCMStream : public Audio::Ima_ADPCMStream {
00036 public:
00037     ISSADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
00038         : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {}
00039 
00040 protected:
00041     int readBuffer(int16 *buffer, const int numSamples) {
00042         // Similar to MS IMA, but without the four-bytes-per-channel requirement
00043         int samples;
00044 
00045         assert(numSamples % 2 == 0);
00046 
00047         for (samples = 0; samples < numSamples && !endOfData(); samples += 2) {
00048             if (_blockPos[0] == _blockAlign) {
00049                 // read block header
00050                 for (byte i = 0; i < _channels; i++) {
00051                     _status.ima_ch[i].last = _stream->readSint16LE();
00052                     _status.ima_ch[i].stepIndex = _stream->readSint16LE();
00053                 }
00054                 _blockPos[0] = 4 * _channels;
00055             }
00056 
00057             byte data = _stream->readByte();
00058             buffer[samples + (isStereo() ? 1 : 0)] = decodeIMA(data & 0x0f, isStereo() ? 1 : 0);
00059             buffer[samples + (isStereo() ? 0 : 1)] = decodeIMA((data >> 4) & 0x0f);
00060             _blockPos[0]++;
00061         }
00062 
00063         return samples;
00064     }
00065 };
00066 
00067 static Common::String readString(Common::SeekableReadStream *stream) {
00068     Common::String ret = "";
00069     byte ch;
00070     while ((ch = stream->readByte()) != 0x20)
00071         ret += ch;
00072 
00073     return ret;
00074 }
00075 
00076 Audio::RewindableAudioStream *makeISSStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
00077     Common::String codec;
00078     uint16 blockSize, channels, freq;
00079     uint32 size;
00080     byte flags;
00081 
00082     codec = readString(stream);
00083 
00084     if (codec.equals("IMA_ADPCM_Sound")) {
00085 
00086         codec = readString(stream);
00087         blockSize = (uint16)strtol(codec.c_str(), 0, 10);
00088 
00089         readString(stream);
00090         // name ?
00091 
00092         readString(stream);
00093         // ?
00094 
00095         codec = readString(stream);
00096         channels = (uint16)strtol(codec.c_str(), 0, 10) + 1;
00097 
00098         readString(stream);
00099         // ?
00100 
00101         codec = readString(stream);
00102         freq = 44100 / (uint16)strtol(codec.c_str(), 0, 10);
00103 
00104         readString(stream);
00105 
00106         readString(stream);
00107 
00108         codec = readString(stream);
00109         size = (uint32)strtol(codec.c_str(), 0, 10);
00110 
00111         return new ISSADPCMStream(stream, DisposeAfterUse::YES, size, freq, channels, blockSize);
00112     } else if (codec.equals("Sound")) {
00113 
00114         readString(stream);
00115         // name ?
00116 
00117         codec = readString(stream);
00118         // sample count ?
00119 
00120         codec = readString(stream);
00121         channels = (uint16)strtol(codec.c_str(), 0, 10) + 1;
00122 
00123         readString(stream);
00124         // ?
00125 
00126         codec = readString(stream);
00127         freq = 44100 / (uint16)strtol(codec.c_str(), 0, 10);
00128 
00129         readString(stream);
00130 
00131         readString(stream);
00132 
00133         flags = Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN;
00134         if (channels == 2)
00135             flags |= Audio::FLAG_STEREO;
00136         return Audio::makeRawStream(new Common::SeekableSubReadStream(stream, stream->pos(), stream->size(), DisposeAfterUse::YES), freq, flags, DisposeAfterUse::YES);
00137     } else {
00138         error("Unknown ISS codec '%s'", codec.c_str());
00139     }
00140 }
00141 
00142 } // End of namespace Formats
00143 } // End of namespace Stark


Generated on Sat Jun 15 2019 05:01:16 for ResidualVM by doxygen 1.7.1
curved edge   curved edge