WSS File Format: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
No edit summary
 
m (added to file formats)
Line 86: Line 86:
   else PCMData[j] = (j == 0) ? (Int16)0 : PCMData[j - 1];
   else PCMData[j] = (j == 0) ? (Int16)0 : PCMData[j - 1];
  }
  }
[[Category:BIS_File_Formats]]

Revision as of 02:13, 25 January 2010

Introduction

WSS files are used since OFP times to store sound data and its file format is pretty much like the RIFF WAVE file format used for .wav files.

File Format

Offset Datatype Content Description
0 char[4] "WSS0" file signature
4 ulong <compression> if <compression> == 8 the PCM data is compressed, otherwise <compression> == 0
8 ushort <format tag> defines in which format the data is saved. Always 0x0001 in WSS files
10 ushort <channels> number of channels: 1=mono, 2=stereo
12 ulong <sample rate> sample rate in Hz (e.g. 44100Hz)
16 ulong <bytes/second> <sample rate> * <block align>
20 ushort <block align> <channels> * (<bits/sample> / 8)
22 ushort <bits/sample> usually 0x0010 in WSS files
24 ushort <unknown> unknown value
26 byte[fileSize-26] <soundData> here the PCM data of the sound is stored

Decompression

If the <soundData> is compressed the following (C#) code can be used for decompression:

PCMData = new Int16[soundData.Length];
for (int j = 0; j < PCMData.Length; j++)
{
  SByte srcSample = (SByte)soundData[j];
  if (srcSample != 0)
  {
    double asFloat = Math.Abs(srcSample) / 28.12574042515172;
    asFloat *= 2.3025850929940456840; //ln(10)
    asFloat *= 1.4426950408889634070; //log2(e)
    double rnd = Math.Round(asFloat);
    double mantisse = Math.Pow(2.0, asFloat - rnd);
    asFloat = mantisse * Math.Pow(2, rnd);
    if (srcSample < 0) asFloat *= -1;
    Int32 asInt = (int)Math.Round(asFloat);
    asInt = (j == 0) ? asInt : (asInt + PCMData[j - 1]);
    if (asInt > short.MaxValue) asInt = short.MaxValue;
    if (asInt < short.MinValue) asInt = short.MinValue;
    PCMData[j] = (Int16)asInt;
  }
  else PCMData[j] = (j == 0) ? (Int16)0 : PCMData[j - 1];
}