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); }
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; } }); }
public double Tick2Time(long Tick) { return(MidiMathUtils.Tick2Time(Tick, baseTempo)); }
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); }