Implemented WestwoodCompression for AUD files.
This commit is contained in:
86
OpenRA.Mods.Common/FileFormats/WestwoodCompressedReader.cs
Normal file
86
OpenRA.Mods.Common/FileFormats/WestwoodCompressedReader.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
#region Copyright & License Information
|
||||
|
||||
/*
|
||||
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenRA.Mods.Common.FileFormats
|
||||
{
|
||||
public class WestwoodCompressedReader
|
||||
{
|
||||
static readonly int[] AudWsStepTable2 = { -2, -1, 0, 1 };
|
||||
static readonly int[] AudWsStepTable4 = { -9, -8, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 8 };
|
||||
|
||||
public static void DecodeWestwoodCompressedSample(byte[] input, byte[] output)
|
||||
{
|
||||
if (input.Length == output.Length)
|
||||
{
|
||||
Array.Copy(input, output, output.Length);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var sample = 0x80;
|
||||
var r = 0;
|
||||
var w = 0;
|
||||
|
||||
while (r < input.Length)
|
||||
{
|
||||
var count = input[r++] & 0x3f;
|
||||
|
||||
switch (input[r - 1] >> 6)
|
||||
{
|
||||
case 0:
|
||||
for (count++; count > 0; count--)
|
||||
{
|
||||
var code = input[r++];
|
||||
output[w++] = (byte)(sample = (sample + AudWsStepTable2[(code >> 0) & 0x03]).Clamp(byte.MinValue, byte.MaxValue));
|
||||
output[w++] = (byte)(sample = (sample + AudWsStepTable2[(code >> 2) & 0x03]).Clamp(byte.MinValue, byte.MaxValue));
|
||||
output[w++] = (byte)(sample = (sample + AudWsStepTable2[(code >> 4) & 0x03]).Clamp(byte.MinValue, byte.MaxValue));
|
||||
output[w++] = (byte)(sample = (sample + AudWsStepTable2[(code >> 6) & 0x03]).Clamp(byte.MinValue, byte.MaxValue));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (count++; count > 0; count--)
|
||||
{
|
||||
var code = input[r++];
|
||||
output[w++] = (byte)(sample = (sample + AudWsStepTable4[(code >> 0) & 0x0f]).Clamp(byte.MinValue, byte.MaxValue));
|
||||
output[w++] = (byte)(sample = (sample + AudWsStepTable4[(code >> 4) & 0xff]).Clamp(byte.MinValue, byte.MaxValue));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2 when (count & 0x20) != 0:
|
||||
output[w++] = (byte)(sample += (sbyte)((sbyte)count << 3) >> 3);
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (count++; count > 0; count--)
|
||||
output[w++] = input[r++];
|
||||
|
||||
sample = input[r - 1];
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
for (count++; count > 0; count--)
|
||||
output[w++] = (byte)sample;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user