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");
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<char*>(&header), kSampledSoundHeaderLength);
ByteswapStructs(kSampledSoundHeaderPackFormat, kSampledSoundHeaderLength, 1, reinterpret_cast<char*>(&header));
UnpackStructs(kSampledSoundHeaderPackFormat, kSampledSoundHeaderLength, 1, reinterpret_cast<char*>(&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<Pomme::Sound::Codec> 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;
}

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);
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)
{

View File

@ -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)