[Scummvm-git-logs] scummvm master -> 88f265bd9a67d5154a6d484a44081a9835b09c50

sev- sev at scummvm.org
Wed Apr 14 16:36:51 UTC 2021


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

Summary:
4ea4627b11 AUDIO: Add support for 24 bit PCM WAV
88f265bd9a AUDIO: Remove macro and break conditions to improve readability


Commit: 4ea4627b1187b343ed95da8fcaa9d5292e9d0217
    https://github.com/scummvm/scummvm/commit/4ea4627b1187b343ed95da8fcaa9d5292e9d0217
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2021-04-14T18:36:47+02:00

Commit Message:
AUDIO: Add support for 24 bit PCM WAV

Changed paths:
    audio/decoders/raw.cpp
    audio/decoders/raw.h
    audio/decoders/wave.cpp


diff --git a/audio/decoders/raw.cpp b/audio/decoders/raw.cpp
index 477a8e7967..15836006a4 100644
--- a/audio/decoders/raw.cpp
+++ b/audio/decoders/raw.cpp
@@ -35,8 +35,8 @@ namespace Audio {
 // us to go with the macro approach. So far this is
 // the only template function that MSVC6 seemed to
 // compile incorrectly. Knock on wood.
-#define READ_ENDIAN_SAMPLE(is16Bit, isUnsigned, ptr, isLE) \
-	((is16Bit ? (isLE ? READ_LE_UINT16(ptr) : READ_BE_UINT16(ptr)) : (*ptr << 8)) ^ (isUnsigned ? 0x8000 : 0))
+#define READ_ENDIAN_SAMPLE(bytesPerSample, isUnsigned, ptr, isLE) \
+	((bytesPerSample == 1 ? (*ptr << 8) : (bytesPerSample == 2 ? (isLE ? READ_LE_UINT16(ptr) : READ_BE_UINT16(ptr)) : (int16)((isLE ? READ_LE_UINT24(ptr) : READ_BE_UINT24(ptr)) >> 8))) ^ (isUnsigned ? 0x8000 : 0))
 
 
 #pragma mark -
@@ -46,17 +46,17 @@ namespace Audio {
 /**
  * This is a stream, which allows for playing raw PCM data from a stream.
  */
-template<bool is16Bit, bool isUnsigned, bool isLE>
+template<int bytesPerSample, bool isUnsigned, bool isLE>
 class RawStream : public SeekableAudioStream {
 public:
 	RawStream(int rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream)
 		: _rate(rate), _isStereo(stereo), _playtime(0, rate), _stream(stream, disposeStream), _endOfData(false), _buffer(0) {
 		// Setup our buffer for readBuffer
-		_buffer = new byte[kSampleBufferLength * (is16Bit ? 2 : 1)];
+		_buffer = new byte[kSampleBufferLength * bytesPerSample];
 		assert(_buffer);
 
 		// Calculate the total playtime of the stream
-		_playtime = Timestamp(0, _stream->size() / (_isStereo ? 2 : 1) / (is16Bit ? 2 : 1), rate);
+		_playtime = Timestamp(0, _stream->size() / (_isStereo ? 2 : 1) / bytesPerSample, rate);
 	}
 
 	~RawStream() {
@@ -99,8 +99,8 @@ private:
 	int fillBuffer(int maxSamples);
 };
 
-template<bool is16Bit, bool isUnsigned, bool isLE>
-int RawStream<is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffer, const int numSamples) {
+template<int bytesPerSample, bool isUnsigned, bool isLE>
+int RawStream<bytesPerSample, isUnsigned, isLE>::readBuffer(int16 *buffer, const int numSamples) {
 	int samplesLeft = numSamples;
 
 	while (samplesLeft > 0) {
@@ -118,16 +118,16 @@ int RawStream<is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffer, const int nu
 		// Copy the data to the caller's buffer.
 		const byte *src = _buffer;
 		while (len-- > 0) {
-			*buffer++ = READ_ENDIAN_SAMPLE(is16Bit, isUnsigned, src, isLE);
-			src += (is16Bit ? 2 : 1);
+			*buffer++ = READ_ENDIAN_SAMPLE(bytesPerSample, isUnsigned, src, isLE);
+			src += bytesPerSample;
 		}
 	}
 
 	return numSamples - samplesLeft;
 }
 
-template<bool is16Bit, bool isUnsigned, bool isLE>
-int RawStream<is16Bit, isUnsigned, isLE>::fillBuffer(int maxSamples) {
+template<int bytesPerSample, bool isUnsigned, bool isLE>
+int RawStream<bytesPerSample, isUnsigned, isLE>::fillBuffer(int maxSamples) {
 	int bufferedSamples = 0;
 	byte *dst = _buffer;
 
@@ -140,11 +140,11 @@ int RawStream<is16Bit, isUnsigned, isLE>::fillBuffer(int maxSamples) {
 	while (maxSamples > 0 && !endOfData()) {
 		// Try to read all the sample data and update the
 		// destination pointer.
-		const int bytesRead = _stream->read(dst, maxSamples * (is16Bit ? 2 : 1));
+		const int bytesRead = _stream->read(dst, maxSamples * bytesPerSample);
 		dst += bytesRead;
 
 		// Calculate how many samples we actually read.
-		const int samplesRead = bytesRead / (is16Bit ? 2 : 1);
+		const int samplesRead = bytesRead / bytesPerSample;
 
 		// Update all status variables
 		bufferedSamples += samplesRead;
@@ -159,15 +159,15 @@ int RawStream<is16Bit, isUnsigned, isLE>::fillBuffer(int maxSamples) {
 	return bufferedSamples;
 }
 
-template<bool is16Bit, bool isUnsigned, bool isLE>
-bool RawStream<is16Bit, isUnsigned, isLE>::seek(const Timestamp &where) {
+template<int bytesPerSample, bool isUnsigned, bool isLE>
+bool RawStream<bytesPerSample, isUnsigned, isLE>::seek(const Timestamp &where) {
 	_endOfData = true;
 
 	if (where > _playtime)
 		return false;
 
 	const uint32 seekSample = convertTimeToStreamPos(where, getRate(), isStereo()).totalNumberOfFrames();
-	_stream->seek(seekSample * (is16Bit ? 2 : 1), SEEK_SET);
+	_stream->seek(seekSample * bytesPerSample, SEEK_SET);
 
 	// In case of an error we will not continue stream playback.
 	if (!_stream->err() && !_stream->eos() && _stream->pos() != _stream->size())
@@ -190,23 +190,28 @@ bool RawStream<is16Bit, isUnsigned, isLE>::seek(const Timestamp &where) {
  */
 
 #define MAKE_RAW_STREAM(UNSIGNED) \
-		if (is16Bit) { \
+		if (bytesPerSample == 3) { \
 			if (isLE) \
-				return new RawStream<true, UNSIGNED, true>(rate, isStereo, disposeAfterUse, stream); \
+				return new RawStream<3, UNSIGNED, true>(rate, isStereo, disposeAfterUse, stream); \
 			else  \
-				return new RawStream<true, UNSIGNED, false>(rate, isStereo, disposeAfterUse, stream); \
+				return new RawStream<3, UNSIGNED, false>(rate, isStereo, disposeAfterUse, stream); \
+		} else if (bytesPerSample == 2) { \
+			if (isLE) \
+				return new RawStream<2, UNSIGNED, true>(rate, isStereo, disposeAfterUse, stream); \
+			else  \
+				return new RawStream<2, UNSIGNED, false>(rate, isStereo, disposeAfterUse, stream); \
 		} else \
-			return new RawStream<false, UNSIGNED, false>(rate, isStereo, disposeAfterUse, stream)
+			return new RawStream<1, UNSIGNED, false>(rate, isStereo, disposeAfterUse, stream)
 
 SeekableAudioStream *makeRawStream(Common::SeekableReadStream *stream,
                                    int rate, byte flags,
                                    DisposeAfterUse::Flag disposeAfterUse) {
-	const bool isStereo   = (flags & Audio::FLAG_STEREO) != 0;
-	const bool is16Bit    = (flags & Audio::FLAG_16BITS) != 0;
-	const bool isUnsigned = (flags & Audio::FLAG_UNSIGNED) != 0;
-	const bool isLE       = (flags & Audio::FLAG_LITTLE_ENDIAN) != 0;
+	const bool isStereo      = (flags & Audio::FLAG_STEREO) != 0;
+	const int bytesPerSample = (flags & Audio::FLAG_24BITS ? 3 : (flags & Audio::FLAG_16BITS ? 2 : 1));
+	const bool isUnsigned    = (flags & Audio::FLAG_UNSIGNED) != 0;
+	const bool isLE          = (flags & Audio::FLAG_LITTLE_ENDIAN) != 0;
 
-	assert(stream->size() % ((is16Bit ? 2 : 1) * (isStereo ? 2 : 1)) == 0);
+	assert(stream->size() % (bytesPerSample * (isStereo ? 2 : 1)) == 0);
 
 	if (isUnsigned) {
 		MAKE_RAW_STREAM(true);
diff --git a/audio/decoders/raw.h b/audio/decoders/raw.h
index 7ccbcdaded..a13f4fe444 100644
--- a/audio/decoders/raw.h
+++ b/audio/decoders/raw.h
@@ -54,11 +54,14 @@ enum RawFlags {
 	/** sound is 16 bits wide (default: 8bit) */
 	FLAG_16BITS = 1 << 1,
 
+	/** sound is 24 bits wide (default: 8bit) */
+	FLAG_24BITS = 1 << 2,
+
 	/** samples are little endian (default: big endian) */
-	FLAG_LITTLE_ENDIAN = 1 << 2,
+	FLAG_LITTLE_ENDIAN = 1 << 3,
 
 	/** sound is in stereo (default: mono) */
-	FLAG_STEREO = 1 << 3
+	FLAG_STEREO = 1 << 4
 };
 
 /**
diff --git a/audio/decoders/wave.cpp b/audio/decoders/wave.cpp
index 113ffc7e61..67e0b31d83 100644
--- a/audio/decoders/wave.cpp
+++ b/audio/decoders/wave.cpp
@@ -141,6 +141,8 @@ bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate,
 		flags |= Audio::FLAG_UNSIGNED;
 	else if (bitsPerSample == 16)	// 16 bit data is signed little endian
 		flags |= (Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN);
+	else if (bitsPerSample == 24)	// 24 bit data is signed little endian
+		flags |= (Audio::FLAG_24BITS | Audio::FLAG_LITTLE_ENDIAN);
 	else if (bitsPerSample == 4 && (type == kWaveFormatMSADPCM || type == kWaveFormatMSIMAADPCM))
 		flags |= Audio::FLAG_16BITS;
 	else {
@@ -193,7 +195,7 @@ SeekableAudioStream *makeWAVStream(Common::SeekableReadStream *stream, DisposeAf
 		return 0;
 	}
 	int channels = (flags & Audio::FLAG_STEREO) ? 2 : 1;
-	int bytesPerSample = (flags & Audio::FLAG_16BITS) ? 2 : 1;
+	int bytesPerSample = (flags & Audio::FLAG_24BITS) ? 3 : ((flags & Audio::FLAG_16BITS) ? 2 : 1);
 
 	// Raw PCM, make sure the last packet is complete
 	if (type == kWaveFormatPCM) {


Commit: 88f265bd9a67d5154a6d484a44081a9835b09c50
    https://github.com/scummvm/scummvm/commit/88f265bd9a67d5154a6d484a44081a9835b09c50
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2021-04-14T18:36:47+02:00

Commit Message:
AUDIO: Remove macro and break conditions to improve readability

Changed paths:
    audio/decoders/raw.cpp


diff --git a/audio/decoders/raw.cpp b/audio/decoders/raw.cpp
index 15836006a4..2ecc791870 100644
--- a/audio/decoders/raw.cpp
+++ b/audio/decoders/raw.cpp
@@ -30,15 +30,6 @@
 
 namespace Audio {
 
-// This used to be an inline template function, but
-// buggy template function handling in MSVC6 forced
-// us to go with the macro approach. So far this is
-// the only template function that MSVC6 seemed to
-// compile incorrectly. Knock on wood.
-#define READ_ENDIAN_SAMPLE(bytesPerSample, isUnsigned, ptr, isLE) \
-	((bytesPerSample == 1 ? (*ptr << 8) : (bytesPerSample == 2 ? (isLE ? READ_LE_UINT16(ptr) : READ_BE_UINT16(ptr)) : (int16)((isLE ? READ_LE_UINT24(ptr) : READ_BE_UINT24(ptr)) >> 8))) ^ (isUnsigned ? 0x8000 : 0))
-
-
 #pragma mark -
 #pragma mark --- RawStream ---
 #pragma mark -
@@ -118,7 +109,13 @@ int RawStream<bytesPerSample, isUnsigned, isLE>::readBuffer(int16 *buffer, const
 		// Copy the data to the caller's buffer.
 		const byte *src = _buffer;
 		while (len-- > 0) {
-			*buffer++ = READ_ENDIAN_SAMPLE(bytesPerSample, isUnsigned, src, isLE);
+			if (bytesPerSample == 1)
+				*buffer++ = (*src << 8) ^ (isUnsigned ? 0x8000 : 0);
+			else if (bytesPerSample == 2)
+				*buffer++ = ((isLE ? READ_LE_UINT16(src) : READ_BE_UINT16(src)) ^ (isUnsigned ? 0x8000 : 0));
+			else // if (bytesPerSample == 3)
+				*buffer++ = (((int16)((isLE ? READ_LE_UINT24(src) : READ_BE_UINT24(src)) >> 8)) ^ (isUnsigned ? 0x8000 : 0));
+
 			src += bytesPerSample;
 		}
 	}




More information about the Scummvm-git-logs mailing list