Ticket #9067: wave_endianness_fix_3.diff

File wave_endianness_fix_3.diff, 12.1 KB (added by SF/mthreepwood, 10 years ago)

Patch against current trunk (r45085)

  • engines/tucker/sequences.cpp

     
    601601                case kAnimationSoundType16BitsRAW:
    602602                        size = f.size();
    603603                        rate = 22050;
    604                         flags = Audio::Mixer::FLAG_UNSIGNED;
    605                         if (type == kAnimationSoundType16BitsRAW) {
     604                        flags = Audio::Mixer::FLAG_UNSIGNED|Audio::Mixer::FLAG_AUTOFREE;
     605                        if (type == kAnimationSoundType16BitsRAW)
    606606                                flags = Audio::Mixer::FLAG_LITTLE_ENDIAN | Audio::Mixer::FLAG_16BITS;
     607                       
     608                        if (size != 0) {
     609                                uint8 *sampleData = (uint8 *)malloc(size);
     610                                if (sampleData) {
     611                                        f.read(sampleData, size);
     612                                        stream = Audio::makeLinearInputStream(sampleData, size, rate, flags, 0, 0);
     613                                }
    607614                        }
    608615                        break;
    609616                case kAnimationSoundTypeWAV:
    610617                case kAnimationSoundTypeLoopingWAV:
    611                         Audio::loadWAVFromStream(f, size, rate, flags);
    612                         if (type == kAnimationSoundTypeLoopingWAV) {
    613                                 flags |= Audio::Mixer::FLAG_LOOP;
    614                         }
     618                        stream = Audio::makeWAVStream(&f, true, type == kAnimationSoundTypeLoopingWAV);
    615619                        break;
    616620                }
    617                 if (size != 0) {
    618                         uint8 *sampleData = (uint8 *)malloc(size);
    619                         if (sampleData) {
    620                                 f.read(sampleData, size);
    621                                 flags |= Audio::Mixer::FLAG_AUTOFREE;
    622                                 stream = Audio::makeLinearInputStream(sampleData, size, rate, flags, 0, 0);
    623                         }
    624                 }
     621               
    625622        }
    626623        return stream;
    627624}
  • 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);
     
    252215        if (!_audioSource) {
    253216                sprintf(fileName, "%s.wav", fileBase);
    254217                if (_file.open(fileName))
    255                         _audioSource = new WaveAudioStream(&_file, loop);
     218                        _audioSource = Audio::makeWAVStream(&_file, false, loop ? 0 : 1);
    256219        }
    257220
    258221        if (!_audioSource) {
  • engines/scumm/he/sound_he.cpp

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

     
    282282}
    283283
    284284void MoviePlayerDXA::startSound() {
    285         byte *buffer;
    286285        uint32 offset, size;
    287286
    288287        if (getSoundTag() == MKID_BE('WAVE')) {
     
    302301                        offset = in.readUint32LE();
    303302                        size = in.readUint32LE();
    304303
    305                         buffer = (byte *)malloc(size);
    306304                        in.seek(offset, SEEK_SET);
    307                         in.read(buffer, size);
     305                        _bgSoundStream = Audio::makeWAVStream(in.readStream(size), true);
    308306                        in.close();
    309307                } else {
    310                         buffer = (byte *)malloc(size);
    311                         _fileStream->read(buffer, size);
     308                        _bgSoundStream = Audio::makeWAVStream(_fileStream->readStream(size), true);
    312309                }
    313 
    314                 Common::MemoryReadStream stream(buffer, size);
    315                 _bgSoundStream = Audio::makeWAVStream(&stream, false);
    316                 free(buffer);
    317310        } else {
    318311                _bgSoundStream = Audio::AudioStream::openStreamFile(baseName);
    319312        }
  • 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"
     
    786785        uint16 compType;
    787786        int blockAlign, rate;
    788787
    789         // TODO: Use makeWAVStream() in future, when makeADPCMStream() allows sound looping
    790788        int size = READ_LE_UINT32(soundData + 4);
    791789        Common::MemoryReadStream stream(soundData, size);
    792         if (!Audio::loadWAVFromStream(stream, size, rate, flags, &compType, &blockAlign))
    793                 error("playSoundData: Not a valid WAV data");
     790        Audio::AudioStream *sndStream = Audio::makeWAVStream(&stream, true, loop);
    794791
    795792        convertVolume(vol);
    796793        convertPan(pan);
    797794
    798         if (loop == true)
    799                 flags |= Audio::Mixer::FLAG_LOOP;
    800 
    801         if (compType == 2) {
    802                 Audio::AudioStream *sndStream = Audio::makeADPCMStream(&stream, false, size, Audio::kADPCMMS, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);
    803                 buffer = (byte *)malloc(size * 4);
    804                 size = sndStream->readBuffer((int16*)buffer, size * 2);
    805                 size *= 2; // 16bits.
    806                 delete sndStream;
    807         } else {
    808                 buffer = (byte *)malloc(size);
    809                 memcpy(buffer, soundData + stream.pos(), size);
    810         }
    811 
    812         _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer, size, rate, flags | Audio::Mixer::FLAG_AUTOFREE, -1, vol, pan);
     795        _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, sndStream, -1, vol, pan);
    813796}
    814797
    815798void 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