How to create destroyable wheels: Difference between revisions
Jump to navigation
Jump to search
mNo edit summary |
No edit summary |
||
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]; | |||
} |
Revision as of 23:29, 24 January 2010
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]; }