Skip to content

Instantly share code, notes, and snippets.

@simontime
Last active November 30, 2025 14:15
Show Gist options
  • Select an option

  • Save simontime/f3ebd219b5922a20287e3bee1ff13b9f to your computer and use it in GitHub Desktop.

Select an option

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]);
}
}
}
}
}
@Rolls-Stevenson
Copy link
Copy Markdown

Wait how in the first place I'm running this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment