private static void WriteXMAFile(BlamSound blamSound) { using (EndianWriter output = new EndianWriter(new FileStream(XMAFile, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian)) { XMAFile XMAfile = new XMAFile(blamSound); XMAfile.Write(output); } }
public void ExtractXMA(CacheFile.IndexItem blamTag, string directory) { if (BlamSoundGestalt == null) { BlamSoundGestalt = PortingContextFactory.LoadSoundGestalt(CacheContext, ref BlamCache); } var blamContext = new CacheSerializationContext(ref BlamCache, blamTag); var sound = BlamCache.Deserializer.Deserialize <Sound>(blamContext); var xmaFileSize = BlamSoundGestalt.GetFileSize(sound.SoundReference.PitchRangeIndex, sound.SoundReference.PitchRangeCount); if (xmaFileSize < 0) { return; } var xmaData = BlamCache.GetSoundRaw(sound.SoundReference.ZoneAssetHandle, xmaFileSize); if (xmaData == null) { Console.WriteLine($"ERROR: Failed to find sound data!"); return; } var parts = blamTag.Name.Split('\\'); string baseName = parts[parts.Length - 1]; for (int pitchRangeIndex = sound.SoundReference.PitchRangeIndex; pitchRangeIndex < sound.SoundReference.PitchRangeIndex + sound.SoundReference.PitchRangeCount; pitchRangeIndex++) { var relativePitchRangeIndex = pitchRangeIndex - sound.SoundReference.PitchRangeIndex; var permutationCount = BlamSoundGestalt.GetPermutationCount(pitchRangeIndex); for (int i = 0; i < permutationCount; i++) { BlamSound blamSound = SoundConverter.GetXMA(BlamCache, BlamSoundGestalt, sound, relativePitchRangeIndex, i, xmaData); string permutationName = $"{baseName}_{relativePitchRangeIndex}_{i}"; var fileName = $"{directory}\\{permutationName}.xma"; using (EndianWriter output = new EndianWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian)) { XMAFile XMAfile = new XMAFile(blamSound); XMAfile.Write(output); } } } }
public void ExtractXMA(string directory) { if (BlamSoundGestalt == null) { using (var stream = Cache.OpenCacheRead()) BlamSoundGestalt = PortingContextFactory.LoadSoundGestalt(Cache, stream); } var resourceDefinition = Cache.ResourceCache.GetSoundResourceDefinition(Sound.Resource); var xmaFileSize = BlamSoundGestalt.GetFileSize(Sound.SoundReference.PitchRangeIndex, Sound.SoundReference.PitchRangeCount); if (xmaFileSize < 0) { return; } var xmaData = resourceDefinition.Data.Data; if (xmaData == null) { Console.WriteLine($"ERROR: Failed to find sound data!"); return; } var parts = Tag.Name.Split('\\'); string baseName = parts[parts.Length - 1]; for (int pitchRangeIndex = Sound.SoundReference.PitchRangeIndex; pitchRangeIndex < Sound.SoundReference.PitchRangeIndex + Sound.SoundReference.PitchRangeCount; pitchRangeIndex++) { var relativePitchRangeIndex = pitchRangeIndex - Sound.SoundReference.PitchRangeIndex; var permutationCount = BlamSoundGestalt.GetPermutationCount(pitchRangeIndex); for (int i = 0; i < permutationCount; i++) { BlamSound blamSound = SoundConverter.GetXMA(Cache, BlamSoundGestalt, Sound, relativePitchRangeIndex, i, xmaData); string permutationName = $"{baseName}_{relativePitchRangeIndex}_{i}"; var fileName = $"{directory}\\{permutationName}.xma"; using (EndianWriter output = new EndianWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian)) { XMAFile XMAfile = new XMAFile(blamSound); XMAfile.Write(output); } } } }
public static string ConvertXMAPermutation(byte[] buffer, int channelCount, int sampleRate, bool loopingSound, bool useCache, string permutationName) { if (!File.Exists(@"Tools\ffmpeg.exe")) { Console.WriteLine("Missing tools, please install all the required tools before porting sounds."); return(null); } var gui = Guid.NewGuid(); var audioFile = permutationName; var tempXMA = $"{audioFile}.xma"; var tempWAV = $"{audioFile}_temp.wav"; var fixedWAV = $"{audioFile}_truncated.wav"; var tempMP3 = $"{audioFile}_temp.mp3"; var resultWAV = $"{audioFile}.wav"; var resultMP3 = $"{audioFile}.mp3"; CLEAN_FILES: try { if (File.Exists(tempXMA)) { File.Delete(tempXMA); } if (File.Exists(tempWAV)) { File.Delete(tempWAV); } if (File.Exists(fixedWAV)) { File.Delete(fixedWAV); } if (File.Exists(resultWAV)) { File.Delete(resultWAV); } if (File.Exists(resultMP3)) { File.Delete(resultMP3); } if (File.Exists(tempMP3)) { File.Delete(tempMP3); } } catch (Exception e) { Console.WriteLine(e.Message); goto CLEAN_FILES; } using (EndianWriter output = new EndianWriter(new FileStream(tempXMA, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian)) { XMAFile XMAfile = new XMAFile(buffer, channelCount, sampleRate); XMAfile.Write(output); } if (!ConvertXMAToWAV(tempXMA, tempWAV)) { return(null); } // Convert to MP3 and remove header if (loopingSound && channelCount <= 2) { if (!ConvertWAVToMP3Looping(tempWAV, tempMP3)) { return(null); } } else { // truncate file byte[] originalWAVdata = File.ReadAllBytes(tempWAV); byte[] truncatedWAVdata = TruncateWAVFile(originalWAVdata, sampleRate, channelCount, 0x2C); using (EndianWriter writer = new EndianWriter(new FileStream(fixedWAV, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian)) { WAVFile WAVfile = new WAVFile(truncatedWAVdata, channelCount, sampleRate); WAVfile.Write(writer); } // add code to handle looping sounds with more than 2 channels here. Mp3Loop does not handle that kind of file. if (!ConvertWAVToMP3(fixedWAV, tempMP3)) { return(null); } } int size = (int)(new FileInfo(tempMP3).Length - 0x2D); byte[] MP3stream = File.ReadAllBytes(tempMP3); using (var output = new FileStream(resultMP3, FileMode.Create, FileAccess.Write, FileShare.None)) output.Write(MP3stream, 0x2D, size); CLEAN_FILES2: try { if (File.Exists(tempXMA)) { File.Delete(tempXMA); } if (File.Exists(tempWAV)) { File.Delete(tempWAV); } if (File.Exists(fixedWAV)) { File.Delete(fixedWAV); } if (File.Exists(resultWAV)) { File.Delete(resultWAV); } if (File.Exists(tempMP3)) { File.Delete(tempMP3); } } catch (Exception e) { Console.WriteLine(e.Message); goto CLEAN_FILES2; } return(resultMP3); }