예제 #1
0
        public override PlatformData Create(string path, Game game, ProgressIndicator progress)
        {
            PlatformData data = new PlatformData(this, game);

            data.Session["path"] = path;

            if (Directory.Exists(path))
            {
                Exceptions.Error("An RBN archive must be a file.");
            }

            if (File.Exists(path))
            {
                try {
                    RBA rba = new RBA(new EndianReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), Endianness.LittleEndian));
                    data.Session["rba"] = rba;

                    SongData song = HarmonixMetadata.GetSongData(data, DTA.Create(rba.Data));

                    song.ID = ImportMap.GetShortName(song.Name);

                    AddSong(data, song, progress);
                } catch (Exception exception) {
                    Exceptions.Error(exception, "An error occurred while opening the RBN archive.");
                }
            }

            return(data);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        public override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress)
        {
            FormatData formatdata = new TemporaryFormatData(song, data);

            DirectoryNode dir = data.Session["songdir"] as DirectoryNode;

            int         delay      = 0;
            bool        eighthhopo = false;
            int         hopofreq   = -1;
            AudioFormat format     = new AudioFormat();
            FileNode    songini    = dir.Navigate("song.ini", false, true) as FileNode;

            if (songini != null)
            {
                Ini ini = Ini.Create(songini.Data);
                songini.Data.Close();
                string value = ini.GetValue("song", "name"); if (value != null)
                {
                    song.Name = value;
                }
                value = ini.GetValue("song", "artist"); if (value != null)
                {
                    song.Artist = value;
                }
                value = ini.GetValue("song", "album"); if (value != null)
                {
                    song.Album = value;
                }
                value = ini.GetValue("song", "genre"); if (value != null)
                {
                    song.Genre = value;
                }
                value = ini.GetValue("song", "year"); if (value != null)
                {
                    song.Year = int.Parse(value);
                }
                value = ini.GetValue("song", "version"); if (value != null)
                {
                    song.Version = int.Parse(value);
                }
                value = ini.GetValue("song", "delay"); if (value != null)
                {
                    delay = int.Parse(value);
                }
                value = ini.GetValue("song", "eighthnote_hopo"); if (value != null)
                {
                    eighthhopo = string.Compare(value, "true", true) == 0 ? true : false;
                }
                value = ini.GetValue("song", "hopofreq"); if (value != null)
                {
                    hopofreq = int.Parse(value);
                }
                value = ini.GetValue("song", "tags"); if (value != null)
                {
                    song.Master = string.Compare(value, "cover", true) == 0 ? false : true;
                }
                value = ini.GetValue("song", "icon"); if (value != null)
                {
                    song.Game = GetGameFromIcon(value);
                }
                value = ini.GetValue("song", "diff_band"); if (value != null)
                {
                    song.Difficulty[Instrument.Ambient] = ImportMap.GetBaseRank(Instrument.Ambient, int.Parse(value));
                }
                value = ini.GetValue("song", "diff_bass"); if (value != null)
                {
                    song.Difficulty[Instrument.Bass] = ImportMap.GetBaseRank(Instrument.Bass, int.Parse(value));
                }
                value = ini.GetValue("song", "diff_drums"); if (value != null)
                {
                    song.Difficulty[Instrument.Drums] = ImportMap.GetBaseRank(Instrument.Drums, int.Parse(value));
                }
                value = ini.GetValue("song", "diff_guitar"); if (value != null)
                {
                    song.Difficulty[Instrument.Guitar] = ImportMap.GetBaseRank(Instrument.Guitar, int.Parse(value));
                }
            }

            format.InitialOffset = -delay;

            FileNode album = dir.Navigate("album.png", false, true) as FileNode;

            if (album != null)
            {
                song.AlbumArt = new Bitmap(album.Data);
            }

            FileNode  chartfile = dir.Navigate("notes.mid", false, true) as FileNode;
            NoteChart chart     = null;

            if (chartfile != null)
            {
                ChartFormatRB.Instance.Create(formatdata, chartfile.Data, null, 0, null, null, 0, false, true);
                chart = NoteChart.Create(Midi.Create(Mid.Create(chartfile.Data)));
                chartfile.Data.Close();
            }

            if (chart != null && eighthhopo)
            {
                song.HopoThreshold = chart.Division.TicksPerBeat / 2 + 10;
            }
            else if (hopofreq >= 0)
            {
                // TODO: This
            }

            List <Stream> streams = new List <Stream>();

            foreach (Node node in dir)
            {
                FileNode file = node as FileNode;
                if (file == null)
                {
                    continue;
                }
                string extension = Path.GetExtension(file.Name).ToLower();
                if (extension != ".ogg")
                {
                    continue;
                }

                string            name       = Path.GetFileNameWithoutExtension(file.Name);
                Instrument        instrument = Platform.InstrumentFromString(name);
                RawkAudio.Decoder decoder    = new RawkAudio.Decoder(file.Data, RawkAudio.Decoder.AudioFormat.VorbisOgg);
                for (int i = 0; i < decoder.Channels; i++)
                {
                    format.Mappings.Add(new AudioFormat.Mapping(0, 0, instrument));
                }
                decoder.Dispose();
                file.Data.Close();

                streams.Add(file.Data);
            }
            format.AutoBalance();

            if (streams.Count > 0)
            {
                AudioFormatOgg.Instance.Create(formatdata, streams.ToArray(), format);
            }
            else if (chartfile == null)
            {
                return(false);
            }

            data.AddSong(formatdata);

            return(true);
        }
예제 #6
0
        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();
        }
예제 #7
0
        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));
        }
예제 #8
0
        public static bool ImportChart(SongData song, NoteChart chart)
        {
            ImportMap import = new ImportMap(song.Game);

            return(import.PopulateChart(song, chart));
        }
예제 #9
0
        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));
        }