Exemplo n.º 1
0
            public bool Equals(VCCV_English_Syllable obj)
            {
                if (obj == null)
                {
                    return(false);
                }

                return(obj.Onset.SequenceEqual(this.Onset) &&
                       obj.Nucleus.SequenceEqual(this.Nucleus) &&
                       obj.Coda.SequenceEqual(this.Coda));
            }
Exemplo n.º 2
0
            /// <summary>
            /// takes a lyric and splits it into its onset/nucleus/coda parts
            /// returns a VCCV_English_Syllable of [null, null, null] if not recognized
            /// </summary>
            /// <param name="lyric"></param>
            /// <returns></returns>
            public static VCCV_English_Syllable SplitSyllable(string lyric)
            {
                var matches = Syllable_RE.Match(lyric).Groups;
                var result  = new VCCV_English_Syllable();

                if (matches.Count < 3)
                {
                    // not recognized
                    result.Onset   = null;
                    result.Nucleus = null;
                    result.Coda    = null;
                    return(new VCCV_English_Syllable((string)null, null, null));
                }

                result.Onset.Add(matches[1].Value);
                result.Nucleus.Add(matches[2].Value);
                result.Coda.Add(matches[3].Value); //TODO: recognize multiple ending sounds

                // otherwise, return as expected
                return(result);
            }
