Ticket #9067: wave_endianness_fix_2.diff

File wave_endianness_fix_2.diff, 12.9 KB (added by dhewg, 15 years ago)

Patch superseeding wave_endianness_fix.diff

  • engines/tucker/resource.cpp

     
    884884                char fileName[64];
    885885                snprintf(fileName, sizeof(fileName), fmt, num);
    886886                Common::File f;
    887                 if (f.open(fileName)) {
    888                         int size, rate;
    889                         uint8 flags = 0;
    890                         if (Audio::loadWAVFromStream(f, size, rate, flags)) {
    891                                 uint8 *data = (uint8 *)malloc(size);
    892                                 if (data) {
    893                                         f.read(data, size);
    894                                         flags |= Audio::Mixer::FLAG_AUTOFREE;
    895                                         if (loop) {
    896                                                 flags |= Audio::Mixer::FLAG_LOOP;
    897                                         }
    898                                         stream = Audio::makeLinearInputStream(data, size, rate, flags, 0, 0);
    899                                 }
    900                         }
    901                 }
     887                if (f.open(fileName))
     888                        stream = Audio::makeWAVStream(&f, true, loop);
    902889        } else {
    903890                int offset = 0;
    904891                switch (type) {
  • engines/tucker/sequences.cpp

     
    598598                case kAnimationSoundType16BitsRAW:
    599599                        size = f.size();
    600600                        rate = 22050;
    601                         flags = Audio::Mixer::FLAG_UNSIGNED;
    602                         if (type == kAnimationSoundType16BitsRAW) {
     601                        flags = Audio::Mixer::FLAG_UNSIGNED|Audio::Mixer::FLAG_AUTOFREE;
     602                        if (type == kAnimationSoundType16BitsRAW)
    603603                                flags = Audio::Mixer::FLAG_LITTLE_ENDIAN | Audio::Mixer::FLAG_16BITS;
     604                       
     605                        if (size != 0) {
     606                                uint8 *sampleData = (uint8 *)malloc(size);
     607                                if (sampleData) {
     608                                        f.read(sampleData, size);
     609                                        stream = Audio::makeLinearInputStream(sampleData, size, rate, flags, 0, 0);
     610                                }
    604611                        }
    605612                        break;
    606613                case kAnimationSoundTypeWAV:
    607614                case kAnimationSoundTypeLoopingWAV:
    608                         Audio::loadWAVFromStream(f, size, rate, flags);
    609                         if (type == kAnimationSoundTypeLoopingWAV) {
    610                                 flags |= Audio::Mixer::FLAG_LOOP;
    611                         }
     615                        stream = Audio::makeWAVStream(&f, true, type == kAnimationSoundTypeLoopingWAV);
    612616                        break;
    613617                }
    614                 if (size != 0) {
    615                         uint8 *sampleData = (uint8 *)malloc(size);
    616                         if (sampleData) {
    617                                 f.read(sampleData, size);
    618                                 flags |= Audio::Mixer::FLAG_AUTOFREE;
    619                                 stream = Audio::makeLinearInputStream(sampleData, size, rate, flags, 0, 0);
    620                         }
    621                 }
     618               
    622619        }
    623620        return stream;
    624621}
  • engines/sword1/music.cpp

     
    120120        return retVal;
    121121}
    122122
    123 class WaveAudioStream : public BaseAudioStream {
    124 public:
    125         WaveAudioStream(Common::SeekableReadStream *source, bool loop);
    126         virtual int readBuffer(int16 *buffer, const int numSamples);
    127 private:
    128         virtual void rewind();
    129 };
    130123
    131 WaveAudioStream::WaveAudioStream(Common::SeekableReadStream *source, bool loop) : BaseAudioStream(source, loop) {
    132         rewind();
    133 
    134         if (_samplesLeft == 0)
    135                 _loop = false;
    136 }
    137 
    138 void WaveAudioStream::rewind() {
    139         int rate, size;
    140         byte flags;
    141 
    142         _sourceStream->seek(0);
    143 
    144         if (Audio::loadWAVFromStream(*_sourceStream, size, rate, flags)) {
    145                 reinit(size, rate, flags);
    146         }
    147 }
    148 
    149 int WaveAudioStream::readBuffer(int16 *buffer, const int numSamples) {
    150         int retVal = BaseAudioStream::readBuffer(buffer, numSamples);
    151 
    152         if (_bitsPerSample == 16) {
    153                 for (int i = 0; i < retVal; i++) {
    154                         buffer[i] = (int16)READ_LE_UINT16(buffer + i);
    155                 }
    156         }
    157 
    158         return retVal;
    159 }
    160 
    161124class AiffAudioStream : public BaseAudioStream {
    162125public:
    163126        AiffAudioStream(Common::SeekableReadStream *source, bool loop);
     
    239202        if (!_audioSource) {
    240203                sprintf(fileName, "%s.wav", fileBase);
    241204                if (_file.open(fileName))
    242                         _audioSource = new WaveAudioStream(&_file, loop);
     205                        _audioSource = Audio::makeWAVStream(&_file, false, loop ? 0 : 1);
    243206        }
    244207
    245208        if (!_audioSource) {
  • engines/scumm/he/sound_he.cpp

     
    655655                                _heChannel[heChannel].timer = size * 1000 / rate;
    656656
    657657                        flags |= Audio::Mixer::FLAG_AUTOFREE;
     658                       
     659                        // makeADPCMStream returns a stream in native endianness, but LinearInputStream (and playRaw)
     660                        // is defaulted to Big Endian. If we're on a Little Endian system, set the LE flag.
     661#ifdef SCUMM_LITTLE_ENDIAN
     662                        flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN;
     663#endif
     664                       
    658665                        _mixer->playRaw(type, &_heSoundChannels[heChannel], sound + heOffset, size - heOffset, rate, flags, soundID);
    659666                } else {
    660667                        _mixer->playRaw(type, &_heSoundChannels[heChannel], ptr + stream.pos() + heOffset, size - heOffset, rate, flags, soundID);
  • engines/agos/animation.cpp

     
    273273}
    274274
    275275void MoviePlayerDXA::startSound() {
    276         byte *buffer;
    277276        uint32 offset, size;
    278277
    279278        if (getSoundTag() == MKID_BE('WAVE')) {
     
    293292                        offset = in.readUint32LE();
    294293                        size = in.readUint32LE();
    295294
    296                         buffer = (byte *)malloc(size);
    297295                        in.seek(offset, SEEK_SET);
    298                         in.read(buffer, size);
     296                        _bgSoundStream = Audio::makeWAVStream(in.readStream(size), true);
    299297                        in.close();
    300298                } else {
    301                         buffer = (byte *)malloc(size);
    302                         _fileStream->read(buffer, size);
     299                        _bgSoundStream = Audio::makeWAVStream(_fileStream->readStream(size), true);
    303300                }
    304 
    305                 Common::MemoryReadStream stream(buffer, size);
    306                 _bgSoundStream = Audio::makeWAVStream(&stream, false);
    307                 free(buffer);
    308301        } else {
    309302                _bgSoundStream = Audio::AudioStream::openStreamFile(baseName);
    310303        }
  • engines/agos/sound.cpp

     
    3131#include "agos/agos.h"
    3232#include "agos/sound.h"
    3333
    34 #include "sound/adpcm.h"
    3534#include "sound/audiostream.h"
    3635#include "sound/flac.h"
    3736#include "sound/mixer.h"
     
    782781        uint16 compType;
    783782        int blockAlign, rate;
    784783
    785         // TODO: Use makeWAVStream() in future, when makeADPCMStream() allows sound looping
    786784        int size = READ_LE_UINT32(soundData + 4);
    787785        Common::MemoryReadStream stream(soundData, size);
    788         if (!Audio::loadWAVFromStream(stream, size, rate, flags, &compType, &blockAlign))
    789                 error("playSoundData: Not a valid WAV data");
     786        Audio::AudioStream *sndStream = Audio::makeWAVStream(&stream, true, loop);
    790787
    791788        convertVolume(vol);
    792789        convertPan(pan);
    793790
    794         if (loop == true)
    795                 flags |= Audio::Mixer::FLAG_LOOP;
    796 
    797         if (compType == 2) {
    798                 Audio::AudioStream *sndStream = Audio::makeADPCMStream(&stream, false, size, Audio::kADPCMMS, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);
    799                 buffer = (byte *)malloc(size * 4);
    800                 size = sndStream->readBuffer((int16*)buffer, size * 2);
    801                 size *= 2; // 16bits.
    802                 delete sndStream;
    803         } else {
    804                 buffer = (byte *)malloc(size);
    805                 memcpy(buffer, soundData + stream.pos(), size);
    806         }
    807 
    808         _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer, size, rate, flags | Audio::Mixer::FLAG_AUTOFREE, -1, vol, pan);
     791        _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, sndStream, -1, vol, pan);
    809792}
    810793
    811794void Sound::stopSfx5() {
  • sound/wave.cpp

     
    121121                flags |= Audio::Mixer::FLAG_UNSIGNED;
    122122        else if (bitsPerSample == 16)   // 16 bit data is signed little endian
    123123                flags |= (Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_LITTLE_ENDIAN);
    124         else if (bitsPerSample == 4 && type == 17)      // MS IMA ADPCM compressed. We decompress it
    125                 flags |= (Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_LITTLE_ENDIAN);
    126         else if (bitsPerSample == 4 && type == 2)       // MS ADPCM compressed. We decompress it
    127                 flags |= (Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_LITTLE_ENDIAN);
     124        else if (bitsPerSample == 4 && (type == 2 || type == 17))
     125                flags |= Audio::Mixer::FLAG_16BITS;
    128126        else {
    129127                warning("getWavInfo: unsupported bitsPerSample %d", bitsPerSample);
    130128                return false;
     
    163161        return true;
    164162}
    165163
    166 AudioStream *makeWAVStream(Common::SeekableReadStream *stream, bool disposeAfterUse) {
     164AudioStream *makeWAVStream(Common::SeekableReadStream *stream, bool disposeAfterUse, bool loop) {
    167165        int size, rate;
    168         byte *data, flags;
     166        byte flags;
    169167        uint16 type;
    170168        int blockAlign;
    171169
     
    175173                return 0;
    176174        }
    177175
    178         if (type == 17) { // MS IMA ADPCM
    179                 Audio::AudioStream *sndStream = Audio::makeADPCMStream(stream, false, size, Audio::kADPCMMSIma, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);
    180                 data = (byte *)malloc(size * 4);
    181                 assert(data);
    182                 size = sndStream->readBuffer((int16*)data, size * 2);
    183                 size *= 2; // 16bits.
    184                 delete sndStream;
    185         } else if (type == 2) { // MS ADPCM
    186                 Audio::AudioStream *sndStream = Audio::makeADPCMStream(stream, false, size, Audio::kADPCMMS, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);
    187                 data = (byte *)malloc(size * 4);
    188                 assert(data);
    189                 size = sndStream->readBuffer((int16*)data, size * 2);
    190                 size *= 2; // 16bits.
    191                 delete sndStream;
    192         } else {
    193                 // Plain data. Just read everything at once.
    194                 // TODO: More elegant would be to wrap the stream.
    195                 data = (byte *)malloc(size);
    196                 assert(data);
    197                 stream->read(data, size);
    198         }
     176        if (type == 17) // MS IMA ADPCM
     177                return makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMSIma, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign, loop ? 0 : 1);
     178        else if (type == 2) // MS ADPCM
     179                return makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMS, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign, loop ? 0 : 1);
     180       
     181        // Raw PCM. Just read everything at once.
     182        // TODO: More elegant would be to wrap the stream.
     183        byte *data = (byte *)malloc(size);
     184        assert(data);
     185        stream->read(data, size);
    199186
    200187        if (disposeAfterUse)
    201188                delete stream;
    202189
    203190        // Since we allocated our own buffer for the data, we must set the autofree flag.
    204191        flags |= Audio::Mixer::FLAG_AUTOFREE;
     192       
     193        if (loop)
     194                flags |= Audio::Mixer::FLAG_LOOP;
    205195
    206196        return makeLinearInputStream(data, size, rate, flags, 0, 0);
    207197}
  • sound/adpcm.cpp

     
    204204
    205205        for (samples = 0; samples < numSamples && !_stream->eos() && _stream->pos() < _endpos; samples += 2) {
    206206                data = _stream->readByte();
    207                 buffer[samples] = TO_LE_16(decodeOKI((data >> 4) & 0x0f));
    208                 buffer[samples + 1] = TO_LE_16(decodeOKI(data & 0x0f));
     207                buffer[samples] = decodeOKI((data >> 4) & 0x0f);
     208                buffer[samples + 1] = decodeOKI(data & 0x0f);
    209209        }
    210210        return samples;
    211211}
     
    241241                for (; samples < numSamples && _blockPos < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2) {
    242242                        data = _stream->readByte();
    243243                        _blockPos++;
    244                         buffer[samples] = TO_LE_16(decodeIMA(data & 0x0f));
    245                         buffer[samples + 1] = TO_LE_16(decodeIMA((data >> 4) & 0x0f));
     244                        buffer[samples] = decodeIMA(data & 0x0f);
     245                        buffer[samples + 1] = decodeIMA((data >> 4) & 0x0f);
    246246                }
    247247        }
    248248        return samples;
     
    263263
    264264                        for (nibble = 0; nibble < 8; nibble++) {
    265265                                k = ((data & 0xf0000000) >> 28);
    266                                 buffer[samples + channel + nibble * 2] = TO_LE_16(decodeIMA(k));
     266                                buffer[samples + channel + nibble * 2] = decodeIMA(k);
    267267                                data <<= 4;
    268268                        }
    269269                }
     
    302302                        for (i = 0; i < channels; i++)
    303303                                _status.ch[i].sample1 = _stream->readSint16LE();
    304304
    305                         for (i = 0; i < channels; i++) {
    306                                 _status.ch[i].sample2 = _stream->readSint16LE();
    307                                 buffer[samples++] = TO_LE_16(_status.ch[i].sample2);
    308                         }
     305                        for (i = 0; i < channels; i++)
     306                                buffer[samples++] = _status.ch[i].sample2 = _stream->readSint16LE();
    309307
    310308                        for (i = 0; i < channels; i++)
    311                                 buffer[samples++] = TO_LE_16(_status.ch[i].sample1);
     309                                buffer[samples++] = _status.ch[i].sample1;
    312310
    313311                        _blockPos = channels * 7;
    314312                }
     
    316314                for (; samples < numSamples && _blockPos < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2) {
    317315                        data = _stream->readByte();
    318316                        _blockPos++;
    319                         buffer[samples] = TO_LE_16(decodeMS(&_status.ch[0], (data >> 4) & 0x0f));
    320                         buffer[samples + 1] = TO_LE_16(decodeMS(&_status.ch[channels - 1], data & 0x0f));
     317                        buffer[samples] = decodeMS(&_status.ch[0], (data >> 4) & 0x0f);
     318                        buffer[samples + 1] = decodeMS(&_status.ch[channels - 1], data & 0x0f);
    321319                }
    322320        }
    323321
  • sound/wave.h

     
    6969 *
    7070 * @param stream                        the SeekableReadStream from which to read the WAVE data
    7171 * @param disposeAfterUse       whether to delete the stream after use
     72 * @param loop                          whether to loop the sound (infinitely)
    7273 * @return      a new AudioStream, or NULL, if an error occured
    7374 */
    7475AudioStream *makeWAVStream(
    7576        Common::SeekableReadStream *stream,
    76         bool disposeAfterUse = false);
     77        bool disposeAfterUse = false,
     78        bool loop = false);
    7779
    7880} // End of namespace Audio
    7981