|
|
Line 1: |
Line 1: |
| ==File Format==
| |
|
| |
|
| {| border="1"
| |
| !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];
| |
| }
| |