(MioDecoder.DecodeSoundPCM16): use unsafe block to pack 16-bit samples into byte array.

This commit is contained in:
morkt 2015-11-07 14:40:40 +04:00
parent 4543d06841
commit a44c9b15a5

View File

@ -219,18 +219,21 @@ namespace GameRes.Formats.Entis
uint nSampleCount = datahdr.SampleCount; uint nSampleCount = datahdr.SampleCount;
uint nChannelCount = (uint)m_mioih.ChannelCount; uint nChannelCount = (uint)m_mioih.ChannelCount;
uint nAllSampleCount = nSampleCount * nChannelCount; uint nAllSampleCount = nSampleCount * nChannelCount;
uint nBytes = nAllSampleCount * sizeof(short);
if (ptrWaveBuf.Length < wave_pos + (int)nBytes)
return false;
if (nSampleCount > m_nBufLength) if (nSampleCount > m_nBufLength)
{ {
m_ptrBuffer3 = new sbyte[nAllSampleCount * sizeof(short)]; m_ptrBuffer3 = new sbyte[nBytes];
m_ptrBuffer4 = new byte[nAllSampleCount * sizeof(short)]; m_ptrBuffer4 = new byte[nBytes];
m_nBufLength = nSampleCount; m_nBufLength = nSampleCount;
} }
if (0 != (datahdr.Flags & MIO_LEAD_BLOCK)) if (0 != (datahdr.Flags & MIO_LEAD_BLOCK))
{ {
(context as HuffmanDecodeContext).PrepareToDecodeERINACode(); (context as HuffmanDecodeContext).PrepareToDecodeERINACode();
} }
uint nBytes = nAllSampleCount * sizeof(short);
if (context.DecodeBytes (m_ptrBuffer3, nBytes) < nBytes) if (context.DecodeBytes (m_ptrBuffer3, nBytes) < nBytes)
{ {
return false; return false;
@ -251,22 +254,29 @@ namespace GameRes.Formats.Entis
m_ptrBuffer4[pbytDstBuf + j * sizeof(short) + 1] = (byte)(bytHigh ^ (bytLow >> 7)); m_ptrBuffer4[pbytDstBuf + j * sizeof(short) + 1] = (byte)(bytHigh ^ (bytLow >> 7));
} }
} }
int ptrSrcBuf = 0; // (SWORD*) m_ptrBuffer4; if (m_ptrBuffer4.Length < nBytes)
int nStep = m_mioih.ChannelCount*sizeof(short); return false;
unsafe
{
fixed (byte* rawBuffer4 = m_ptrBuffer4, rawWaveBuf = &ptrWaveBuf[wave_pos])
{
int nStep = m_mioih.ChannelCount;
short* ptrSrcBuf = (short*)rawBuffer4;
for (int i = 0; i < m_mioih.ChannelCount; i++) for (int i = 0; i < m_mioih.ChannelCount; i++)
{ {
int ptrDstBuf = wave_pos + i*sizeof(short); // (SWORD*) ptrWaveBuf; short* ptrDstBuf = (short*)rawWaveBuf + i; // (SWORD*) ptrWaveBuf;
short wValue = 0; short wValue = 0;
short wDelta = 0; short wDelta = 0;
for (uint j = 0; j < nSampleCount; j++) for (uint j = 0; j < nSampleCount; j++)
{ {
wDelta += LittleEndian.ToInt16 (m_ptrBuffer4, ptrSrcBuf); wDelta += *ptrSrcBuf++;
wValue += wDelta; wValue += wDelta;
LittleEndian.Pack (wValue, ptrWaveBuf, ptrDstBuf); // *ptrDstBuf = wValue; *ptrDstBuf = wValue;
ptrSrcBuf += sizeof(short);
ptrDstBuf += nStep; ptrDstBuf += nStep;
} }
} }
}
}
return true; return true;
} }