public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode maindir = data.GetDirectoryStructure(path); List <DirectoryNode> dirs = new List <DirectoryNode>(maindir.Directories); dirs.Add(maindir); progress.NewTask(dirs.Count); foreach (DirectoryNode dir in dirs) { SongData song = new SongData(data); song.Name = dir.Name; try { data.Session["songdir"] = dir; AddSong(data, song, progress); data.Session.Remove("songdir"); } catch (Exception exception) { Exceptions.Warning(exception, "Unable to parse the Frets on Fire song from " + song.Name); } progress.Progress(); } progress.EndTask(); return(data); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode dir = data.GetDirectoryStructure(path); data.Game = Platform.DetermineGame(data); FileNode tracklist = dir.Navigate("/Common/AUDIO/Audiotracks/TrackListing.xml") as FileNode; XmlReader reader = XmlReader.Create(tracklist.Data); tracklist.Data.Close(); XmlDocument doc = new XmlDocument(); doc.Load(reader); var elements = doc.DocumentElement.GetElementsByTagName("Track"); progress.NewTask(elements.Count); foreach (XmlElement element in elements) { SongData song = FreeStyleGamesMetadata.GetSongData(element); AddSong(data, song, progress); progress.Progress(); } return(data); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode dir = data.GetDirectoryStructure(path); data.Game = Platform.DetermineGame(data); FileNode qbpak = dir.Navigate("pak/qb.pak.ngc") as FileNode; if (qbpak == null) { Exceptions.Error("Couldn't find qb.pak.ngc on Guitar Hero 3 Wii disc."); } try { Pak qb = new Pak(new EndianReader(qbpak.Data, Endianness.BigEndian)); FileNode songlistfile = qb.Root.Find("songlist.qb.ngc", SearchOption.AllDirectories) as FileNode; FileNode albumfile = dir.Navigate("pak/album_covers/album_covers.pak.ngc", false, true) as FileNode; QbFile songlist = new QbFile(songlistfile.Data, PakFormat); QbItemStruct list = songlist.FindItem(QbKey.Create(NeversoftMetadata.SonglistKeys[0]), true) as QbItemStruct; data.Session["rootdir"] = dir; data.Session["rootqb"] = qb; if (albumfile != null) { data.Session["albumpak"] = new Pak(new EndianReader(albumfile.Data, Endianness.BigEndian)); } var items = list.Items; progress.NewTask(items.Count); foreach (QbItemStruct item in items) { SongData song = NeversoftMetadata.GetSongData(data, item); try { AddSong(data, song, progress); } catch (Exception exception) { Exceptions.Warning(exception, "Unable to properly parse " + song.Name); } progress.Progress(); } progress.EndTask(); } catch (Exception exception) { Exceptions.Error(exception, "An error occurred while parsing the Guitar Hero 3 Wii disc."); } return(data); }
public static void Transcode(FormatType type, FormatData data, IList <IFormat> targets, FormatData destination, ProgressIndicator progress) { foreach (IFormat format in targets) { if (format.HasFormat(data)) { Transfer(format, data, destination, progress); return; } } IList <IFormat> formats = FindTranscodePath(data.GetFormats(type), targets); if (formats.Count == 0) { throw new UnsupportedTranscodeException("Could not find a supported transcode path."); } if (formats.Count == 1) { if (formats[0].CanTransfer(data)) { Transfer(formats[0], data, destination, progress); return; } else { formats.Add(formats[0]); } } FormatData tempdata = null; if (formats.Count > 2) { tempdata = new TemporaryFormatData(); } progress.NewTask(formats.Count - 1); for (int i = 1; i < formats.Count; i++) { FormatData dest = i < formats.Count - 1 ? tempdata : destination; Transcode(formats[i - 1], data, formats[i], dest, progress); data = dest; progress.Progress(); } progress.EndTask(); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode dir = data.GetDirectoryStructure(path); List <DirectoryNode> dirs = new List <DirectoryNode>(); dirs.Add(dir); dirs.AddRange(dir.Directories); progress.NewTask(dirs.Count); foreach (DirectoryNode songdir in dirs) { data.Session["songdir"] = songdir; FileNode datafile = songdir.Navigate("data", false, true) as FileNode; FileNode newdatafile = songdir.Navigate("songdata", false, true) as FileNode; if (datafile == null && newdatafile == null) { Exceptions.Warning("Unable to find a custom in " + songdir.Filename); continue; } try { SongData song = null; if (datafile != null) { song = HarmonixMetadata.GetSongData(data, DTB.Create(new EndianReader(datafile.Data, Endianness.LittleEndian))); datafile.Data.Close(); AddSongOld(data, song, progress); } else { song = SongData.Create(newdatafile.Data); newdatafile.Data.Close(); AddSongNew(data, song, progress); } } catch (Exception exception) { Exceptions.Error(exception, "Unable to open the custom from " + songdir.Filename); } progress.Progress(); } progress.EndTask(); return(data); }
public static void TranscodePreview(IList <int> previewtimes, List <AudioFormat.Mapping> maps, IDecoder decoder, Stream stream, ProgressIndicator progress) { RawkAudio.Encoder encoder; if (maps != null && maps.Count(m => m.Instrument == Instrument.Preview) > 0) { decoder.Seek(0); List <ushort> masks = new List <ushort>(); foreach (var m in maps) { if (m.Instrument == Instrument.Preview) { masks.Add((ushort)(1 << maps.IndexOf(m))); } } ushort[] mask = masks.ToArray(); encoder = new RawkAudio.Encoder(stream, mask.Length, decoder.SampleRate, 28000); long samples = decoder.Samples; progress.NewTask("Transcoding Preview", samples); JaggedShortArray buffer = new JaggedShortArray(encoder.Channels, decoder.AudioBuffer.Rank2); while (samples > 0) { int read = decoder.Read((int)Math.Min(samples, decoder.AudioBuffer.Rank2)); if (read <= 0) { break; } decoder.AudioBuffer.DownmixTo(buffer, mask, read); encoder.Write(buffer, read); samples -= read; progress.Progress(read); } progress.EndTask(); } else { long start = Math.Min(decoder.Samples, (long)previewtimes[0] * decoder.SampleRate / 1000); decoder.Seek(start); long duration = Math.Min(decoder.Samples - start, (long)(previewtimes[1] - previewtimes[0]) * decoder.SampleRate / 1000); encoder = new RawkAudio.Encoder(stream, 1, decoder.SampleRate); AudioFormat.Transcode(encoder, decoder, duration, progress); } encoder.Dispose(); }
internal void EncodeOggAudio(AudioFormat data, FormatData destination, IFormat format, Stream stream, ProgressIndicator progress) { IDecoder decoder = data.Decoder; RawkAudio.Encoder encoder = new RawkAudio.Encoder(stream, decoder.Channels, decoder.SampleRate); AudioFormat.ProcessOffset(decoder, encoder, data.InitialOffset); progress.NewTask(1); AudioFormat.Transcode(encoder, decoder, progress); progress.Progress(); encoder.Dispose(); destination.CloseStream(format, AudioName); decoder.Dispose(); data.Save(destination.AddStream(format, FormatName)); destination.CloseStream(format, FormatName); progress.EndTask(); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } PlatformData data = new PlatformData(this, game); data.Session["rootpath"] = path; DirectoryInfo[] dirs = new DirectoryInfo(path).GetDirectories(); progress.NewTask(dirs.Length); foreach (DirectoryInfo dir in dirs) { progress.Progress(); if (!File.Exists(Path.Combine(dir.FullName, "songdata"))) { continue; } try { FormatData format = new FolderFormatData(data, dir.FullName); if (format.Song != null) { data.AddSong(format); } } catch (Exception exception) { Exceptions.Warning(exception, "Unable to open the custom at " + dir.FullName); } } progress.EndTask(); return(data); }
public static void Transcode(IEncoder encoder, IDecoder decoder, long samples, ProgressIndicator progress) { long downmix = decoder.Channels == encoder.Channels ? 0 : encoder.Channels; progress.NewTask("Transcoding Audio", samples); while (samples > 0) { int read = decoder.Read((int)Math.Min(samples, RawkAudio.Decoder.BufferSize)); if (read <= 0) { break; } if (downmix == 1) { decoder.AudioBuffer.DownmixTo(decoder.AudioBuffer, new ushort[] { 0xFFFF }, read); } encoder.Write(decoder.AudioBuffer, read); samples -= read; progress.Progress(read); } progress.EndTask(); }
public static void Transfer(IFormat format, FormatData data, FormatData destination, ProgressIndicator progress) { string[] streams = data.GetStreamNames(); progress.NewTask(streams.Length); foreach (string fullname in streams) { if (fullname.StartsWith(format.ID + ".")) { string name = fullname.Split(new char[] { '.' }, 2)[1]; Stream ostream = destination.AddStream(format, name); Stream istream = data.GetStream(format, name); Util.StreamCopy(ostream, istream); destination.CloseStream(ostream); data.CloseStream(istream); progress.Progress(); } } progress.EndTask(); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode dir = data.GetDirectoryStructure(path); data.Game = Platform.DetermineGame(data); try { FileNode qbpak = dir.Navigate("pak/qb.pak.ngc") as FileNode; if (qbpak == null) { throw new FormatException("Couldn't find qb.pak on Guitar Hero Wii disc."); } FileNode qspak = dir.Navigate("pak/qs.pak.ngc") as FileNode; if (qspak == null) { throw new FormatException("Couldn't find qs.pak on Guitar Hero Wii disc."); } Pak qs = new Pak(new EndianReader(qspak.Data, Endianness.BigEndian)); StringList strings = new StringList(); foreach (Pak.Node node in qs.Nodes) { strings.ParseFromStream(node.Data); } Pak qb = new Pak(new EndianReader(qbpak.Data, Endianness.BigEndian)); FileNode songlistfile = qb.FindFile(@"scripts\guitar\songlist.qb.ngc"); if (songlistfile == null) { songlistfile = qb.FindFile(@"scripts\guitar\songlist.qb"); } if (songlistfile == null) { throw new FormatException("Couldn't find the songlist on the Guitar Hero Wii disc pak."); } QbFile songlist = new QbFile(songlistfile.Data, PakFormat); data.Session["rootdir"] = dir; List <QbKey> listkeys = new List <QbKey>(); foreach (uint songlistkey in NeversoftMetadata.SonglistKeys) { QbKey key = QbKey.Create(songlistkey); QbItemStruct list = songlist.FindItem(key, true) as QbItemStruct; if (list != null && list.Items.Count > 0) { listkeys.Add(key); } } progress.NewTask(listkeys.Count); List <string> songsadded = new List <string>(); foreach (QbKey songlistkey in listkeys) { QbItemStruct list = songlist.FindItem(songlistkey, true) as QbItemStruct; progress.NewTask(list.Items.Count); foreach (QbItemArray item in list.Items.OfType <QbItemArray>()) { item.Items[0].ItemQbKey = item.ItemQbKey; SongData song = NeversoftMetadata.GetSongData(data, item.Items[0] as QbItemStruct, strings); progress.Progress(); if (songsadded.Contains(song.ID)) { continue; } try { if (AddSong(data, song, progress)) { songsadded.Add(song.ID); } } catch (Exception exception) { Exceptions.Warning(exception, "Unable to properly parse " + song.Name); } } progress.EndTask(); progress.Progress(); } progress.EndTask(); qbpak.Data.Close(); qspak.Data.Close(); } catch (Exception exception) { Exceptions.Error(exception, "An error occurred while parsing the Guitar Hero Wii disc."); } return(data); }
public override void EncodeAudio(AudioFormat audioformat, FormatData formatdata, ProgressIndicator progress) { progress.NewTask(20); Stream audio = formatdata.AddStream(this, AudioName); progress.SetNextWeight(1); List <AudioFormat.Mapping> oldmaps = audioformat.Mappings; ushort[] masks = PlatformRB2WiiCustomDLC.RemixAudioTracks(formatdata.Song, audioformat); progress.SetNextWeight(14); long samples = audioformat.Decoder.Samples; CryptedMoggStream mogg = new CryptedMoggStream(audio); //mogg.WriteHeader(samples); mogg.WriteHeader(); RawkAudio.Encoder encoder = new RawkAudio.Encoder(mogg, audioformat.Channels, audioformat.Decoder.SampleRate, 28000); progress.NewTask("Transcoding Audio", samples); JaggedShortArray buffer = new JaggedShortArray(encoder.Channels, audioformat.Decoder.AudioBuffer.Rank2); AudioFormat.ProcessOffset(audioformat.Decoder, encoder, audioformat.InitialOffset); while (samples > 0) { //int read = audioformat.Decoder.Read((int)Math.Min(samples, 0x4E20)); //int read = audioformat.Decoder.Read((int)Math.Min(samples, 0x20)); int read = audioformat.Decoder.Read((int)Math.Min(samples, buffer.Rank2)); if (read <= 0) { break; } audioformat.Decoder.AudioBuffer.DownmixTo(buffer, masks, read); encoder.Write(buffer, read); samples -= read; progress.Progress(read); //mogg.Update(read); } progress.EndTask(); progress.Progress(14); encoder.Dispose(); mogg.WriteEntries(); formatdata.CloseStream(audio); progress.SetNextWeight(6); Stream preview = formatdata.AddStream(this, PreviewName); mogg = new CryptedMoggStream(preview); mogg.WriteHeader(); PlatformRB2WiiCustomDLC.TranscodePreview(formatdata.Song.PreviewTimes, oldmaps, audioformat.Decoder != null ? audioformat.Decoder : new ZeroDecoder(1, 28000, 0x7FFFFFFFFFFFFFFF), mogg, progress); formatdata.CloseStream(preview); progress.EndTask(); progress.Progress(6); Stream formatstream = formatdata.AddStream(this, FormatName); audioformat.Save(formatstream); formatdata.CloseStream(formatstream); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { if (File.Exists(path)) { if (String.Compare(Path.GetExtension(path), ".ark", true) == 0 || String.Compare(Path.GetExtension(path), ".hdr", true) == 0) { path = Path.GetDirectoryName(path); } } PlatformData data = new PlatformData(this, game); data.Game = Platform.DetermineGame(data); Ark ark = data.GetHarmonixArk(path); DirectoryNode songdir = ark.Root.Find("songs", true) as DirectoryNode; if (songdir == null) { Exceptions.Error("This is not a Guitar Hero PS2 disc; the songs dir is missing from the ark."); } FileNode songsdtbfile = ark.Root.Navigate("config/gen/songs.dtb", false, true) as FileNode; if (songsdtbfile == null) { Exceptions.Error("Couldn't find songs.dtb; this is not a Guitar Hero PS2 disc."); } data.Session["songdir"] = songdir; try { List <SongsDTA> dtas = new List <SongsDTA>(); Stream dtbstream = new MemoryStream((int)songsdtbfile.Size); CryptedDtbStream.DecryptOld(dtbstream, new EndianReader(songsdtbfile.Data, Endianness.LittleEndian), (int)songsdtbfile.Size); dtbstream.Position = 0; DTB.NodeTree dtb = DTB.Create(new EndianReader(dtbstream, Endianness.LittleEndian)); progress.NewTask(dtb.Nodes.Count); foreach (DTB.Node node in dtb.Nodes) { DTB.NodeTree tree = node as DTB.NodeTree; if (tree == null || tree.Nodes[0].Type != 0x00000005 || songdir.Find((tree.Nodes[0] as DTB.NodeString).Text) == null) { progress.Progress(); continue; } SongsDTA dta = SongsDTA.Create(tree); if (dtas.FirstOrDefault(d => d.BaseName == dta.BaseName) != null) { progress.Progress(); continue; // Don't import songs twice } dtas.Add(dta); SongData song = HarmonixMetadata.GetSongData(data, tree); try { AddSong(data, song, progress); } catch (Exception exception) { Exceptions.Warning(exception, "Unable to properly parse " + song.Name); } progress.Progress(); } progress.EndTask(); } catch (Exception exception) { Exceptions.Error(exception, "An error occurred while parsing the Guitar Hero PS2 disc."); } return(data); }
public override void SaveSong(PlatformData data, FormatData formatdata, ProgressIndicator progress) { string path = data.Session["maindirpath"] as string; string otitle; ushort oindex; progress.NewTask(10); using (DelayedStreamCache cache = new DelayedStreamCache()) { progress.SetNextWeight(6); string audioextension = ".mogg"; Stream audio = null; Stream preview = null; AudioFormat audioformat = null; IList <IFormat> formats = formatdata.Formats; if (formats.Contains(AudioFormatRB2Mogg.Instance)) { audio = AudioFormatRB2Mogg.Instance.GetAudioStream(formatdata); preview = AudioFormatRB2Mogg.Instance.GetPreviewStream(formatdata); audioformat = AudioFormatRB2Mogg.Instance.DecodeAudioFormat(formatdata); } else if (formats.Contains(AudioFormatRB2Bink.Instance)) { audio = AudioFormatRB2Bink.Instance.GetAudioStream(formatdata); preview = AudioFormatRB2Bink.Instance.GetPreviewStream(formatdata, progress); if (!formatdata.HasStream(preview)) { cache.AddStream(preview); } audioformat = AudioFormatRB2Bink.Instance.DecodeAudioFormat(formatdata); audioextension = ".bik"; } else { throw new NotSupportedException(); } progress.Progress(6); ChartFormat chartformat = (formatdata.GetFormat(FormatType.Chart) as IChartFormat).DecodeChart(formatdata, progress); Stream album = null; Stream chart = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.ChartFile); Stream pan = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.PanFile); Stream weights = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.WeightsFile); Stream milo = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.MiloFile); progress.SetNextWeight(2); if (chart != null && ChartFormatRB.Instance.NeedsFixing(formatdata)) { formatdata.CloseStream(chart); chart = null; } if (chart == null) { chart = new TemporaryStream(); cache.AddStream(chart); AdjustChart(formatdata.Song, audioformat, chartformat).ToMidi().ToMid().Save(chart); chart.Position = 0; } if (weights == null) { weights = new TemporaryStream(); cache.AddStream(weights); CreateWeights(weights, chartformat); weights.Position = 0; } if (pan == null) { pan = new TemporaryStream(); cache.AddStream(pan); CreatePan(pan, chartformat); pan.Position = 0; } if (milo == null) { milo = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.Milo3File); if (milo == null) { milo = new MemoryStream(Properties.Resources.rawksd_milo); } else { Stream milostream = new TemporaryStream(); cache.AddStream(milostream); Milo milofile = new Milo(new EndianReader(milo, Endianness.LittleEndian)); FaceFX fx = new FaceFX(new EndianReader(milofile.Data[0], Endianness.BigEndian)); TemporaryStream fxstream = new TemporaryStream(); fx.Save(new EndianReader(fxstream, Endianness.LittleEndian)); milofile.Data[0] = fxstream; milofile.Compressed = true; milofile.Save(new EndianReader(milostream, Endianness.LittleEndian)); fxstream.Close(); formatdata.CloseStream(milo); milo = milostream; milo.Position = 0; } } //if (album == null) // album = new MemoryStream(Properties.Resources.rawksd_albumart); progress.Progress(2); SongData song = new SongData(formatdata.Song); SongsDTA dta = GetSongsDTA(song, audioformat); if (album == null) { dta.AlbumArt = false; } else { dta.AlbumArt = true; } dta.Song.MidiFile = "dlc/content/songs/" + song.ID + "/" + song.ID + ".mid"; DTB.NodeTree dtb = dta.ToDTB(PlatformRawkFile.Instance.IsRawkSD2(song)); MemoryStream songsdta = new MemoryStream(); cache.AddStream(songsdta); dtb.SaveDTA(songsdta); songsdta.Position = 0; U8 appdta = new U8(); DirectoryNode dir = new DirectoryNode("content"); appdta.Root.AddChild(dir); DirectoryNode songsdir = new DirectoryNode("songs"); dir.AddChild(songsdir); DirectoryNode songdir = new DirectoryNode(song.ID); songsdir.AddChild(songdir); songdir.AddChild(new FileNode(song.ID + "_prev.mogg", preview)); songdir.AddChild(new FileNode("songs.dta", songsdta)); DirectoryNode gendir; if (dta.AlbumArt.Value && album != null) { gendir = new DirectoryNode("gen"); songdir.AddChild(gendir); gendir.AddChild(new FileNode(song.ID + "_nomip_keep.bmp_wii", album)); } U8 appsong = new U8(); dir = new DirectoryNode("content"); appsong.Root.AddChild(dir); songsdir = new DirectoryNode("songs"); dir.AddChild(songsdir); songdir = new DirectoryNode(song.ID); songsdir.AddChild(songdir); songdir.AddChild(new FileNode(song.ID + audioextension, audio)); songdir.AddChild(new FileNode(song.ID + ".mid", chart)); songdir.AddChild(new FileNode(song.ID + ".pan", pan)); gendir = new DirectoryNode("gen"); songdir.AddChild(gendir); gendir.AddChild(new FileNode(song.ID + ".milo_wii", milo)); gendir.AddChild(new FileNode(song.ID + "_weights.bin", weights)); Stream memoryDta = new TemporaryStream(); cache.AddStream(memoryDta); appdta.Save(memoryDta); Stream memorySong = new TemporaryStream(); cache.AddStream(memorySong); appsong.Save(memorySong); formatdata.CloseStream(audio); formatdata.CloseStream(preview); formatdata.CloseStream(chart); formatdata.CloseStream(album); formatdata.CloseStream(pan); formatdata.CloseStream(weights); formatdata.CloseStream(milo); FindUnusedContent(data, formatdata.Song, out otitle, out oindex); TMD tmd = GenerateDummyTMD(otitle); dta.Song.Name = "dlc/" + otitle + "/" + Util.Pad(oindex.ToString(), 3) + "/content/songs/" + song.ID + "/" + song.ID; dtb = dta.ToDTB(PlatformRawkFile.Instance.IsRawkSD2(song)); HarmonixMetadata.SetSongsDTA(song, dtb); string dirpath = Path.Combine(Path.Combine(path, "rawk"), "rb2"); if (!Directory.Exists(Path.Combine(dirpath, "customs"))) { Directory.CreateDirectory(Path.Combine(dirpath, "customs")); } Directory.CreateDirectory(Path.Combine(Path.Combine(dirpath, "customs"), song.ID)); FileStream savestream = new FileStream(Path.Combine(Path.Combine(Path.Combine(dirpath, "customs"), song.ID), "data"), FileMode.Create); dtb.Save(new EndianReader(savestream, Endianness.LittleEndian)); savestream.Close(); TmdContent contentDta = new TmdContent(); contentDta.ContentID = oindex; contentDta.Index = oindex; contentDta.Type = 0x4001; TmdContent contentSong = new TmdContent(); contentSong.ContentID = oindex + 1U; contentSong.Index = (ushort)(oindex + 1); contentSong.Type = 0x4001; memoryDta.Position = 0; contentDta.Hash = Util.SHA1Hash(memoryDta); contentDta.Size = memoryDta.Length; memorySong.Position = 0; contentSong.Hash = Util.SHA1Hash(memorySong); contentSong.Size = memorySong.Length; for (int i = 1; i <= oindex + 1; i++) { if (i == oindex) { tmd.Contents.Add(contentDta); } else if (i == oindex + 1) { tmd.Contents.Add(contentSong); } else { tmd.Contents.Add(new TmdContent() { Index = (ushort)i, ContentID = (uint)i, Size = 1, Type = 0x4001 }); } } tmd.Fakesign(); uint consoleid = GetConsoleID(path); progress.Progress(); dirpath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(path, "private"), "wii"), "data"), "sZAE"); TemporaryStream binstream; DlcBin bin; if (consoleid != 0 && !File.Exists(Path.Combine(dirpath, "000.bin"))) { Directory.CreateDirectory(dirpath); binstream = new TemporaryStream(); binstream.Write(Properties.Resources.rawksd_000bin, 0, Properties.Resources.rawksd_000bin.Length); binstream.Position = 8; new EndianReader(binstream, Endianness.BigEndian).Write(consoleid); binstream.ClosePersist(); File.Move(binstream.Name, Path.Combine(dirpath, "000.bin")); binstream.Close(); } dirpath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(path, "private"), "wii"), "data"), otitle); if (!Directory.Exists(dirpath)) { Directory.CreateDirectory(dirpath); } binstream = new TemporaryStream(); bin = new DlcBin(); bin.Bk.ConsoleID = consoleid; bin.TMD = tmd; bin.Content = tmd.Contents[oindex]; bin.Data = memoryDta; bin.Generate(); bin.Bk.ContentSize = bin.Bk.TotalSize = 0; bin.Bk.TitleID = 0x00010000535A4145UL; bin.Save(binstream); binstream.ClosePersist(); string dtabinpath = Path.Combine(dirpath, Util.Pad(oindex.ToString(), 3) + ".bin"); Util.Delete(dtabinpath); File.Move(binstream.Name, dtabinpath); binstream.Close(); binstream = new TemporaryStream(); bin = new DlcBin(); bin.Bk.ConsoleID = consoleid; bin.TMD = tmd; bin.Content = tmd.Contents[oindex + 1]; bin.Data = memorySong; bin.Generate(); bin.Bk.ContentSize = bin.Bk.TotalSize = 0; bin.Bk.TitleID = 0x00010000535A4145UL; bin.Save(binstream); binstream.ClosePersist(); string songbinpath = Path.Combine(dirpath, Util.Pad((oindex + 1).ToString(), 3) + ".bin"); Util.Delete(songbinpath); File.Move(binstream.Name, songbinpath); binstream.Close(); data.Mutex.WaitOne(); string mainbinpath = Path.Combine(dirpath, "000.bin"); if (!File.Exists(mainbinpath)) { binstream = new TemporaryStream(); bin = new DlcBin(); bin.Bk.ConsoleID = consoleid; bin.TMD = tmd; bin.Content = tmd.Contents[0]; bin.Data = new MemoryStream(Properties.Resources.rawksd_savebanner, false); bin.Generate(); bin.Bk.TitleID = 0x00010000535A4145UL; bin.Save(binstream); binstream.ClosePersist(); File.Move(binstream.Name, mainbinpath); binstream.Close(); } AddSongFromBins(data, song, dtabinpath, songbinpath, progress, true); SaveDTBCache(data); data.Mutex.ReleaseMutex(); cache.Dispose(); progress.Progress(); } progress.EndTask(); }
public override void SaveSong(PlatformData data, FormatData formatdata, ProgressIndicator progress) { string path = data.Session["path"] as string; SongData song = formatdata.Song; progress.NewTask(8); int i; string songpath = null; for (i = 0; i < 0x1000; i++) { songpath = Path.Combine(path, song.ID + (i == 0 ? "" : i.ToString())); if (!Directory.Exists(songpath)) { break; } } Directory.CreateDirectory(songpath); AudioFormat audio = (formatdata.GetFormat(FormatType.Audio) as IAudioFormat).DecodeAudio(formatdata, progress); progress.Progress(); ChartFormat chart = (formatdata.GetFormat(FormatType.Chart) as IChartFormat).DecodeChart(formatdata, progress); progress.Progress(); Stream chartstream = new FileStream(Path.Combine(songpath, "notes.mid"), FileMode.Create, FileAccess.Write); chart.Save(chartstream); chartstream.Close(); Ini ini = new Ini(); ini.SetValue("song", "name", song.Name); ini.SetValue("song", "artist", song.Artist); ini.SetValue("song", "album", song.Album); ini.SetValue("song", "genre", song.Genre); ini.SetValue("song", "year", song.Year.ToString()); ini.SetValue("song", "diff_band", ImportMap.GetBaseTier(Instrument.Ambient, song.Difficulty[Instrument.Ambient]).ToString()); ini.SetValue("song", "diff_guitar", ImportMap.GetBaseTier(Instrument.Guitar, song.Difficulty[Instrument.Guitar]).ToString()); ini.SetValue("song", "diff_bass", ImportMap.GetBaseTier(Instrument.Bass, song.Difficulty[Instrument.Bass]).ToString()); ini.SetValue("song", "diff_drums", ImportMap.GetBaseTier(Instrument.Drums, song.Difficulty[Instrument.Drums]).ToString()); Stream inistream = new FileStream(Path.Combine(songpath, "song.ini"), FileMode.Create, FileAccess.Write); ini.Save(inistream); inistream.Close(); if (song.AlbumArt != null) { Stream albumart = new FileStream(Path.Combine(songpath, "album.png"), FileMode.Create, FileAccess.Write); song.AlbumArt.Save(albumart, ImageFormat.Png); albumart.Close(); } JaggedShortArray encoderdata; var instruments = audio.Mappings.GroupBy(m => m.Instrument == Instrument.Vocals ? Instrument.Ambient : m.Instrument); encoderdata = new JaggedShortArray(2, RawkAudio.Decoder.BufferSize); int count = instruments.Count(); Stream[] streams = new Stream[count]; IEncoder[] encoders = new IEncoder[count]; ushort[][] masks = new ushort[count][]; i = 0; foreach (var item in instruments) { string filename = null; switch (item.Key) { case Instrument.Guitar: filename = "guitar.ogg"; break; case Instrument.Bass: filename = "rhythm.ogg"; break; case Instrument.Drums: filename = "drums.ogg"; break; case Instrument.Ambient: filename = "song.ogg"; break; case Instrument.Preview: filename = "preview.ogg"; break; } streams[i] = new FileStream(Path.Combine(songpath, filename), FileMode.Create, FileAccess.Write); masks[i] = new ushort[2]; foreach (var map in item) { int index = audio.Mappings.IndexOf(map); if (map.Balance <= 0) { masks[i][0] |= (ushort)(1 << index); } if (map.Balance >= 0) { masks[i][1] |= (ushort)(1 << index); } } encoders[i] = new RawkAudio.Encoder(streams[i], 2, audio.Decoder.SampleRate, 44100); i++; } if (audio.InitialOffset > 0) { AudioFormat.ProcessOffset(audio.Decoder, encoders[0], audio.InitialOffset); } else { for (i = 0; i < encoders.Length; i++) { AudioFormat.ProcessOffset(audio.Decoder, encoders[i], audio.InitialOffset); } } long samples = audio.Decoder.Samples; progress.NewTask("Transcoding Audio", samples, 6); while (samples > 0) { int read = audio.Decoder.Read(); if (read <= 0) { break; } // TODO: Apply volumes to each channel for (i = 0; i < count; i++) { audio.Decoder.AudioBuffer.DownmixTo(encoderdata, masks[i], read, false); encoders[i].Write(encoderdata, read); } samples -= read; progress.Progress(read); } for (i = 0; i < count; i++) { encoders[i].Dispose(); streams[i].Close(); } progress.EndTask(); progress.Progress(6); progress.EndTask(); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { progress.NewTask(10); progress.SetNextWeight(9); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } PlatformData data = new PlatformData(this, game); data.Session["maindirpath"] = path; string customdir = Path.Combine(path, "rawk/rb2/customs"); if (Directory.Exists(customdir)) { string dtapath = Path.Combine(customdir, "data"); DTB.NodeTree dtb = null; if (File.Exists(dtapath)) { Stream dtafile = new FileStream(dtapath, FileMode.Open, FileAccess.Read, FileShare.Read); try { dtb = DTB.Create(new EndianReader(dtafile, Endianness.LittleEndian)); } catch (Exception exception) { Exceptions.Warning(exception, "The rawk/rb2/customs/data cache DTB is corrupt."); } dtafile.Close(); } if (dtb != null) { progress.NewTask(dtb.Nodes.Count); foreach (DTB.NodeTree node in dtb.Nodes) { try { AddSongFromDTB(path, data, node, progress); } catch (Exception exception) { Exceptions.Warning(exception, "Could not import RawkSD custom from data cache."); } progress.Progress(); } progress.EndTask(); } else { string[] dirs = Directory.GetDirectories(customdir); progress.NewTask(dirs.Length); foreach (string folder in dirs) { try { dtapath = Path.Combine(folder, "data"); if (File.Exists(dtapath)) { dtb = null; Stream dtafile = new FileStream(dtapath, FileMode.Open, FileAccess.Read, FileShare.Read); try { dtb = DTB.Create(new EndianReader(dtafile, Endianness.LittleEndian)); } catch (Exception exception) { Exceptions.Warning(exception, "The data file for \"" + folder + "\" is corrupt."); } dtafile.Close(); if (dtb != null) { AddSongFromDTB(path, data, dtb, progress); } } } catch (Exception exception) { Exceptions.Warning(exception, "Could not import RawkSD custom from " + folder); } progress.Progress(); } progress.EndTask(); } progress.Progress(9); } RefreshUnusedContent(data); progress.Progress(); progress.EndTask(); return(data); }
public override ChartFormat DecodeChart(FormatData data, ProgressIndicator progress) { if (!data.HasStream(this, ChartName) || !data.HasStream(this, SectionsName)) { throw new FormatException(); } progress.NewTask(6 + 8); Stream chartstream = data.GetStream(this, ChartName); Stream sectionstream = data.GetStream(this, SectionsName); PakFormat format = NeversoftMetadata.GetSongItemType(data.Song); SongData song = NeversoftMetadata.GetSongData(data.PlatformData, NeversoftMetadata.GetSongItem(data)); Pak chartpak = new Pak(new EndianReader(chartstream, Endianness.BigEndian)); // TODO: Endianness based on format? FileNode chartfile = chartpak.Root.Find(song.ID + ".mid.qb.ngc", SearchOption.AllDirectories, true) as FileNode; QbFile qbsections = new QbFile(sectionstream, format); QbFile qbchart = new QbFile(chartfile.Data, format); NoteChart chart = new NoteChart(); chart.PartGuitar = new NoteChart.Guitar(chart); chart.PartBass = new NoteChart.Bass(chart); chart.Events = new NoteChart.EventsTrack(chart); chart.Venue = new NoteChart.VenueTrack(chart); chart.Beat = new NoteChart.BeatTrack(chart); progress.Progress(); DecodeChartFretbars(song, qbchart, chart); progress.Progress(); DecodeChartMarkers(song, qbsections, qbchart, chart); progress.Progress(); for (NoteChart.TrackType track = NoteChart.TrackType.Guitar; track <= NoteChart.TrackType.Bass; track++) { for (NoteChart.Difficulty difficulty = NoteChart.Difficulty.Easy; difficulty <= NoteChart.Difficulty.Expert; difficulty++) { DecodeChartNotes(data, song, qbchart, chart, track, difficulty, data.Song.Data.GetValue <bool>("GH3ChartCoop")); progress.Progress(); } } progress.Progress(); DecodeChartDrums(song, qbchart, chart); progress.Progress(); DecodeChartVenue(song, qbchart, chart); ImportMap.ImportChart(data.Song, chart); progress.Progress(); data.CloseStream(chartstream); data.CloseStream(sectionstream); progress.EndTask(); return(new ChartFormat(chart)); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); Ark ark = data.GetHarmonixArk(path); data.Game = Platform.DetermineGame(data); if (data.Game == Game.RockBand2 || data.Game == Game.RockBandBeatles) { Exceptions.Error("Unable to parse song list from Rock Band Wii disc."); } data.Session["songdir"] = ark.Root; string[] songdirs = new string[] { "songs", "songs_regional/na", "songs_regional/eu" }; progress.NewTask(songdirs.Length); foreach (string songdirname in songdirs) { DirectoryNode songdir = ark.Root.Navigate(songdirname) as DirectoryNode; if (songdir == null) { continue; } FileNode songsdtbfile = songdir.Navigate("gen/songs.dtb") as FileNode; if (songsdtbfile == null) { continue; } try { List <SongsDTA> dtas = new List <SongsDTA>(); DTB.NodeTree dtb = DTB.Create(new EndianReader(new CryptedDtbStream(new EndianReader(songsdtbfile.Data, Endianness.LittleEndian)), Endianness.LittleEndian)); progress.NewTask(dtb.Nodes.Count); foreach (DTB.Node node in dtb.Nodes) { DTB.NodeTree tree = node as DTB.NodeTree; if (tree == null || tree.Nodes[0].Type != 0x00000005 || songdir.Find((tree.Nodes[0] as DTB.NodeString).Text) == null) { progress.Progress(); continue; } SongsDTA dta = SongsDTA.Create(tree); if (dtas.Find(d => d.BaseName == dta.BaseName) != null) { progress.Progress(); continue; // Don't import songs twice } dtas.Add(dta); try { SongData song = HarmonixMetadata.GetSongData(data, tree); AddSong(data, song, progress); } catch (Exception exception) { Exceptions.Warning(exception, "Could not import " + dta.Name + " from the Rock Band Wii disc."); } progress.Progress(); } } catch (Exception exception) { Exceptions.Warning(exception, "Unable to parse song list from Rock Band Wii disc: " + songdirname); } progress.EndTask(); progress.Progress(); } progress.EndTask(); return(data); }
public ChartFormat DecodeChart(FormatData data, ProgressIndicator progress, params Stream[] chartstreams) { progress.NewTask(5 + 12); PakFormat format = NeversoftMetadata.GetSongItemType(data.Song); SongData song = NeversoftMetadata.GetSongData(data.PlatformData, NeversoftMetadata.GetSongItem(data)); List <Pak> chartpaks = new List <Pak>(); foreach (Stream stream in chartstreams) { chartpaks.Add(new Pak(new EndianReader(stream, Endianness.BigEndian))); // TODO: Endianness based on format? } FileNode chartfile = null; foreach (Pak pak in chartpaks) { chartfile = pak.FindFile(song.ID + ".mid.qb.ngc") ?? chartfile; chartfile = pak.FindFile(song.ID + ".mid.qb") ?? chartfile; } if (chartfile == null) { foreach (Pak pak in chartpaks) { chartfile = chartfile ?? pak.FindFileType(0xa7f505c4); } } QbFile qbchart = null; if (chartfile != null) { qbchart = new QbFile(chartfile.Data, format); } StringList strings = new StringList(); foreach (Pak pak in chartpaks) { foreach (Pak.Node n in pak.Nodes) { if (!n.Filename.HasValue()) { strings.ParseFromStream(n.Data); } } } QbFile qbsections = null; FileNode qbsectionfile = null; foreach (Pak pak in chartpaks) { qbsectionfile = pak.FindFile(song.ID + ".mid_text.qb.ngc") as FileNode ?? qbsectionfile; qbsectionfile = pak.FindFile(song.ID + ".mid_text.qb") as FileNode ?? qbsectionfile; } if (qbsectionfile != null) { qbsections = new QbFile(qbsectionfile.Data, format); } Notes notes = null; FileNode notesfile = null; foreach (Pak pak in chartpaks) { notesfile = notesfile ?? pak.FindFileType(0xa9d5bc8f); notesfile = pak.FindFile(song.ID + ".note.ngc") as FileNode ?? notesfile; notesfile = pak.FindFile(song.ID + ".note") as FileNode ?? notesfile; } if (notesfile == null) { foreach (Pak pak in chartpaks) { notesfile = pak.FindFileType(0xa9d5bc8f) ?? notesfile; } } if (notesfile != null) { notesfile.Data.Position = 0; notes = Notes.Create(new EndianReader(notesfile.Data, Endianness.BigEndian)); } NoteChart chart = new NoteChart(); chart.PartGuitar = new NoteChart.Guitar(chart); chart.PartBass = new NoteChart.Bass(chart); chart.PartDrums = new NoteChart.Drums(chart); chart.PartVocals = new NoteChart.Vocals(chart); chart.Events = new NoteChart.EventsTrack(chart); chart.Venue = new NoteChart.VenueTrack(chart); chart.Beat = new NoteChart.BeatTrack(chart); bool gh4v2 = NeversoftMetadata.IsGuitarHero4(data.PlatformData.Game) && data.PlatformData.Game != Game.GuitarHeroWorldTour; string drumconfig = gh4v2 ? "drums3" : "drums2"; chart.PartDrums.Mixing.Add(new Pair <NoteChart.Point, Pair <NoteChart.Difficulty, string> >(new NoteChart.Point(0), new Pair <NoteChart.Difficulty, string>(NoteChart.Difficulty.Easy, drumconfig + "easy"))); chart.PartDrums.Mixing.Add(new Pair <NoteChart.Point, Pair <NoteChart.Difficulty, string> >(new NoteChart.Point(0), new Pair <NoteChart.Difficulty, string>(NoteChart.Difficulty.Medium, drumconfig))); chart.PartDrums.Mixing.Add(new Pair <NoteChart.Point, Pair <NoteChart.Difficulty, string> >(new NoteChart.Point(0), new Pair <NoteChart.Difficulty, string>(NoteChart.Difficulty.Hard, drumconfig))); chart.PartDrums.Mixing.Add(new Pair <NoteChart.Point, Pair <NoteChart.Difficulty, string> >(new NoteChart.Point(0), new Pair <NoteChart.Difficulty, string>(NoteChart.Difficulty.Expert, drumconfig))); progress.Progress(); DecodeChartFretbars(song, qbchart, notes, chart); progress.Progress(); DecodeChartSections(song, qbchart, strings, qbsections, notes, chart); progress.Progress(); for (NoteChart.TrackType track = NoteChart.TrackType.Guitar; track <= NoteChart.TrackType.Drums;) { for (NoteChart.Difficulty difficulty = NoteChart.Difficulty.Easy; difficulty <= NoteChart.Difficulty.Expert; difficulty++) { DecodeChartNotes(song, qbchart, notes, chart, track, difficulty); progress.Progress(); } switch (track) { case NoteChart.TrackType.Guitar: track = NoteChart.TrackType.Bass; break; case NoteChart.TrackType.Bass: track = NoteChart.TrackType.Drums; break; case NoteChart.TrackType.Drums: track = NoteChart.TrackType.Events; break; } } // Automatic Drum Fills - 1-measure fills every 4 measures, if there's no overdrive overlap FillSections(chart, 1, 4, 3, chart.PartDrums.DrumFills, chart.PartDrums.Overdrive); progress.Progress(); if (DecodeChartVocals(song, qbchart, strings, notes, chart)) { DecodeChartVocalPhrases(song, qbchart, notes, chart); } ImportMap.ImportChart(data.Song, chart); progress.Progress(); progress.EndTask(); return(new ChartFormat(chart)); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode dir = data.GetDirectoryStructure(path); FileNode binfile = dir.Navigate("001.bin") as FileNode; if (binfile == null) { Exceptions.Error("Unable to open Guitar Hero World Tour DLC because 001.bin is missing."); } data.Session["rootdir"] = dir; try { DlcBin bin = new DlcBin(binfile.Data); U8 u8 = new U8(bin.Data); FileNode listfile = u8.Root.Navigate("DLC1.pak.ngc") as FileNode; Pak qb = new Pak(new EndianReader(listfile.Data, Endianness.BigEndian)); FileNode songlistfile = qb.Root.Find("catalog_info.qb.ngc", SearchOption.AllDirectories) as FileNode; QbFile songlist = new QbFile(songlistfile.Data, PakFormat); StringList strings = new StringList(); foreach (Pak.Node node in qb.Nodes) { if (!node.Filename.HasValue()) { strings.ParseFromStream(node.Data); } } List <QbKey> listkeys = new List <QbKey>(); foreach (uint songlistkey in NeversoftMetadata.SonglistKeys) { QbKey key = QbKey.Create(songlistkey); QbItemStruct list = songlist.FindItem(key, true) as QbItemStruct; if (list != null && list.Items.Count > 0) { listkeys.Add(key); } } Stream str = new FileStream(@"C:\ghwt.xml", FileMode.Create); StreamWriter writer = new StreamWriter(str); progress.NewTask(listkeys.Count); foreach (QbKey songlistkey in listkeys) { QbItemStruct list = songlist.FindItem(songlistkey, true) as QbItemStruct; progress.NewTask(list.Items.Count); foreach (QbItemArray item in list.Items.OfType <QbItemArray>()) { item.Items[0].ItemQbKey = item.ItemQbKey; SongData song = NeversoftMetadata.GetSongData(data, item.Items[0] as QbItemStruct, strings); writer.WriteLine("\t<song id=\"" + song.ID + "\">"); writer.WriteLine("\t\t<pack>Guitar Hero World Tour DLC</pack>"); writer.WriteLine("\t\t<nameprefix>[GHWT DLC]</nameprefix>"); writer.WriteLine("\t\t<name>" + song.Name + "</name>"); writer.WriteLine("\t\t<artist>" + song.Artist + "</artist>"); writer.WriteLine("\t\t<album>" + song.Album + "</album>"); writer.WriteLine("\t\t<genre>" + song.Genre + "</genre>"); writer.WriteLine("\t\t<track>" + song.AlbumTrack.ToString() + "</track>"); writer.WriteLine("\t\t<difficulty instrument=\"band\" rank=\"1\" />"); writer.WriteLine("\t\t<difficulty instrument=\"guitar\" rank=\"1\" />"); writer.WriteLine("\t\t<difficulty instrument=\"bass\" rank=\"1\" />"); writer.WriteLine("\t\t<difficulty instrument=\"drum\" rank=\"1\" />"); writer.WriteLine("\t\t<difficulty instrument=\"vocals\" rank=\"1\" />"); writer.WriteLine("\t</song>"); try { AddSong(data, song, progress); } catch (Exception exception) { Exceptions.Warning(exception, "Unable to properly parse " + song.Name); } progress.Progress(); } progress.EndTask(); progress.Progress(); } progress.EndTask(); writer.Close(); binfile.Data.Close(); } catch (Exception exception) { Exceptions.Error(exception, "An error occurred while parsing the Guitar Hero World Tour DLC list."); } return(data); }