[Scummvm-git-logs] scummvm master -> 4375d7edc5d53c63bd4300a019f26fcf6052a015
NMIError
noreply at scummvm.org
Sat Jun 18 12:51:08 UTC 2022
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
79c778c6c9 AUDIO: Enable subclassing of VocStream
d81d6e593e CHEWY: Fix pops at start of SFX and speech
4375d7edc5 AUDIO: Fix VOC infinite loop
Commit: 79c778c6c9dcda57b57c05650cc39961e9428557
https://github.com/scummvm/scummvm/commit/79c778c6c9dcda57b57c05650cc39961e9428557
Author: Coen Rampen (crampen at gmail.com)
Date: 2022-06-18T14:13:32+02:00
Commit Message:
AUDIO: Enable subclassing of VocStream
Changed paths:
audio/decoders/voc.cpp
audio/decoders/voc.h
diff --git a/audio/decoders/voc.cpp b/audio/decoders/voc.cpp
index b55b86e1267..30bb2ed0412 100644
--- a/audio/decoders/voc.cpp
+++ b/audio/decoders/voc.cpp
@@ -19,6 +19,8 @@
*
*/
+#include "audio/decoders/voc.h"
+
#include "common/debug.h"
#include "common/endian.h"
#include "common/util.h"
@@ -32,8 +34,6 @@
namespace Audio {
-namespace {
-
bool checkVOCHeader(Common::ReadStream &stream) {
VocFileHeader fileHeader;
@@ -73,83 +73,6 @@ bool checkVOCHeader(Common::ReadStream &stream) {
return true;
}
-class VocStream : public SeekableAudioStream {
-public:
- VocStream(Common::SeekableReadStream *stream, bool isUnsigned, DisposeAfterUse::Flag disposeAfterUse);
- ~VocStream();
-
- int readBuffer(int16 *buffer, const int numSamples) override;
-
- bool isStereo() const override { return false; }
-
- int getRate() const override { return _rate; }
-
- bool endOfData() const override { return (_curBlock == _blocks.end()) && (_blockLeft == 0); }
-
- bool seek(const Timestamp &where) override;
-
- Timestamp getLength() const override { return _length; }
-private:
- void preProcess();
-
- Common::SeekableReadStream *const _stream;
- const DisposeAfterUse::Flag _disposeAfterUse;
-
- const bool _isUnsigned;
-
- int _rate;
- Timestamp _length;
-
- struct Block {
- uint8 code;
- uint32 length;
-
- union {
- struct {
- uint32 offset;
- int rate;
- int samples;
- } sampleBlock;
-
- struct {
- int count;
- } loopBlock;
- };
- };
-
- typedef Common::List<Block> BlockList;
- BlockList _blocks;
-
- BlockList::const_iterator _curBlock;
- uint32 _blockLeft;
-
- /**
- * Advance one block in the stream in case
- * the current one is empty.
- */
- void updateBlockIfNeeded();
-
- // Do some internal buffering for systems with really slow slow disk i/o
- enum {
- /**
- * How many samples we can buffer at once.
- *
- * TODO: Check whether this size suffices
- * for systems with slow disk I/O.
- */
- kSampleBufferLength = 2048
- };
- byte _buffer[kSampleBufferLength];
-
- /**
- * Fill the temporary sample buffer used in readBuffer.
- *
- * @param maxSamples Maximum samples to read.
- * @return actual count of samples read.
- */
- int fillBuffer(int maxSamples);
-};
-
VocStream::VocStream(Common::SeekableReadStream *stream, bool isUnsigned, DisposeAfterUse::Flag disposeAfterUse)
: _stream(stream), _disposeAfterUse(disposeAfterUse), _isUnsigned(isUnsigned), _rate(0),
_length(), _blocks(), _curBlock(_blocks.end()), _blockLeft(0), _buffer() {
@@ -533,8 +456,6 @@ void VocStream::preProcess() {
rewind();
}
-} // End of anonymous namespace
-
int getSampleRateFromVOCRate(int vocSR) {
if (vocSR == 0xa5 || vocSR == 0xa6) {
return 11025;
diff --git a/audio/decoders/voc.h b/audio/decoders/voc.h
index 2e33c2628ba..a92972db965 100644
--- a/audio/decoders/voc.h
+++ b/audio/decoders/voc.h
@@ -23,6 +23,7 @@
* @file
* Sound decoder used in engines:
* - agos
+ * - chewy (subclass)
* - kyra
* - saga
* - scumm
@@ -32,6 +33,9 @@
#ifndef AUDIO_VOC_H
#define AUDIO_VOC_H
+#include "audio/audiostream.h"
+
+#include "common/list.h"
#include "common/scummsys.h"
#include "common/types.h"
@@ -64,6 +68,84 @@ struct VocBlockHeader {
#include "common/pack-end.h" // END STRUCT PACKING
+class VocStream : public SeekableAudioStream {
+public:
+ VocStream(Common::SeekableReadStream *stream, bool isUnsigned, DisposeAfterUse::Flag disposeAfterUse);
+ virtual ~VocStream();
+
+ int readBuffer(int16 *buffer, const int numSamples) override;
+
+ bool isStereo() const override { return false; }
+
+ int getRate() const override { return _rate; }
+
+ bool endOfData() const override { return (_curBlock == _blocks.end()) && (_blockLeft == 0); }
+
+ bool seek(const Timestamp &where) override;
+
+ Timestamp getLength() const override { return _length; }
+
+protected:
+ void preProcess();
+
+ Common::SeekableReadStream *const _stream;
+ const DisposeAfterUse::Flag _disposeAfterUse;
+
+ const bool _isUnsigned;
+
+ int _rate;
+ Timestamp _length;
+
+ struct Block {
+ uint8 code;
+ uint32 length;
+
+ union {
+ struct {
+ uint32 offset;
+ int rate;
+ int samples;
+ } sampleBlock;
+
+ struct {
+ int count;
+ } loopBlock;
+ };
+ };
+
+ typedef Common::List<Block> BlockList;
+ BlockList _blocks;
+
+ BlockList::const_iterator _curBlock;
+ uint32 _blockLeft;
+
+ /**
+ * Advance one block in the stream in case
+ * the current one is empty.
+ */
+ void updateBlockIfNeeded();
+
+ // Do some internal buffering for systems with really slow slow disk i/o
+ enum {
+ /**
+ * How many samples we can buffer at once.
+ *
+ * TODO: Check whether this size suffices
+ * for systems with slow disk I/O.
+ */
+ kSampleBufferLength = 2048
+ };
+ byte _buffer[kSampleBufferLength];
+
+ /**
+ * Fill the temporary sample buffer used in readBuffer.
+ *
+ * @param maxSamples Maximum samples to read.
+ * @return actual count of samples read.
+ */
+ int fillBuffer(int maxSamples);
+};
+
/**
* Take a sample rate parameter as it occurs in a VOC sound header, and
* return the corresponding sample frequency.
Commit: d81d6e593e6a6cd498f6a62441b8ce325acd79cf
https://github.com/scummvm/scummvm/commit/d81d6e593e6a6cd498f6a62441b8ce325acd79cf
Author: Coen Rampen (crampen at gmail.com)
Date: 2022-06-18T14:13:32+02:00
Commit Message:
CHEWY: Fix pops at start of SFX and speech
SFX and speech data are actually VOC format without the header. This was not
correctly processed and non-audio data was played as audio, causing popping.
This commit adds a VocStream subclass to handle this variant of the VOC format.
Changed paths:
A engines/chewy/audio/chewy_voc.cpp
A engines/chewy/audio/chewy_voc.h
A engines/chewy/audio/module_tmf.cpp
A engines/chewy/audio/module_tmf.h
A engines/chewy/audio/tmf_stream.cpp
A engines/chewy/audio/tmf_stream.h
R engines/chewy/music/module_tmf.cpp
R engines/chewy/music/module_tmf.h
R engines/chewy/music/tmf_stream.cpp
R engines/chewy/music/tmf_stream.h
engines/chewy/module.mk
engines/chewy/resource.cpp
engines/chewy/sound.cpp
diff --git a/engines/chewy/audio/chewy_voc.cpp b/engines/chewy/audio/chewy_voc.cpp
new file mode 100644
index 00000000000..80aadbc9fd1
--- /dev/null
+++ b/engines/chewy/audio/chewy_voc.cpp
@@ -0,0 +1,63 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "chewy/audio/chewy_voc.h"
+
+#include "common/stream.h"
+
+namespace Chewy {
+
+ChewyVocStream::ChewyVocStream(Common::SeekableReadStream* stream, DisposeAfterUse::Flag disposeAfterUse) :
+ VocStream(stream, true, disposeAfterUse) {
+ removeHeaders();
+}
+
+void ChewyVocStream::removeHeaders() {
+ // Check the sample blocks for non-standard headers.
+ for (BlockList::iterator i = _blocks.begin(), end = _blocks.end(); i != end; ++i) {
+ if (i->code == 1 && i->sampleBlock.samples > 80) {
+ // Found a sample block. Check for the headers.
+ int headerSize = 0;
+ if (_stream->readUint32BE() == FOURCC_RIFF) {
+ // Found a RIFF header.
+ headerSize = 44;
+ } else {
+ _stream->seek(i->sampleBlock.offset + 76);
+ if (_stream->readUint32BE() == FOURCC_SCRS) {
+ // Found an SCRS (?) header.
+ headerSize = 80;
+ }
+ }
+
+ if (headerSize > 0) {
+ // Move the offset past the header and adjust the length.
+ i->sampleBlock.offset += headerSize;
+ i->sampleBlock.samples -= headerSize;
+ _length = _length.addFrames(-headerSize);
+ }
+ }
+ }
+
+ // Reset the stream.
+ rewind();
+}
+
+} // End of namespace Chewy
diff --git a/engines/chewy/audio/chewy_voc.h b/engines/chewy/audio/chewy_voc.h
new file mode 100644
index 00000000000..b925e157997
--- /dev/null
+++ b/engines/chewy/audio/chewy_voc.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef CHEWY_AUDIO_CHEWY_VOC_H
+#define CHEWY_AUDIO_CHEWY_VOC_H
+
+#include "audio/decoders/voc.h"
+
+#include "common/endian.h"
+
+namespace Chewy {
+
+// This stream differs from the standard VOC stream on 2 points:
+// - VOC data header is not present, so not processed.
+// - Some VOC blocks contain non-standard headers. These are removed because
+// otherwise they will be interpreted as audio data and cause static.
+class ChewyVocStream : public Audio::VocStream {
+protected:
+ static const uint32 FOURCC_SCRS = MKTAG('S', 'C', 'R', 'S');
+ static const uint32 FOURCC_RIFF = MKTAG('R', 'I', 'F', 'F');
+
+public:
+ ChewyVocStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse);
+
+protected:
+ void removeHeaders();
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/engines/chewy/music/module_tmf.cpp b/engines/chewy/audio/module_tmf.cpp
similarity index 99%
rename from engines/chewy/music/module_tmf.cpp
rename to engines/chewy/audio/module_tmf.cpp
index 97547260bc1..36efeb1fa21 100644
--- a/engines/chewy/music/module_tmf.cpp
+++ b/engines/chewy/audio/module_tmf.cpp
@@ -19,7 +19,7 @@
*
*/
-#include "chewy/music/module_tmf.h"
+#include "chewy/audio/module_tmf.h"
#include "common/array.h"
#include "common/stream.h"
diff --git a/engines/chewy/music/module_tmf.h b/engines/chewy/audio/module_tmf.h
similarity index 100%
rename from engines/chewy/music/module_tmf.h
rename to engines/chewy/audio/module_tmf.h
diff --git a/engines/chewy/music/tmf_stream.cpp b/engines/chewy/audio/tmf_stream.cpp
similarity index 94%
rename from engines/chewy/music/tmf_stream.cpp
rename to engines/chewy/audio/tmf_stream.cpp
index fcbfed95a4d..d47a2811445 100644
--- a/engines/chewy/music/tmf_stream.cpp
+++ b/engines/chewy/audio/tmf_stream.cpp
@@ -19,9 +19,9 @@
*
*/
-#include "chewy/music/tmf_stream.h"
+#include "chewy/audio/tmf_stream.h"
-#include "chewy/music/module_tmf.h"
+#include "chewy/audio/module_tmf.h"
Chewy::TMFStream::TMFStream(Common::SeekableReadStream *stream, int offs) : ProtrackerStream(44100, true) {
_module = new Module_TMF();
diff --git a/engines/chewy/music/tmf_stream.h b/engines/chewy/audio/tmf_stream.h
similarity index 100%
rename from engines/chewy/music/tmf_stream.h
rename to engines/chewy/audio/tmf_stream.h
diff --git a/engines/chewy/module.mk b/engines/chewy/module.mk
index d8b77a1d456..b981a9a9e00 100644
--- a/engines/chewy/module.mk
+++ b/engines/chewy/module.mk
@@ -29,14 +29,15 @@ MODULE_OBJS = \
text.o \
timer.o \
types.o \
+ audio/chewy_voc.o \
+ audio/module_tmf.o \
+ audio/tmf_stream.o \
dialogs/cinema.o \
dialogs/credits.o \
dialogs/files.o \
dialogs/inventory.o \
dialogs/main_menu.o \
dialogs/options.o \
- music/module_tmf.o \
- music/tmf_stream.o \
video/cfo_decoder.o \
video/video_player.o \
rooms/room00.o \
diff --git a/engines/chewy/resource.cpp b/engines/chewy/resource.cpp
index 337d6daef81..7998b18da09 100644
--- a/engines/chewy/resource.cpp
+++ b/engines/chewy/resource.cpp
@@ -287,42 +287,11 @@ SoundChunk *SoundResource::getSound(uint num) {
Chunk *chunk = &_chunkList[num];
SoundChunk *sound = new SoundChunk();
+ sound->size = chunk->size;
+ sound->data = new uint8[sound->size];
_stream.seek(chunk->pos, SEEK_SET);
-
- uint8 blocksRemaining;
- uint32 totalLength = 0;
- uint32 blockSize;
-
- do {
- blocksRemaining = _stream.readByte();
-
- uint8 b1 = _stream.readByte();
- uint8 b2 = _stream.readByte();
- uint8 b3 = _stream.readByte();
- blockSize = b1 + (b2 << 8) + (b3 << 16);
-
- totalLength += blockSize;
- _stream.skip(blockSize);
- } while (blocksRemaining > 1);
-
- sound->size = totalLength;
- sound->data = new uint8[totalLength];
- uint8 *ptr = sound->data;
-
- _stream.seek(chunk->pos, SEEK_SET);
-
- do {
- blocksRemaining = _stream.readByte();
-
- uint8 b1 = _stream.readByte();
- uint8 b2 = _stream.readByte();
- uint8 b3 = _stream.readByte();
- blockSize = b1 + (b2 << 8) + (b3 << 16);
-
- _stream.read(ptr, blockSize);
- ptr += blockSize;
- } while (blocksRemaining > 1);
+ _stream.read(sound->data, sound->size);
return sound;
}
diff --git a/engines/chewy/sound.cpp b/engines/chewy/sound.cpp
index e8741bf0e68..cce6a6c67f3 100644
--- a/engines/chewy/sound.cpp
+++ b/engines/chewy/sound.cpp
@@ -24,12 +24,14 @@
#include "audio/decoders/raw.h"
#include "audio/mods/protracker.h"
#include "common/config-manager.h"
+#include "common/memstream.h"
#include "common/system.h"
#include "chewy/resource.h"
#include "chewy/sound.h"
#include "chewy/types.h"
#include "chewy/globals.h"
-#include "chewy/music/tmf_stream.h"
+#include "chewy/audio/chewy_voc.h"
+#include "chewy/audio/tmf_stream.h"
namespace Chewy {
@@ -75,10 +77,10 @@ void Sound::playSound(int num, uint channel, bool loop) {
void Sound::playSound(uint8 *data, uint32 size, uint channel, bool loop, DisposeAfterUse::Flag dispose) {
Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawStream(data,
- size, 22050, Audio::FLAG_UNSIGNED,
- dispose),
- loop ? 0 : 1);
+ new ChewyVocStream(
+ new Common::MemorySeekableReadWriteStream(data, size, dispose),
+ dispose),
+ loop ? 0 : 1);
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[channel], stream);
}
@@ -175,9 +177,9 @@ void Sound::playSpeech(int num, bool waitForFinish) {
delete sound;
// Play it
- Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawStream(data, size, 22050, Audio::FLAG_UNSIGNED,
- DisposeAfterUse::YES), 1);
+ Audio::AudioStream *stream = new ChewyVocStream(
+ new Common::MemorySeekableReadWriteStream(data, size, DisposeAfterUse::YES),
+ DisposeAfterUse::YES);
_mixer->playStream(Audio::Mixer::kSpeechSoundType,
&_speechHandle, stream);
Commit: 4375d7edc5d53c63bd4300a019f26fcf6052a015
https://github.com/scummvm/scummvm/commit/4375d7edc5d53c63bd4300a019f26fcf6052a015
Author: Coen Rampen (crampen at gmail.com)
Date: 2022-06-18T14:13:32+02:00
Commit Message:
AUDIO: Fix VOC infinite loop
This fixes a possible infinite loop in VocStream. It depends on the stream size
matching the size specified in the VOC block headers, but if the size in the
headers is incorrect and larger than the stream size, it will keep trying to
read the stream. This is fixed by adding an end-of-stream check to the error
check.
Changed paths:
audio/decoders/voc.cpp
diff --git a/audio/decoders/voc.cpp b/audio/decoders/voc.cpp
index 30bb2ed0412..0fb80634080 100644
--- a/audio/decoders/voc.cpp
+++ b/audio/decoders/voc.cpp
@@ -168,9 +168,9 @@ int VocStream::fillBuffer(int maxSamples) {
maxSamples -= samplesRead;
_blockLeft -= samplesRead;
- // In case of an error we will stop
+ // In case of an error or end of stream we will stop
// stream playback.
- if (_stream->err()) {
+ if (_stream->err() || _stream->eos()) {
_blockLeft = 0;
_curBlock = _blocks.end();
break;
More information about the Scummvm-git-logs
mailing list