public List <SplitAtom> GetCurrentNoteAtom(string prev, string current, string next, double BaseTempo)
        {
            List <string> GetCurrent = GetAtomItem(current);

            if (GetCurrent.Count == 0)
            {
                SplitAtom sa = new SplitAtom();
                sa.PhonemeAtom = current;
                return(new List <SplitAtom>()
                {
                    sa
                });
            }
            List <string>    GetPrev = GetAtomItem(prev);
            List <string>    GetNext = GetAtomItem(next);
            List <SplitAtom> RetAtom = new List <SplitAtom>();

            string[] List = _FunctionString.Split('|');
            for (int i = 0; i < List.Length; i++)
            {
                string si         = List[i];
                int    sIdx       = si.LastIndexOf('$');
                string AtomBody   = sIdx > 0?si.Substring(0, sIdx):si;
                string AtomLength = "0";
                if (sIdx > 0 && sIdx + 1 < si.Length)
                {
                    AtomLength = si.Substring(sIdx + 1);
                }

                string AtomStr = CalcAtomStr(AtomBody, GetPrev, GetCurrent, GetNext).Trim();
                if (AtomStr.Trim() != "")
                {
                    SplitAtom sa = new SplitAtom();
                    sa.PhonemeAtom = AtomStr;
                    sa.AtomLength  = (long)Microsoft.VisualBasic.Conversion.Val(AtomLength);
                    if (AtomLength.IndexOf('%') != -1)
                    {
                        sa.LengthIsPercent = true;
                    }
                    else if (BaseTempo != 120)
                    {
                        double db = MidiMathUtils.Tick2Time(sa.AtomLength, BaseTempo);
                        sa.AtomLength = (long)Math.Round((double)MidiMathUtils.Time2Tick(db, BaseTempo));
                    }
                    RetAtom.Add(sa);
                }
            }
            return(RetAtom);
        }
        static void Main1(string[] args)
        {
            long rt = (int)(MidiMathUtils.Tick2Time((long)(480), 180) * 1000);
            long rb = UtauToolUtils.Resampler_SortNear50((int)rt);

            /*
             * 连续音符A,B,C
             *
             * WavTool.A.Length= [email protected] - B.PreUtter + B.Overlap
             * WavTool.B.Length= [email protected] + B.PreUtter - C.PreUtter + C.Overlap
             * WavTool.C.Length= [email protected] + C.PreUTter
             */

            SoundAtom.PreUtterOverlapArgs ou = new SoundAtom.PreUtterOverlapArgs();
            ou.OverlapMs    = 50;
            ou.PreUtterance = 100;

            SoundAtom sa = new SoundAtom();

            sa.WavFile                           = @"D:\VocalUtau\VocalUtau.DebugExampleFiles\UTAUKernel\voice\uta\偁.wav";
            sa.PhonemeSymbol                     = "a";
            sa.SoundStartMs                      = 6;
            sa.FixedConsonantLengthMs            = 52;
            sa.FixedReleasingLengthMs            = 69;
            sa.PreutterOverlapsArgs.PreUtterance = 0;
            sa.PreutterOverlapsArgs.OverlapMs    = 0;

            VocalUtau.Formats.Model.Utils.UtauRendCommanderUtils.ResamplerArgs rarg = new VocalUtau.Formats.Model.Utils.UtauRendCommanderUtils.ResamplerArgs(sa, @"D:\OUT.wav", 120, 1920, "D4");
            rarg.ThisPreutterOverlapsArgs = ou;
            rarg.NextPreutterOverlapsArgs = ou.Clone();
            string arp = UtauRendCommanderUtils.GetResamplerArg(rarg);

            VocalUtau.Formats.Model.Utils.UtauRendCommanderUtils.WavtoolArgs rab = new VocalUtau.Formats.Model.Utils.UtauRendCommanderUtils.WavtoolArgs();
            rab.TickLength               = 960;
            rab.Tempo                    = 120;
            rab.StartPointMs             = 0;
            rab.InputWavfile             = "in.wav";
            rab.OutputWavfile            = "out.wav";
            rab.ThisPreutterOverlapsArgs = ou;
            rab.NextPreutterOverlapsArgs = ou.Clone();
            rab.EnvlopePoints.Add(100, 200);
            rab.EnvlopePoints.Add(110, 200);
            rab.EnvlopePoints.Add(190, 200);
            rab.EnvlopePoints.Add(2000, 400);
            string arb = UtauRendCommanderUtils.GetWavtoolArgs(rab);
        }
