[Scummvm-cvs-logs] scummvm master -> 2f707bf20723a72e769c872f433fbcb67f0dccdf

clone2727 clone2727 at gmail.com
Fri Jun 5 01:50:11 CEST 2015


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
c76e30d01c SCI: Only use makeAIFFStream instead of loading the sound twice
3d1da64249 AUDIO: Only expose makeAIFFStream to clients
4266d76ce4 AUDIO: Mark AIFF as being used by BBVS
b986b44827 AUDIO: Do not read the entire AIFF buffer into memory
2f707bf207 AUDIO: Rewrite the AIFF decoder to support AIFC


Commit: c76e30d01c47279df8e0edb9f1b1b4b7da852b82
    https://github.com/scummvm/scummvm/commit/c76e30d01c47279df8e0edb9f1b1b4b7da852b82
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-06-04T19:47:23-04:00

Commit Message:
SCI: Only use makeAIFFStream instead of loading the sound twice

Changed paths:
    engines/sci/sound/audio.cpp



diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp
index 8e35d6b..757d622 100644
--- a/engines/sci/sound/audio.cpp
+++ b/engines/sci/sound/audio.cpp
@@ -391,18 +391,7 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32
 		} else if (audioRes->size > 4 && READ_BE_UINT32(audioRes->data) == MKTAG('F','O','R','M')) {
 			// AIFF detected
 			Common::SeekableReadStream *waveStream = new Common::MemoryReadStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);
