Пример #1
0
        private double EndiannessHeuristicValue(UShortAccess data, uint dataSize, ref uint maxSamples)
        {
            if (data == null)
            {
                return(50000); // the heuristic value for the wrong endianess is about 21000 (1/3rd of the 16 bits range)
            }
            double diff_sum   = 0;
            uint   cpt        = 0;
            short  prev_value = (short)data[0];

            for (int i = 1; i < dataSize && cpt < maxSamples; ++i)
            {
                short value = (short)data[i];
                if (value != prev_value)
                {
                    diff_sum += Math.Abs((double)(value - prev_value));
                    ++cpt;
                    prev_value = value;
                }
            }
            if (cpt == 0)
            {
                return(50000);
            }
            maxSamples = cpt;
            return(diff_sum / cpt);
        }
Пример #2
0
 public void LoadLiveList(UShortAccess src)
 {
     for (var cnt = 0; cnt < TOTAL_SECTIONS; cnt++)
     {
         if (_liveList[cnt] != 0)
         {
             _resMan.ResClose(_objectList[cnt]);
             _cptData[cnt] = null;
         }
         _liveList[cnt] = src[cnt];
         if (_liveList[cnt] != 0)
         {
             _cptData[cnt] = new ByteAccess(_resMan.CptResOpen(_objectList[cnt]), Header.Size);
         }
     }
 }
Пример #3
0
        private void CalcWaveVolume(UShortAccess data, int length)
        {
            var  blkPos = new UShortAccess(data.Data, data.Offset + 918 * 2);
            uint cnt;

            for (cnt = 0; cnt < WAVE_VOL_TAB_LENGTH; cnt++)
            {
                _waveVolume[cnt] = false;
            }
            _waveVolPos = 0;
            for (uint blkCnt = 1; blkCnt < length / 918; blkCnt++)
            {
                if (blkCnt >= WAVE_VOL_TAB_LENGTH)
                {
                    // TODO: warning("Wave vol tab too small");
                    return;
                }
                int average = 0;
                for (cnt = 0; cnt < 918; cnt++)
                {
                    average += blkPos[(int)cnt];
                }
                average /= 918;
                uint diff = 0;
                for (cnt = 0; cnt < 918; cnt++)
                {
                    short smpDiff = (short)(blkPos[0] - average);
                    diff          += (uint)Math.Abs(smpDiff);
                    blkPos.Offset += 2;
                }
                if (diff > WAVE_VOL_THRESHOLD)
                {
                    _waveVolume[blkCnt - 1] = true;
                }
            }
        }
Пример #4
0
        private UShortAccess UncompressSpeech(uint index, uint cSize, out uint size)
        {
            _cowFile.BaseStream.Seek(index, SeekOrigin.Begin);
            var  fBuf      = _cowFile.ReadBytes((int)cSize);
            uint headerPos = 0;

            while ((fBuf.ToUInt32BigEndian((int)headerPos) != ScummHelper.MakeTag('d', 'a', 't', 'a')) && (headerPos < 100))
            {
                headerPos++;
            }

            UShortAccess srcData;

            if (headerPos < 100)
            {
                int   resSize;
                uint  srcPos;
                short length;
                cSize     /= 2;
                headerPos += 4; // skip 'data' tag
                if (_cowMode != CowMode.CowDemo)
                {
                    resSize    = (int)(fBuf.ToUInt32((int)headerPos) >> 1);
                    headerPos += 4;
                }
                else
                {
                    // the demo speech files have the uncompressed size
                    // embedded in the compressed stream *sigh*
                    //
                    // But not always, apparently. See bug #2182450. Is
                    // there any way to figure out the size other than
                    // decoding the sound in that case?

                    if (fBuf[headerPos + 1] == 0)
                    {
                        if (fBuf.ToInt16((int)headerPos) == 1)
                        {
                            resSize  = fBuf.ToInt16((int)(headerPos + 2));
                            resSize |= fBuf.ToInt16((int)(headerPos + 6)) << 16;
                        }
                        else
                        {
                            resSize = fBuf.ToInt32((int)(headerPos + 2));
                        }
                        resSize >>= 1;
                    }
                    else
                    {
                        resSize = 0;
                        srcData = new UShortAccess(fBuf);
                        srcPos  = headerPos >> 1;
                        while (srcPos < cSize)
                        {
                            length = (short)srcData[(int)srcPos];
                            srcPos++;
                            if (length < 0)
                            {
                                resSize -= length;
                                srcPos++;
                            }
                            else
                            {
                                resSize += length;
                                srcPos   = (uint)(srcPos + length);
                            }
                        }
                    }
                }
                Debug.Assert((headerPos & 1) == 0);
                srcData = new UShortAccess(fBuf);
                srcPos  = headerPos >> 1;
                uint dstPos      = 0;
                var  dstData     = new UShortAccess(new byte[resSize * 2]);
                int  samplesLeft = resSize;
                while (srcPos < cSize && samplesLeft > 0)
                {
                    length = (short)(_bigEndianSpeech ? ScummHelper.SwapBytes(srcData[(int)srcPos]) : srcData[(int)srcPos]);
                    srcPos++;
                    if (length < 0)
                    {
                        length = (short)-length;
                        if (length > samplesLeft)
                        {
                            length = (short)samplesLeft;
                        }
                        short value;
                        if (_bigEndianSpeech)
                        {
                            value = (short)ScummHelper.SwapBytes(srcData[(int)srcPos]);
                        }
                        else
                        {
                            value = (short)srcData[(int)srcPos];
                        }
                        for (ushort cnt = 0; cnt < (ushort)length; cnt++)
                        {
                            dstData[(int)dstPos++] = (ushort)value;
                        }
                        srcPos++;
                    }
                    else
                    {
                        if (length > samplesLeft)
                        {
                            length = (short)samplesLeft;
                        }
                        if (_bigEndianSpeech)
                        {
                            for (ushort cnt = 0; cnt < length; cnt++)
                            {
                                dstData[(int)dstPos++] = ScummHelper.SwapBytes(srcData[(int)srcPos++]);
                            }
                        }
                        else
                        {
                            Array.Copy(srcData.Data, (int)(srcData.Offset + srcPos * 2), dstData.Data, (int)(dstData.Offset + dstPos * 2), length * 2);
                            dstPos = (uint)(dstPos + length);
                            srcPos = (uint)(srcPos + length);
                        }
                    }
                    samplesLeft -= length;
                }
                if (samplesLeft > 0)
                {
                    dstData.Data.Set((int)(dstData.Offset + dstPos), 0, samplesLeft * 2);
                }
                if (_cowMode == CowMode.CowDemo) // demo has wave output size embedded in the compressed data
                {
                    dstData.Data.WriteUInt32(dstData.Offset, 0);
                }
                size = (uint)(resSize * 2);
                CalcWaveVolume(dstData, resSize);
                return(dstData);
            }
            else
            {
                // TODO: warning("Sound::uncompressSpeech(): DATA tag not found in wave header");
                size = 0;
                return(null);
            }
        }