Example #1
0
    private Voice CreateMergedVoice(Dictionary <string, Voice> voices)
    {
        if (voices.Count == 1)
        {
            return(voices.Values.First());
        }

        MutableVoice    mergedVoice  = new MutableVoice();
        List <Sentence> allSentences = voices.Values.SelectMany(voice => voice.Sentences).ToList();
        List <Note>     allNotes     = allSentences.SelectMany(sentence => sentence.Notes).ToList();

        // Sort notes by start beat
        allNotes.Sort((note1, note2) => note1.StartBeat.CompareTo(note2.StartBeat));
        // Find sentence borders
        List <int> lineBreaks = allSentences.Select(sentence => sentence.LinebreakBeat).Where(lineBreak => lineBreak > 0).ToList();

        lineBreaks.Sort();
        int lineBreakIndex    = 0;
        int nextLineBreakBeat = lineBreaks[lineBreakIndex];
        // Create sentences
        MutableSentence mutableSentence = new MutableSentence();

        foreach (Note note in allNotes)
        {
            if (!mutableSentence.GetNotes().IsNullOrEmpty() &&
                (nextLineBreakBeat >= 0 && note.StartBeat > nextLineBreakBeat))
            {
                // Finish the last sentence
                mutableSentence.SetLinebreakBeat(nextLineBreakBeat);
                mergedVoice.Add((Sentence)mutableSentence);
                mutableSentence = new MutableSentence();

                lineBreakIndex++;
                if (lineBreakIndex < lineBreaks.Count)
                {
                    nextLineBreakBeat = lineBreaks[lineBreakIndex];
                }
                else
                {
                    lineBreakIndex = -1;
                }
            }
            mutableSentence.Add(note);
        }

        // Finish the last sentence
        mergedVoice.Add((Sentence)mutableSentence);
        return((Voice)mergedVoice);
    }
Example #2
0
 public void TestInit()
 {
     mv = new MutableVoice();
 }
Example #3
0
    public static Dictionary <string, Voice> ParseFile(string path, Encoding enc, IEnumerable <string> voiceIdentifiers)
    {
        Dictionary <string, MutableVoice> res = new Dictionary <string, MutableVoice>();

        foreach (string voiceIdentifier in voiceIdentifiers)
        {
            res.Add(voiceIdentifier, new MutableVoice());
        }
        MutableVoice    currentVoice    = null;
        MutableSentence currentSentence = null;
        bool            endFound        = false;

        // if this is a solo song (without a named voice) then just add one with identifier "" (empty string)
        if (res.Count == 0)
        {
            res.Add("", new MutableVoice());
            currentVoice = res[""];
        }

        using (StreamReader reader = TxtReader.GetFileStreamReader(path, enc))
        {
            uint lineNumber = 0;
            while (!endFound && !reader.EndOfStream)
            {
                ++lineNumber;
                string line = reader.ReadLine();
                switch (line[0])
                {
                case '#':
                    // headers are ignored at this stage
                    break;

                case 'E':
                    // finish any current open sentence
                    if (currentVoice != null && currentSentence != null)
                    {
                        currentVoice.Add((Sentence)currentSentence);
                    }
                    // now we are done
                    endFound = true;
                    break;

                case 'P':
                    // save the current sentence, if any
                    if (currentVoice != null && currentSentence != null)
                    {
                        currentVoice.Add((Sentence)currentSentence);
                    }
                    // switch to the new voice
                    try
                    {
                        currentVoice    = res[line];
                        currentSentence = null;
                    }
                    catch (KeyNotFoundException)
                    {
                        ThrowLineError(lineNumber, "No such voice: " + line);
                    }
                    break;

                case '-':
                    if (currentVoice == null)
                    {
                        ThrowLineError(lineNumber, "Linebreak encountered but no voice is active");
                    }
                    else if (currentSentence == null)
                    {
                        ThrowLineError(lineNumber, "Linebreak encountered without preceding notes");
                    }
                    try
                    {
                        currentSentence.SetLinebreakBeat(ParseLinebreak(line.Substring(2)));
                        currentVoice.Add((Sentence)currentSentence);
                        currentSentence = null;
                    }
                    catch (VoicesBuilderException e)
                    {
                        ThrowLineError(lineNumber, e.Message);
                    }
                    break;

                case ':':
                case '*':
                case 'F':
                case 'R':
                case 'G':
                    if (currentVoice == null)
                    {
                        ThrowLineError(lineNumber, "Note encountered but no voice is active");
                    }
                    else if (currentSentence == null)
                    {
                        currentSentence = new MutableSentence();
                    }
                    try
                    {
                        currentSentence.Add(ParseNote(line));
                    }
                    catch (VoicesBuilderException e)
                    {
                        ThrowLineError(lineNumber, e.Message);
                    }
                    break;

                default:
                    ThrowLineError(lineNumber, "Invalid instruction: " + line);
                    break;
                }
            }
        }

        Dictionary <string, Voice> actualRes = new Dictionary <string, Voice>();

        foreach (var item in res)
        {
            actualRes.Add(item.Key, (Voice)item.Value);
        }
        return(actualRes);
    }