-
-			// Calculate samplelen from AIFF header
-			int waveSize = 0, waveRate = 0;
-			byte waveFlags = 0;
-			bool ret = Audio::loadAIFFFromStream(*waveStream, waveSize, waveRate, waveFlags);
-			if (!ret)
-				error("Failed to load AIFF from stream");
-
-			*sampleLen = (waveFlags & Audio::FLAG_16BITS ? waveSize >> 1 : waveSize) * 60 / waveRate;
-
-			waveStream->seek(0, SEEK_SET);
-			audioStream = Audio::makeAIFFStream(waveStream, DisposeAfterUse::YES);
+			audioSeekStream = Audio::makeAIFFStream(waveStream, DisposeAfterUse::YES);
 		} else if (audioRes->size > 14 && READ_BE_UINT16(audioRes->data) == 1 && READ_BE_UINT16(audioRes->data + 2) == 1
 				&& READ_BE_UINT16(audioRes->data + 4) == 5 && READ_BE_UINT32(audioRes->data + 10) == 0x00018051) {
 			// Mac snd detected


Commit: 3d1da64249b89d021d73744503bf690786011adb
    https://github.com/scummvm/scummvm/commit/3d1da64249b89d021d73744503bf690786011adb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-06-04T19:47:28-04:00

Commit Message:
AUDIO: Only expose makeAIFFStream to clients

Changed paths:
    audio/decoders/aiff.h



diff --git a/audio/decoders/aiff.h b/audio/decoders/aiff.h
index afb0342..a27990b 100644
--- a/audio/decoders/aiff.h
+++ b/audio/decoders/aiff.h
@@ -44,20 +44,9 @@ namespace Audio {
 class SeekableAudioStream;
 
 /**
- * Try to load an AIFF from the given seekable stream. Returns true if
- * successful. In that case, the stream's seek position will be set to the
- * start of the audio data, and size, rate and flags contain information
- * necessary for playback. Currently this function only supports uncompressed
- * raw PCM.
- */
-extern bool loadAIFFFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags);
-
-/**
  * Try to load an AIFF from the given seekable stream and create an AudioStream
  * from that data.
  *
- * This function uses loadAIFFFromStream() internally.
- *
  * @param stream			the SeekableReadStream from which to read the AIFF data
  * @param disposeAfterUse	whether to delete the stream after use
  * @return	a new SeekableAudioStream, or NULL, if an error occurred


Commit: 4266d76ce4d81d3e29cf323e3e9e9ab77130fe87
    https://github.com/scummvm/scummvm/commit/4266d76ce4d81d3e29cf323e3e9e9ab77130fe87
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-06-04T19:47:32-04:00

Commit Message:
AUDIO: Mark AIFF as being used by BBVS

Changed paths:
    audio/decoders/aiff.h



diff --git a/audio/decoders/aiff.h b/audio/decoders/aiff.h
index a27990b..5f21fc9 100644
--- a/audio/decoders/aiff.h
+++ b/audio/decoders/aiff.h
@@ -23,6 +23,7 @@
 /**
  * @file
  * Sound decoder used in engines:
+ *  - bbvs
  *  - pegasus
  *  - saga
  *  - sci


Commit: b986b44827664c0f1e1b7ae5908d9d8f52def73d
    https://github.com/scummvm/scummvm/commit/b986b44827664c0f1e1b7ae5908d9d8f52def73d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-06-04T19:47:37-04:00

Commit Message:
AUDIO: Do not read the entire AIFF buffer into memory

Changed paths:
    audio/decoders/aiff.cpp



diff --git a/audio/decoders/aiff.cpp b/audio/decoders/aiff.cpp
index b714721..ef666d1 100644
--- a/audio/decoders/aiff.cpp
+++ b/audio/decoders/aiff.cpp
@@ -30,6 +30,7 @@
 
 #include "common/endian.h"
 #include "common/stream.h"
+#include "common/substream.h"
 #include "common/textconsole.h"
 
 #include "audio/decoders/aiff.h"
@@ -159,7 +160,7 @@ bool loadAIFFFromStream(Common::SeekableReadStream &stream, int &size, int &rate
 SeekableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream,
 	DisposeAfterUse::Flag disposeAfterUse) {
 	int size, rate;
-	byte *data, flags;
+	byte flags;
 
 	if (!loadAIFFFromStream(*stream, size, rate, flags)) {
 		if (disposeAfterUse == DisposeAfterUse::YES)
@@ -167,15 +168,10 @@ SeekableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream,
 		return 0;
 	}
 
-	data = (byte *)malloc(size);
-	assert(data);
-	stream->read(data, size);
+	Common::SeekableReadStream *dataStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + size, disposeAfterUse);
 
-	if (disposeAfterUse == DisposeAfterUse::YES)
-		delete stream;
-
-	// Since we allocated our own buffer for the data, we must specify DisposeAfterUse::YES.
-	return makeRawStream(data, size, rate, flags);
+	// Since we allocated our own stream for the data, we must specify DisposeAfterUse::YES.
+	return makeRawStream(dataStream, rate, flags);
 }
 
 } // End of namespace Audio


Commit: 2f707bf20723a72e769c872f433fbcb67f0dccdf
    https://github.com/scummvm/scummvm/commit/2f707bf20723a72e769c872f433fbcb67f0dccdf
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-06-04T19:47:41-04:00

Commit Message:
AUDIO: Rewrite the AIFF decoder to support AIFC

Changed paths:
    audio/decoders/aiff.cpp



diff --git a/audio/decoders/aiff.cpp b/audio/decoders/aiff.cpp
index ef666d1..1fc8119 100644
--- a/audio/decoders/aiff.cpp
+++ b/audio/decoders/aiff.cpp
@@ -24,10 +24,10 @@
  * The code in this file is based on information found at
  * http://www.borg.com/~jglatt/tech/aiff.htm
  *
- * We currently only implement uncompressed AIFF. If we ever need AIFF-C, SoX
- * (http://sox.sourceforge.net) may be a good place to start from.
+ * Also partially based on libav's aiffdec.c
  */
 
+#include "common/debug.h"
 #include "common/endian.h"
 #include "common/stream.h"
 #include "common/substream.h"
@@ -63,23 +63,34 @@ uint32 readExtended(Common::SeekableReadStream &stream) {
 	return mantissa;
 }
 
-bool loadAIFFFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags) {
-	byte buf[4];
+// AIFF versions
+static const uint32 kVersionAIFF = MKTAG('A', 'I', 'F', 'F');
+static const uint32 kVersionAIFC = MKTAG('A', 'I', 'F', 'C');
 
-	stream.read(buf, 4);
-	if (memcmp(buf, "FORM", 4) != 0) {
-		warning("loadAIFFFromStream: No 'FORM' header");
-		return false;
+// Codecs
+static const uint32 kCodecPCM = MKTAG('N', 'O', 'N', 'E'); // very original
+
+SeekableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream,	DisposeAfterUse::Flag disposeAfterUse) {
+	if (stream->readUint32BE() != MKTAG('F', 'O', 'R', 'M')) {
+		warning("makeAIFFStream: No 'FORM' header");
+
+		if (disposeAfterUse == DisposeAfterUse::YES)
+			delete stream;
+
+		return 0;
 	}
 
-	stream.readUint32BE();
+	stream->readUint32BE(); // file size
+
+	uint32 version = stream->readUint32BE();
 
-	// This could be AIFC, but we don't handle that case.
+	if (version != kVersionAIFF && version != kVersionAIFC) {
+		warning("makeAIFFStream: No 'AIFF' or 'AIFC' header");
+
+		if (disposeAfterUse == DisposeAfterUse::YES)
+			delete stream;
 
-	stream.read(buf, 4);
-	if (memcmp(buf, "AIFF", 4) != 0) {
-		warning("loadAIFFFromStream: No 'AIFF' header");
-		return false;
+		return 0;
 	}
 
 	// From here on, we only care about the COMM and SSND chunks, which are
@@ -88,90 +99,124 @@ bool loadAIFFFromStream(Common::SeekableReadStream &stream, int &size, int &rate
 	bool foundCOMM = false;
 	bool foundSSND = false;
 
-	uint16 numChannels = 0, bitsPerSample = 0;
-	uint32 numSampleFrames = 0, offset = 0, blockSize = 0, soundOffset = 0;
+	uint16 channels = 0, bitsPerSample = 0;
+	uint32 blockAlign = 0, rate = 0;
+	uint32 codec = kCodecPCM; // AIFF default
+	Common::SeekableReadStream *dataStream = 0;
 
-	while (!(foundCOMM && foundSSND) && !stream.err() && !stream.eos()) {
-		uint32 length, pos;
+	while (!(foundCOMM && foundSSND) && !stream->err() && !stream->eos()) {
+		uint32 tag = stream->readUint32BE();
+		uint32 length = stream->readUint32BE();
+		uint32 pos = stream->pos();
 
-		stream.read(buf, 4);
-		length = stream.readUint32BE();
-		pos = stream.pos();
+		if (stream->eos() || stream->err())
+			break;
 
-		if (memcmp(buf, "COMM", 4) == 0) {
+		switch (tag) {
+		case MKTAG('C', 'O', 'M', 'M'):
 			foundCOMM = true;
-			numChannels = stream.readUint16BE();
-			numSampleFrames = stream.readUint32BE();
-			bitsPerSample = stream.readUint16BE();
-			rate = readExtended(stream);
-			size = numSampleFrames * numChannels * (bitsPerSample / 8);
-		} else if (memcmp(buf, "SSND", 4) == 0) {
+			channels = stream->readUint16BE();
+			/* frameCount = */ stream->readUint32BE();
+			bitsPerSample = stream->readUint16BE();
+			rate = readExtended(*stream);
+
+			if (version == kVersionAIFC)
+				codec = stream->readUint32BE();
+			break;
+		case MKTAG('S', 'S', 'N', 'D'):
 			foundSSND = true;
-			offset = stream.readUint32BE();
-			blockSize = stream.readUint32BE();
-			soundOffset = stream.pos();
+			/* uint32 offset = */ stream->readUint32BE();
+			blockAlign = stream->readUint32BE();
+			dataStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + length - 8, disposeAfterUse);
+			break;
+		case MKTAG('F', 'V', 'E', 'R'):
+			switch (stream->readUint32BE()) {
+			case 0:
+				version = kVersionAIFF;
+				break;
+			case 0xA2805140:
+				version = kVersionAIFC;
+				break;
+			default:
+				warning("Unknown AIFF version chunk version");
+				break;
+			}
+			break;
+		case MKTAG('w', 'a', 'v', 'e'):
+			warning("Found unhandled AIFF-C extra data chunk");
+
+			if (!dataStream && disposeAfterUse == DisposeAfterUse::YES)
+				delete stream;
+
+			delete dataStream;
+			return 0;
+		default:
+			debug(1, "Skipping AIFF '%s' chunk", tag2str(tag));
+			break; 
 		}
 
-		stream.seek(pos + length);
+		stream->seek(pos + length + (length & 1)); // ensure we're also word-aligned
 	}
 
 	if (!foundCOMM) {
-		warning("loadAIFFFromStream: Cound not find 'COMM' chunk");
-		return false;
-	}
-
-	if (!foundSSND) {
-		warning("loadAIFFFromStream: Cound not find 'SSND' chunk");
-		return false;
-	}
-
-	// We only implement a subset of the AIFF standard.
-
-	if (numChannels < 1 || numChannels > 2) {
-		warning("loadAIFFFromStream: Only 1 or 2 channels are supported, not %d", numChannels);
-		return false;
-	}
+		warning("makeAIFFStream: Cound not find 'COMM' chunk");
 
-	if (bitsPerSample != 8 && bitsPerSample != 16) {
-		warning("loadAIFFFromStream: Only 8 or 16 bits per sample are supported, not %d", bitsPerSample);
-		return false;
-	}
+		if (!dataStream && disposeAfterUse == DisposeAfterUse::YES)
+			delete stream;
 
-	if (offset != 0 || blockSize != 0) {
-		warning("loadAIFFFromStream: Block-aligned data is not supported");
-		return false;
+		delete dataStream;
+		return 0;
 	}
 
-	// Samples are always signed, and big endian.
-
-	flags = 0;
-	if (bitsPerSample == 16)
-		flags |= Audio::FLAG_16BITS;
-	if (numChannels == 2)
-		flags |= Audio::FLAG_STEREO;
-
-	stream.seek(soundOffset);
-
-	// Stream now points at the sample data
-
-	return true;
-}
-
-SeekableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream,
-	DisposeAfterUse::Flag disposeAfterUse) {
-	int size, rate;
-	byte flags;
+	if (!foundSSND) {
+		warning("makeAIFFStream: Cound not find 'SSND' chunk");
 
-	if (!loadAIFFFromStream(*stream, size, rate, flags)) {
 		if (disposeAfterUse == DisposeAfterUse::YES)
 			delete stream;
+
 		return 0;
 	}
 
-	Common::SeekableReadStream *dataStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + size, disposeAfterUse);
+	// We only implement a subset of the AIFF standard.
 
-	// Since we allocated our own stream for the data, we must specify DisposeAfterUse::YES.
-	return makeRawStream(dataStream, rate, flags);
+	if (channels < 1 || channels > 2) {
+		warning("makeAIFFStream: Only 1 or 2 channels are supported, not %d", channels);
+		delete dataStream;
+		return 0;
+	}
+
+	switch (codec) {
+	case kCodecPCM:
+	case MKTAG('t', 'w', 'o', 's'):
+	case MKTAG('s', 'o', 'w', 't'): {
+		// PCM samples are always signed.
+		byte rawFlags = 0;
+		if (bitsPerSample == 16)
+			rawFlags |= Audio::FLAG_16BITS;
+		if (channels == 2)
+			rawFlags |= Audio::FLAG_STEREO;
+		if (codec == MKTAG('s', 'o', 'w', 't'))
+			rawFlags |= Audio::FLAG_LITTLE_ENDIAN;
+
+		return makeRawStream(dataStream, rate, rawFlags); 
+	}
+	case MKTAG('i', 'm', 'a', '4'):
+		// TODO: QT IMA ADPCM is not Seekable
+		// Need to make this function return only an AudioStream and adapt
+		// calling code to use dynamic_cast.
+		warning("Unhandled AIFF-C QT IMA ADPCM compression");
+		break;
+	case MKTAG('Q', 'D', 'M', '2'):
+		// TODO: Need to figure out how to integrate this
+		// (But hopefully never needed)
+		warning("Unhandled AIFF-C QDM2 compression"); 
+		break;
+	default:
+		warning("Unhandled AIFF-C compression tag '%s'", tag2str(codec));
+	}
+	
+	delete dataStream;
+	return 0;
 }
 
 } // End of namespace Audio






More information about the Scummvm-git-logs mailing list