[Scummvm-git-logs] scummvm master -> e877b4fdc200ae1c040bb5dc40704b9eca898022
djsrv
dservilla at gmail.com
Tue Jun 16 15:20:16 UTC 2020
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e877b4fdc2 DIRECTOR: Improve 'snd ' decoding
Commit: e877b4fdc200ae1c040bb5dc40704b9eca898022
https://github.com/scummvm/scummvm/commit/e877b4fdc200ae1c040bb5dc40704b9eca898022
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-16T11:19:42-04:00
Commit Message:
DIRECTOR: Improve 'snd ' decoding
Changed paths:
engines/director/sound.cpp
engines/director/sound.h
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index ddfc1d4a0c..241786ea11 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -20,6 +20,10 @@
*
*/
+// SNDDecoder based on snd2wav by Abraham Macias Paredes
+// https://github.com/System25/drxtract/blob/master/snd2wav
+// License: GNU GPL v2 (see COPYING file for details)
+
#include "common/file.h"
#include "common/substream.h"
@@ -261,42 +265,113 @@ bool SNDDecoder::loadStream(Common::SeekableSubReadStreamEndian &stream) {
stream.hexdump(0x4e);
}
- // unk1
- for (uint32 i = 0; i < 0x14; i++) {
- stream.readByte();
+ uint16 format = stream.readUint16();
+ if (format == 1) {
+ uint16 dataTypeCount = stream.readUint16();
+ for (uint16 i = 0; i < dataTypeCount; i++) {
+ uint16 dataType = stream.readUint16();
+ if (dataType == 5) {
+ // Sampled sound data
+ uint32 options = stream.readUint32();
+ _channels = (options & 0x80) ? 1 : 2;
+ if (!processCommands(stream))
+ return false;
+ } else {
+ warning("SNDDecoder: Unsupported data type: %d", dataType);
+ return false;
+ }
+ }
+ } else if (format == 2) {
+ _channels = 1;
+ /*uint16 refCount =*/stream.readUint16();
+ if (!processCommands(stream))
+ return false;
+ } else {
+ warning("SNDDecoder: Bad format: %d", format);
+ return false;
+ }
+
+ return true;
+}
+
+bool SNDDecoder::processCommands(Common::SeekableSubReadStreamEndian &stream) {
+ uint16 cmdCount = stream.readUint16();
+ for (uint16 i = 0; i < cmdCount; i++) {
+ uint16 cmd = stream.readUint16();
+ if (cmd == 0x8051) {
+ if (!processBufferCommand(stream))
+ return false;
+ } else {
+ warning("SNDDecoder: Unsupported command: %d", cmd);
+ return false;
+ }
}
- _channels = stream.readUint16();
- if (!(_channels == 1 || _channels == 2)) {
- warning("STUB: SNDDecoder::loadStream: no support for old sound format");
+
+ return true;
+}
+
+bool SNDDecoder::processBufferCommand(Common::SeekableSubReadStreamEndian &stream) {
+ if (_data) {
+ warning("SNDDecoder: Already read data");
return false;
}
- _rate = stream.readUint16();
- // unk2
- for (uint32 i = 0; i < 0x06; i++) {
- stream.readByte();
+ /*uint16 unk1 =*/stream.readUint16();
+ int32 offset = stream.readUint32();
+ if (offset != stream.pos()) {
+ warning("SNDDecoder: Bad sound header offset. Expected: %d, read: %d", stream.pos(), offset);
+ return false;
}
- uint32 length = stream.readUint32();
- /*uint16 unk3 =*/stream.readUint16();
- /*uint32 length_copy =*/stream.readUint32();
- /*uint8 unk4 =*/stream.readByte();
- /*uint8 unk5 =*/stream.readByte();
- /*uint16 unk6 =*/stream.readUint16();
- // unk7
- for (uint32 i = 0; i < 0x12; i++) {
- stream.readByte();
+ /*uint32 dataPtr =*/stream.readUint32();
+ uint32 param = stream.readUint32();
+ _rate = stream.readUint16();
+ /*uint16 rateExt =*/stream.readUint16();
+ /*uint32 loopStart =*/stream.readUint32();
+ /*uint32 loopEnd =*/stream.readUint32();
+ byte encoding = stream.readByte();
+ byte baseFrequency = stream.readByte();
+ if (baseFrequency != 0x3c) {
+ warning("SNDDecoder: Unsupported base frequency: %d", baseFrequency);
+ return false;
}
- uint16 bits = stream.readUint16();
- // unk8
- for (uint32 i = 0; i < 0x0e; i++) {
- stream.readByte();
+ uint32 frameCount = 0;
+ uint16 bits = 8;
+ if (encoding == 0x00) {
+ // Standard sound header
+ uint16 dataLength = param;
+ frameCount = dataLength / _channels;
+ } else if (encoding == 0xff) {
+ // Extended sound header
+ _channels = param;
+ frameCount = stream.readUint32();
+ for (uint32 i = 0; i < 0x0a; i++) {
+ // aiff sample rate
+ stream.readByte();
+ }
+ /*uint32 markerChunk =*/stream.readUint32();
+ /*uint32 instrumentsChunk =*/stream.readUint32();
+ /*uint32 aesRecording =*/stream.readUint32();
+ bits = stream.readUint16();
+
+ // future use
+ stream.readUint16();
+ stream.readUint32();
+ stream.readUint32();
+ stream.readUint32();
+ } else if (encoding == 0xfe) {
+ // Compressed sound header
+ warning("SNDDecoder: Compressed sound header not supported");
+ return false;
+ } else {
+ warning("SNDDecoder: Bad encoding: %d", encoding);
+ return false;
}
_flags = 0;
- _flags |= _channels == 2 ? Audio::FLAG_STEREO : 0;
- _flags |= bits == 16 ? Audio::FLAG_16BITS : 0;
- _flags |= bits == 8 ? Audio::FLAG_UNSIGNED : 0;
- _size = length * _channels * (bits == 16 ? 2 : 1);
+ _flags |= (_channels == 2) ? Audio::FLAG_STEREO : 0;
+ _flags |= (bits == 16) ? Audio::FLAG_16BITS : 0;
+ _flags |= (bits == 8) ? Audio::FLAG_UNSIGNED : 0;
+ _size = frameCount * _channels * (bits == 16 ? 2 : 1);
_data = (byte *)malloc(_size);
assert(_data);
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 5591fa329b..b45c588b94 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -77,6 +77,8 @@ public:
~SNDDecoder();
bool loadStream(Common::SeekableSubReadStreamEndian &stream);
+ bool processCommands(Common::SeekableSubReadStreamEndian &stream);
+ bool processBufferCommand(Common::SeekableSubReadStreamEndian &stream);
Audio::SeekableAudioStream *getAudioStream();
Audio::AudioStream *getLoopingAudioStream();
More information about the Scummvm-git-logs
mailing list