public void ReadFile(string path) { var bytes = File.ReadAllBytes(path); using (var stream = new BinaryStream(new MemoryStream(bytes))) { if (stream.ReadString(4) != magic) { throw new InvalidDataException("Not an ESGX file. Please open an ESGX file and try again."); } stream.Position += 4; SGXDPointer = stream.ReadUInt32(); sampleAmount = stream.ReadUInt32(); settingsPointer = stream.ReadUInt32(); unk = stream.ReadBytes(4); stream.Position = settingsPointer; for (int i = 0; i < sampleAmount; i++) { SampleSetting sample = new SampleSetting(); sample.rpmPitch = stream.ReadInt16(); sample.rpmStart = stream.ReadInt16(); sample.rpmEnd = stream.ReadInt16(); sample.rpmVolume = stream.ReadInt16(); sample.rpmFrequency = stream.ReadInt32(); sample.SGXDOffset = stream.ReadInt32(); sampleSettings.Add(sample); } stream.Position += 12; for (int i = 0; i < sampleAmount; i++) { stream.Position = sampleSettings[i].SGXDOffset; SGXDEntry entry = new SGXDEntry(); entry.waveChunk = new WaveChunk(); entry.nameChunk = new NameChunk(); stream.Position += 4; entry.namePointer = stream.ReadUInt32(); entry.dataOffset = stream.ReadUInt32(); entry.fileSize = stream.ReadUInt16(); entry.unknown = stream.ReadUInt16(); stream.Position += 4; entry.waveChunk.chunkSize = stream.ReadUInt32(); stream.Position += 4; entry.waveChunk.soundAmount = stream.ReadUInt32(); entry.waveChunk.flag2 = stream.ReadUInt32(); entry.waveChunk.nameOffset = stream.ReadUInt32(); entry.waveChunk.codecType = stream.Read1Byte(); entry.waveChunk.channels = stream.Read1Byte(); stream.Position += 2; entry.waveChunk.soundSampleRate = stream.ReadUInt32(); entry.waveChunk.bitRate = stream.ReadUInt32(); stream.Position += 4; entry.waveChunk.volumeL = stream.ReadUInt16(); entry.waveChunk.volumeR = stream.ReadUInt16(); entry.waveChunk.loopStartSample = stream.ReadUInt32(); stream.Position += 8; entry.waveChunk.loopEndSample = stream.ReadUInt32(); entry.waveChunk.streamSize = stream.ReadUInt32(); stream.Position += 20; entry.nameChunk.chunkSize = stream.ReadUInt32(); entry.nameChunk.unknown = stream.ReadBytes(24); entry.nameChunk.fileName = stream.ReadString(StringCoding.ZeroTerminated); stream.Position = sampleSettings[i].SGXDOffset + entry.dataOffset; entry.audioStream = stream.ReadBytes(entry.fileSize); sgxdEntries.Add(entry); } } }
public void ReadESFile(string path) { var bytes = File.ReadAllBytes(path); using (var stream = new BinaryStream(new MemoryStream(bytes), ByteConverter.Little)) { if (stream.ReadString(4) != esMagic) { throw new InvalidDataException("Not an ES file. Please open an ES file and try again."); } stream.Position += 4; soundStartPointer = stream.ReadUInt32(); stream.Position += 4; audioChunkSize = stream.ReadUInt32(); stream.Position += 4; sampleAmount = stream.ReadUInt32(); stream.Position += 20; for (int i = 0; i < sampleAmount; i++) { SampleSetting sample = new SampleSetting(); sample.rpmPitch = stream.ReadInt16(); sample.rpmStart = stream.ReadInt16(); sample.rpmEnd = stream.ReadInt16(); sample.rpmVolume = stream.ReadInt16(); sample.rpmFrequency = stream.ReadInt32(); sample.SGXDOffset = stream.ReadInt32(); sampleSettings.Add(sample); } int j = 0; foreach (SampleSetting setting in sampleSettings) { stream.Position = soundStartPointer + setting.SGXDOffset + 16; // 16 empty bytes at the start of each SGXDEntry entry = new SGXDEntry(); entry.waveChunk = new WaveChunk(); entry.nameChunk.fileName = string.Format("{0}_{1}", Path.GetFileNameWithoutExtension(path), j); entry.waveChunk.soundSampleRate = (uint)setting.rpmFrequency * 10; if (j == 0) { entry.audioStream = stream.ReadBytes(sampleSettings[j + 1].SGXDOffset - 16); } if (j == sampleSettings.Count - 1) { entry.audioStream = stream.ReadBytes(int.Parse(stream.Length.ToString()) - int.Parse(stream.Position.ToString())); } else { entry.audioStream = stream.ReadBytes(sampleSettings[j + 1].SGXDOffset - sampleSettings[j].SGXDOffset - 16); } entry.fileSize = ushort.Parse(entry.audioStream.Length.ToString()); sgxdEntries.Add(entry); j++; } } // Just set all RPM Frequencies to 4200 as this seems to work globally foreach (SampleSetting setting in sampleSettings) { setting.rpmFrequency = 4200; } // Read loop start and end samples foreach (SGXDEntry entry in sgxdEntries) { File.WriteAllBytes(string.Format("{0}.tmp", Path.Combine(Path.GetDirectoryName(path), "tempAudio")), entry.audioStream); var test = new AudioFileReader(Path.Combine(Path.GetDirectoryName(path), "tempAudio")).Length; byte[] currentLine; int loopStart, loopEnd, numSamples; using (var stream = new BinaryStream(new MemoryStream(entry.audioStream))) { numSamples = (entry.audioStream.Length / 16) * 28; //stream.Position = 16; while (stream.Position <= entry.audioStream.Length) { currentLine = stream.ReadBytes(16); // Read second byte of a line - 6 = loop start, 3 = loop end, determine sample count from where we are in seek if (currentLine[1] == 6) { entry.waveChunk.loopStartSample = (uint)(stream.Position - 16) / 16 * 28; } if (currentLine[1] == 3) { entry.waveChunk.loopEndSample = (uint)(stream.Position - 16) / 16 * 28; break; } } } } }