public static SongsDTA GetSongData(SongData data) { SongsDTA dta = GetSongsDTA(data) ?? new SongsDTA(); dta.Album = data.Album; dta.Track = data.AlbumTrack; dta.Artist = data.Artist; dta.BaseName = data.ID; dta.Genre = data.Genre; dta.Master = data.Master; dta.Name = data.Name; dta.Pack = data.Pack; dta.Vocalist = data.Vocalist; dta.Year = data.Year; dta.Version = data.Version; if (data.PreviewTimes.Count == 2) { dta.Preview[0] = data.PreviewTimes[0]; dta.Preview[1] = data.PreviewTimes[1]; } if (data.HopoThreshold > 0) { dta.Song.HopoThreshold = data.HopoThreshold; } for (Instrument instrument = Instrument.Ambient; instrument <= Instrument.Vocals; instrument++) { SongsDTA.Rankings rank = dta.Rank.SingleOrDefault(r => r.Name == InstrumentToString(instrument)); if (rank != null) { rank.Rank = data.Difficulty[instrument]; } } return(dta); }
private void BankCombo_SelectedIndexChanged(object sender, EventArgs e) { if (Song == null) { return; } SongsDTA dta = GetOrCreateDTA(); switch (BankCombo.SelectedIndex) { case 0: dta.Bank = "sfx/tambourine_bank.milo"; break; case 1: dta.Bank = "sfx/cowbell_bank.milo"; break; case 2: dta.Bank = "sfx/triangle_bank.milo"; break; case 3: dta.Bank = "sfx/handclap_bank.milo"; break; default: return; } SaveDTA(dta); }
private static IList <SongsDTA> GetInstalledCustoms(string path, string sdpath) { if (!Directory.Exists(path)) { return(new List <SongsDTA>()); } List <SongsDTA> list = new List <SongsDTA>(); string[] dirs = Directory.GetDirectories(path, "*", SearchOption.TopDirectoryOnly); foreach (string file in dirs) { if (File.Exists(Path.Combine(file, "data"))) { FileStream fstream = null; try { fstream = new FileStream(Path.Combine(file, "data"), FileMode.Open); list.Add(SongsDTA.Create(DTB.Create(new EndianReader(fstream, Endianness.LittleEndian)))); } catch { } if (fstream != null) { fstream.Close(); } } } return(list); }
private void AnimationTempoCombo_SelectedIndexChanged(object sender, EventArgs e) { if (Song == null) { return; } SongsDTA dta = GetOrCreateDTA(); switch (AnimationTempoCombo.SelectedIndex) { case 0: dta.AnimTempo = 0x10; break; case 1: dta.AnimTempo = 0x20; break; case 2: dta.AnimTempo = 0x40; break; default: return; } SaveDTA(dta); }
public static AudioFormat GetAudioFormat(SongData song) { AudioFormat format = new AudioFormat(); SongsDTA dta = GetSongsDTA(song); if (dta == null) { return(null); } bool notracks = dta.Song.Tracks.Sum(t => t.Tracks.Count) == 0; for (int i = 0; i < dta.Song.Vols.Count; i++) { AudioFormat.Mapping map = new AudioFormat.Mapping(); map.Balance = dta.Song.Pans[i]; map.Volume = dta.Song.Vols[i]; SongsDTA.SongTracks track = dta.Song.Tracks.SingleOrDefault(s => s.Tracks.Contains(i)); if (track != null) { map.Instrument = Platform.InstrumentFromString(track.Name); } else if (notracks && dta.Song.Cores[i] == 1) { map.Instrument = Instrument.Guitar; } format.Mappings.Add(map); } return(format); }
private void SaveDTBCache(PlatformData data) { data.Mutex.WaitOne(); string path = Path.Combine(Path.Combine(Path.Combine(Path.Combine(data.Session["maindirpath"] as string, "rawk"), "rb2"), "customs"), "data"); if (data.Songs.Count == 0) { if (File.Exists(path)) { Util.Delete(path); } data.Mutex.ReleaseMutex(); return; } DTB.NodeTree tree = new DTB.NodeTree(); foreach (FormatData formatdata in data.Songs) { SongsDTA dta = HarmonixMetadata.GetSongsDTA(formatdata.Song); tree.Nodes.Add(dta.ToDTB(PlatformRawkFile.Instance.IsRawkSD2(formatdata.Song))); } FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None); tree.Save(new EndianReader(file, Endianness.LittleEndian)); file.Close(); data.Mutex.ReleaseMutex(); }
public static SongsDTA GetSongsDTA(SongData song) { DataArray tree = song.Data.GetSubtree("HmxSongsDtb"); if (tree != null) { return(SongsDTA.Create(tree.GetSubtree())); } return(null); }
private void ScrollSpeedNumeric_ValueChanged(object sender, EventArgs e) { if (Song == null) { return; } SongsDTA dta = GetOrCreateDTA(); dta.SongScrollSpeed = (int)ScrollSpeedNumeric.Value; SaveDTA(dta); }
private static bool GetSongBin(SongData song, out string title, out ushort index) { title = null; index = 0; SongsDTA dta = HarmonixMetadata.GetSongsDTA(song); if (dta == null) { return(false); } title = dta.Song.Name.Substring(4, 4); return(ushort.TryParse(dta.Song.Name.Substring(9, 3), out index)); }
public static SongsDTA GetSongsDTA(SongData song, AudioFormat audioformat, bool idioticdrums = true) { SongsDTA dta = HarmonixMetadata.GetSongData(song); dta.Downloaded = true; if ((dta.Decade == null || dta.Decade.Length == 0) && dta.Year.ToString().Length > 2) { dta.Decade = "the" + dta.Year.ToString()[2] + "0s"; } dta.BaseName = "rwk" + dta.Version.ToString() + dta.BaseName; dta.Genre = ImportMap.GetShortGenre(dta.Genre); dta.Song.Cores.Clear(); dta.Song.Pans.Clear(); dta.Song.Vols.Clear(); foreach (SongsDTA.SongTracks track in dta.Song.Tracks) { track.Tracks.Clear(); } dta.Song.TracksCount.Clear(); var maps = audioformat.Mappings.Where(m => m.Instrument != Instrument.Preview).ToList(); foreach (AudioFormat.Mapping map in maps) { dta.Song.Cores.Add(map.Instrument == Instrument.Guitar ? 1 : -1); dta.Song.Pans.Add(map.Balance); dta.Song.Vols.Add(map.Volume); SongsDTA.SongTracks track = dta.Song.Tracks.FirstOrDefault(t => t.Name == HarmonixMetadata.InstrumentToString(map.Instrument)); if (track != null) { track.Tracks.Add(maps.IndexOf(map)); } } if (idioticdrums) { // For safety with customs messing with mix and not knowing what they're doing SongsDTA.SongTracks drumtrack = dta.Song.Tracks.FirstOrDefault(t => t.Name == "drum"); while (drumtrack != null && drumtrack.Tracks.Count > 0 && drumtrack.Tracks.Count < 6) { drumtrack.Tracks.Add(drumtrack.Tracks[drumtrack.Tracks.Count - 1]); } } return(dta); }
public override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress) { if (IterateBins) { return(PlatformRB2WiiDisc.Instance.AddSong(data, song, progress)); } else { FormatData formatdata = new TemporaryFormatData(song, data); SongsDTA dta = HarmonixMetadata.GetSongsDTA(song); data.AddSong(formatdata); return(true); } }
private void AddSongFromDTB(string path, PlatformData data, DTB.NodeTree dtb, ProgressIndicator progress) { SongData song = HarmonixMetadata.GetSongData(data, dtb); SongsDTA dta = HarmonixMetadata.GetSongsDTA(song); if (song.ID.StartsWith("rwk")) { song.ID = dta.Song.Name.Split('/').Last(); } string title = dta.Song.Name.Substring(4, 4); int index = int.Parse(dta.Song.Name.Substring(9, 3)); string indexpath = Util.Pad((index + 1).ToString(), 3); string contentpath = Path.Combine(path, "private/wii/data/" + title + "/" + indexpath + ".bin"); string dtapath = Path.Combine(path, "private/wii/data/" + title + "/" + Util.Pad(index.ToString(), 3) + ".bin"); AddSongFromBins(data, song, dtapath, contentpath, progress); }
public static void SaveAudioFormat(AudioFormat data, FormatData destination, int id) { SongsDTA dta = new SongsDTA(); for (int i = 0; i < data.Channels; i++) { AudioFormat.Mapping map = data.Mappings[i]; dta.Song.Vols.Add(map.Volume); dta.Song.Pans.Add(map.Balance); dta.Song.Cores.Add(map.Instrument == Instrument.Guitar ? 1 : -1); string trackname = InstrumentToString(map.Instrument); SongsDTA.SongTracks track = dta.Song.Tracks.SingleOrDefault(t => t.Name == trackname); if (track != null) { track.Tracks.Add(i); } } destination.Song.Data.SetSubtree("HmxSongsDtb", dta.ToDTB()); }
public static SongData GetSongData(PlatformData platformdata, DTB.NodeTree dtb) { SongData data = new SongData(platformdata); data.Data.SetSubtree("HmxSongsDtb", dtb); SongsDTA dta = SongsDTA.Create(dtb); data.Album = dta.Album; if (dta.Track.HasValue) { data.AlbumTrack = dta.Track.Value; } data.Artist = dta.Artist; data.ID = dta.BaseName; for (Instrument instrument = Instrument.Ambient; instrument <= Instrument.Vocals; instrument++) { SongsDTA.Rankings rank = dta.Rank.SingleOrDefault(r => r.Name == InstrumentToString(instrument)); if (rank != null) { data.Difficulty[instrument] = rank.Rank; } } data.Genre = dta.Genre; data.Master = dta.Master; data.Name = dta.Name; data.Pack = dta.Pack; data.Vocalist = dta.Vocalist; data.Year = dta.Year; data.Version = dta.Version; data.PreviewTimes = dta.Preview; if (dta.Song.HopoThreshold.HasValue) { data.HopoThreshold = dta.Song.HopoThreshold.Value; } return(data); }
public override void DeleteSong(PlatformData data, FormatData formatdata, ProgressIndicator progress) { string path = data.Session["maindirpath"] as string; string dtapath = "rawk/rb2/customs/" + formatdata.Song.ID; FileStream dtafile = new FileStream(Path.Combine(path, dtapath + "/data"), FileMode.Open, FileAccess.Read, FileShare.Read); EndianReader reader = new EndianReader(dtafile, Endianness.LittleEndian); DTB.NodeTree dtb = DTB.Create(reader); dtafile.Close(); SongsDTA dta = SongsDTA.Create(dtb); string title = dta.Song.Name.Substring(4, 4); int index = int.Parse(dta.Song.Name.Substring(9, 3)); Util.Delete(Path.Combine(path, "private/wii/data/" + title + "/" + Util.Pad((index).ToString(), 3) + ".bin")); Util.Delete(Path.Combine(path, "private/wii/data/" + title + "/" + Util.Pad((index + 1).ToString(), 3) + ".bin")); Directory.Delete(Path.Combine(path, dtapath), true); base.DeleteSong(data, formatdata, progress); SaveDTBCache(data); }
private void EditForm_Load(object sender, EventArgs e) { SongData song = Data.Song; if (!Writable) { IdText.ReadOnly = true; NameText.ReadOnly = true; ArtistText.ReadOnly = true; AlbumText.ReadOnly = true; TrackNumeric.Enabled = false; YearNumeric.Enabled = false; GenreCombo.Enabled = false; VocalistCombo.Enabled = false; MasterCheckbox.Enabled = false; HopoNumeric.Enabled = false; CharterText.Enabled = false; PackText.ReadOnly = true; VersionNumeric.Enabled = false; PreviewStartNumeric.Enabled = false; PreviewEndNumeric.Enabled = false; AnimationTempoCombo.Enabled = false; ScrollSpeedNumeric.Enabled = false; BankCombo.Enabled = false; BandTierNumeric.Enabled = false; GuitarTierNumeric.Enabled = false; DrumsTierNumeric.Enabled = false; VocalsTierNumeric.Enabled = false; BassTierNumeric.Enabled = false; ReplaceChartButton.Enabled = false; ReplaceAudioButton.Enabled = false; } // Song Info IdText.Text = song.ID; NameText.Text = song.Name; ArtistText.Text = song.Artist; AlbumText.Text = song.Album; TrackNumeric.Value = song.AlbumTrack; YearNumeric.Value = song.Year; GenreCombo.Text = song.TidyGenre; VocalistCombo.Text = song.Vocalist; MasterCheckbox.Checked = song.Master; Bitmap albumart = song.AlbumArt; if (albumart != null) { AlbumArt.Image = albumart; } else { AlbumArt.Image = Program.Form.AlbumImage; } // Engine Data HopoNumeric.Value = song.HopoThreshold; CharterText.Text = song.Charter; PackText.Text = song.Pack; VersionNumeric.Value = song.Version; PreviewStartNumeric.Value = song.PreviewTimes[0]; PreviewEndNumeric.Value = song.PreviewTimes[1]; // RB2 Data SongsDTA dta = HarmonixMetadata.GetSongsDTA(song); if (dta != null) { ScrollSpeedNumeric.Value = dta.SongScrollSpeed; switch (dta.AnimTempo) { case 0x10: AnimationTempoCombo.SelectedIndex = 0; break; case 0x20: AnimationTempoCombo.SelectedIndex = 1; break; case 0x40: AnimationTempoCombo.SelectedIndex = 2; break; default: throw new FormatException(); } switch (dta.Bank) { case "sfx/tambourine_bank.milo": BankCombo.SelectedIndex = 0; break; case "sfx/cowbell_bank.milo": BankCombo.SelectedIndex = 1; break; case "sfx/triangle_bank.milo": BankCombo.SelectedIndex = 2; break; case "sfx/handclap_bank.milo": BankCombo.SelectedIndex = 3; break; default: throw new FormatException(); } } BandTierNumeric.Value = song.Difficulty[Instrument.Ambient]; GuitarTierNumeric.Value = song.Difficulty[Instrument.Guitar]; DrumsTierNumeric.Value = song.Difficulty[Instrument.Drums]; VocalsTierNumeric.Value = song.Difficulty[Instrument.Vocals]; BassTierNumeric.Value = song.Difficulty[Instrument.Bass]; UpdateChartSizes(); UpdateAudioSizes(); Song = song; }
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 bool AddSong(PlatformData data, SongData song, ProgressIndicator progress) { FormatData formatdata = new TemporaryFormatData(song, data); DirectoryNode songdir = data.Session["songdir"] as DirectoryNode; SongsDTA dta = HarmonixMetadata.GetSongsDTA(song); if (dta == null) // LRB's <addsong /> { dta = HarmonixMetadata.GetSongData(song); dta.Song.Cores = new List <int>() { -1, -1, -1, -1, -1, 1, 1, -1, -1 }; dta.Song.Vols = new List <float>() { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; dta.Song.Pans = new List <float>() { 0, 0, -1, 1, 0, -1, 1, 0, 0 }; dta.Song.Tracks.Find(t => t.Name == "drum").Tracks.AddRange(new int[] { 0, 1, 2, 3 }); dta.Song.Tracks.Find(t => t.Name == "bass").Tracks.AddRange(new int[] { 4 }); dta.Song.Tracks.Find(t => t.Name == "guitar").Tracks.AddRange(new int[] { 5, 6 }); dta.Song.Tracks.Find(t => t.Name == "vocals").Tracks.AddRange(new int[] { 7 }); dta.Song.Name = "songs/" + song.ID + "/" + song.ID; HarmonixMetadata.SetSongsDTA(song, dta.ToDTB()); } string dtaname = dta.Song.Name; if (dtaname.StartsWith("dlc")) { dtaname = dtaname.Split(new char[] { '/' }, 4)[3]; } int lastslash = dtaname.LastIndexOf('/'); string basename = dtaname.Substring(lastslash + 1); dtaname = dtaname.Substring(0, lastslash); DirectoryNode songnode = songdir.Navigate(dtaname) as DirectoryNode; if (songnode == null) { return(false); } FileNode songaudiofile = songnode.Navigate(basename + ".bik", false, true) as FileNode; AudioFormat audio = null; if (songaudiofile == null) { songaudiofile = songnode.Navigate(basename + ".mogg", false, true) as FileNode; if (songaudiofile == null) { return(false); } if (HarmonixMetadata.IsRockBand1(data.Game)) { audio = HarmonixMetadata.GetAudioFormat(song); audio.InitialOffset = 3000; } AudioFormatMogg.Instance.Create(formatdata, songaudiofile.Data, audio); } else { AudioFormatRB2Bink.Instance.Create(formatdata, songaudiofile.Data, null); } // TODO: SongInfo // TODO: Preview FileNode chartfile = songnode.Find(basename + ".mid") as FileNode; FileNode panfile = songnode.Find(basename + ".pan") as FileNode; FileNode weightsfile = songnode.Navigate("gen/" + basename + "_weights.bin") as FileNode; FileNode milofile = songnode.Navigate("gen/" + basename + ".milo_wii") as FileNode; FileNode albumfile = songnode.Navigate("gen/" + basename + "_keep.png_wii") as FileNode; if (chartfile == null) { return(false); } if (albumfile == null) { albumfile = songnode.Navigate("gen/" + basename + "_nomip_keep.bmp_wii") as FileNode; } if (albumfile != null) { song.AlbumArt = WiiImage.Create(new EndianReader(albumfile.Data, Endianness.LittleEndian)).Bitmap; albumfile.Data.Close(); } ChartFormatRB.Instance.Create(formatdata, chartfile == null ? null : chartfile.Data, panfile == null ? null : panfile.Data, weightsfile == null ? null : weightsfile.Data, milofile == null ? null : milofile.Data, false, false, data.Game); data.AddSong(formatdata); return(true); }
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 override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode maindir = DirectoryNode.FromPath(path, data.Cache, FileAccess.Read); char[] regions = new char[] { 'E', 'P' }; DirectoryNode dir = maindir.Navigate("private/wii/data", false, true) as DirectoryNode; if (dir == null) dir = maindir; for (char letter = 'A'; letter <= 'Z'; letter++) { foreach (char region in regions) { DirectoryNode subdir = dir.Find("SZ" + letter + region, true) as DirectoryNode; if (subdir == null) continue; foreach (FileNode file in subdir.Files) { if (String.Compare(Path.GetExtension(file.Name), ".bin", true) != 0) continue; try { file.Data.Position = 0; DlcBin bin = new DlcBin(file.Data); U8 u8; try { u8 = new U8(bin.Data); } catch (FormatException) { file.Data.Close(); continue; } FileNode songsdta = u8.Root.Find("songs.dta", SearchOption.AllDirectories) as FileNode; if (songsdta == null) { file.Data.Close(); continue; } DTB.NodeTree dtb = DTA.Create(songsdta.Data); SongsDTA dta = SongsDTA.Create(dtb); file.Data.Close(); SongData song = HarmonixMetadata.GetSongData(data, dtb); string contentbin = dta.Song.Name.Substring(9, 3); // Example, "dlc/sZAE/023/content/songs/simpleman/simpleman" FileNode contentfile = subdir.Find(contentbin + ".bin", true) as FileNode; if (contentfile == null) continue; FormatData formatdata = new TemporaryFormatData(song, data); Create(formatdata, file.Data, contentfile.Data); data.AddSong(formatdata); contentfile.Data.Close(); } catch (FormatException) { } // Not a DLC bin we care about } } } return data; }
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); }
internal static void Export360(string path, FormatData original) { Program.Form.Progress.QueueTask(progress => { progress.NewTask("Exporting to 360 DLC file", 16); SongData song = original.Song; StfsArchive stfs = new StfsArchive(); stfs.Stfs.ContentType = StfsFile.ContentTypes.Marketplace; stfs.Stfs.TitleID = 0x45410829; for (int i = 0; i < stfs.Stfs.DisplayName.Length; i++) { stfs.Stfs.DisplayName[i] = song.Artist + " - " + song.Name; } for (int i = 0; i < stfs.Stfs.DisplayDescription.Length; i++) { stfs.Stfs.DisplayDescription[i] = "RawkSD DLC - http://rawksd.japaneatahand.com"; } stfs.Stfs.TitleName = "Rawk Band 2"; stfs.Stfs.Publisher = "RawkSD"; stfs.Stfs.TitleThumbnail = WiiImage.Create(new EndianReader(new MemoryStream(ConsoleHaxx.RawkSD.Properties.Resources.rawksd_albumart), Endianness.LittleEndian)).Bitmap; if (song.AlbumArt != null) { stfs.Stfs.Thumbnail = song.AlbumArt; } else { stfs.Stfs.Thumbnail = stfs.Stfs.TitleThumbnail; } StfsFile.SignedHeader header = new StfsFile.SignedHeader(StfsFile.FileTypes.LIVE); stfs.Stfs.Header = header; header.Licenses[0].ID = 0xFFFFFFFFFFFFFFFF; stfs.Stfs.MetadataVersion = 2; StfsFile.PackageDescriptor desc = new StfsFile.PackageDescriptor(); stfs.Stfs.Descriptor = desc; desc.StructSize = 0x24; desc.BlockSeparation = 1; desc.FileTableBlockCount = 0x100; // byte apparently stfs.Stfs.TransferFlags = 0xC0; FormatData data = original; Program.Form.TaskMutex.WaitOne(); bool local = data.PlatformData.Platform == PlatformLocalStorage.Instance; bool ownformat = false; if (!local && Configuration.MaxConcurrentTasks > 1) { data = new TemporaryFormatData(data.Song, data.PlatformData); original.SaveTo(data); ownformat = true; } Program.Form.TaskMutex.ReleaseMutex(); Stream songs = null; Stream audio = null; Stream chart = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.ChartFile); Stream pan = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.PanFile); Stream weights = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.WeightsFile); Stream milo = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.MiloFile); milo = new MemoryStream(Properties.Resources.rbn_milo); // TODO: properly convert milo if (milo == null) { milo = new MemoryStream(ConsoleHaxx.RawkSD.Properties.Resources.rawksd_milo); } using (DelayedStreamCache cache = new DelayedStreamCache()) { AudioFormat audioformat = (data.GetFormat(FormatType.Audio) as IAudioFormat).DecodeAudio(data, progress); ushort[] masks = PlatformRB2WiiCustomDLC.RemixAudioTracks(data.Song, audioformat); progress.Progress(); // RBN Required DTA settings SongsDTA dta = PlatformRB2WiiCustomDLC.GetSongsDTA(song, audioformat, false); dta.AlbumArt = false; dta.Song.Name = "songs/" + song.ID + "/" + song.ID; dta.Song.MidiFile = "songs/" + song.ID + "/" + song.ID + ".mid"; dta.Rating = 4; dta.SubGenre = "subgenre_core"; dta.Format = 4; //dta.SongID = 0; dta.Origin = "rb2"; //dta.Ugc = 1; //dta.SongLength = 300000; dta.Context = 2000; dta.BasePoints = 0; if (!dta.TuningOffsetCents.HasValue) { dta.TuningOffsetCents = 0; } audio = new TemporaryStream(); cache.AddStream(audio); progress.Progress(); progress.SetNextWeight(10); long samples = audioformat.Decoder.Samples; CryptedMoggStream mogg = new CryptedMoggStream(audio); mogg.WriteHeader(); RawkAudio.Encoder encoder = new RawkAudio.Encoder(mogg, audioformat.Mappings.Count, audioformat.Decoder.SampleRate); 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, audioformat.Decoder.AudioBuffer.Rank2)); if (read <= 0) { break; } audioformat.Decoder.AudioBuffer.DownmixTo(buffer, masks, read); encoder.Write(buffer, read); samples -= read; progress.Progress(read); } progress.EndTask(); progress.Progress(10); encoder.Dispose(); audioformat.Decoder.Dispose(); audio.Position = 0; dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Drums)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Bass)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Guitar)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Vocals)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Ambient)); for (int i = 0; i < dta.Song.Cores.Count; i++) { dta.Song.Cores[i] = -1; } songs = new TemporaryStream(); cache.AddStream(songs); dta.ToDTB().SaveDTA(songs); ChartFormat chartformat = (data.GetFormat(FormatType.Chart) as IChartFormat).DecodeChart(data, progress); if (chart != null && ChartFormatRB.Instance.NeedsFixing(data)) { data.CloseStream(chart); chart = null; } if (chart == null) { chart = new TemporaryStream(); cache.AddStream(chart); PlatformRB2WiiCustomDLC.AdjustChart(song, audioformat, chartformat).ToMidi().ToMid().Save(chart); chart.Position = 0; } if (weights == null) { weights = new TemporaryStream(); cache.AddStream(weights); PlatformRB2WiiCustomDLC.CreateWeights(weights, chartformat); weights.Position = 0; } if (pan == null) { pan = new TemporaryStream(); cache.AddStream(pan); PlatformRB2WiiCustomDLC.CreatePan(pan, chartformat); pan.Position = 0; } progress.Progress(3); DirectoryNode dir = new DirectoryNode("songs"); stfs.Root.AddChild(dir); dir.AddChild(new FileNode("songs.dta", songs)); DirectoryNode songdir = new DirectoryNode(song.ID); dir.AddChild(songdir); songdir.AddChild(new FileNode(song.ID + ".mogg", audio)); songdir.AddChild(new FileNode(song.ID + ".mid", chart)); DirectoryNode gendir = new DirectoryNode("gen"); songdir.AddChild(gendir); gendir.AddChild(new FileNode(song.ID + ".milo_xbox", milo)); gendir.AddChild(new FileNode(song.ID + "_weights.bin", weights)); Stream ostream = new FileStream(path, FileMode.Create); stfs.Save(ostream); ostream.Close(); data.CloseStream(audio); data.CloseStream(chart); data.CloseStream(pan); data.CloseStream(weights); data.CloseStream(milo); if (ownformat) { data.Dispose(); } progress.Progress(); progress.EndTask(); } }); }
private void SaveDTA(SongsDTA dta) { HarmonixMetadata.SetSongsDTA(Song, dta.ToDTB()); }
private SongsDTA GetOrCreateDTA() { SongsDTA dta = HarmonixMetadata.GetSongsDTA(Song); return(dta ?? new SongsDTA()); }
public override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress) { DirectoryNode songdir = data.Session["songdir"] as DirectoryNode; SongsDTA dta = HarmonixMetadata.GetSongsDTA(song); if (dta == null) // GH1's <addsong /> { dta = HarmonixMetadata.GetSongData(song); dta.Song.Cores = new List <int>() { -1, -1, 1, 1 }; dta.Song.Vols = new List <float>() { 0, 0, 0, 0 }; dta.Song.Pans = new List <float>() { -1, 1, -1, 1 }; dta.Song.Tracks.Find(t => t.Name == "guitar").Tracks.AddRange(new int[] { 2, 3 }); HarmonixMetadata.SetSongsDTA(song, dta.ToDTB()); } dta.Bank = "sfx/tambourine_bank.milo"; DirectoryNode songnode = songdir.Navigate(song.ID) as DirectoryNode; FileNode chartfile = songnode.Find(song.ID + ".mid") as FileNode; if (chartfile == null) { return(false); } for (int coop = 0; coop < 2; coop++) { if (coop == 1) { song = new SongData(song); song.ID += "_coop"; song.Name += " [coop]"; if (dta.SongCoop != null) { dta.Song = dta.SongCoop; dta.SongCoop = null; } else { return(false); } } HarmonixMetadata.SetSongsDTA(song, dta.ToDTB()); FormatData formatdata = new TemporaryFormatData(song, data); FileNode songaudiofile = songnode.Find(song.ID + ".vgs") as FileNode; if (songaudiofile == null) { songaudiofile = songnode.Find(song.ID + "_sp.vgs") as FileNode; } if (songaudiofile == null) { return(false); } if (data.Game == Game.GuitarHero1) { ChartFormatGH1.Instance.Create(formatdata, chartfile == null ? null : chartfile.Data); } else { ChartFormatGH2.Instance.Create(formatdata, chartfile == null ? null : chartfile.Data, coop == 1); } AudioFormatVGS.Instance.Create(formatdata, songaudiofile.Data, null); data.AddSong(formatdata); } return(true); }
public static void ExportRBN(string path, FormatData original) { Program.Form.Progress.QueueTask(progress => { progress.NewTask("Exporting to RBA file", 16); RBA rba = new RBA(); FormatData data = original; Program.Form.TaskMutex.WaitOne(); bool local = data.PlatformData.Platform == PlatformLocalStorage.Instance; bool ownformat = false; if (!local && Configuration.MaxConcurrentTasks > 1) { data = new TemporaryFormatData(data.Song, data.PlatformData); original.SaveTo(data); ownformat = true; } Program.Form.TaskMutex.ReleaseMutex(); using (DelayedStreamCache cache = new DelayedStreamCache()) { AudioFormat audioformat = (data.GetFormat(FormatType.Audio) as IAudioFormat).DecodeAudio(data, progress); ushort[] masks = PlatformRB2WiiCustomDLC.RemixAudioTracks(data.Song, audioformat); progress.Progress(); // RBN Required DTA settings SongsDTA dta = PlatformRB2WiiCustomDLC.GetSongsDTA(data.Song, audioformat, false); dta.AlbumArt = true; dta.BaseName = "song"; dta.Song.Name = "songs/" + dta.BaseName + "/" + dta.BaseName; dta.Song.MidiFile = "songs/" + dta.BaseName + "/" + dta.BaseName + ".mid"; dta.Rating = 4; dta.Genre = "rock"; dta.SubGenre = "subgenre_rock"; dta.Format = 4; dta.SongID = 0; dta.Origin = "rb2"; dta.Ugc = 1; dta.SongLength = 300000; dta.Preview[0] = 0; dta.Preview[1] = 30000; dta.Context = 2000; dta.BasePoints = 0; if (!dta.TuningOffsetCents.HasValue) { dta.TuningOffsetCents = 0; } rba.Audio = new TemporaryStream(); cache.AddStream(rba.Audio); progress.Progress(); progress.SetNextWeight(10); long samples = audioformat.Decoder.Samples; CryptedMoggStream mogg = new CryptedMoggStream(rba.Audio); mogg.WriteHeader(); RawkAudio.Encoder encoder = new RawkAudio.Encoder(mogg, audioformat.Mappings.Count, audioformat.Decoder.SampleRate); 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, audioformat.Decoder.AudioBuffer.Rank2)); if (read <= 0) { break; } audioformat.Decoder.AudioBuffer.DownmixTo(buffer, masks, read); encoder.Write(buffer, read); samples -= read; progress.Progress(read); } progress.EndTask(); progress.Progress(10); encoder.Dispose(); audioformat.Decoder.Dispose(); rba.Audio.Position = 0; dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Drums)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Bass)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Guitar)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Vocals)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Ambient)); for (int i = 0; i < dta.Song.Cores.Count; i++) { dta.Song.Cores[i] = -1; } rba.Data = new TemporaryStream(); cache.AddStream(rba.Data); dta.Save(rba.Data); Stream stream = new MemoryStream(Properties.Resources.rbn_metadata); rba.Metadata = stream; stream = new MemoryStream(Properties.Resources.rbn_album); rba.AlbumArt = stream; stream = new MemoryStream(Properties.Resources.rbn_milo); rba.Milo = stream; stream = new MemoryStream(Properties.Resources.rbn_weights); rba.Weights = stream; if (data.Formats.Contains(ChartFormatRB.Instance) && !ChartFormatRB.Instance.NeedsFixing(data)) { rba.Chart = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.ChartFile); } else { IChartFormat chartformat = data.GetFormat(FormatType.Chart) as IChartFormat; NoteChart chart = PlatformRB2WiiCustomDLC.AdjustChart(data.Song, audioformat, chartformat.DecodeChart(data, progress)); rba.Chart = new TemporaryStream(); cache.AddStream(rba.Chart); chart.ToMidi().ToMid().Save(rba.Chart); } progress.Progress(3); rba.Strings.Add(((char)0x02).ToString()); rba.Strings.Add(((char)0x22).ToString()); rba.Strings.Add((char)0x02 + "090923"); rba.Strings.Add("090923"); rba.Strings.Add(string.Empty); rba.Strings.Add(string.Empty); rba.Strings.Add((char)0x02 + "090923"); rba.Strings.Add("s/rawk/a"); Stream ostream = new FileStream(path, FileMode.Create); rba.Save(ostream); ostream.Close(); data.CloseStream(rba.Chart); if (ownformat) { data.Dispose(); } progress.Progress(); progress.EndTask(); } }); }