mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-02 13:51:52 +00:00
Always output 16-bit samples from SmackerDecoder
This commit is contained in:
parent
3b6723e6f2
commit
d11e2ef1ac
3 changed files with 38 additions and 65 deletions
|
@ -611,7 +611,6 @@ struct AudioData
|
|||
{
|
||||
SmackerAudioInfo inf;
|
||||
|
||||
std::vector<uint16_t> samples;
|
||||
int nWrite = 0;
|
||||
int nRead = 0;
|
||||
};
|
||||
|
@ -625,7 +624,7 @@ class SmkPlayer : public MoviePlayer
|
|||
uint8_t palette[768];
|
||||
AnimTextures animtex;
|
||||
TArray<uint8_t> pFrame;
|
||||
TArray<uint8_t> audioBuffer;
|
||||
TArray<int16_t> audioBuffer;
|
||||
int nFrames;
|
||||
bool fullscreenScale;
|
||||
uint64_t nFrameNs;
|
||||
|
@ -672,10 +671,13 @@ public:
|
|||
if (avail >= skip)
|
||||
{
|
||||
audiooffset += skip / framesize;
|
||||
adata.nRead += skip / 2;
|
||||
if (adata.nRead >= adata.nWrite)
|
||||
adata.nRead = adata.nWrite = 0;
|
||||
avail -= skip;
|
||||
if (avail > skip)
|
||||
{
|
||||
adata.nRead += skip / 2;
|
||||
avail -= skip;
|
||||
}
|
||||
else
|
||||
adata.nRead = adata.nWrite = avail = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -685,12 +687,11 @@ public:
|
|||
skip -= avail;
|
||||
avail = 0;
|
||||
|
||||
auto read = Smacker_GetAudioData(hSMK, 0, (int16_t*)audioBuffer.Data());
|
||||
auto read = Smacker_GetAudioData(hSMK, 0, audioBuffer.Data());
|
||||
if (read == 0) break;
|
||||
|
||||
if (adata.inf.bitsPerSample == 8) copy8bitSamples(read);
|
||||
else copy16bitSamples(read);
|
||||
avail += read;
|
||||
adata.nWrite = read / 2;
|
||||
avail = read;
|
||||
}
|
||||
}
|
||||
else if(delay < 0.0)
|
||||
|
@ -700,18 +701,17 @@ public:
|
|||
|
||||
if(avail == 0)
|
||||
{
|
||||
auto read = Smacker_GetAudioData(hSMK, 0, (int16_t*)audioBuffer.Data());
|
||||
auto read = Smacker_GetAudioData(hSMK, 0, audioBuffer.Data());
|
||||
if (read == 0) return false;
|
||||
|
||||
if (adata.inf.bitsPerSample == 8) copy8bitSamples(read);
|
||||
else copy16bitSamples(read);
|
||||
avail += read;
|
||||
adata.nWrite = read / 2;
|
||||
avail = read;
|
||||
}
|
||||
|
||||
// Offset the measured audio position to account for the duplicated samples.
|
||||
audiooffset -= dup/framesize;
|
||||
|
||||
char *src = (char*)&adata.samples[adata.nRead];
|
||||
char *src = (char*)&audioBuffer[adata.nRead];
|
||||
char *dst = (char*)buff;
|
||||
|
||||
for(int i=0;i < dup;++i)
|
||||
|
@ -726,7 +726,7 @@ public:
|
|||
{
|
||||
if (avail == 0)
|
||||
{
|
||||
auto read = Smacker_GetAudioData(hSMK, 0, (int16_t*)audioBuffer.Data());
|
||||
auto read = Smacker_GetAudioData(hSMK, 0, audioBuffer.Data());
|
||||
if (read == 0)
|
||||
{
|
||||
if (wrote == 0)
|
||||
|
@ -734,14 +734,13 @@ public:
|
|||
break;
|
||||
}
|
||||
|
||||
if (adata.inf.bitsPerSample == 8) copy8bitSamples(read);
|
||||
else copy16bitSamples(read);
|
||||
avail += read;
|
||||
adata.nWrite = read / 2;
|
||||
avail = read;
|
||||
}
|
||||
|
||||
int todo = std::min(len-wrote, avail);
|
||||
|
||||
memcpy((char*)buff+wrote, &adata.samples[adata.nRead], todo);
|
||||
memcpy((char*)buff+wrote, &audioBuffer[adata.nRead], todo);
|
||||
adata.nRead += todo / 2;
|
||||
if(adata.nRead == adata.nWrite)
|
||||
adata.nRead = adata.nWrite = 0;
|
||||
|
@ -756,33 +755,6 @@ public:
|
|||
static bool StreamCallbackC(SoundStream* stream, void* buff, int len, void* userdata)
|
||||
{ return static_cast<SmkPlayer*>(userdata)->StreamCallback(stream, buff, len); }
|
||||
|
||||
void copy8bitSamples(unsigned count)
|
||||
{
|
||||
for (unsigned i = 0; i < count;)
|
||||
{
|
||||
unsigned todo = std::min<unsigned>(count-i, std::size(adata.samples)-adata.nWrite);
|
||||
for (unsigned j = 0;j < todo;++j)
|
||||
adata.samples[adata.nWrite+j] = (audioBuffer[i+j] - 128) << 8;
|
||||
adata.nWrite += todo;
|
||||
if (adata.nWrite >= (int)std::size(adata.samples)) adata.nWrite = 0;
|
||||
i += todo;
|
||||
}
|
||||
}
|
||||
|
||||
void copy16bitSamples(unsigned count)
|
||||
{
|
||||
auto ptr = (uint16_t*)audioBuffer.Data();
|
||||
count /= 2;
|
||||
for (unsigned i = 0; i < count;)
|
||||
{
|
||||
unsigned todo = std::min<unsigned>(count-i, std::size(adata.samples)-adata.nWrite);
|
||||
memcpy(&adata.samples[adata.nWrite], ptr, todo*2);
|
||||
adata.nWrite += todo;
|
||||
if (adata.nWrite >= (int)std::size(adata.samples)) adata.nWrite = 0;
|
||||
i += todo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SmkPlayer(const char *fn, TArray<int>& ans, int flags_) : animSnd(std::move(ans))
|
||||
{
|
||||
|
@ -807,8 +779,7 @@ public:
|
|||
adata.inf = Smacker_GetAudioTrackDetails(hSMK, 0);
|
||||
if (adata.inf.idealBufferSize > 0)
|
||||
{
|
||||
audioBuffer.Resize(adata.inf.idealBufferSize);
|
||||
adata.samples.resize(adata.inf.idealBufferSize);
|
||||
audioBuffer.Resize(adata.inf.idealBufferSize / 2);
|
||||
hassound = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,6 @@ struct SmackerAudioInfo
|
|||
{
|
||||
uint32_t sampleRate;
|
||||
uint8_t nChannels;
|
||||
uint8_t bitsPerSample;
|
||||
|
||||
uint32_t idealBufferSize;
|
||||
};
|
||||
|
|
|
@ -449,13 +449,18 @@ bool SmackerDecoder::Open(const char *fileName)
|
|||
{
|
||||
if (frameFlag & 1)
|
||||
{
|
||||
// skip size
|
||||
file.Skip(4);
|
||||
|
||||
uint32_t size = file.ReadUint32LE();
|
||||
uint32_t unpackedSize = file.ReadUint32LE();
|
||||
|
||||
// If the track isn't 16-bit, double the buffer size for converting 8-bit to 16-bit.
|
||||
if (!(audioTracks[i].flags & SMK_AUD_16BITS))
|
||||
unpackedSize *= 2;
|
||||
|
||||
audioTracks[i].bufferSize = unpackedSize;
|
||||
audioTracks[i].buffer = new uint8_t[unpackedSize];
|
||||
|
||||
// skip size
|
||||
file.Skip(size - 8);
|
||||
}
|
||||
frameFlag >>= 1;
|
||||
}
|
||||
|
@ -725,6 +730,7 @@ void SmackerDecoder::GetNextFrame()
|
|||
}
|
||||
SmackerPacket pkt = std::move(framePacketData.front());
|
||||
framePacketData.pop_front();
|
||||
flock.unlock();
|
||||
|
||||
uint32_t frameSize = pkt.size;
|
||||
uint8_t frameFlag = frameFlags[currentFrame];
|
||||
|
@ -1017,18 +1023,14 @@ int SmackerDecoder::DecodeAudio(const uint8_t *dataPtr, uint32_t size, SmackerAu
|
|||
int pred[2] = {0, 0};
|
||||
|
||||
int16_t *samples = reinterpret_cast<int16_t*>(track.buffer);
|
||||
int8_t *samples8 = reinterpret_cast<int8_t*>(track.buffer);
|
||||
|
||||
int buf_size = track.bufferSize;
|
||||
|
||||
if (buf_size <= 4) {
|
||||
Printf("SmackerDecoder::DecodeAudio() - Packet is too small\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
SmackerCommon::BitReader bits(dataPtr, size);
|
||||
|
||||
unpackedSize = bits.GetBits(32);
|
||||
if (unpackedSize <= 4) {
|
||||
Printf("SmackerDecoder::DecodeAudio() - Packet is too small\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!bits.GetBit()) {
|
||||
// no sound data
|
||||
|
@ -1101,7 +1103,7 @@ int SmackerDecoder::DecodeAudio(const uint8_t *dataPtr, uint32_t size, SmackerAu
|
|||
for (i = stereo; i >= 0; i--)
|
||||
pred[i] = bits.GetBits(8);
|
||||
for (i = 0; i <= stereo; i++)
|
||||
*samples8++ = pred[i];
|
||||
*samples++ = (pred[i]-128) << 8;
|
||||
for (; i < unpackedSize; i++) {
|
||||
if (i & stereo){
|
||||
if (VLC_GetSize(vlc[1]))
|
||||
|
@ -1109,16 +1111,17 @@ int SmackerDecoder::DecodeAudio(const uint8_t *dataPtr, uint32_t size, SmackerAu
|
|||
else
|
||||
res = 0;
|
||||
pred[1] += (int8_t)h[1].values[res];
|
||||
*samples8++ = pred[1];
|
||||
*samples++ = (pred[1]-128) << 8;
|
||||
} else {
|
||||
if (VLC_GetSize(vlc[0]))
|
||||
res = VLC_GetCodeBits(bits, vlc[0]);
|
||||
else
|
||||
res = 0;
|
||||
pred[0] += (int8_t)h[0].values[res];
|
||||
*samples8++ = pred[0];
|
||||
*samples++ = (pred[0]-128) << 8;
|
||||
}
|
||||
}
|
||||
unpackedSize *= 2;
|
||||
}
|
||||
|
||||
track.bytesReadThisFrame = unpackedSize;
|
||||
|
@ -1201,7 +1204,6 @@ SmackerAudioInfo SmackerDecoder::GetAudioTrackDetails(uint32_t trackIndex)
|
|||
|
||||
info.sampleRate = track->sampleRate;
|
||||
info.nChannels = track->nChannels;
|
||||
info.bitsPerSample = track->bitsPerSample;
|
||||
|
||||
// audio buffer size in bytes
|
||||
info.idealBufferSize = track->bufferSize;
|
||||
|
@ -1228,6 +1230,7 @@ uint32_t SmackerDecoder::GetAudioData(uint32_t trackIndex, int16_t *audioBuffer)
|
|||
}
|
||||
SmackerPacket pkt = std::move(track->packetData.front());
|
||||
track->packetData.pop_front();
|
||||
flock.unlock();
|
||||
|
||||
track->bytesReadThisFrame = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue