Ejemplo n.º 1
0
        private void _CalcMedley()
        {
            if (IsDuet)
            {
                Medley.Source = EDataSource.None;
                return;
            }

            if (!_CalculateMedley || Medley.Source != EDataSource.None)
            {
                return;
            }

            List <SSeries> series = _GetSeries();

            if (series == null)
            {
                return;
            }

            // search for longest series
            int longest = 0;

            for (int i = 0; i < series.Count; i++)
            {
                if (series[i].Length > series[longest].Length)
                {
                    longest = i;
                }
            }

            CVoice voice = Notes.GetVoice(0);

            // set medley vars
            if (series.Count > 0 && series[longest].Length > CBase.Settings.GetMedleyMinSeriesLength())
            {
                Medley.StartBeat = voice.Lines[series[longest].Start].FirstNoteBeat;
                Medley.EndBeat   = voice.Lines[series[longest].End].LastNoteBeat;

                bool foundEnd = CBase.Game.GetTimeFromBeats(Medley.EndBeat, BPM) - CBase.Game.GetTimeFromBeats(Medley.StartBeat, BPM) < CBase.Settings.GetMedleyMinDuration();

                // set end if duration < MedleyMinDuration

                if (!foundEnd)
                {
                    for (int i = series[longest].End + 1; i < voice.NumLines - 1; i++)
                    {
                        if (CBase.Game.GetTimeFromBeats(voice.Lines[i].LastNoteBeat, BPM) - CBase.Game.GetTimeFromBeats(Medley.StartBeat, BPM) <
                            CBase.Settings.GetMedleyMinDuration())
                        {
                            foundEnd       = true;
                            Medley.EndBeat = voice.Lines[i].LastNoteBeat;
                            break;
                        }
                    }
                }

                if (foundEnd)
                {
                    Medley.Source      = EDataSource.Calculated;
                    Medley.FadeInTime  = CBase.Settings.GetDefaultMedleyFadeInTime();
                    Medley.FadeOutTime = CBase.Settings.GetDefaultMedleyFadeOutTime();
                }
            }
        }
Ejemplo n.º 2
0
            private bool _AddNote(int player, CSongNote note)
            {
                CVoice voice = _Song.Notes.GetVoice(player, true);

                return(voice.AddNote(note, false));
            }
Ejemplo n.º 3
0
            private bool _NewSentence(int player, int start)
            {
                CVoice voice = _Song.Notes.GetVoice(player, true);

                return(voice.AddLine(start));
            }
