Sound mixer big-endian compatibility

This commit is contained in:
Iliyas Jorio 2022-09-03 00:51:25 +02:00
parent 191500dec1
commit a1e1b62681
3 changed files with 21 additions and 16 deletions

View File

@ -38,7 +38,7 @@ static_assert(sizeof(SampledSoundHeader) >= 22 && sizeof(SampledSoundHeader) <=
"unexpected SampledSoundHeader size"); "unexpected SampledSoundHeader size");
constexpr int kSampledSoundHeaderLength = 22; constexpr int kSampledSoundHeaderLength = 22;
constexpr const char* kSampledSoundHeaderPackFormat = "IiIIIbb"; constexpr const char* kSampledSoundHeaderPackFormat = ">IiIIIbb";
enum SampledSoundEncoding enum SampledSoundEncoding
{ {
@ -138,7 +138,7 @@ void Pomme::Sound::GetSoundInfo(const Ptr sndhdr, SampledSoundInfo& info)
// Read in SampledSoundHeader and unpack it. // Read in SampledSoundHeader and unpack it.
SampledSoundHeader header; SampledSoundHeader header;
f.Read(reinterpret_cast<char*>(&header), kSampledSoundHeaderLength); f.Read(reinterpret_cast<char*>(&header), kSampledSoundHeaderLength);
ByteswapStructs(kSampledSoundHeaderPackFormat, kSampledSoundHeaderLength, 1, reinterpret_cast<char*>(&header)); UnpackStructs(kSampledSoundHeaderPackFormat, kSampledSoundHeaderLength, 1, reinterpret_cast<char*>(&header));
if (header.zero != 0) if (header.zero != 0)
{ {
@ -159,7 +159,7 @@ void Pomme::Sound::GetSoundInfo(const Ptr sndhdr, SampledSoundInfo& info)
case kSampledSoundEncoding_stdSH: case kSampledSoundEncoding_stdSH:
info.compressionType = 'raw '; // unsigned (in AIFF-C files, 'NONE' means signed!) info.compressionType = 'raw '; // unsigned (in AIFF-C files, 'NONE' means signed!)
info.isCompressed = false; info.isCompressed = false;
info.bigEndian = false; info.bigEndian = kIsBigEndianNative; // just use the native endianness for this
info.codecBitDepth = 8; info.codecBitDepth = 8;
info.nChannels = 1; info.nChannels = 1;
info.nPackets = header.stdSH_nBytes; info.nPackets = header.stdSH_nBytes;
@ -187,7 +187,7 @@ void Pomme::Sound::GetSoundInfo(const Ptr sndhdr, SampledSoundInfo& info)
std::unique_ptr<Pomme::Sound::Codec> codec = Pomme::Sound::GetCodec(info.compressionType); std::unique_ptr<Pomme::Sound::Codec> codec = Pomme::Sound::GetCodec(info.compressionType);
info.isCompressed = true; info.isCompressed = true;
info.bigEndian = false; info.bigEndian = kIsBigEndianNative; // just use the native endianness for this
info.nChannels = header.cmpSH_nChannels; info.nChannels = header.cmpSH_nChannels;
info.dataStart = sndhdr + f.Tell(); info.dataStart = sndhdr + f.Tell();
info.codecBitDepth = codec->AIFFBitDepth(); info.codecBitDepth = codec->AIFFBitDepth();
@ -318,16 +318,16 @@ Boolean Pomme_DecompressSoundResource(SndListHandle* sndHandlePtr, long* offsetT
memcpy(outDataStart, inDataStart, inInfo.decompressedLength); memcpy(outDataStart, inDataStart, inInfo.decompressedLength);
// If it's big endian, swap the bytes // If the PCM data's endianness doesn't match our native endianness, swap the bytes
int bytesPerSample = inInfo.codecBitDepth / 8; int bytesPerSample = inInfo.codecBitDepth / 8;
if (inInfo.bigEndian && bytesPerSample > 1) if (inInfo.bigEndian != kIsBigEndianNative && bytesPerSample > 1)
{ {
int nIntegers = inInfo.decompressedLength / bytesPerSample; int nIntegers = inInfo.decompressedLength / bytesPerSample;
if (inInfo.decompressedLength != nIntegers * bytesPerSample) if (inInfo.decompressedLength != nIntegers * bytesPerSample)
throw std::runtime_error("unexpected big-endian raw PCM decompressed length"); throw std::runtime_error("unexpected big-endian raw PCM decompressed length");
ByteswapInts(bytesPerSample, nIntegers, outDataStart); ByteswapInts(bytesPerSample, nIntegers, outDataStart);
outInfo.bigEndian = false; outInfo.bigEndian = kIsBigEndianNative;
} }
} }
else else
@ -337,8 +337,13 @@ Boolean Pomme_DecompressSoundResource(SndListHandle* sndHandlePtr, long* offsetT
auto spanOut = std::span(outDataStart, inInfo.decompressedLength); auto spanOut = std::span(outDataStart, inInfo.decompressedLength);
codec->Decode(inInfo.nChannels, spanIn, spanOut); codec->Decode(inInfo.nChannels, spanIn, spanOut);
#if __BIG_ENDIAN__
outInfo.compressionType = 'twos';
outInfo.bigEndian = true; // convert to native endianness
#else
outInfo.compressionType = 'swot'; outInfo.compressionType = 'swot';
outInfo.bigEndian = false; outInfo.bigEndian = false; // convert to native endianness
#endif
outInfo.codecBitDepth = 16; outInfo.codecBitDepth = 16;
outInfo.nPackets = codec->SamplesPerPacket() * inInfo.nPackets; outInfo.nPackets = codec->SamplesPerPacket() * inInfo.nPackets;
} }

View File

@ -150,7 +150,7 @@ static void InstallSoundInChannel(SndChannelPtr chan, const Ptr sampledSoundHead
std::unique_ptr<Pomme::Sound::Codec> codec = Pomme::Sound::GetCodec(info.compressionType); std::unique_ptr<Pomme::Sound::Codec> codec = Pomme::Sound::GetCodec(info.compressionType);
codec->Decode(info.nChannels, spanIn, spanOut); codec->Decode(info.nChannels, spanIn, spanOut);
impl.source.Init(info.sampleRate, 16, info.nChannels, false, spanOut); impl.source.Init(info.sampleRate, 16, info.nChannels, kIsBigEndianNative, spanOut);
} }
else if (forceCopy) else if (forceCopy)
{ {

View File

@ -496,7 +496,7 @@ void WavStream::ClearImplementation()
{ {
bitdepth = 0; bitdepth = 0;
channels = 0; channels = 0;
bigEndian = false; bigEndian = kIsBigEndianNative;
idx = 0; idx = 0;
userBuffer.clear(); userBuffer.clear();
} }
@ -550,29 +550,29 @@ void WavStream::FillBuffer(int16_t* dst, int fillLength)
if (bigEndian && bitdepth == 16 && channels == 1) if (bigEndian && bitdepth == 16 && channels == 1)
{ {
WAV_PROCESS_LOOP({ WAV_PROCESS_LOOP({
dst[0] = dst[1] = ByteswapScalar(data16()[idx]); dst[0] = dst[1] = UnpackI16BE(&data16()[idx]);
}); });
} }
else if (bigEndian && bitdepth == 16 && channels == 2) else if (bigEndian && bitdepth == 16 && channels == 2)
{ {
WAV_PROCESS_LOOP({ WAV_PROCESS_LOOP({
x = idx * 2; x = idx * 2;
dst[0] = ByteswapScalar(data16()[x]); dst[0] = UnpackI16BE(&data16()[x]);
dst[1] = ByteswapScalar(data16()[x + 1]); dst[1] = UnpackI16BE(&data16()[x + 1]);
}); });
} }
else if (bitdepth == 16 && channels == 1) else if (bitdepth == 16 && channels == 1)
{ {
WAV_PROCESS_LOOP({ WAV_PROCESS_LOOP({
dst[0] = dst[1] = data16()[idx]; dst[0] = dst[1] = UnpackI16LE(&data16()[idx]);
}); });
} }
else if (bitdepth == 16 && channels == 2) else if (bitdepth == 16 && channels == 2)
{ {
WAV_PROCESS_LOOP({ WAV_PROCESS_LOOP({
x = idx * 2; x = idx * 2;
dst[0] = data16()[x]; dst[0] = UnpackI16LE(&data16()[x]);
dst[1] = data16()[x + 1]; dst[1] = UnpackI16LE(&data16()[x + 1]);
}); });
} }
else if (bitdepth == 8 && channels == 1) else if (bitdepth == 8 && channels == 1)