[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