WSS File Format

From Bohemia Interactive Community
Revision as of 01:38, 25 January 2010 by T D (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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