예제 #3
0
        public void FillPartsNotes(PartsObject parts, long StartTick)
        {
            if (StartTick < 0)
            {
                return;
            }
            if (parts.TickLength < StartTick)
            {
                return;
            }
            double           partsTempo = parts.Tempo;
            int              firstIndex = parts.NoteCompiler.FindTickIn(StartTick, 0, parts.NoteList.Count);
            VocalIndexObject vio        = SingerDataFinder.GetVocalIndexObject(parts);
            string           fio        = SingerDataFinder.GetSingerFolder(parts);
            SingerObject     sobject    = SingerDataFinder.GetSingerObject(parts);

            if (vio == null)
            {
                return;
            }
            Object locker = new Object();

            //完成初步演算
            Parallel.For(firstIndex < 0 ? 0 : firstIndex, parts.NoteList.Count, (i) => {
                if (parts.NoteList[i].Tick + parts.NoteList[i].Length > StartTick)
                {
                    NoteObject curNote       = parts.NoteList[i];
                    List <NotePreRender> NPR = new List <NotePreRender>();
                    List <long> NPT          = PhonemeSplitTools.SplitedTickList(curNote.Length, curNote.PhonemeAtoms);
                    long TotalTick           = curNote.Tick;
                    for (int j = 0; j < curNote.PhonemeAtoms.Count; j++)
                    {
                        NotePreRender pra     = new NotePreRender();
                        pra.Tempo             = parts.Tempo;
                        pra.partStartTime     = parts.StartTime;
                        pra.ConsonantVelocity = (int)defDouble(curNote.PhonemeAtoms[j].Velocity, 100);
                        pra.Tick       = TotalTick;
                        pra.Length     = NPT[j];
                        pra.TimeLen    = MidiMathUtils.Tick2Time(pra.Length, parts.Tempo) * 1000;
                        TotalTick     += pra.Length;
                        pra.Note       = GetNote(curNote.PitchValue.NoteNumber);
                        pra.StartPoint = defDouble(curNote.PhonemeAtoms[j].StartPoint, 0);
                        string defflag = "";
                        string resamp  = "";
                        try
                        {
                            defflag = sobject.Flags;
                        }catch {; }
                        try
                        {
                            resamp = sobject.getRealResamplerPath();
                        }
                        catch {; }
                        pra.Flags     = curNote.PhonemeAtoms[j].getFlags(parts.getFlags(defflag));
                        pra.Resampler = parts.getResampler(resamp);

                        pra.VolumePercentInt = curNote.PhonemeAtoms[j].VolumePercentInt;

                        SoundAtom baa = new SoundAtom();
                        uint nn       = curNote.PitchValue.NoteNumber;
                        string pref   = "";
                        string suff   = "";
                        if (vio.PrefixAtomList.PreFix.ContainsKey(nn))
                        {
                            pref = vio.PrefixAtomList.PreFix[nn];
                        }
                        if (vio.PrefixAtomList.SufFix.ContainsKey(nn))
                        {
                            suff = vio.PrefixAtomList.SufFix[nn];
                        }
                        baa.PhonemeSymbol = pref + curNote.PhonemeAtoms[j].PhonemeAtom + suff;
                        int vid           = vio.SndAtomList.IndexOf(baa);
                        if (vid == -1 && pref != "" && suff != "")
                        {
                            baa.PhonemeSymbol = curNote.PhonemeAtoms[j].PhonemeAtom;
                            vid = vio.SndAtomList.IndexOf(baa);
                        }
                        if (vid > -1)
                        {
                            pra.OtoAtom = (SoundAtom)vio.SndAtomList[vid].Clone();
                            pra.OtoAtom.PreutterOverlapsArgs.PreUtterance = defDouble(curNote.PhonemeAtoms[j].PreUtterance, pra.OtoAtom.PreutterOverlapsArgs.PreUtterance);
                            pra.OtoAtom.PreutterOverlapsArgs.OverlapMs    = defDouble(curNote.PhonemeAtoms[j].Overlap, pra.OtoAtom.PreutterOverlapsArgs.OverlapMs);
                            pra.RealPreUtterOverArgs.PreUtterance         = pra.OtoAtom.PreutterOverlapsArgs.PreUtterance;
                            pra.RealPreUtterOverArgs.OverlapMs            = pra.OtoAtom.PreutterOverlapsArgs.OverlapMs;
                            pra.OtoAtom.WavFile = PathUtils.AbsolutePath(fio, pra.OtoAtom.WavFile);
                            pra.FadeInLengthMs  = curNote.PhonemeAtoms[j].FadeInLengthMs;
                            pra.FadeOutLengthMs = curNote.PhonemeAtoms[j].FadeOutLengthMs;
                            if (j > 0)
                            {
                                pra.FadeInLengthMs = pra.OtoAtom.PreutterOverlapsArgs.OverlapMs;
                                if (pra.Tick - NPR[j - 1].Tick - NPR[j - 1].Length < 2)
                                {
                                    NPR[j - 1].FadeOutLengthMs = pra.OtoAtom.PreutterOverlapsArgs.OverlapMs;
                                }
                            }
                            pra.Intensity  = defDouble(curNote.PhonemeAtoms[j].Intensity, 100);
                            pra.Moduration = defDouble(curNote.PhonemeAtoms[j].Modulation, 0);
                            //pra.StartTime = MidiMathUtils.Tick2Time(pra.Tick, pra.Tempo);
                            pra.StartTimeAttend = -pra.OtoAtom.PreutterOverlapsArgs.OverlapMs / 1000;
                            pra.StartTick       = MidiMathUtils.Time2Tick(pra.StartTime, pra.Tempo);
                            if (StartTick - pra.Tick > pra.Length)
                            {
                                pra.passTime = double.MaxValue;
                            }
                            else if (StartTick - pra.Tick > 0)
                            {
                                pra.passTime = MidiMathUtils.Tick2Time(StartTick - pra.Tick, pra.Tempo) * 1000;
                            }
                            else
                            {
                                pra.passTime = 0;
                            }

                            if (pra.StartTick < 0)
                            {
                                pra.StartTick = 0;
                            }
                            List <int> PointVS = new List <int>();
                            SortedDictionary <double, long> EnvVs = new SortedDictionary <double, long>();
                            long lastDYNValue = -100;
                            for (long k = pra.StartTick; k <= pra.StartTick + pra.Length + 50; k = k + 5)
                            {
                                PointVS.Add((int)(parts.PitchCompiler.getRealPitch(k) - curNote.PitchValue.NoteNumber) * 100);
                                long dyn = (long)(parts.DynCompiler.getDynValue(k) + parts.DynBaseValue);
                                if (dyn != lastDYNValue)
                                {
                                    double TimeMs = (MidiMathUtils.Tick2Time(k - pra.StartTick, parts.Tempo) * 1000);
                                    if (!EnvVs.ContainsKey(TimeMs))
                                    {
                                        EnvVs.Add(TimeMs, dyn);
                                    }
                                }
                            }
                            pra.EnvlopePoints = EnvVs;
                            pra.PitchString   = PitchEncoderUtils.Encode(PointVS);
                            NPR.Add(pra);
                        }
                        else
                        {
                            pra.OtoAtom = new SoundAtom();
                            pra.OtoAtom.PhonemeSymbol = "{R}";
                            pra.Note = "{R}";
                            //pra.StartTime = MidiMathUtils.Tick2Time(pra.Tick, pra.Tempo);
                            if (StartTick - pra.Tick > pra.Length)
                            {
                                pra.passTime = double.MaxValue;
                            }
                            else if (StartTick - pra.Tick > 0)
                            {
                                pra.passTime = MidiMathUtils.Tick2Time(StartTick - pra.Tick, pra.Tempo) * 1000;
                            }
                            else
                            {
                                pra.passTime = 0;
                            }

                            if (pra.StartTick < 0)
                            {
                                pra.StartTick = 0;
                            }
                            lock (locker)
                            {
                                NPR.Add(pra);
                            }
                        }
                    }
                    lock (locker)
                    {
                        _NotePreRenderList.AddRange(NPR.ToArray());
                    }
                }
            });
            _NotePreRenderList.Sort();
            int TotC = _NotePreRenderList.Count;

            Parallel.For(0, TotC, (i) =>
            {
                NotePreRender Cur = _NotePreRenderList[i];
                NotePreRender Pre = null;
                if (i > 0)
                {
                    //不是第一个
                    Pre      = _NotePreRenderList[i - 1];
                    long dbp = Cur.Tick - Pre.Tick - Pre.Length;
                    if (dbp > 0)
                    {
                        long totalp = dbp;
                        while (totalp > 0)
                        {
                            NotePreRender npr         = new NotePreRender();
                            npr.ConsonantVelocity     = 100;
                            npr.OtoAtom               = new SoundAtom();
                            npr.OtoAtom.PhonemeSymbol = "{R}";
                            npr.Tick    = Pre.Tick + Pre.Length;
                            npr.Length  = totalp > 480 ? 480 : totalp;
                            totalp     -= 480;
                            npr.Tempo   = parts.Tempo;
                            npr.Note    = "{R}";
                            npr.TimeLen = MidiMathUtils.Tick2Time(npr.Length, parts.Tempo) * 1000;
                            lock (locker)
                            {
                                _NotePreRenderList.Add(npr);
                            }
                        }
                    }
                }
                else
                {
                    long dbp = Cur.Tick - StartTick;
                    if (dbp > 0)
                    {
                        long totalp = dbp;
                        while (totalp > 0)
                        {
                            NotePreRender npr         = new NotePreRender();
                            npr.ConsonantVelocity     = 100;
                            npr.OtoAtom               = new SoundAtom();
                            npr.OtoAtom.PhonemeSymbol = "{R}";
                            npr.Tick    = dbp - totalp;
                            npr.Tempo   = parts.Tempo;
                            npr.Length  = totalp > 480 ? 480 : totalp;
                            totalp     -= 480;
                            npr.Note    = "{R}";
                            npr.TimeLen = MidiMathUtils.Tick2Time(npr.Length, parts.Tempo) * 1000;
                            lock (locker)
                            {
                                _NotePreRenderList.Add(npr);
                            }
                        }
                    }
                }
            });
            _NotePreRenderList.Sort();

            Parallel.For(0, _NotePreRenderList.Count, (i) =>
            {
                NotePreRender Nxt = null;
                if (i + 1 < _NotePreRenderList.Count)
                {
                    Nxt = _NotePreRenderList[i + 1];
                }

                /*
                 * 修正PreOverlap
                 */
                if (Nxt != null)
                {
                    double PRE       = Nxt.RealPreUtterOverArgs.PreUtterance;
                    double OVL       = Nxt.RealPreUtterOverArgs.OverlapMs;
                    double KickFront = PRE - OVL;
                    double halfNote  = _NotePreRenderList[i].TimeLen / 2;
                    if (_NotePreRenderList[i].Note == "{R}")
                    {
                        halfNote = _NotePreRenderList[i].TimeLen;
                    }
                    if (halfNote < KickFront)
                    {
                        //NEED FIX
                        double ovl = OVL / (PRE - OVL) * halfNote;
                        double pre = PRE / (PRE - OVL) * halfNote;
                        if (Nxt.FadeInLengthMs == OVL && _NotePreRenderList[i].FadeOutLengthMs == OVL)
                        {
                            Nxt.FadeInLengthMs = ovl;
                            _NotePreRenderList[i].FadeOutLengthMs = ovl;
                        }
                        Nxt.RealPreUtterOverArgs.OverlapMs    = ovl;
                        Nxt.RealPreUtterOverArgs.PreUtterance = pre;
                        Nxt.StartPoint = PRE - pre;
                        //DEG
                        Nxt.StartTimeAttend = -Nxt.RealPreUtterOverArgs.OverlapMs / 1000;
                    }
                }

                /*
                 * 修正结束
                 */
                if (_NotePreRenderList[i].FadeInLengthMs < _NotePreRenderList[i].RealPreUtterOverArgs.OverlapMs)
                {
                    _NotePreRenderList[i].FadeInLengthMs = _NotePreRenderList[i].RealPreUtterOverArgs.OverlapMs;
                }
                if (Nxt != null)
                {
                    if (_NotePreRenderList[i].FadeOutLengthMs < Nxt.RealPreUtterOverArgs.OverlapMs)
                    {
                        _NotePreRenderList[i].FadeOutLengthMs = Nxt.RealPreUtterOverArgs.OverlapMs;
                    }
                }
                UtauRendCommanderUtils.ResamplerArgs ra = _NotePreRenderList[i].Note == "{R}"?null:NPR2ResamplerArgs(_NotePreRenderList[i], Nxt, "{RESAMPLEROUTPUT}");
                string[] ResList = ra == null ? new string[0] : UtauRendCommanderUtils.GetResamplerArg(ra);
                UtauRendCommanderUtils.WavtoolArgs wa = NPR2WavtoolArgs(_NotePreRenderList[i], Nxt, "{RESAMPLEROUTPUT}", "{WAVOUTPUT}");
                string[] WavList = wa == null ? new string[0] : UtauRendCommanderUtils.GetWavtoolArgs(wa);
                lock (locker)
                {
                    // List<string> LSL = new List<string>();
                    // for (int j = 0; j <= Math.Min(12, WavList.Length - 1); j++) LSL.Add(WavList[j]);
                    _NotePreRenderList[i].ResamplerArg     = ra;
                    _NotePreRenderList[i].ResamplerArgList = ResList;
                    _NotePreRenderList[i].WavtoolArgs      = wa;
                    _NotePreRenderList[i].WavtoolArgList   = WavList;// LSL.ToArray();// WavList;
                }
            });
        }
