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