private async void ReplaceWEMAudioFromWave(string sourceFile = null) { object currentWEMItem = ExportInfoListBox.SelectedItem; if (currentWEMItem is EmbeddedWEMFile && CurrentLoadedExport.FileRef.Game == MEGame.ME3) { EmbeddedWEMFile wemToReplace = (EmbeddedWEMFile)currentWEMItem; string wwisePath = GetWwiseCLIPath(false); if (wwisePath == null) { return; } if (sourceFile == null) { OpenFileDialog d = new OpenFileDialog(); d.Filter = "Wave PCM|*.wav"; bool?res = d.ShowDialog(); if (res.HasValue && res.Value) { sourceFile = d.FileName; } else { return; } } //Convert and rpelace ReplaceWEMAudioFromWwiseOgg(await RunWwiseConversion(wwisePath, sourceFile), wemToReplace); } }
/// <summary> /// Rewrites the soundbank export with new data from the ogg. /// </summary> /// <param name="oggPath"></param> private void ReplaceWEMAudioFromWwiseOgg(string oggPath, EmbeddedWEMFile wem) { WwiseBank w = new WwiseBank(CurrentLoadedExport); if (oggPath == null) { OpenFileDialog d = new OpenFileDialog(); d.Filter = "Wwise Encoded Ogg|*.ogg"; bool?res = d.ShowDialog(); if (res.HasValue && res.Value) { oggPath = d.FileName; } else { return; } } MemoryStream convertedStream = null; using (var fileStream = new FileStream(oggPath, FileMode.Open)) { convertedStream = WwiseStream.ConvertWwiseOggToME3Ogg(fileStream); } //Update the EmbeddedWEMFile. As this is an object it will be updated in the references. if (wem.HasBeenFixed) { wem.OriginalWemData = convertedStream.ToArray(); } else { wem.WemData = convertedStream.ToArray(); } w.UpdateDataChunk(AllWems); //updates this export's data. File.Delete(oggPath); MessageBox.Show("Done"); }
// Player commands private void ExportAudio(object p) { if (CurrentLoadedExport.ClassName == "WwiseStream") { SaveFileDialog d = new SaveFileDialog(); d.Filter = "Wave PCM File|*.wav"; d.FileName = CurrentLoadedExport.ObjectName + ".wav"; if (d.ShowDialog().Value) { WwiseStream w = new WwiseStream(CurrentLoadedExport); string wavPath = w.CreateWave(w.getPathToAFC()); if (wavPath != null && File.Exists(wavPath)) { File.Copy(wavPath, d.FileName, true); } MessageBox.Show("Done."); } } if (CurrentLoadedExport.ClassName == "WwiseBank") { EmbeddedWEMFile currentWEMItem = (EmbeddedWEMFile)ExportInfoListBox.SelectedItem; SaveFileDialog d = new SaveFileDialog(); d.Filter = "Wave PCM|*.wav"; d.FileName = CurrentLoadedExport.ObjectName + "_0x" + currentWEMItem.Id.ToString("X8") + ".wav"; if (d.ShowDialog().Value) { Stream ms = getPCMStream(); ms.Seek(0, SeekOrigin.Begin); using (FileStream fs = new FileStream(d.FileName, FileMode.OpenOrCreate)) { ms.CopyTo(fs); fs.Flush(); } MessageBox.Show("Done."); } } }
/// <summary> /// Gets a PCM stream of data (WAV) from either teh currently loaded export or selected WEM /// </summary> /// <param name="forcedWemFile">WEM that we will force to get a stream for</param> /// <returns></returns> public Stream getPCMStream(IExportEntry forcedWwiseStreamExport = null, EmbeddedWEMFile forcedWemFile = null) { IExportEntry localCurrentExport = forcedWwiseStreamExport ?? CurrentLoadedExport; if (localCurrentExport != null || forcedWemFile != null) { if (localCurrentExport != null && localCurrentExport.ClassName == "WwiseStream") { w = new WwiseStream(localCurrentExport); string path; if (w.IsPCCStored) { path = localCurrentExport.FileRef.FileName; } else { path = w.getPathToAFC(); // only to check if AFC exists. } if (path != "") { return(w.CreateWaveStream(path)); } } if (forcedWemFile != null || (localCurrentExport != null && localCurrentExport.ClassName == "WwiseBank")) { object currentWEMItem = forcedWemFile ?? ExportInfoListBox.SelectedItem; if (currentWEMItem == null || currentWEMItem is string) { return(null); //nothing selected, or current wem is not playable } var wemObject = (EmbeddedWEMFile)currentWEMItem; string basePath = System.IO.Path.GetTempPath() + "ME3EXP_SOUND_" + Guid.NewGuid().ToString(); File.WriteAllBytes(basePath + ".dat", wemObject.WemData); return(WwiseStream.ConvertRiffToWav(basePath + ".dat", wemObject.Game == MEGame.ME2)); } } return(null); }
public override void LoadExport(IExportEntry exportEntry) { ExportInformationList.Clear(); AllWems.Clear(); //Check if we need to first gather wwiseevents for wem IDing //Uncomment when HIRC stuff is implemented, if ever... /*if (exportEntry.FileRef != CurrentPackage) * { * //update * WemIdsToWwwiseEventIdMapping.Clear(); * List<IExportEntry> wwiseEventExports = exportEntry.FileRef.Exports.Where(x => x.ClassName == "WwiseEvent").ToList(); * foreach (IExportEntry wwiseEvent in wwiseEventExports) * { * StructProperty relationships = wwiseEvent.GetProperty<StructProperty>("Relationships"); * IntProperty id = wwiseEvent.GetProperty<IntProperty>("Id"); * FloatProperty DurationMilliseconds = wwiseEvent.GetProperty<FloatProperty>("DurationMilliseconds"); * * if (relationships != null) * { * ObjectProperty bank = relationships.GetProp<ObjectProperty>("Bank"); * if (bank != null && bank.Value > 0) * { * //export in this file * List<Tuple<string, int, double>> bankWemInfosList; * Tuple<string, int, double> newData = new Tuple<string, int, double>(wwiseEvent.ObjectName, id.Value, DurationMilliseconds.Value); * if (WemIdsToWwwiseEventIdMapping.TryGetValue(exportEntry.FileRef.Exports[bank.Value - 1], out bankWemInfosList)) * { * bankWemInfosList.Add(newData); * } * else * { * WemIdsToWwwiseEventIdMapping[exportEntry.FileRef.Exports[bank.Value - 1]] = new List<Tuple<string, int, double>>(); * WemIdsToWwwiseEventIdMapping[exportEntry.FileRef.Exports[bank.Value - 1]].Add(newData); * } * } * } * } * * } * CurrentPackage = exportEntry.FileRef;*/ ExportInformationList.Add("#" + exportEntry.Index + " " + exportEntry.ClassName + " : " + exportEntry.ObjectName); if (exportEntry.ClassName == "WwiseStream") { WwiseStream w = new WwiseStream(exportEntry); ExportInformationList.Add("Filename : " + (w.FileName ?? "Stored in this PCC")); ExportInformationList.Add("Data size: " + w.DataSize + " bytes"); ExportInformationList.Add("Data offset: 0x" + w.DataOffset.ToString("X8")); string wemId = "ID: 0x" + w.Id.ToString("X8"); if (Properties.Settings.Default.SoundplorerReverseIDDisplayEndianness) { wemId += $" | 0x{ReverseBytes((uint)w.Id).ToString("X8")} (Reversed)"; } ExportInformationList.Add(wemId); CurrentLoadedExport = exportEntry; } if (exportEntry.ClassName == "WwiseBank") { WwiseBank wb = new WwiseBank(exportEntry); var embeddedWEMFiles = wb.GetWEMFilesMetadata(); var data = wb.GetChunk("DATA"); int i = 0; if (embeddedWEMFiles.Count > 0) { foreach (var singleWemMetadata in embeddedWEMFiles) { byte[] wemData = new byte[singleWemMetadata.Item3]; //copy WEM data to buffer. Add 0x8 to skip DATA and DATASIZE header for this block. Buffer.BlockCopy(data, singleWemMetadata.Item2 + 0x8, wemData, 0, singleWemMetadata.Item3); //check for RIFF header as some don't seem to have it and are not playable. string wemHeader = "" + (char)wemData[0] + (char)wemData[1] + (char)wemData[2] + (char)wemData[3]; string wemId = singleWemMetadata.Item1.ToString("X8"); if (Properties.Settings.Default.SoundplorerReverseIDDisplayEndianness) { wemId = ReverseBytes(singleWemMetadata.Item1).ToString("X8") + " (Reversed)"; } string wemName = "Embedded WEM 0x" + wemId;// + "(" + singleWemMetadata.Item1 + ")"; /* //HIRC lookup, if I ever get around to supporting HIRC * List<Tuple<string, int, double>> wemInfo; * if (WemIdsToWwwiseEventIdMapping.TryGetValue(exportEntry, out wemInfo)) * { * var info = wemInfo.FirstOrDefault(x => x.Item2 == singleWemMetadata.Item1); //item2 in x = ID, singleWemMetadata.Item1 = ID * if (info != null) * { * //have info * wemName = info.Item1; * } * }*/ EmbeddedWEMFile wem = new EmbeddedWEMFile(wemData, i + ": " + wemName, exportEntry.FileRef.Game, singleWemMetadata.Item1); if (wemHeader == "RIFF") { ExportInformationList.Add(wem); } else { ExportInformationList.Add(i + ": " + wemName + " - No RIFF header"); } AllWems.Add(wem); i++; } } else { ExportInformationList.Add("This soundbank has no embedded WEM files"); } CurrentLoadedExport = exportEntry; } }