From a1e1b62681dff4f849314a8e9e7b14c8d3d6979d Mon Sep 17 00:00:00 2001 From: Iliyas Jorio Date: Sat, 3 Sep 2022 00:51:25 +0200 Subject: [PATCH] Sound mixer big-endian compatibility --- src/SoundFormats/SoundFormats.cpp | 21 +++++++++++++-------- src/SoundMixer/SoundManager.cpp | 2 +- src/SoundMixer/cmixer.cpp | 14 +++++++------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/SoundFormats/SoundFormats.cpp b/src/SoundFormats/SoundFormats.cpp index d04577e..a629657 100644 --- a/src/SoundFormats/SoundFormats.cpp +++ b/src/SoundFormats/SoundFormats.cpp @@ -38,7 +38,7 @@ static_assert(sizeof(SampledSoundHeader) >= 22 && sizeof(SampledSoundHeader) <= "unexpected SampledSoundHeader size"); constexpr int kSampledSoundHeaderLength = 22; -constexpr const char* kSampledSoundHeaderPackFormat = "IiIIIbb"; +constexpr const char* kSampledSoundHeaderPackFormat = ">IiIIIbb"; enum SampledSoundEncoding { @@ -138,7 +138,7 @@ void Pomme::Sound::GetSoundInfo(const Ptr sndhdr, SampledSoundInfo& info) // Read in SampledSoundHeader and unpack it. SampledSoundHeader header; f.Read(reinterpret_cast(&header), kSampledSoundHeaderLength); - ByteswapStructs(kSampledSoundHeaderPackFormat, kSampledSoundHeaderLength, 1, reinterpret_cast(&header)); + UnpackStructs(kSampledSoundHeaderPackFormat, kSampledSoundHeaderLength, 1, reinterpret_cast(&header)); if (header.zero != 0) { @@ -159,7 +159,7 @@ void Pomme::Sound::GetSoundInfo(const Ptr sndhdr, SampledSoundInfo& info) case kSampledSoundEncoding_stdSH: info.compressionType = 'raw '; // unsigned (in AIFF-C files, 'NONE' means signed!) info.isCompressed = false; - info.bigEndian = false; + info.bigEndian = kIsBigEndianNative; // just use the native endianness for this info.codecBitDepth = 8; info.nChannels = 1; info.nPackets = header.stdSH_nBytes; @@ -187,7 +187,7 @@ void Pomme::Sound::GetSoundInfo(const Ptr sndhdr, SampledSoundInfo& info) std::unique_ptr codec = Pomme::Sound::GetCodec(info.compressionType); info.isCompressed = true; - info.bigEndian = false; + info.bigEndian = kIsBigEndianNative; // just use the native endianness for this info.nChannels = header.cmpSH_nChannels; info.dataStart = sndhdr + f.Tell(); info.codecBitDepth = codec->AIFFBitDepth(); @@ -318,16 +318,16 @@ Boolean Pomme_DecompressSoundResource(SndListHandle* sndHandlePtr, long* offsetT 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; - if (inInfo.bigEndian && bytesPerSample > 1) + if (inInfo.bigEndian != kIsBigEndianNative && bytesPerSample > 1) { int nIntegers = inInfo.decompressedLength / bytesPerSample; if (inInfo.decompressedLength != nIntegers * bytesPerSample) throw std::runtime_error("unexpected big-endian raw PCM decompressed length"); ByteswapInts(bytesPerSample, nIntegers, outDataStart); - outInfo.bigEndian = false; + outInfo.bigEndian = kIsBigEndianNative; } } else @@ -337,8 +337,13 @@ Boolean Pomme_DecompressSoundResource(SndListHandle* sndHandlePtr, long* offsetT auto spanOut = std::span(outDataStart, inInfo.decompressedLength); codec->Decode(inInfo.nChannels, spanIn, spanOut); +#if __BIG_ENDIAN__ + outInfo.compressionType = 'twos'; + outInfo.bigEndian = true; // convert to native endianness +#else outInfo.compressionType = 'swot'; - outInfo.bigEndian = false; + outInfo.bigEndian = false; // convert to native endianness +#endif outInfo.codecBitDepth = 16; outInfo.nPackets = codec->SamplesPerPacket() * inInfo.nPackets; } diff --git a/src/SoundMixer/SoundManager.cpp b/src/SoundMixer/SoundManager.cpp index d8b6b6d..e02a9fe 100644 --- a/src/SoundMixer/SoundManager.cpp +++ b/src/SoundMixer/SoundManager.cpp @@ -150,7 +150,7 @@ static void InstallSoundInChannel(SndChannelPtr chan, const Ptr sampledSoundHead std::unique_ptr codec = Pomme::Sound::GetCodec(info.compressionType); 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) { diff --git a/src/SoundMixer/cmixer.cpp b/src/SoundMixer/cmixer.cpp index b4cf72f..55346ad 100644 --- a/src/SoundMixer/cmixer.cpp +++ b/src/SoundMixer/cmixer.cpp @@ -496,7 +496,7 @@ void WavStream::ClearImplementation() { bitdepth = 0; channels = 0; - bigEndian = false; + bigEndian = kIsBigEndianNative; idx = 0; userBuffer.clear(); } @@ -550,29 +550,29 @@ void WavStream::FillBuffer(int16_t* dst, int fillLength) if (bigEndian && bitdepth == 16 && channels == 1) { WAV_PROCESS_LOOP({ - dst[0] = dst[1] = ByteswapScalar(data16()[idx]); + dst[0] = dst[1] = UnpackI16BE(&data16()[idx]); }); } else if (bigEndian && bitdepth == 16 && channels == 2) { WAV_PROCESS_LOOP({ x = idx * 2; - dst[0] = ByteswapScalar(data16()[x]); - dst[1] = ByteswapScalar(data16()[x + 1]); + dst[0] = UnpackI16BE(&data16()[x]); + dst[1] = UnpackI16BE(&data16()[x + 1]); }); } else if (bitdepth == 16 && channels == 1) { WAV_PROCESS_LOOP({ - dst[0] = dst[1] = data16()[idx]; + dst[0] = dst[1] = UnpackI16LE(&data16()[idx]); }); } else if (bitdepth == 16 && channels == 2) { WAV_PROCESS_LOOP({ x = idx * 2; - dst[0] = data16()[x]; - dst[1] = data16()[x + 1]; + dst[0] = UnpackI16LE(&data16()[x]); + dst[1] = UnpackI16LE(&data16()[x + 1]); }); } else if (bitdepth == 8 && channels == 1)