public override ChartFormat DecodeChart(FormatData data, ProgressIndicator progress) { if (!data.HasStream(this, ChartFile)) { throw new FormatException(); } Stream stream = data.GetStream(this, ChartFile); Midi midi = Midi.Create(Mid.Create(stream)); if (data.Song.Data.GetValue <bool>("RBChartExpertPlus")) { Midi.Track track = midi.GetTrack("PART DRUMS"); if (track != null) { foreach (Midi.NoteEvent note in track.Notes) { if (note.Note == 95) { note.Note = 96; } } } } ChartFormat chart = ChartFormat.Create(midi); data.CloseStream(stream); return(chart); }
public override void EncodeChart(ChartFormat data, FormatData destination, ProgressIndicator progress) { Stream stream = destination.AddStream(this, ChartFile); data.Save(stream); destination.CloseStream(stream); }
public static void CreateWeights(Stream weights, ChartFormat chartformat) { EndianReader writer = new EndianReader(weights, Endianness.LittleEndian); NoteChart chart = chartformat.Chart; //if (chart.PartVocals == null) // return; ulong duration = chart.GetTime(chart.FindLastNote()); for (ulong i = 0; i < 60 * duration / 1000000; i++) { //for (ulong i = 0; i < 0x100; i++) //writer.Write((byte)0x00); writer.Write((byte)0x90); } /* foreach (var lyric in chart.PartVocals.Lyrics) { * if (!lyric.Value.EndsWith("#") && !lyric.Value.EndsWith("^")) * continue; * * var gem = chart.PartVocals.Gems.FirstOrDefault(g => g.Time == lyric.Key.Time); * if (gem == null) * continue; * * ulong time = chart.GetTime(gem.Time); * time = 60 * time / 1000000; * for (ulong i = (ulong)writer.Position; i < time; i++) * writer.Write((byte)0xFE); * ulong duration = chart.GetTimeDuration(gem.Time, gem.Duration); * for (ulong i = 0; i < duration; i += 1000000/60) * writer.Write((byte)0x90); * } */ }
public static NoteChart AdjustChart(SongData song, AudioFormat audioformat, ChartFormat chartformat) { NoteChart chart = chartformat.Chart; if (song.Difficulty[Instrument.Guitar] == 0) { chart.PartGuitar = null; } if (song.Difficulty[Instrument.Bass] == 0) { chart.PartBass = null; } if (song.Difficulty[Instrument.Drums] == 0) { chart.PartDrums = null; } if (song.Difficulty[Instrument.Vocals] == 0) { chart.PartVocals = null; } if (chart.PartDrums != null) { int drumcount = audioformat.Mappings.Count(m => m.Instrument == Instrument.Drums); foreach (var mix in chart.PartDrums.Mixing) { if (drumcount == 2 && mix.Value.Value != "drums0" && mix.Value.Value != "drums0d") { mix.Value.Value = "drums0"; } // TODO: Better validation } } if (chart.PartVocals != null) { foreach (var lyric in chart.PartVocals.Lyrics) { if (lyric.Value.EndsWith("*")) { lyric.Value = lyric.Value.Substring(0, lyric.Value.Length - 1) + "^"; } } } return(chart); }
public static void CreatePan(Stream pan, ChartFormat chartformat) { EndianReader writer = new EndianReader(pan, Endianness.LittleEndian); NoteChart chart = chartformat.Chart; //if (chart.PartVocals == null) // return; ulong duration = chart.GetTime(chart.FindLastNote()); for (ulong i = 0; i < 8 * 60 * duration / 1000000; i++) { //for (ulong i = 0; i < 0x100; i++) //writer.Write((byte)0x00); writer.Write((byte)0xFF); } }
public override ChartFormat DecodeChart(FormatData data, ProgressIndicator progress) { if (!data.HasStream(this, ChartName)) { throw new FormatException(); } Stream[] streams = GetChartStreams(data); ChartFormat format = ChartFormatGH5.Instance.DecodeChart(data, progress, streams); foreach (Stream stream in streams) { data.CloseStream(stream); } return(format); }
public bool NeedsFixing(FormatData data) { if (data.Song.Data.GetValue <bool>("RBChartFixForQuickplay") || data.Song.Data.GetValue <bool>("RBChartExpertPlus")) { return(true); } ChartFormat chart = DecodeChart(data, new ProgressIndicator()); if (chart.Chart.PartVocals != null) { foreach (var lyric in chart.Chart.PartVocals.Lyrics) { if (lyric.Value.EndsWith("*")) { return(true); } } } return(false); }
public override ChartFormat DecodeChart(FormatData data, ProgressIndicator progress) { if (!data.HasStream(this, ChartFile)) { throw new FormatException(); } Stream stream = data.GetStream(this, ChartFile); Midi midi = Midi.Create(Mid.Create(stream)); data.CloseStream(stream); ChartFormat chart = new ChartFormat(NoteChart.Create(midi)); DecodeLeftHandAnimations(chart.Chart, midi); ChartFormatGH2.DecodeDrums(chart.Chart, midi, true); ChartFormatGH2.DecodeOverdrive(chart.Chart); ImportMap.ImportChart(data.Song, chart.Chart); return(chart); }
public override ChartFormat DecodeChart(FormatData data, ProgressIndicator progress) { if (!data.HasStream(this, ChartFile)) { throw new FormatException(); } Stream stream = data.GetStream(this, ChartFile); Midi midi = Midi.Create(Mid.Create(stream)); data.CloseStream(stream); DecodeCoop(midi, data.Song.Data.GetValue <bool>("GH2ChartCoop")); ChartFormat chart = new ChartFormat(NoteChart.Create(midi)); DecodeDrums(chart.Chart, midi, false); DecodeOverdrive(chart.Chart); ImportMap.ImportChart(data.Song, chart.Chart); return(chart); }
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 void EncodeChart(ChartFormat data, FormatData destination, ProgressIndicator progress) { throw new NotImplementedException(); }
public abstract void EncodeChart(ChartFormat data, FormatData destination, ProgressIndicator progress);
public static ChartFormat Create(Midi midi) { ChartFormat format = new ChartFormat(NoteChart.Create(midi)); return(format); }
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(); }