Ejemplo n.º 4
0
            /// <summary>
            ///     Read notes. First try to read notes normally (assume standard)<br />
            ///     If there are more than _MaxZeroNoteCt with length &lt; 1,  try to read notes adding 1 to length<br />
            ///     Then if there are more than _MaxOverlapNoteCt fallback to first version ignoring notes with length &lt; 1
            /// </summary>
            /// <param name="forceReload"></param>
            /// <returns></returns>
            public bool ReadNotes(bool forceReload = false)
            {
                //Skip loading if already done and no reload is forced
                if (_Song.NotesLoaded && !forceReload)
                {
                    return(true);
                }

                string filePath = Path.Combine(_Song.Folder, _Song.FileName);

                if (!File.Exists(filePath))
                {
                    CLog.CSongLog.Error("[{SongFileName}] The file songfile does not exist", CLog.Params(_Song.FileName));
                    return(false);
                }

                int       currentBeat = 0;     //Used for relative songs
                CSongNote lastNote    = null;  //Holds last parsed note. Get's reset on player change
                bool      endFound    = false; // True if end tag was found

                int player = 1;

                _LineNr = 0;

                char[] trimChars  = { ' ', ':' };
                char[] splitChars = { ' ' };

                var changesMade = new CAutoChanges();

                StreamReader sr = null;

                try
                {
                    sr = new StreamReader(filePath, _Song.Encoding, true);

                    _Song.Notes.Reset();

                    //Search for Note Beginning
                    while (!sr.EndOfStream && !endFound)
                    {
                        string line = sr.ReadLine();
                        _LineNr++;

                        if (String.IsNullOrEmpty(line))
                        {
                            continue;
                        }

                        char tag = line[0];
                        //Remove tag and potential space
                        line = (line.Length >= 2 && line[1] == ' ') ? line.Substring(2) : line.Substring(1);

                        int beat, length;
                        switch (tag)
                        {
                        case '#':
                            continue;

                        case 'E':
                            endFound = true;
                            break;

                        case 'P':
                            line = line.Trim(trimChars);

                            if (!int.TryParse(line, out player))
                            {
                                CLog.CSongLog.Error("[{SongFileName}] Wrong or missing number after \"P\" (in line {LineNr})", CLog.Params(_Song.FileName, _LineNr));
                                return(false);
                            }
                            currentBeat = 0;
                            lastNote    = null;
                            break;

                        case ':':
                        case '*':
                        case 'F':
                            string[] noteData = line.Split(splitChars, 4);
                            if (noteData.Length < 4)
                            {
                                if (noteData.Length == 3)
                                {
                                    CLog.CSongLog.Warning("[{SongFileName}] Ignored note without text (in line {LineNr})", CLog.Params(_Song.FileName, _LineNr));
                                    changesMade.NoTextNoteCt++;
                                    continue;
                                }
                                CLog.CSongLog.Error("[{SongFileName}] Invalid note found (in line {LineNr}): {noteData}", CLog.Params(_Song.FileName, _LineNr, noteData));
                                sr.Dispose();
                                return(false);
                            }
                            int tone;
                            if (!int.TryParse(noteData[0], out beat) || !int.TryParse(noteData[1], out length) || !int.TryParse(noteData[2], out tone))
                            {
                                CLog.CSongLog.Error("[{SongFileName}] Invalid note found (non-numeric values) (in line {LineNr}): {noteData}", CLog.Params(_Song.FileName, _LineNr, noteData));
                                sr.Dispose();
                                return(false);
                            }
                            string text = noteData[3].TrimMultipleWs();
                            if (text == "")
                            {
                                CLog.CSongLog.Warning("[{SongFileName}] Ignored note without text (in line {LineNr})", CLog.Params(_Song.FileName, _LineNr));
                                changesMade.NoTextNoteCt++;
                                continue;
                            }
                            if (_CurrentReadMode == ENoteReadMode.ZeroBased)
                            {
                                length++;
                            }
                            if (length < 1)
                            {
                                changesMade.ZeroLengthNoteCt++;
                                if (_CurrentReadMode == ENoteReadMode.Normal && changesMade.ZeroLengthNoteCt > _MaxZeroNoteCt && changesMade.OverlapNoteCt <= _MaxOverlapNoteCt)
                                {
                                    CLog.CSongLog.Warning("[{SongFileName}] Found more than {MaxZeroNoteCt} notes with length < 1. Trying alternative read mode.", CLog.Params(_Song.FileName, _MaxZeroNoteCt));
                                    _CurrentReadMode = ENoteReadMode.ZeroBased;
                                    sr.Dispose();
                                    return(ReadNotes(true));
                                }
                                CLog.CSongLog.Warning("[{SongFileName}] Ignored note with length < 1 (in line {LineNr})", CLog.Params(_Song.FileName, _LineNr));
                            }
                            else
                            {
                                ENoteType noteType;

                                if (tag.Equals('*'))
                                {
                                    noteType = ENoteType.Golden;
                                }
                                else if (tag.Equals('F'))
                                {
                                    noteType = ENoteType.Freestyle;
                                }
                                else
                                {
                                    noteType = ENoteType.Normal;
                                }

                                if (_Song.Relative)
                                {
                                    beat += currentBeat;
                                }

                                bool ignored = false;
                                foreach (int curPlayer in player.GetSetBits())
                                {
                                    //Create the note here as we want independent instances in the lines. Otherwhise we can't modify them later
                                    lastNote = new CSongNote(beat, length, tone, text, noteType);
                                    if (!_AddNote(curPlayer, lastNote))
                                    {
                                        if (!ignored)
                                        {
                                            ignored = true;
                                            changesMade.OverlapNoteCt++;
                                            if (changesMade.OverlapNoteCt > _MaxOverlapNoteCt && _CurrentReadMode == ENoteReadMode.ZeroBased)
                                            {
                                                CLog.CSongLog.Warning("[{SongFileName}] Found more than {MaxOverlapNoteCt} overlapping notes. Using standard mode.", CLog.Params(_Song.FileName, _MaxOverlapNoteCt));
                                                _CurrentReadMode = ENoteReadMode.OneBased;
                                                sr.Dispose();
                                                return(ReadNotes(true));
                                            }
                                        }
                                        CLog.CSongLog.Warning("[{SongFileName}] Ignored note for player {CurrentPlayerNumber} because it overlaps with other note (in line {LineNr})", CLog.Params(_Song.FileName, (curPlayer + 1), _LineNr));
                                    }
                                }
                            }
                            break;

                        case '-':
                            string[] lineBreakData = line.Split(splitChars);
                            if (lineBreakData.Length < 1)
                            {
                                CLog.CSongLog.Error("[{SongFileName}] Invalid line break found (No beat) (in line {LineNr}): {LineBreakData}", CLog.Params(_Song.FileName, _LineNr, lineBreakData));
                                sr.Dispose();
                                return(false);
                            }
                            if (!int.TryParse(lineBreakData[0], out beat))
                            {
                                CLog.CSongLog.Error("[{SongFileName}] Invalid line break found (Non-numeric value) (in line {LineNr}): {LineBreakData}", CLog.Params(_Song.FileName, _LineNr, lineBreakData));
                                sr.Dispose();
                                return(false);
                            }

                            if (_Song.Relative)
                            {
                                beat += currentBeat;
                                if (lineBreakData.Length < 2 || !int.TryParse(lineBreakData[1], out length))
                                {
                                    CLog.CSongLog.Warning("[{SongFileName}] Missing line break length (in line {LineNr}):{LineBreakData}", CLog.Params(_Song.FileName, _LineNr, lineBreakData));
                                    changesMade.NoLengthBreakCt++;
                                    currentBeat = beat;
                                }
                                else
                                {
                                    currentBeat += length;
                                }
                            }

                            if (lastNote != null && beat <= lastNote.EndBeat)
                            {
                                CLog.CSongLog.Warning("[{SongFileName}] Line break is before previous note end. Adjusted. (in line {LineNr})", CLog.Params(_Song.FileName, _LineNr));

                                changesMade.AjustedBreakCt++;
                                if (_Song.Relative)
                                {
                                    currentBeat += lastNote.EndBeat - beat + 1;
                                }
                                beat = lastNote.EndBeat + 1;
                            }

                            if (beat < 1)
                            {
                                CLog.CSongLog.Warning("[{SongFileName}] Ignored line break because position is < 1 (in line {LineNr})", CLog.Params(_Song.FileName, _LineNr));
                                changesMade.InvalidPosBreakCt++;
                            }
                            else
                            {
                                foreach (int curPlayer in player.GetSetBits())
                                {
                                    if (!_NewSentence(curPlayer, beat))
                                    {
                                        CLog.CSongLog.Warning("[{SongFileName}] Ignored line break for player {CurPlayerNr} (Overlapping or duplicate) (in line {LineNr})", CLog.Params(_Song.FileName, (curPlayer + 1), _LineNr));
                                    }
                                }
                            }
                            break;

                        default:
                            CLog.CSongLog.Error("[{SongFileName}] Unexpected or missing character ({Tag})", CLog.Params(_Song.FileName, tag));
                            return(false);
                        }
                    }

                    for (int i = 0; i < _Song.Notes.VoiceCount; i++)
                    {
                        CVoice voice      = _Song.Notes.GetVoice(i);
                        int    emptyLines = voice.RemoveEmptyLines();
                        if (emptyLines > 0)
                        {
                            CLog.CSongLog.Warning("[{SongFileName}] Removed {NumEmptyLines} empty lines from P .This often indicates a problem with the line breaks in the file", CLog.Params(_Song.FileName, emptyLines));
                        }
                        voice.UpdateTimings();
                    }
                }
                catch (Exception e)
                {
                    CLog.CSongLog.Error(e, "[{SongFileName}] An unhandled exception occured: {ExceptionMessage}", CLog.Params(_Song.FileName, e.Message));
                    if (sr != null)
                    {
                        sr.Dispose();
                    }
                    return(false);
                }
                sr.Dispose();
                try
                {
                    _Song._CalcMedley();
                    _Song._CheckPreview();
                    _Song._FindShortEnd();
                    _Song.NotesLoaded = true;
                    if (_Song.IsDuet)
                    {
                        _Song._CheckDuet();
                    }
                }
                catch (Exception e)
                {
                    CLog.CSongLog.Error(e, "[{SongFileName}] An unhandled exception occured: {ExceptionMessage}", CLog.Params(_Song.FileName, e.Message));
                    return(false);
                }

                if (changesMade.IsModified)
                {
                    CLog.Warning("Automatic changes have been made to {FilePath} Please check result!\r\n{ChangesMade}", CLog.Params(filePath, changesMade));
                    if (CBase.Config.GetSaveModifiedSongs() == EOffOn.TR_CONFIG_ON)
                    {
                        string name = Path.GetFileNameWithoutExtension(_Song.FileName);
                        _Song.Save(Path.Combine(_Song.Folder, name + ".fix"));
                    }
                }
                return(true);
            }