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 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)); }