private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { int n = listBox1.SelectedIndex; if (n == -1) { return; } rtb1.Text = ""; rtb1.Visible = true; hb1.Visible = false; int index = ObjectIndexes[n]; PCCObject.ExportEntry ex = pcc.Exports[index]; if (ex.ClassName == "WwiseStream") { w = new WwiseStream(pcc, index); string s = "#" + index + " WwiseStream : " + ex.ObjectName + "\n\n"; s += "Filename : \"" + w.FileName + "\"\n"; s += "Data size: " + w.DataSize + " bytes\n"; s += "Data offset: 0x" + w.DataOffset.ToString("X8") + "\n"; s += "ID: 0x" + w.Id.ToString("X8") + " = " + w.Id + "\n"; rtb1.Text = s; } if (ex.ClassName == "WwiseBank") { rtb1.Visible = false; hb1.Visible = true; wb = new WwiseBank(pcc, index); hb1.ByteProvider = new DynamicByteProvider(wb.getBinary()); } }
private void playToolStripMenuItem_Click(object sender, EventArgs e) { int n = listBox1.SelectedIndex; if (n == -1) { return; } int index = ObjectIndexes[n]; IExportEntry ex = pcc.Exports[index]; if (ex.ClassName == "WwiseStream") { Stop(); w = new WwiseStream(pcc as ME3Package, index); string path; if (w.IsPCCStored) { path = pcc.FileName; } else { path = getPathToAFC(); } if (path != "") { Status.Text = "Loading..."; w.Play(path); Status.Text = "Ready"; } } }
public void ImportSound() { if (listView1.SelectedItems.Count != 1 || pcc == null) { return; } ListViewItem item = listView1.SelectedItems[0]; int index = Convert.ToInt32(item.Name); if (pcc.Exports[index].ClassName == "WwiseStream") { OpenFileDialog o = new OpenFileDialog(); o.Filter = "Wwise wav (*.wav)|*.wav"; if (o.ShowDialog() == DialogResult.OK) { w = new WwiseStream(pcc, index); w.ImportFromFile(o.FileName, pathCooked); byte[] buff = new byte[w.memsize]; for (int i = 0; i < w.memsize; i++) { buff[i] = w.memory[i]; } PCCObject.ExportEntry ent = pcc.Exports[index]; ent.Data = buff; //pcc.ChangeExportEntry(index, CopyExport(ent)); MessageBox.Show("Done."); } } }
/// <summary> /// Replaces the audio in the current loaded export, or the forced export. Will prompt user for a Wwise Encoded Ogg file. /// </summary> /// <param name="forcedExport">Export to update. If null, the currently loadedo ne is used instead.</param> public void ReplaceAudioFromWwiseOgg(string oggPath = null, IExportEntry forcedExport = null) { IExportEntry exportToWorkOn = forcedExport ?? CurrentLoadedExport; if (exportToWorkOn != null && exportToWorkOn.ClassName == "WwiseStream") { WwiseStream w = new WwiseStream(exportToWorkOn); if (w.IsPCCStored) { //TODO: enable replacing of PCC-stored sounds MessageBox.Show("Cannot replace pcc-stored sounds yet."); return; } 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; } } w.ImportFromFile(oggPath, w.getPathToAFC()); CurrentLoadedExport.Data = w.memory.TypedClone(); MessageBox.Show("Done"); } }
private void ExportRaw_Clicked(object sender, RoutedEventArgs e) { SoundplorerExport spExport = (SoundplorerExport)SoundExports_ListBox.SelectedItem; if (spExport != null && spExport.Export.ClassName == "WwiseStream") { SaveFileDialog d = new SaveFileDialog(); d.Filter = "Wwise WEM|*.wem"; d.FileName = spExport.Export.ObjectName + ".wem"; bool?res = d.ShowDialog(); if (res.HasValue && res.Value) { WwiseStream w = new WwiseStream(spExport.Export); if (w.ExtractRawFromStream(d.FileName, w.getPathToAFC())) { MessageBox.Show("Done."); } else { MessageBox.Show("Error extracting WEM file.\nMetadata for this raw data may be incorrect (e.g. too big for file)."); } } } }
private void PlaySound(int n) { int index = ObjectIndexes[n]; IExportEntry ex = pcc.Exports[index]; if (ex.ClassName == "WwiseStream") { Stop(); w = new WwiseStream(pcc as ME3Package, index); string path; if (w.IsPCCStored) { path = pcc.FileName; } else { path = getPathToAFC(); } if (path != "") { Status.Text = "Loading..."; w.Play(path); Status.Text = "Ready"; } } }
public void PlaySound() { if (listView1.SelectedItems.Count != 1 || pcc == null) { return; } ListViewItem item = listView1.SelectedItems[0]; int index = Convert.ToInt32(item.Name); if (pcc.Exports[index].ClassName == "WwiseStream") { w = new WwiseStream(pcc, index); w.Play(pathCooked); } }
/// <summary> /// ME2 SPECIFIC<para/> /// Repoint a WwiseStream to play the data from another precomputed stream. /// </summary> /// <param name="originalExport">The audio you want to play (e.g. this is the audio that will be 'installed')</param> /// <param name="targetAudioStream">The audio stream that you want to replace.</param> public static void RepointWwiseStreamToInfo(RMusic.MusicStreamInfo streamInfo, ExportEntry targetAudioStream) { WwiseStream stream = new WwiseStream(); stream.Filename = ""; // Just make sure it's not set to null so internal code thinks this is not Pcc stored. stream.DataSize = streamInfo.DataSize; stream.Unk1 = stream.Unk2 = stream.Unk3 = stream.Unk4 = stream.Unk5 = 1; stream.UnkGuid = streamInfo.UnkGuid; stream.DataOffset = streamInfo.DataOffset; PropertyCollection props = new PropertyCollection(); props.Add(targetAudioStream.GetProperty <IntProperty>("Id")); // Use the existing Id props.Add(new NameProperty(streamInfo.Filename, "Filename")); // AFC file props.Add(new NameProperty(streamInfo.BankName, "BankName")); // ? targetAudioStream.WritePropertiesAndBinary(props, stream); }
private void ExportWave(SoundplorerExport spExport, string outputLocation = null) { if (spExport != null && spExport.Export.ClassName == "WwiseStream") { bool silent = outputLocation != null; if (outputLocation == null) { SaveFileDialog d = new SaveFileDialog(); d.Filter = "Wave PCM|*.wav"; d.FileName = spExport.Export.ObjectName + ".wav"; bool?res = d.ShowDialog(); if (res.HasValue && res.Value) { outputLocation = d.FileName; } else { return; } } WwiseStream w = new WwiseStream(spExport.Export); Stream source = w.CreateWaveStream(w.getPathToAFC()); if (source != null) { using (var fileStream = File.Create(outputLocation)) { source.Seek(0, SeekOrigin.Begin); source.CopyTo(fileStream); } if (!silent) { MessageBox.Show("Done."); } } else { if (!silent) { MessageBox.Show("Error creating Wave file.\nThis might not be a supported codec or the AFC data may be incorrect."); } } } }
public void PlaySound() { if (listView1.SelectedItems.Count != 1 || pcc == null) { return; } ListViewItem item = listView1.SelectedItems[0]; int index = Convert.ToInt32(item.Name); if (pcc.Exports[index].ClassName == "WwiseStream") { using (ME3Package package = MEPackageHandler.OpenME3Package(pcc.pccFileName)) { w = new WwiseStream(package, index); w.Play(pathCooked); } } }
private void playToolStripMenuItem_Click(object sender, EventArgs e) { int n = listBox1.SelectedIndex; if (n == -1) { return; } int index = ObjectIndexes[n]; PCCObject.ExportEntry ex = pcc.Exports[index]; if (ex.ClassName == "WwiseStream") { Stop(); w = new WwiseStream(pcc, ex.Data); string path = ME3Directory.cookedPath; Status.Text = "Loading..."; w.Play(path); Status.Text = "Ready"; } }
/// <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"); }
/// <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); }
private void ExportOgg_Clicked(object sender, RoutedEventArgs e) { SoundplorerExport spExport = (SoundplorerExport)SoundExports_ListBox.SelectedItem; if (spExport != null && spExport.Export.ClassName == "WwiseStream") { SaveFileDialog d = new SaveFileDialog(); d.Filter = "Ogg Vorbis|*.ogg"; d.FileName = spExport.Export.ObjectName + ".ogg"; bool?res = d.ShowDialog(); if (res.HasValue && res.Value) { WwiseStream w = new WwiseStream(spExport.Export); string riffOutputFile = System.IO.Path.Combine(Directory.GetParent(d.FileName).FullName, System.IO.Path.GetFileNameWithoutExtension(d.FileName)) + ".dat"; if (w.ExtractRawFromStream(riffOutputFile, w.getPathToAFC())) { MemoryStream oggStream = WwiseStream.ConvertRIFFToWWwiseOGG(riffOutputFile, spExport.Export.FileRef.Game == MEGame.ME2); //string outputOggPath = if (oggStream != null)// && File.Exists(outputOggPath)) { oggStream.Seek(0, SeekOrigin.Begin); using (FileStream fs = new FileStream(d.FileName, FileMode.OpenOrCreate)) { oggStream.CopyTo(fs); fs.Flush(); } MessageBox.Show("Done."); } else { MessageBox.Show("Error extracting Ogg file.\nMetadata for the raw data may be incorrect (e.g. header specifies data is longer than it actually is)."); } } } } }
// 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."); } } }
public void LoadData() { if (Export.ClassName == "WwiseStream") { WwiseStream w = new WwiseStream(Export); string afcPath = w.getPathToAFC(); if (afcPath == "") { SubText = "Could not find AFC"; } else { TimeSpan?time = w.GetSoundLength(); if (time != null) { //here backslash must be present to tell that parser colon is //not the part of format, it just a character that we want in output SubText = time.Value.ToString(@"mm\:ss\:fff"); } else { SubText = "Error getting length, may be unsupported"; } } NeedsLoading = false; Icon = FontAwesomeIcon.VolumeUp; } if (Export.ClassName == "WwiseBank") { WwiseBank wb = new WwiseBank(Export); var embeddedWEMFiles = wb.GetWEMFilesMetadata(); SubText = embeddedWEMFiles.Count() + " embedded WEM" + (embeddedWEMFiles.Count() != 1 ? "s" : ""); NeedsLoading = false; Icon = FontAwesomeIcon.University; } }
private void Pause_Clicked(object sender, RoutedEventArgs e) { WwiseStream w = new WwiseStream(CurrentLoadedExport.FileRef as ME3Package, CurrentLoadedExport.Index); }
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; } }
internal MemoryStream GetWaveStream() { //string outPath = Path.Combine(path, currentFileName); if (isOgg) { string basePath = System.IO.Path.GetTempPath() + "ME3EXP_SOUND_" + Guid.NewGuid().ToString() + ".ogg"; File.WriteAllBytes(basePath, DataAsStored); MemoryStream waveStream = WwiseStream.ConvertOggToWave(basePath); return(waveStream); } else if (isPCM) //research shows both ogg and pcm can be set... somehow { Debug.WriteLine("PCM FILE"); return(null); } else { switch (CodecID2) { case 0x3F4CCCCD: int headerSize = 52; MemoryStream ms = new MemoryStream(); //WAVE HEADER ms.WriteBytes(Encoding.ASCII.GetBytes("RIFF")); ms.WriteInt32(headerSize - 8); //size - header is 52 bytes, - 8 for RIFF and this part. we will update this later though. ms.WriteBytes(Encoding.ASCII.GetBytes("WAVE")); ms.WriteBytes(Encoding.ASCII.GetBytes("fmt ")); ms.WriteUInt32(16); //Chunk size ms.WriteUInt16(1); //Wave Format PCM ms.WriteUInt16((ushort)numberOfChannels); ms.WriteUInt32(sampleRate); ms.WriteUInt32(sampleRate * numberOfChannels * 2); //originally is value / 8, but the input was 16 so this will always be * 2 //byterate ms.WriteUInt16((ushort)(numberOfChannels * 2)); //BlockAlign (channels * bitrate/8, so 16/2 = 2) (2 bytes) ms.WriteUInt16((ushort)(16)); //16 bits per sample ms.WriteBytes(Encoding.ASCII.GetBytes("data")); long dataSizePosition = ms.Position; ms.WriteUInt32(0); //data len = this will have to be updated later, i think ms.Write(DataAsStored, 0, DataAsStored.Length); //XboxADPCMDecoder decoder = new XboxADPCMDecoder(numberOfChannels); /* MemoryStream xboxADPCMStream = new MemoryStream(DataAsStored); * MemoryStream decodedStream = KoopsAudioDecoder.Decode(xboxADPCMStream); * decodedStream.Position = 0; * decodedStream.CopyTo(ms); * * File.WriteAllBytes(@"C:\users\public\xbox_decodeddata.wav", decodedStream.ToArray()); */ //update sizes ms.Seek(dataSizePosition, SeekOrigin.Begin); ms.WriteUInt32((uint)DataAsStored.Length); ms.Seek(4, SeekOrigin.Begin); ms.WriteUInt32((uint)ms.Length - 8); return(ms); } return(null); } /* OLD XBOX CODE (doesn't work for this game) * int headerSize = 52; * MemoryStream ms = new MemoryStream(); * //WAVE HEADER * ms.WriteBytes(Encoding.ASCII.GetBytes("RIFF")); * ms.WriteInt32(headerSize - 8); //size - header is 52 bytes, - 8 for RIFF and this part. * ms.WriteBytes(Encoding.ASCII.GetBytes("WAVE")); * ms.WriteBytes(Encoding.ASCII.GetBytes("fmt ")); * ms.WriteUInt32(16); //Chunk size * * ms.WriteUInt16(1); //Wave Format PCM * ms.WriteUInt16((ushort)numberOfChannels); * * ms.WriteUInt32(sampleRate); * ms.WriteUInt32(sampleRate * numberOfChannels * 2); //originally is value / 8, but the input was 16 so this will always be * 2 //byterate * * ms.WriteUInt16((ushort)(numberOfChannels * 2)); //BlockAlign (channels * bitrate/8, so 16/2 = 2) (2 bytes) * ms.WriteUInt16((ushort)(16)); //16 bits per sample * * * ms.WriteBytes(Encoding.ASCII.GetBytes("data")); * long dataSizePosition = ms.Position; * ms.WriteUInt32(0); //data len = this will have to be updated later, i think * * //XboxADPCMDecoder decoder = new XboxADPCMDecoder(numberOfChannels); * MemoryStream xboxADPCMStream = new MemoryStream(DataAsStored); * MemoryStream decodedStream = KoopsAudioDecoder.Decode(xboxADPCMStream); * decodedStream.Position = 0; * decodedStream.CopyTo(ms); * * File.WriteAllBytes(@"C:\users\public\xbox_decodeddata.wav", decodedStream.ToArray()); * * //update sizes * ms.Seek(dataSizePosition, SeekOrigin.Begin); * ms.WriteUInt32((uint)decodedStream.Length); * * ms.Seek(4, SeekOrigin.Begin); * ms.WriteUInt32((uint)ms.Length - 8); * decodedStream.Dispose(); * return ms;*/ }