예제 #4
0
 public double Tick2Time(long Tick)
 {
     return(MidiMathUtils.Tick2Time(Tick, baseTempo));
 }
예제 #5
0
        public List <NoteListCalculator.NotePreRender> CalcTracker(double TimePosition, TrackerObject tracker, double BaseTempo)
        {
            List <NoteListCalculator.NotePreRender> ResultList             = new List <NoteListCalculator.NotePreRender>();
            Dictionary <int, NoteListCalculator.NotePreRender[]> PreCalcer = new Dictionary <int, NoteListCalculator.NotePreRender[]>();
            Object oLocker = new Object();

            Parallel.For(0, tracker.PartList.Count, (i, ParallelLoopState) =>
            {
                if (tracker.PartList[i].getStartTime() + tracker.PartList[i].getDuringTime() < TimePosition)
                {
                    ParallelLoopState.Break();
                }
                else
                {
                    NoteListCalculator nlc = new NoteListCalculator(SingerDataFinder);
                    nlc.FillPartsNotes(tracker.PartList[i], 0);
                    lock (oLocker)
                    {
                        PreCalcer.Add(i, nlc.NotePreRenderList.ToArray());
                    }
                }
            });
            double DelayTime = TimePosition;
            double TimeState = 0;

            for (int i = 0; i < tracker.PartList.Count; i++)
            {
                PartsObject p        = tracker.PartList[i];
                double      TimeDert = p.getStartTime() - TimeState;
                VocalUtau.Calculators.NoteListCalculator.NotePreRender LastR = null;
                if (TimeDert > 0)
                {
                    long TickRStart = MidiMathUtils.Time2Tick(TimeState, BaseTempo);
                    long TickLength = MidiMathUtils.Time2Tick(TimeDert, BaseTempo);
                    while (TickLength > 0)
                    {
                        VocalUtau.Calculators.NoteListCalculator.NotePreRender npr = new VocalUtau.Calculators.NoteListCalculator.NotePreRender();
                        npr.OtoAtom = new VocalUtau.Formats.Model.Database.VocalDatabase.SoundAtom();
                        npr.OtoAtom.PhonemeSymbol = "{R}";
                        npr.Tick          = TickRStart;
                        npr.Length        = TickLength > 480 ? 480 : TickLength;
                        TickLength       -= 480;
                        TickRStart       += 480;
                        npr.Tempo         = BaseTempo;
                        npr.partStartTime = TimeState;
                        npr.Note          = "{R}";
                        npr.TimeLen       = MidiMathUtils.Tick2Time(npr.Length, BaseTempo) * 1000;
                        LastR             = npr;

                        VocalUtau.Calculators.NoteListCalculator.NotePreRender fn = null;
                        if (PreCalcer.ContainsKey(i))
                        {
                            try
                            {
                                fn = PreCalcer[i][0];
                            }
                            catch {; }
                        }
                        UtauRendCommanderUtils.WavtoolArgs wa = NoteListCalculator.NPR2WavtoolArgs(npr, (TickLength >= 480)?npr:fn, "{RESAMPLEROUTPUT}", "{WAVOUTPUT}");
                        npr.WavtoolArgs    = wa;
                        npr.WavtoolArgList = UtauRendCommanderUtils.GetWavtoolArgs(wa);
                        ResultList.Add(npr);
                    }
                }
                //FixFirstNode
                if (PreCalcer.ContainsKey(i))
                {
                    if (LastR != null)
                    {
                        try
                        {
                            VocalUtau.Calculators.NoteListCalculator.NotePreRender Nxt = PreCalcer[i][0];
                            if (Nxt != null)
                            {
                                if (Nxt.Note != "{R}")
                                {
                                    double PRE       = Nxt.RealPreUtterOverArgs.PreUtterance;
                                    double OVL       = Nxt.RealPreUtterOverArgs.OverlapMs;
                                    double KickFront = PRE - OVL;
                                    double halfNote  = LastR.TimeLen;
                                    if (halfNote < KickFront)
                                    {
                                        //NEED FIX
                                        double ovl = OVL / (PRE - OVL) * halfNote;
                                        double pre = PRE / (PRE - OVL) * halfNote;
                                        if (Nxt.FadeInLengthMs == OVL)
                                        {
                                            Nxt.FadeInLengthMs = ovl;
                                        }
                                        Nxt.RealPreUtterOverArgs.OverlapMs    = ovl;
                                        Nxt.RealPreUtterOverArgs.PreUtterance = pre;
                                        Nxt.StartPoint      = PRE - pre;
                                        Nxt.StartTimeAttend = -Nxt.RealPreUtterOverArgs.OverlapMs / 1000;
                                    }
                                }
                            }
                        }
                        catch {; }
                    }
                    NoteListCalculator.NotePreRender[] LCL = PreCalcer[i];
                    for (int k = 0; k < LCL.Length; k++)
                    {
                        NoteListCalculator.NotePreRender pcr = LCL[k];
                        ResultList.Add(pcr);
                    }
                    TimeState = p.getStartTime() + p.getDuringTime();
                }
            }
            for (int i = 0; i < ResultList.Count; i++)
            {
                double EndTime = ResultList[i].absoluteStartTime * 1000 + ResultList[i].TimeLen;
                if (EndTime == ResultList[i].absoluteStartTime * 1000)
                {
                    long TB = 0;
                }
                if (EndTime < TimePosition * 1000)
                {
                    ResultList.RemoveAt(i);
                    i--;
                }
                else if (ResultList[i].absoluteStartTime < TimePosition)
                {
                    ResultList[i].passTime = (TimePosition - ResultList[i].absoluteStartTime) * 1000;
                }
            }
            //FixFirstNodeEnd
            //  Debug_CreateBat(ResultList, tracker, BaseTempo);
            return(ResultList);
        }