Skip to content

Instantly share code, notes, and snippets.

@simontime
Last active January 9, 2019 09:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simontime/f3ebd219b5922a20287e3bee1ff13b9f to your computer and use it in GitHub Desktop.
Save simontime/f3ebd219b5922a20287e3bee1ff13b9f to your computer and use it in GitHub Desktop.
Need for speed GIN to WAV converter
using System.IO;
internal class Program
{
private static void Main(string[] args)
{
var buffer = new byte[0x4C];
int[] samples = new int[0x20],
coeffs1 = new int[] { 0, 0xF0, 0x1CC, 0x188 },
coeffs2 = new int[] { 0, 0, -0xD0, -0xDC };
using (var inFile = File.OpenRead(args[0]))
using (var br = new BinaryReader(inFile))
using (var outFile = File.OpenWrite($"{Path.GetFileNameWithoutExtension(args[0])}.wav"))
using (var bw = new BinaryWriter(outFile))
{
inFile.Position += 0x10;
int offset1 = br.ReadInt32(),
offset2 = br.ReadInt32();
inFile.Position += sizeof(int);
int sampleRate = br.ReadInt32();
inFile.Position += (offset1 + offset2 + 2) * 4;
int sampleCount = (int)(inFile.Length - inFile.Position) / 0x13 * 0x20,
samplesRead = 0;
bw.Write(0x46464952);
bw.Write(sampleCount * 2 + 0x24);
bw.Write(0x20746D6645564157);
bw.Write(0x10);
bw.Write((short)1);
bw.Write((short)1);
bw.Write(sampleRate);
bw.Write(sampleRate * 2);
bw.Write((short)(2));
bw.Write((short)0x10);
bw.Write(0x61746164);
bw.Write(sampleCount * 2);
while (inFile.Position < inFile.Length)
{
int pos = (int)(inFile.Length - inFile.Position) / 0x13;
for (int i = 0; i < pos; i++, samplesRead += 0x20)
{
inFile.Read(buffer, 0, 0x13);
samples[0] = (short)(buffer[0] & 0xF0 | buffer[1] << 8);
samples[1] = (short)(buffer[2] & 0xF0 | buffer[3] << 8);
int coeffsOffset = buffer[0] & 0xF,
subFactor = buffer[2] & 0xF;
for (int sampleIndex = 2; sampleIndex < 0x20; sampleIndex += 2)
{
int samp1 = (buffer[3 + sampleIndex / 2] & 0xF0) >> 4;
if (samp1 > 7) samp1 -= 0x10;
int samp2 = samples[sampleIndex - 1] * coeffs1[coeffsOffset] +
samples[sampleIndex - 2] * coeffs2[coeffsOffset];
samples[sampleIndex] = samp2 + (samp1 << 0x14 - subFactor) + 0x80 >> 8;
if (samples[sampleIndex] > 0x7FFF) samples[sampleIndex] = 0x7FFF;
if (samples[sampleIndex] < -0x8000) samples[sampleIndex] = -0x8000;
int samp3 = buffer[3 + sampleIndex / 2] & 0xF;
if (samp3 > 7) samp3 -= 0x10;
int samp4 = samples[sampleIndex] * coeffs1[coeffsOffset] +
samples[sampleIndex - 1] * coeffs2[coeffsOffset];
samples[sampleIndex + 1] = samp4 + (samp3 << 0x14 - subFactor) + 0x80 >> 8;
if (samples[sampleIndex + 1] > 0x7FFF) samples[sampleIndex + 1] = 0x7FFF;
if (samples[sampleIndex + 1] < -0x8000) samples[sampleIndex + 1] = -0x8000;
}
for (int j = 0; j < 0x20; j++)
bw.Write((short)samples[j]);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment