Ticket #9358: compress_sci_raw_audio.patch

File compress_sci_raw_audio.patch, 7.0 KB (added by SF/agf863, 13 years ago)

Compress KQ5 & Jones in the Fast Lane raw audio files

  • engines/sci/compress_sci.cpp

    diff --git a/engines/sci/compress_sci.cpp b/engines/sci/compress_sci.cpp
    index 3d82b7e..ec30bb6 100644
    a b CompressSci::CompressSci(const std::string &name) : CompressionTool(name, TOOLTY  
    5858
    5959        _outputToDirectory = false;
    6060
    61         _shorthelp = "Used to compress Sierra resource.aud/resource.sfx files. (NOT SCI32 compatible!)";
     61        _shorthelp = "Used to compress Sierra resource.aud/.sfx and AUDIO001.002 files. (NOT SCI32 compatible!)";
    6262        _helptext = "\nUsage: " + getName() + " [mode-params] [-o outputname] <inputname>\n";
    6363}
    6464
    6565// header is first 6 bytes read from file
    6666SciResourceDataType CompressSci::detectData(byte *header, bool compressMode) {
    67         byte buffer[20];
    6867        uint32 dataSize;
     68        if (_rawAudio) {
     69                // File is a raw audio file
     70                dataSize = _rawAudioMap[_inputOffset];
     71                _inputEndOffset = _inputOffset + dataSize;
     72                return kSciResourceDataTypeRaw;
     73        }
     74        byte buffer[20];
    6975        memcpy(&buffer, header, 6);
    7076        if ((memcmp(buffer + 1, "RIFF", 4) == 0) || (memcmp(buffer + 1, "\x8d\x0bSOL", 4) == 0)) {
    7177                // Fixup for pharkas resource.sfx, several WAVE files contain a size thats not right (-1 byte)
    static void deDPCM8(byte *soundBuf, byte *inputBuf, uint32 n) {  
    220226void CompressSci::compressData(SciResourceDataType dataType) {
    221227        int orgDataSize = _inputEndOffset - _inputOffset;
    222228        int newDataSize = 0;
    223         byte *orgData = new byte[orgDataSize];
    224229        byte *newData = 0;
    225230
    226231        int sampleRate = 0;
    void CompressSci::compressData(SciResourceDataType dataType) {  
    230235        uint8 sampleBits = 8;
    231236        byte sampleFlags = 0;
    232237
    233         if (!orgData)
    234                 error("malloc error");
    235 
    236238        switch (dataType) {
    237239        case kSciResourceDataTypeWAVE:
    238240                print("WAVE found\n");
    void CompressSci::compressData(SciResourceDataType dataType) {  
    281283                }
    282284                break;
    283285        }
     286        case kSciResourceDataTypeRaw:
     287                sampleRate = 11025;
     288                // No headers so just use the original data as sample data
     289                sampleDataSize = orgDataSize;
     290                sampleData = new byte[sampleDataSize];
     291                if (!sampleData)
     292                        error("malloc error");
     293                _input.read_throwsOnError(sampleData, sampleDataSize);
     294                break;
    284295        case kSciResourceTypeTypeSync:
    285296                print("SYNC found at %lx\n", _inputOffset);
    286297                // Simply copy original data over
    287                 _input.read_throwsOnError(orgData, orgDataSize);
    288                 newData = orgData;
    289298                newDataSize = orgDataSize;
     299                newData = new byte[newDataSize];
     300                if (!newData)
     301                        error("malloc error");
     302                _input.read_throwsOnError(newData, newDataSize);
    290303                break;
    291304        default:
    292305                error("Unsupported datatype");
    void CompressSci::compressData(SciResourceDataType dataType) {  
    305318                Common::File tempfileEnc(TEMP_ENC, "rb");
    306319                newDataSize = tempfileEnc.size();
    307320                newData = new byte[newDataSize];
     321                if (!newData)
     322                        error("malloc error");
    308323                tempfileEnc.read_throwsOnError(newData, newDataSize);
    309324                tempfileEnc.close();
    310325        }
    311326
    312327        _output.write(newData, newDataSize);
     328        delete[] newData;
     329}
    313330
    314         if ((newData) && (newData != orgData))
    315                 delete[] newData;
    316         delete[] orgData;
     331uint CompressSci::parseRawAudioMap() {
     332        Common::Filename mapFileName = _inputPaths[0].path;
     333        // Assume the map is in the same dir as the resource file
     334        // and is called AUDIO001.MAP
     335        mapFileName.setFullName("AUDIO001.MAP");
     336        warning("Trying %s as resource map\n", mapFileName.getFullPath().data());
     337        Common::File mapFile;
     338        mapFile.open(mapFileName, "rb");
     339        // Ten byte entries, the last one is fake
     340        uint32 numEntries = (mapFile.size() / 10) - 1;
     341        uint32 offset = 0;
     342        uint32 size = 0;
     343        for (uint32 i = 0; i < numEntries; i++) {
     344                // shouldn't reach the fake entry but break if we do
     345                if (mapFile.readUint16LE() == 0xffff) break;
     346                // mask out the resource volume number
     347                offset = mapFile.readUint32LE() & 0x0fffffff;
     348                size = mapFile.readUint32LE();
     349                _rawAudioMap[offset] = size;
     350        }
     351        mapFile.close();
     352        return _rawAudioMap.size();
    317353}
    318354
    319355void CompressSci::execute() {
    void CompressSci::execute() {  
    325361        _inputSize = _input.size();
    326362
    327363        // First find out how many samples are in this file
    328         //  We only support SOL audio and WAVE
    329         //  We can't support games that use "raw" audio (would have to walk through audio map for those, which would
    330         //   complicate this code - all talkie games that use this (kq5) don't use much space anyway, so not supporting
    331         //   those isn't a big issue
    332364
     365        _rawAudio = false;
    333366        _input.seek(0, SEEK_SET);
    334367        byte header[6];
    335368
    void CompressSci::execute() {  
    343376                error("This resource file is already FLAC-compressed, aborting...\n");
    344377
    345378        int resourceCount = 0;
    346         do {
    347                 recognizedDataType = detectData(header, false);
    348                 if (!recognizedDataType)
    349                         error("Unsupported data at offset %lx", _inputOffset);
    350                 _input.seek(_inputEndOffset, SEEK_SET);
    351                 _inputOffset = _inputEndOffset;
    352                 resourceCount++;
    353                 // We abort even, if file position is one below size because of pharkas resource.sfx
    354                 if (_inputOffset >= _inputSize - 1)
    355                         break;
     379        if (_input.size() == 0x05C9B000 or _input.size() == 0x0160E000) {
     380                warning("Size matches KQ5 or Jones in the Fast Lane audio file, assuming raw audio\n");
     381                _rawAudio = true;
     382                resourceCount = parseRawAudioMap();
     383        } else {
     384                do {
     385                        recognizedDataType = detectData(header, false);
     386                        if (!recognizedDataType)
     387                                error("Unsupported data at offset %lx", _inputOffset);
     388                        _input.seek(_inputEndOffset, SEEK_SET);
     389                        _inputOffset = _inputEndOffset;
     390                        resourceCount++;
     391                        // We abort even, if file position is one below size because of pharkas resource.sfx
     392                        if (_inputOffset >= _inputSize - 1)
     393                                break;
    356394
    357                 _input.read_throwsOnError(&header, 6);
    358         } while (true);
     395                        _input.read_throwsOnError(&header, 6);
     396                } while (true);
     397        }
    359398
    360399        // This case happens on pharkas resource.sfx
    361400        if (_inputOffset != _inputSize)
    void CompressSci::execute() {  
    394433                _input.seek(_inputOffset, SEEK_SET);
    395434                compressData(recognizedDataType);
    396435
     436                // raw files are 0-padded to 2048 bytes
     437                if (recognizedDataType == kSciResourceDataTypeRaw and _inputEndOffset % 2048)
     438                        _inputEndOffset = (((_inputEndOffset >> 11) + 1) << 11) & 0xffffffff;
     439
    397440                // Seek inputfile to the end of the data
    398441                _input.seek(_inputEndOffset, SEEK_SET);
    399442                // Seek outputfile to mapping table
  • engines/sci/compress_sci.h

    diff --git a/engines/sci/compress_sci.h b/engines/sci/compress_sci.h
    index 3c92d6f..e1e404a 100644
    a b  
    2424#define COMPRESS_SCI_H
    2525
    2626#include "compress.h"
     27#include <map>
    2728
    2829enum SciResourceDataType {
    2930        kSciResourceDataTypeUnknown     = 0,
    3031        kSciResourceDataTypeWAVE        = 1,
    3132        kSciResourceDataTypeSOL         = 2,
    32         kSciResourceTypeTypeSync        = 3
     33        kSciResourceTypeTypeSync        = 3,
     34        kSciResourceDataTypeRaw         = 4
    3335};
    3436
    3537class CompressSci : public CompressionTool {
    public:  
    4143protected:
    4244        SciResourceDataType detectData(byte *header, bool compressMode);
    4345        void compressData(SciResourceDataType dataType);
     46        uint parseRawAudioMap();
    4447
    4548        Common::File _input, _output;
    4649        int _inputOffset;
    4750        int _inputEndOffset;
    4851        int _inputSize;
    4952        int _outputOffset;
     53        bool _rawAudio;
     54        std::map<uint32,uint32> _rawAudioMap;
    5055};
    5156
    5257#endif