public AudioFormat DecodeFormat(FormatData data) { Stream stream = GetFormatStream(data); if (stream == null) { return(NeversoftMetadata.GetAudioFormat(data) ?? HarmonixMetadata.GetAudioFormat(data.Song)); } AudioFormat format = AudioFormat.Create(stream); data.CloseStream(stream); return(format); }
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 override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress) { int index = int.Parse(song.ID.Substring(3)); //song.ID = "dlc" + ImportMap.GetShortName(song.Name); FormatData formatdata = new TemporaryFormatData(song, data); NeversoftMetadata.SaveSongItem(formatdata); DirectoryNode dir = data.Session["rootdir"] as DirectoryNode; FileNode binfile = dir.Navigate(Util.Pad(index.ToString(), 3) + ".bin") as FileNode; if (binfile == null) { return(false); } DlcBin bin = new DlcBin(binfile.Data); U8 u8 = new U8(bin.Data); FileNode chartpak = u8.Root.Find(song.ID + "_song.pak.ngc", SearchOption.AllDirectories) as FileNode; FileNode textpak = u8.Root.Find(song.ID + "_text.pak.ngc", SearchOption.AllDirectories) as FileNode; FileNode audiofile = u8.Root.Find(song.ID + ".bik", SearchOption.AllDirectories) as FileNode; if (chartpak == null || textpak == null || audiofile == null) { return(false); } ChartFormatGH4.Instance.Create(formatdata, new Stream[] { chartpak.Data, textpak.Data }, PlatformGH5WiiDisc.ImportExpertPlus); if (audiofile != null) { AudioFormatBink.Instance.Create(formatdata, audiofile.Data, null, null); } data.AddSong(formatdata); chartpak.Data.Close(); return(true); }
public static void Initialise() { Formats = new List <IFormat>(); //PlatformDJHWiiDisc.Initialise(); PlatformFretsOnFire.Initialise(); PlatformGH2PS2Disc.Initialise(); PlatformGH3WiiDisc.Initialise(); PlatformGH4WiiDLC.Initialise(); PlatformGH5WiiDisc.Initialise(); //PlatformGH5WiiDLC.Initialise(); PlatformLocalStorage.Initialise(); PlatformRawkFile.Initialise(); //PlatformRB2360Disc.Initialise(); //PlatformRB2360DLC.Initialise(); PlatformRB2360RBN.Initialise(); PlatformRB2WiiCustomDLC.Initialise(); PlatformRB2WiiDisc.Initialise(); //PlatformRB2WiiDLC.Initialise(); //ChartFormatChart.Initialise(); //ChartFormatFsgMub.Initialise(); ChartFormatGH1.Initialise(); ChartFormatGH2.Initialise(); ChartFormatGH3.Initialise(); ChartFormatGH4.Initialise(); ChartFormatGH5.Initialise(); ChartFormatRB.Initialise(); AudioFormatBeatlesBink.Initialise(); AudioFormatBink.Initialise(); AudioFormatFFmpeg.Initialise(); AudioFormatGH3WiiFSB.Initialise(); AudioFormatMogg.Initialise(); //AudioFormatMp3.Initialise(); AudioFormatOgg.Initialise(); AudioFormatRB2Bink.Initialise(); AudioFormatRB2Mogg.Initialise(); AudioFormatVGS.Initialise(); NeversoftMetadata.Initialise(); }
public override AudioFormat DecodeAudio(FormatData data, ProgressIndicator progress) { AudioFormat format = DecodeFormat(data); Stream audio = data.GetStream(this, AudioName); uint magic = new EndianReader(audio, Endianness.BigEndian).ReadUInt32(); if (magic != 0x5241574b && (magic & 0xFFFFFF00) != 0x42494b00) { throw new FormatException(); // Must start with "RAWK" or "BIK", this is to prevent encrypted biks from being decoded } audio.Position = 0; Stream preview = null; format.Decoder = new RawkAudio.Decoder(audio, RawkAudio.Decoder.AudioFormat.BinkAudio); if (data.HasStream(this, PreviewName)) { preview = data.GetStream(this, PreviewName); magic = new EndianReader(preview, Endianness.BigEndian).ReadUInt32(); preview.Position = 0; if (magic != 0x5241574b && (magic & 0xFFFFFF00) != 0x42494b00) { throw new FormatException(); } IDecoder decoder = new RawkAudio.Decoder(preview, RawkAudio.Decoder.AudioFormat.BinkAudio); MultiDecoder multi = new MultiDecoder(RawkAudio.Decoder.BufferSize); multi.AddDecoder(format.Decoder); multi.AddDecoder(decoder); format.Decoder = multi; } format.SetDisposeStreams(data, new Stream[] { audio, preview }); Game game = data.Song.Game; if (NeversoftMetadata.IsGuitarHero4(game) || NeversoftMetadata.IsGuitarHero5(game)) { format.Decoder = new AmplifyDecoder(format.Decoder, 1.30f); } return(format); }
public override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress) { FormatData formatdata = new TemporaryFormatData(song, data); NeversoftMetadata.SaveSongItem(formatdata); DirectoryNode dir = data.Session["rootdir"] as DirectoryNode; FileNode chartpak = dir.Navigate("songs/" + song.ID + ".pak.ngc", false, true) as FileNode; if (chartpak == null) { return(false); } if (data.Game == Game.GuitarHero5 || data.Game == Game.BandHero) { ChartFormatGH5.Instance.Create(formatdata, new Stream[] { chartpak.Data }, ImportExpertPlus); } else { ChartFormatGH4.Instance.Create(formatdata, new Stream[] { chartpak.Data }, ImportExpertPlus); } FileNode audiofile = dir.Navigate("music/" + song.ID + ".bik", false, true) as FileNode; FileNode previewfile = dir.Navigate("music/" + song.ID + "_preview.bik", false, true) as FileNode; if (audiofile != null) { AudioFormatBink.Instance.Create(formatdata, audiofile.Data, previewfile == null ? null : previewfile.Data, null); } data.AddSong(formatdata); chartpak.Data.Close(); return(true); }
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 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); }
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 static void Initialise() { Instance = new NeversoftMetadata(); Platform.AddFormat(Instance); }
public static AudioFormat GetAudioFormat(FormatData data) { SongData song = data.Song; AudioFormat audioformat = new AudioFormat(); QbItemStruct item = GetSongItem(data); if (item == null) { return(null); } float bandvolume = 0; float guitarvolume = 0; float bassvolume = 0; float drumvolume = 0; QbItemFloat subitem = item.FindItem(QbKey.Create(0xD8F335CF), false) as QbItemFloat; // GH3: band_playback_volume if (subitem != null) { bandvolume = (subitem as QbItemFloat).Values[0]; bassvolume = bandvolume; } subitem = item.FindItem(QbKey.Create(0xA449CAD3), false) as QbItemFloat; // GH3: guitar_playback_volume if (subitem != null) { guitarvolume = (subitem as QbItemFloat).Values[0]; } subitem = item.FindItem(QbKey.Create(0x46507438), false) as QbItemFloat; // GH4: overall_song_volume if (subitem != null) { bandvolume = (subitem as QbItemFloat).Values[0]; guitarvolume = bandvolume; bassvolume = bandvolume; drumvolume = bandvolume; } // GH4 engine games that came out after GHWT use a different drum audio scheme; the GH5 engine uses the same as GHWT bool gh4v2 = NeversoftMetadata.IsGuitarHero4(song.Game) && song.Game != Game.GuitarHeroWorldTour; // GHVH is the only BIK-based GH game with stereo bass bool ghvh = song.Game == Game.GuitarHeroVanHalen; if (gh4v2) { // Kick audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, -1, Instrument.Drums)); audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 1, Instrument.Drums)); // Snare audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, -1, Instrument.Drums)); audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 1, Instrument.Drums)); } else { // Kick audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 0, Instrument.Drums)); // Snare audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 0, Instrument.Drums)); } // Overhead audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, -1, Instrument.Drums)); audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 1, Instrument.Drums)); // Guitar audioformat.Mappings.Add(new AudioFormat.Mapping(guitarvolume, -1, Instrument.Guitar)); audioformat.Mappings.Add(new AudioFormat.Mapping(guitarvolume, 1, Instrument.Guitar)); // Bass audioformat.Mappings.Add(new AudioFormat.Mapping(bassvolume, ghvh ? -1 : 0, Instrument.Bass)); if (ghvh) { audioformat.Mappings.Add(new AudioFormat.Mapping(bassvolume, 1, Instrument.Bass)); } // Else / Vocals audioformat.Mappings.Add(new AudioFormat.Mapping(bandvolume, -1, Instrument.Ambient)); audioformat.Mappings.Add(new AudioFormat.Mapping(bandvolume, 1, Instrument.Ambient)); // Preview audioformat.Mappings.Add(new AudioFormat.Mapping(bandvolume, -1, Instrument.Preview)); audioformat.Mappings.Add(new AudioFormat.Mapping(bandvolume, 1, Instrument.Preview)); return(audioformat); }
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)); }