public static int GetGINLength(MemoryStream file, GIN gin) { file.WriteString("Gnsu20", StringCoding.Raw); file.WriteBytes(new byte[] { 0x0, 0x0 }); file.WriteBytes(BitConverter.GetBytes(gin.minRpm)); file.WriteBytes(BitConverter.GetBytes(gin.maxRpm)); file.WriteByte(gin.unk1); file.WriteByte(gin.unk2); file.WriteByte(gin.unk3); file.WriteByte(gin.unk4); file.WriteInt32(gin.numGrains); file.WriteInt32(gin.numSamples); file.WriteInt32(gin.sampleRate); foreach (int grain in gin.grainTable1) { file.WriteInt32(grain); } file.WriteInt32(0); foreach (int grain in gin.grainTable2) { file.WriteInt32(grain); } file.WriteBytes(gin.audioData); return((int)file.Length); }
public void WriteTMX(string path) { using (var file = new FileStream(path, FileMode.Create)) //using (var stream = new BinaryStream(file, ByteConverter.Little)) { int cumulativeOffset = 0; //stream.Position = 0; file.WriteBytes(tmxHeader1); file.WriteInt32(ginHeaderOffset); file.WriteInt32(audioDataOffset); file.WriteBytes(tmxHeader2); foreach (AudioEntry entry in audioEntries) { if (audioEntries.IndexOf(entry) > 0) { if (audioEntries[audioEntries.IndexOf(entry) - 1].type == "GIN") { cumulativeOffset += GIN.GetGINLength(new MemoryStream(), audioEntries[audioEntries.IndexOf(entry) - 1].ginData); } else { cumulativeOffset += audioEntries[audioEntries.IndexOf(entry) - 1].audioData.Length; } } file.WriteByte(entry.entrySize); file.WriteString(new string(entry.type.Reverse().ToArray()), StringCoding.Raw); file.WriteInt32(entry.index); file.WriteInt32(cumulativeOffset); file.WriteInt32(entry.unk1); file.WriteInt32(entry.unk2); file.WriteInt32(entry.version); file.WriteInt32(entry.unk3); file.WriteBytes(BitConverter.GetBytes(entry.unk4)); file.WriteInt32(entry.unk5); } foreach (AudioEntry entry in audioEntries) { if (entry.type == "GIN") { GIN.WriteGIN(file, entry.ginData); } else { file.WriteBytes(entry.audioData); } } } }
public static GIN ReadGIN(byte[] data) { GIN gin = new GIN(); using (var stream = new BinaryStream(new MemoryStream(data))) { if (stream.ReadString(4) != "Gnsu") { MessageBox.Show("Type detected as GIN but data is not valid GIN data. Please check the file and try again.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } else { stream.Position = 0x8; gin.minRpm = BitConverter.ToSingle(stream.ReadBytes(4), 0); gin.maxRpm = BitConverter.ToSingle(stream.ReadBytes(4), 0); gin.unk1 = stream.Read1Byte(); gin.unk2 = stream.Read1Byte(); gin.unk3 = stream.Read1Byte(); gin.unk4 = stream.Read1Byte(); gin.numGrains = stream.ReadInt32(); gin.numSamples = stream.ReadInt32(); gin.sampleRate = stream.ReadInt32(); for (int i = 0; i < 51; i++) { gin.grainTable1.Add(stream.ReadInt32()); } stream.Position += 0x4; for (int i = 0; i < gin.numGrains; i++) { gin.grainTable2.Add(stream.ReadInt32()); } gin.audioData = stream.ReadBytes(data.Length - (int)stream.Position); } } return(gin); }
private void Button_Click(object sender, RoutedEventArgs e) { var picker = new CommonOpenFileDialog(); picker.Filters.Add(new CommonFileDialogFilter("GIN/SNR Audio", "gin;snr")); if (picker.ShowDialog() == CommonFileDialogResult.Ok) { byte[] data = File.ReadAllBytes(picker.FileName); int index = tmx.audioEntries.IndexOf(currentEntry); int header; using (var stream = new BinaryStream(new MemoryStream(data))) { header = stream.ReadInt32(); switch ((long)header) { case 0x75736E47L: tmx.audioEntries[index].type = "GIN"; tmx.audioEntries[index].ginData = GIN.ReadGIN(data); break; // No actual header so just read the channel/sample rate info, should only ever be one of these for NFS case 0x80BB0004L: case 0x80BB0404L: case 0x44AC0004L: case 0x44AC0404L: tmx.audioEntries[index].type = "SNR"; tmx.audioEntries[index].audioData = data; break; } } RefreshAudioInfo(tmx); lstAudio.SelectedIndex = index; } }
public TMX ReadTMX(string path) { var bytes = File.ReadAllBytes(path); fileName = path; using (var stream = new BinaryStream(new MemoryStream(bytes))) { audioEntries = new List <AudioEntry>(); if (stream.ReadUInt32() != 2292214557) { MessageBox.Show("Not a valid TMX file. Please open a valid TMX file and try again.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(null); } else { bool searching = true; int offset = -1; List <int> ginOffsets = new List <int>(), snrOffsets = new List <int>(); byte[] ginHeader = new byte[] { 0x20, 0x4E, 0x49, 0x47 }; byte[] snrHeader = new byte[] { 0x20, 0x52, 0x4E, 0x53 }; // Search for GIN headers while (searching) { offset = FindSequenceMultiple(bytes, ginHeader, ginOffsets); if (offset != -1) { ginOffsets.Add(offset); } else { searching = false; } } searching = true; // Search for SNR headers while (searching) { offset = FindSequenceMultiple(bytes, snrHeader, snrOffsets); if (offset != -1) { snrOffsets.Add(offset); } else { searching = false; } } numSounds = ginOffsets.Count + snrOffsets.Count; stream.Position = 0; tmxHeader1 = stream.ReadBytes(88); ginHeaderOffset = stream.ReadInt32(); audioDataOffset = stream.ReadInt32(); tmxHeader2 = stream.ReadBytes(ginHeaderOffset - 96); for (int i = 0; i < numSounds; i++) { AudioEntry entry = new AudioEntry(); entry.entrySize = (byte)stream.ReadByte(); entry.type = new string(stream.ReadString(3).Reverse().ToArray()); entry.index = stream.ReadInt32(); entry.relativeOffset = stream.ReadInt32(); entry.absoluteOffset = entry.relativeOffset + audioDataOffset; entry.unk1 = stream.ReadInt32(); entry.unk2 = stream.ReadInt32(); entry.version = stream.ReadInt32(); entry.unk3 = stream.ReadInt32(); entry.unk4 = BitConverter.ToSingle(stream.ReadBytes(4), 0); entry.unk5 = stream.ReadInt32(); audioEntries.Add(entry); } for (int i = 0; i < audioEntries.Count; i++) { int readTo = 0; stream.Position = audioEntries[i].absoluteOffset; // If last sound file, read to end, otherwise to next header if (i == audioEntries.Count - 1) { readTo = bytes.Length; } else { readTo = audioEntries[i + 1].absoluteOffset; } if (audioEntries[i].type == "GIN") { audioEntries[i].ginData = GIN.ReadGIN(stream.ReadBytes((int)(readTo - stream.Position))); } else { audioEntries[i].audioData = stream.ReadBytes((int)(readTo - stream.Position)); } } } } return(this); }