예제 #1
0
        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);
        }
예제 #2
0
        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);
                    }
                }
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        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);
        }