Exemplo n.º 3
0
        /// <summary>
        /// Return the current note, split up as necessary to match the prev and next notes
        /// (Returns a new copy of all notes; the inputs are unchanged)
        ///
        /// </summary>
        /// <param name="prev"></param>
        /// <param name="curr"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public static List <UtauNote> GetConnectingNotes(UtauNote prev, UtauNote curr, UtauNote next)
        {
            VCCV_English_Syllable lyric_split     = VCCV_English_Syllable.SplitSyllable(curr.Lyric);
            VCCV_English_Syllable nextlyric_split = VCCV_English_Syllable.SplitSyllable(next.Lyric);

            List <UtauNote> toReturn = new List <UtauNote>();

            //if unrecognized, return the note untouched
            if (lyric_split.Onset[0] == null && lyric_split.Nucleus[0] == null)
            {
                return(new List <UtauNote> {
                    new UtauNote(curr)
                });
            }

            // add in the base note
            UtauNote CV = new UtauNote(curr);

            CV.Lyric = lyric_split.Onset[0] + lyric_split.Nucleus[0];
            toReturn.Add(CV);


            // if necessary, add a blending vowel _CV
            string editedV = GetStartingBlendVowel(lyric_split.Onset[0], lyric_split.Nucleus[0]);

            if (editedV != null)
            {
                UtauNote _CV = new UtauNote(curr);
                _CV.Lyric  = editedV;
                _CV.Length = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                CV.Lyric   = lyric_split.Onset[0];
                CV.Length  = 60;
                toReturn.Add(_CV);
                CV = _CV; //relabel references
            }

            // figure out the ending
            List <string> ending_split = EndingParser(lyric_split.Coda[0]);

            if (ending_split.Count == 0)
            {
                string   newNote = GetConnectingSound(lyric_split.Nucleus[0], lyric_split.Coda[0], nextlyric_split.Onset[0], nextlyric_split.Nucleus[0]);
                UtauNote C_V     = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length  = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    C_V.Lyric  = newNote;
                    C_V.Length = 60;
                    toReturn.Add(C_V);
                }
                else if (nextlyric_split.Nucleus[0] == null)
                {
                    UtauNote V_rest = new UtauNote(curr);
                    CV.Length     = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    V_rest.Lyric  = lyric_split.Nucleus[0];
                    V_rest.Length = 60;
                    toReturn.Add(V_rest);
                }
            }
            else if (ending_split.Count == 1)
            {
                string   newNote = GetEndingSound(lyric_split.Nucleus[0], lyric_split.Coda[0]);
                UtauNote VC      = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    VC.Lyric  = newNote;
                    VC.Length = 60;
                    if (Sonorant_Consonant_RE.IsMatch(lyric_split.Coda[0]) && !next.IsRest)
                    {
                        // on ending sonorants, add a dash before a C_C for blending
                        // this doesn't apply if the next sound is a rest
                        VC.Lyric = newNote + "-";
                    }
                    toReturn.Add(VC);
                }

                newNote = GetConnectingSound(lyric_split.Nucleus[0], lyric_split.Coda[0], nextlyric_split.Onset[0], nextlyric_split.Nucleus[0]);
                UtauNote C_V = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length  = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    C_V.Lyric  = newNote;
                    C_V.Length = 60;
                    toReturn.Add(C_V);
                }
            }
            else
            {
                // ending consonant cluster(s) of some sort
                // TODO: more than one consonant cluster is not yet supported
                // e.g. b6lbz, which should be [b6][6l-][lb-][bz] is currently just [b6][6l-][lbz] but lbz is not a single sound

                string   newNote = GetEndingSound(lyric_split.Nucleus[0], ending_split[0]);
                UtauNote VC      = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    VC.Lyric  = newNote + "-";
                    VC.Length = 60;
                    toReturn.Add(VC);
                }

                UtauNote VCC = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length  = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    VCC.Lyric  = string.Join("", ending_split);
                    VCC.Length = 60;
                    toReturn.Add(VCC);
                }

                newNote = GetConnectingSound(ending_split[ending_split.Count - 2], ending_split[ending_split.Count - 1],
                                             nextlyric_split.Onset[0], nextlyric_split.Nucleus[0]);
                UtauNote C_V = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length  = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    C_V.Lyric  = newNote;
                    C_V.Length = 60;
                    toReturn.Add(C_V);
                }
            }


            // adjust first sound if previous note is a rest
            if (prev == null || prev.IsRest)
            {
                toReturn[0].Lyric = "-" + toReturn[0].Lyric;
            }
            else if (lyric_split.Onset[0] == "")
            {
                // if it's not following a rest but it starts with a vowel
                toReturn[0].Lyric = "_" + toReturn[0].Lyric;
            }
            // adjust last sound if following note is a rest
            if (next == null || next.IsRest)
            {
                toReturn[toReturn.Count - 1].Lyric = toReturn[toReturn.Count - 1].Lyric + "-";
            }

            foreach (UtauNote n in toReturn.Skip(1))
            {
                n.MainValues.Remove("Tempo");
                //Remove tempo marking from any except the first (which is where it was originally)
            }

            return(toReturn);
        }
        /// <summary>
        /// Return the current note, split up as necessary to match the prev and next notes
        /// (Returns a new copy of all notes; the inputs are unchanged)
        ///
        /// </summary>
        /// <param name="prev"></param>
        /// <param name="curr"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public static List <UtauNote> GetConnectingNotes(UtauNote prev, UtauNote curr, UtauNote next)
        {
            VCCV_English_Syllable lyric_split     = VCCV_English_Syllable.SplitSyllable(curr.Lyric);
            VCCV_English_Syllable nextlyric_split = VCCV_English_Syllable.SplitSyllable(next.Lyric);

            List <UtauNote> toReturn = new List <UtauNote>();

            //if unrecognized, return the note untouched
            if (lyric_split.Onset[0] == null && lyric_split.Nucleus[0] == null)
            {
                return(new List <UtauNote> {
                    new UtauNote(curr)
                });
            }

            // add in the base note
            UtauNote CV = new UtauNote(curr);

            CV.Lyric = lyric_split.Onset[0] + lyric_split.Nucleus[0];
            toReturn.Add(CV);


            // if necessary, add a blending vowel _CV
            string editedV = GetStartingBlendVowel(lyric_split.Onset[0], lyric_split.Nucleus[0]);

            if (editedV != null)
            {
                UtauNote _CV = new UtauNote(curr);
                _CV.Lyric  = editedV;
                _CV.Length = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                CV.Lyric   = lyric_split.Onset[0];
                CV.Length  = 60;
                toReturn.Add(_CV);
                CV = _CV; //relabel references
            }

            // figure out the ending
            List <string> ending_split = EndingParser(lyric_split.Coda[0]);

            if (ending_split.Count == 0)
            {
                string   newNote = GetConnectingSound(lyric_split.Nucleus[0], lyric_split.Coda[0], nextlyric_split.Onset[0], nextlyric_split.Nucleus[0]);
                UtauNote C_V     = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length  = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    C_V.Lyric  = newNote;
                    C_V.Length = 60;
                    toReturn.Add(C_V);
                }
                else if (nextlyric_split.Nucleus[0] == null)
                {
                    UtauNote V_rest = new UtauNote(curr);
                    CV.Length     = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    V_rest.Lyric  = lyric_split.Nucleus[0];
                    V_rest.Length = 60;
                    toReturn.Add(V_rest);
                }
            }
            else if (ending_split.Count == 1)
            {
                string   newNote = GetEndingSound(lyric_split.Nucleus[0], lyric_split.Coda[0]);
                UtauNote VC      = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    VC.Lyric  = newNote;
                    VC.Length = 60;
                    toReturn.Add(VC);
                }

                newNote = GetConnectingSound(lyric_split.Nucleus[0], lyric_split.Coda[0], nextlyric_split.Onset[0], nextlyric_split.Nucleus[0]);
                UtauNote C_V = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length  = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    C_V.Lyric  = newNote;
                    C_V.Length = 60;
                    toReturn.Add(C_V);
                }
            }
            else
            {
                // ending consonant cluster(s) of some sort
                // TODO: more than one consonant cluster is not yet supported
                // e.g. b6lbz, which should be [b6][6l-][lb-][bz] is just [b6][6l-][lbz] but lbz is not a single sound

                string   newNote = GetEndingSound(lyric_split.Nucleus[0], ending_split[0]);
                UtauNote VC      = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    VC.Lyric  = newNote + "-";
                    VC.Length = 60;
                    toReturn.Add(VC);
                }

                UtauNote VCC = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length  = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    VCC.Lyric  = string.Join("", ending_split);
                    VCC.Length = 60;
                    toReturn.Add(VCC);
                }

                newNote = GetConnectingSound(ending_split[ending_split.Count - 2], ending_split[ending_split.Count - 1],
                                             nextlyric_split.Onset[0], nextlyric_split.Nucleus[0]);
                UtauNote C_V = new UtauNote(curr);
                if (newNote != null)
                {
                    CV.Length  = CV.Length - 60; //TODO: something more clever with lengths. For now, 60 is a 32th note
                    C_V.Lyric  = newNote;
                    C_V.Length = 60;
                    toReturn.Add(C_V);
                }
            }


            // adjust first sound if previous note is a rest
            if (prev == null || prev.IsRest)
            {
                toReturn[0].Lyric = "-" + toReturn[0].Lyric;
            }
            // adjust last sound if following note is a rest
            if (next == null || next.IsRest)
            {
                toReturn[toReturn.Count - 1].Lyric = toReturn[toReturn.Count - 1].Lyric + "-";
            }

            return(toReturn);
        }