protected override void OnRender(DrawingContext drawingContext)
        {
            int    note = UIConstants.MaxNoteNum - 1 - (int)(OffsetY / TrackHeight);
            double top  = TrackHeight * (UIConstants.MaxNoteNum - note - 1) - OffsetY;

            while (top < _size.Height)
            {
                drawingContext.DrawRectangle(
                    MusicMath.IsBlackKey(note) ? ThemeManager.BlackKeyBrushNormal :
                    MusicMath.IsCenterKey(note) ? ThemeManager.CenterKeyBrushNormal : ThemeManager.WhiteKeyBrushNormal,
                    null,
                    new Rect(0, (int)top, _size.Width, TrackHeight));

                if (TrackHeight >= 12)
                {
                    FormattedText text = new FormattedText(
                        MusicMath.GetNoteString(note),
                        System.Threading.Thread.CurrentThread.CurrentUICulture,
                        FlowDirection.LeftToRight,
                        SystemFonts.CaptionFontFamily.GetTypefaces().First(),
                        12,
                        MusicMath.IsBlackKey(note) ? ThemeManager.BlackKeyNameBrushNormal :
                        MusicMath.IsCenterKey(note) ? ThemeManager.CenterKeyNameBrushNormal : ThemeManager.WhiteKeyNameBrushNormal,
                        VisualTreeHelper.GetDpi(this).PixelsPerDip
                        );
                    drawingContext.DrawText(text, new Point(42 - text.Width, (int)(top + (TrackHeight - text.Height) / 2)));
                }
                top += TrackHeight;
                note--;
            }
        }
        protected override void OnRender(DrawingContext drawingContext)
        {
            int    firstTrack = (int)(OffsetY / TrackHeight);
            int    alt        = firstTrack;
            double top        = TrackHeight * firstTrack - OffsetY;

            while (top < _size.Height)
            {
                drawingContext.DrawRectangle(
                    MusicMath.IsBlackKey(alt) ? ThemeManager.BlackKeyBrushNormal :
                    MusicMath.IsCenterKey(alt) ? ThemeManager.CenterKeyBrushNormal : ThemeManager.WhiteKeyBrushNormal,
                    null,
                    new Rect(0, (int)top, _size.Width, TrackHeight));

                if (TrackHeight >= 12)
                {
                    FormattedText text = new FormattedText(
                        MusicMath.GetNoteString(UIConstants.MaxNoteNum - alt - 1),
                        System.Threading.Thread.CurrentThread.CurrentUICulture,
                        FlowDirection.LeftToRight,
                        SystemFonts.CaptionFontFamily.GetTypefaces().First(),
                        12,
                        MusicMath.IsBlackKey(alt) ? ThemeManager.BlackKeyNameBrushNormal :
                        MusicMath.IsCenterKey(alt) ? ThemeManager.CenterKeyNameBrushNormal : ThemeManager.WhiteKeyNameBrushNormal
                        );
                    drawingContext.DrawText(text, new Point(42 - text.Width, (int)(top + (TrackHeight - text.Height) / 2)));
                }
                top += TrackHeight;
                alt++;
            }
        }
    public void DrawNote(Graphics g, PlayingData pd, Note n, object color = null, int dx = 0, int dy = 0)
    {
        Color c;

        if (color == null)
        {
            switch (n.type)
            {//set color for default
            case NoteType.ShortNote:
                c = Color.White;
                break;

            case NoteType.SlideLongNote:
                c = Color.GreenYellow;
                break;

            default:
                c = Color.Red;
                break;
            }
        }
        else
        {
            c = (Color)color;
        }

        g.DrawRectangle(new Pen(c, 2), MusicMath.RectFromNote(n, pd, dx, dy));
    }
        public void Begin(IPointer pointer, Point point)
        {
            pointer.Capture(element);
            var tone = vm.NotesViewModel.PointToTone(point);

            sineGen = PlaybackManager.Inst.PlayTone(MusicMath.ToneToFreq(tone));
        }
        private void DrawPitchBend(UNote note, DrawingContext cxt)
        {
            var _pitchExp = note.PitchBend as PitchBendExpression;
            var _pts      = _pitchExp.Data as List <PitchPoint>;

            if (_pts.Count < 2)
            {
                return;
            }

            double pt0Tick = note.PosTick + MusicMath.MillisecondToTick(_pts[0].X, DocManager.Inst.Project.BPM, DocManager.Inst.Project.BeatUnit, DocManager.Inst.Project.Resolution);
            double pt0X    = midiVM.QuarterWidth * pt0Tick / DocManager.Inst.Project.Resolution;
            double pt0Pit  = note.NoteNum + _pts[0].Y / 10.0;
            double pt0Y    = TrackHeight * ((double)UIConstants.MaxNoteNum - 1.0 - pt0Pit) + TrackHeight / 2;

            if (note.PitchBend.SnapFirst)
            {
                cxt.DrawEllipse(ThemeManager.WhiteKeyNameBrushNormal, penPit, new Point(pt0X, pt0Y), 2.5, 2.5);
            }
            else
            {
                cxt.DrawEllipse(null, penPit, new Point(pt0X, pt0Y), 2.5, 2.5);
            }

            for (int i = 1; i < _pts.Count; i++)
            {
                double pt1Tick = note.PosTick + MusicMath.MillisecondToTick(_pts[i].X, DocManager.Inst.Project.BPM, DocManager.Inst.Project.BeatUnit, DocManager.Inst.Project.Resolution);
                double pt1X    = midiVM.QuarterWidth * pt1Tick / DocManager.Inst.Project.Resolution;
                double pt1Pit  = note.NoteNum + _pts[i].Y / 10.0;
                double pt1Y    = TrackHeight * ((double)UIConstants.MaxNoteNum - 1.0 - pt1Pit) + TrackHeight / 2;

                // Draw arc
                double _x  = pt0X;
                double _x2 = pt0X;
                double _y  = pt0Y;
                double _y2 = pt0Y;
                if (pt1X - pt0X < 5)
                {
                    cxt.DrawLine(penPit, new Point(pt0X, pt0Y), new Point(pt1X, pt1Y));
                }
                else
                {
                    while (_x2 < pt1X)
                    {
                        _x = Math.Min(_x + 4, pt1X);
                        _y = MusicMath.InterpolateShape(pt0X, pt1X, pt0Y, pt1Y, _x, _pts[i - 1].Shape);
                        cxt.DrawLine(penPit, new Point(_x, _y), new Point(_x2, _y2));
                        _x2 = _x;
                        _y2 = _y;
                    }
                }

                pt0Tick = pt1Tick;
                pt0X    = pt1X;
                pt0Pit  = pt1Pit;
                pt0Y    = pt1Y;
                cxt.DrawEllipse(null, penPit, new Point(pt0X, pt0Y), 2.5, 2.5);
            }
        }
Exemple #6
0
    private void HandleTicked(double tickTime, int midiNoteNumber, double duration)
    {
        float pitch = MusicMath.MidiNoteToPitch(midiNoteNumber, MusicMath.MidiNoteC4);

        _samplerVoices[_nextVoiceIndex].Play(_audioClip, pitch, tickTime, _attackTime, duration, _releaseTime);

        _nextVoiceIndex = (_nextVoiceIndex + 1) % _samplerVoices.Length;
    }
        public void Update(IPointer pointer, Point point)
        {
            var tone = vm.NotesViewModel.PointToTone(point);

            if (sineGen != null)
            {
                sineGen.Freq = MusicMath.ToneToFreq(tone);
            }
        }
Exemple #8
0
        private void DrawPitchBend(UNote note, DrawingContext cxt)
        {
            var _pitchExp = note.pitch;
            var _pts      = _pitchExp.data;

            if (_pts.Count < 2)
            {
                return;
            }

            double pt0Tick = note.position + MusicMath.MillisecondToTick(_pts[0].X, DocManager.Inst.Project.bpm, DocManager.Inst.Project.beatUnit, DocManager.Inst.Project.resolution);
            double pt0X    = midiVM.QuarterWidth * pt0Tick / DocManager.Inst.Project.resolution;
            double pt0Pit  = note.tone + _pts[0].Y / 10.0;
            double pt0Y    = TrackHeight * (UIConstants.MaxNoteNum - 1.0 - pt0Pit) + TrackHeight / 2;

            cxt.DrawEllipse(note.pitch.snapFirst ? penPit.Brush : null, penPit, new Point(pt0X, pt0Y), 2.5, 2.5);

            for (int i = 1; i < _pts.Count; i++)
            {
                double pt1Tick = note.position + MusicMath.MillisecondToTick(_pts[i].X, DocManager.Inst.Project.bpm, DocManager.Inst.Project.beatUnit, DocManager.Inst.Project.resolution);
                double pt1X    = midiVM.QuarterWidth * pt1Tick / DocManager.Inst.Project.resolution;
                double pt1Pit  = note.tone + _pts[i].Y / 10.0;
                double pt1Y    = TrackHeight * (UIConstants.MaxNoteNum - 1.0 - pt1Pit) + TrackHeight / 2;

                // Draw arc
                double _x  = pt0X;
                double _x2 = pt0X;
                double _y  = pt0Y;
                double _y2 = pt0Y;
                if (pt1X - pt0X < 5)
                {
                    cxt.DrawLine(penPit, new Point(pt0X, pt0Y), new Point(pt1X, pt1Y));
                }
                else
                {
                    while (_x2 < pt1X)
                    {
                        _x = Math.Min(_x + 4, pt1X);
                        _y = MusicMath.InterpolateShape(pt0X, pt1X, pt0Y, pt1Y, _x, _pts[i - 1].shape);
                        cxt.DrawLine(penPit, new Point(_x, _y), new Point(_x2, _y2));
                        _x2 = _x;
                        _y2 = _y;
                    }
                }

                pt0Tick = pt1Tick;
                pt0X    = pt1X;
                pt0Pit  = pt1Pit;
                pt0Y    = pt1Y;
                cxt.DrawEllipse(null, penPit, new Point(pt0X, pt0Y), 2.5, 2.5);
            }
        }
Exemple #9
0
        /// <summary>
        /// Utility method to map a phoneme alias to proper pitch using prefixmap.
        /// For example, MapPhoneme("あ", 72, singer) may return "あC5".
        /// </summary>
        /// <param name="phoneme">Alias before pitch mapping.</param>
        /// <param name="tone">Music tone of note. C4 = 60.</param>
        /// <param name="singer">The singer.</param>
        /// <returns>Mapped alias.</returns>
        public static string MapPhoneme(string phoneme, int tone, USinger singer)
        {
            var toneName = MusicMath.GetToneName(tone);

            if (singer.PrefixMap.TryGetValue(toneName, out var prefix))
            {
                var phonemeMapped = prefix.Item1 + phoneme + prefix.Item2;
                if (singer.FindOto(phonemeMapped) != null)
                {
                    phoneme = phonemeMapped;
                }
            }
            return(phoneme);
        }
Exemple #10
0
 public void DrawImaginaryNote(Graphics g, PlayingData pd, Note DraggingNote, Note SelectedNote, bool dragging, Point draggingDelta)
 {
     //draw dragging note
     ///todo: draggingnote delta beat
     if (dragging)
     {
         DrawNote(g, pd, DraggingNote, Color.Gray, draggingDelta.X, draggingDelta.Y);
     }
     //draw selected note
     if (SelectedNote != null)
     {
         g.DrawRectangle(new Pen(Color.Yellow, 1), MusicMath.RectFromNote(SelectedNote, pd));
     }
 }
        protected override void OnRender(DrawingContext drawingContext)
        {
            int    note = UIConstants.MaxNoteNum - 1 - (int)(OffsetY / TrackHeight);
            double top  = TrackHeight * (UIConstants.MaxNoteNum - note - 1) - OffsetY;

            while (top < _size.Height)
            {
                drawingContext.DrawRectangle(
                    MusicMath.IsBlackKey(note) ? ThemeManager.TrackBackgroundBrushAlt : ThemeManager.TrackBackgroundBrush,
                    null,
                    new Rect(0, (int)top, _size.Width, TrackHeight));
                top += TrackHeight;
                note--;
            }
        }
        protected override void OnRender(DrawingContext drawingContext)
        {
            int    firstTrack = (int)(OffsetY / TrackHeight);
            int    alt        = firstTrack % 12;
            double top        = TrackHeight * firstTrack - OffsetY;

            while (top < _size.Height)
            {
                drawingContext.DrawRectangle(
                    MusicMath.IsBlackKey(alt) ? ThemeManager.TrackBackgroundBrushAlt : ThemeManager.TrackBackgroundBrush,
                    null,
                    new Rect(0, (int)top, _size.Width, TrackHeight));
                top += TrackHeight;
                alt  = (alt + 1) % 12;
            }
        }
Exemple #13
0
 public EngineInput ToEngineInput()
 {
     return(new EngineInput {
         inputWaveFile = SourceFile,
         NoteString = MusicMath.GetNoteString(NoteNum),
         Velocity = Velocity,
         StrFlags = StrFlags,
         Offset = Oto.Offset,
         RequiredLength = RequiredLength,
         Consonant = Oto.Consonant,
         Cutoff = Oto.Cutoff,
         Volume = Volume,
         Modulation = 0,
         pitchBend = PitchData.ToArray(),
         nPitchBend = PitchData.Count,
         Tempo = Tempo
     });
 }
Exemple #14
0
 public string GetResamplerExeArgs()
 {
     // fresamp.exe <infile> <outfile> <tone> <velocity> <flags> <offset> <length_req>
     // <fixed_length> <endblank> <volume> <modulation> <pitch>
     return(string.Format(
                "{0} {1:D} {2} {3} {4:D} {5} {6} {7:D} {8:D} {9} {10}",
                MusicMath.GetNoteString(NoteNum),
                Velocity,
                StrFlags,
                Oto.Offset,
                RequiredLength,
                Oto.Consonant,
                Oto.Cutoff,
                Volume,
                0,
                Tempo,
                String.Join(",", PitchData)));
 }
        protected override void OnRender(DrawingContext drawingContext)
        {
            double zoomRatio = MusicMath.getZoomRatio(QuarterWidth, BeatPerBar, BeatUnit, MinTickWidth);
            double interval  = zoomRatio * QuarterWidth;
            int    tick      = (int)((OffsetX + QuarterOffset * QuarterWidth) / interval) + 1;
            double left      = tick * interval - OffsetX - QuarterOffset * QuarterWidth;

            while (left < _size.Width)
            {
                double snappedLeft = Math.Round(left) + 0.5;
                if ((tick * zoomRatio * BeatUnit) % (BeatPerBar * 4) == 0)
                {
                    drawingContext.DrawLine(darkPen, new Point(snappedLeft, -0.5), new Point(snappedLeft, ActualHeight + 0.5));
                }
                else if ((tick * zoomRatio * BeatUnit) % 4 == 0)
                {
                    if (TickMode == 1)
                    {
                        drawingContext.DrawLine(darkPen, new Point(snappedLeft, -0.5), new Point(snappedLeft, ActualHeight + 0.5));
                    }
                    else
                    {
                        drawingContext.DrawLine(lightPen, new Point(snappedLeft, -0.5), new Point(snappedLeft, ActualHeight + 0.5));
                    }
                }
                else if ((tick * zoomRatio * BeatUnit) % 1 == 0)
                {
                    if (TickMode == 1)
                    {
                        drawingContext.DrawLine(lightPen, new Point(snappedLeft, -0.5), new Point(snappedLeft, ActualHeight + 0.5));
                    }
                    else
                    {
                        drawingContext.DrawLine(dashedPen, new Point(snappedLeft, -0.5), new Point(snappedLeft, ActualHeight + 0.5));
                    }
                }
                else
                {
                    drawingContext.DrawLine(dashedPen, new Point(snappedLeft, -0.5), new Point(snappedLeft, ActualHeight + 0.5));
                }
                left += interval;
                tick++;
            }
        }
Exemple #16
0
        /// <summary>
        /// 从RenderItem初始化过程
        /// </summary>
        /// <returns></returns>
        internal static EngineInput CreateInputModel(RenderItem renderItem, double Modulation)
        {
            EngineInput Ret = new EngineInput();

            Ret.inputWaveFile  = renderItem.RawFile;
            Ret.NoteString     = MusicMath.GetNoteString(renderItem.NoteNum);
            Ret.Velocity       = renderItem.Velocity;
            Ret.StrFlags       = renderItem.StrFlags;
            Ret.Offset         = renderItem.Oto.Offset;
            Ret.RequiredLength = renderItem.RequiredLength;
            Ret.Consonant      = renderItem.Oto.Consonant;
            Ret.Cutoff         = renderItem.Oto.Cutoff;
            Ret.Volume         = renderItem.Volume;
            Ret.Modulation     = Modulation;
            Ret.pitchBend      = renderItem.PitchData.ToArray();
            Ret.nPitchBend     = renderItem.PitchData.Count;
            Ret.Tempo          = renderItem.Tempo;
            return(Ret);
        }
Exemple #17
0
        public bool TryGetMappedOto(string phoneme, int tone, out UOto oto)
        {
            oto = default;
            string toneName = MusicMath.GetToneName(tone);

            if (PrefixMap.TryGetValue(toneName, out var mapped))
            {
                string phonemeMapped = mapped.Item1 + phoneme + mapped.Item2;
                if (TryGetOto(phonemeMapped, out oto))
                {
                    return(true);
                }
            }
            if (TryGetOto(phoneme, out oto))
            {
                return(true);
            }
            return(false);
        }
        protected override void OnRender(DrawingContext drawingContext)
        {
            double zoomRatio  = MusicMath.getZoomRatio(QuarterWidth, BeatPerBar, BeatUnit, MinTickWidth);
            double interval   = zoomRatio * QuarterWidth;
            int    tick       = (int)((OffsetX + QuarterOffset * QuarterWidth) / interval);
            double left       = tick * interval - OffsetX - QuarterOffset * QuarterWidth;
            bool   first_tick = true;

            while (left < _size.Width)
            {
                double snappedLeft = Math.Round(left) + 0.5;
                if ((tick * zoomRatio * BeatUnit) % (BeatPerBar * 4) == 0)
                {
                    if (!first_tick)
                    {
                        drawingContext.DrawLine(darkPen, new Point(snappedLeft, -0.5), new Point(snappedLeft, ActualHeight + 0.5));
                    }
                    int barNumber = (int)((tick * zoomRatio * BeatUnit) / BeatPerBar / 4 + 1);

                    FormattedText fText;
                    if (!fTextPool.ContainsKey(barNumber))
                    {
                        fText = new FormattedText(
                            barNumber.ToString(),
                            System.Threading.Thread.CurrentThread.CurrentUICulture,
                            FlowDirection.LeftToRight, SystemFonts.CaptionFontFamily.GetTypefaces().First(),
                            12,
                            darkPen.Brush,
                            VisualTreeHelper.GetDpi(this).PixelsPerDip);
                        fTextPool.Add(barNumber, fText);
                    }
                    else
                    {
                        fText = fTextPool[barNumber];
                    }
                    drawingContext.DrawText(fText, new Point(snappedLeft + 3, 3));
                }
                left += interval;
                tick++;
                first_tick = false;
            }
        }
Exemple #19
0
        /// <summary>
        /// 从RenderItem初始化过程
        /// </summary>
        /// <returns></returns>
        internal static EngineInput CreateInputModel(RenderItem renderItem, double Modulation)
        {
            EngineInput Ret = new EngineInput
            {
                inputWaveFile  = renderItem.SourceFile,
                NoteString     = MusicMath.GetNoteString(renderItem.NoteNum),
                Velocity       = renderItem.Velocity,
                StrFlags       = renderItem.StrFlags,
                Offset         = renderItem.Oto.Offset,
                RequiredLength = renderItem.RequiredLength,
                Consonant      = renderItem.Oto.Consonant,
                Cutoff         = renderItem.Oto.Cutoff,
                Volume         = renderItem.Volume,
                Modulation     = Modulation,
                pitchBend      = renderItem.PitchData.ToArray(),
                nPitchBend     = renderItem.PitchData.Count,
                Tempo          = renderItem.Tempo
            };

            return(Ret);
        }
Exemple #20
0
    }//*/
    public void DrawGuideLine(Graphics g, PlayingData pd)
    {
        Pen borderlinedrawer = new Pen(Color.White, 0.5f);

        for (int i = 0; i < pd.hsnapcnt; i++)//Horizontal guideline
        {
            int x = this.Width * (i + 1) / ((int)pd.hsnapcnt + 1);
            g.DrawLine(borderlinedrawer, x, 0, x, this.Height);
        }//Horizontal guideline

        int    beat = ((int)(pd.now * 48 / pd.bsnapcnt)) * pd.bsnapcnt;
        double l    = beat / 48d;

        while (beat < 0)
        {
            beat += 48;
        }
        for (; l < pd.now + pd.scale; l += 1d / 48d)
        {
            Pen linedrawer;
            beat %= 48;//detect beat
            if (beat % (48 / pd.bsnapcnt) != 0)
            {
                beat++;
                continue;
            }

            if (beat == 0 && ((l + 12.1) % 4) < 0.4)//thick line every large beat(4 small beat)
            {
                linedrawer = new Pen(Editor.BeatSnapColor.col[beat], 3);
            }
            else
            {
                linedrawer = new Pen(Editor.BeatSnapColor.col[beat], 1);
            }
            int y = MusicMath.TimingToY(l, pd);
            g.DrawLine(linedrawer, 0, y, pd.width, y);
            beat++;
        }//vertical(beat)guideline
    }
Exemple #21
0
 public double TickToMillisecond(double tick)
 {
     return(MusicMath.TickToMillisecond(tick, BPM, BeatUnit, Resolution));
 }
Exemple #22
0
 public int MillisecondToTick(double ms)
 {
     return(MusicMath.MillisecondToTick(ms, BPM, BeatUnit, Resolution));
 }
Exemple #23
0
 /// <summary>
 /// Utility method to convert milliseconds to ticks.
 /// </summary>
 protected int MsToTick(double ms)
 {
     return(MusicMath.MillisecondToTick(ms, bpm, beatUnit, resolution));
 }
Exemple #24
0
 /// <summary>
 /// Utility method to convert ticks to milliseconds.
 /// </summary>
 protected double TickToMs(int tick)
 {
     return(MusicMath.TickToMillisecond(tick, bpm, beatUnit, resolution));
 }
Exemple #25
0
 public string GetResamplerExeArgs()
 {
     // fresamp.exe <infile> <outfile> <tone> <velocity> <flags> <offset> <length_req>
     // <fixed_length> <endblank> <volume> <modulation> <pitch>
     return($"{MusicMath.GetNoteString(NoteNum)} {Velocity:D} {StrFlags} {Oto.Offset} {RequiredLength:D} {Oto.Consonant} {Oto.Cutoff} {Volume:D} {0:D} {Tempo} {string.Join(",", PitchData)}");
 }
Exemple #26
0
        private List <int> BuildPitchData(UPhoneme phoneme, UVoicePart part, UProject project)
        {
            var pitches  = new List <int>();
            var lastNote = part.Notes.OrderByDescending(x => x).Where(x => x.CompareTo(phoneme.Parent) < 0).FirstOrDefault();
            var nextNote = part.Notes.Where(x => x.CompareTo(phoneme.Parent) > 0).FirstOrDefault();
            // Get relevant pitch points
            var pps = new List <PitchPoint>();

            var lastNoteInvolved = lastNote != null && phoneme.Overlapped;
            var nextNoteInvolved = nextNote != null && nextNote.Phonemes[0].Overlapped;

            double lastVibratoStartMs = 0;
            double lastVibratoEndMs   = 0;
            double vibratoStartMs     = 0;
            double vibratoEndMs       = 0;

            if (lastNoteInvolved)
            {
                var offsetMs = DocManager.Inst.Project.TickToMillisecond(phoneme.Parent.PosTick - lastNote.PosTick);
                foreach (var pp in lastNote.PitchBend.Points)
                {
                    var newpp = pp.Clone();
                    newpp.X -= offsetMs;
                    newpp.Y -= (phoneme.Parent.NoteNum - lastNote.NoteNum) * 10;
                    pps.Add(newpp);
                }
                if (lastNote.Vibrato.Depth != 0)
                {
                    lastVibratoStartMs = -DocManager.Inst.Project.TickToMillisecond(lastNote.DurTick) * lastNote.Vibrato.Length / 100;
                    lastVibratoEndMs   = 0;
                }
            }

            foreach (var pp in phoneme.Parent.PitchBend.Points)
            {
                pps.Add(pp);
            }

            if (phoneme.Parent.Vibrato.Depth != 0)
            {
                vibratoEndMs   = DocManager.Inst.Project.TickToMillisecond(phoneme.Parent.DurTick);
                vibratoStartMs = vibratoEndMs * (1 - phoneme.Parent.Vibrato.Length / 100);
            }

            if (nextNoteInvolved)
            {
                var offsetMs = DocManager.Inst.Project.TickToMillisecond(phoneme.Parent.PosTick - nextNote.PosTick);
                foreach (var pp in nextNote.PitchBend.Points)
                {
                    var newpp = pp.Clone();
                    newpp.X -= offsetMs;
                    newpp.Y -= (phoneme.Parent.NoteNum - nextNote.NoteNum) * 10;
                    pps.Add(newpp);
                }
            }

            var startMs = DocManager.Inst.Project.TickToMillisecond(phoneme.PosTick) - phoneme.Oto.Preutter;
            var endMs   = DocManager.Inst.Project.TickToMillisecond(phoneme.DurTick) -
                          (nextNote != null && nextNote.Phonemes[0].Overlapped ? nextNote.Phonemes[0].Preutter - nextNote.Phonemes[0].Overlap : 0);

            if (pps.Count > 0)
            {
                if (pps.First().X > startMs)
                {
                    pps.Insert(0, new PitchPoint(startMs, pps.First().Y));
                }

                if (pps.Last().X < endMs)
                {
                    pps.Add(new PitchPoint(endMs, pps.Last().Y));
                }
            }
            else
            {
                throw new Exception("Zero pitch points.");
            }

            // Interpolation
            const int intervalTick = 5;
            var       intervalMs   = DocManager.Inst.Project.TickToMillisecond(intervalTick);
            var       currMs       = startMs;
            var       i            = 0;

            while (currMs < endMs)
            {
                while (pps[i + 1].X < currMs)
                {
                    i++;
                }

                var pit = MusicMath.InterpolateShape(pps[i].X, pps[i + 1].X, pps[i].Y, pps[i + 1].Y, currMs, pps[i].Shape);
                pit *= 10;

                // Apply vibratos
                if (currMs < lastVibratoEndMs && currMs >= lastVibratoStartMs)
                {
                    pit += InterpolateVibrato(lastNote.Vibrato, currMs - lastVibratoStartMs);
                }

                if (currMs < vibratoEndMs && currMs >= vibratoStartMs)
                {
                    pit += InterpolateVibrato(phoneme.Parent.Vibrato, currMs - vibratoStartMs);
                }

                pitches.Add((int)pit);
                currMs += intervalMs;
            }

            return(pitches);
        }
Exemple #27
0
 public string GetResamplerExeArgs()
 {
     // fresamp.exe <infile> <outfile> <tone> <velocity> <flags> <offset> <length_req>
     // <fixed_length> <endblank> <volume> <modulation> <pitch>
     return(FormattableString.Invariant($"{MusicMath.GetNoteString(NoteNum)} {Velocity:D} \"{StrFlags}\" {Oto.Offset} {RequiredLength:D} {Oto.Consonant} {Oto.Cutoff} {Volume:D} {Modulation:D} {Tempo} {Base64.Base64EncodeInt12(PitchData.ToArray())}"));
 }
Exemple #28
0
        public PitchPointHitTestResult HitTestPitchPoint(Point mousePos)
        {
            foreach (var note in midiVM.Part.Notes)
            {
                if (midiVM.NoteIsInView(note)) // FIXME this is not enough
                {
                    if (note.Error)
                    {
                        continue;
                    }
                    double          lastX = 0, lastY = 0;
                    PitchPointShape lastShape = PitchPointShape.l;
                    for (int i = 0; i < note.PitchBend.Points.Count; i++)
                    {
                        var    pit     = note.PitchBend.Points[i];
                        int    posTick = note.PosTick + Project.MillisecondToTick(pit.X);
                        double noteNum = note.NoteNum + pit.Y / 10;
                        double x       = midiVM.TickToCanvas(posTick);
                        double y       = midiVM.NoteNumToCanvas(noteNum) + midiVM.TrackHeight / 2;
                        if (Math.Abs(mousePos.X - x) < 4 && Math.Abs(mousePos.Y - y) < 4)
                        {
                            return new PitchPointHitTestResult()
                                   {
                                       Note = note, Index = i, OnPoint = true
                                   }
                        }
                        ;
                        else if (mousePos.X < x && i > 0 && mousePos.X > lastX)
                        {
                            // Hit test curve
                            var lastPit = note.PitchBend.Points[i - 1];

                            double castY = MusicMath.InterpolateShape(lastX, x, lastY, y, mousePos.X, lastShape) - mousePos.Y;
                            if (y >= lastY)
                            {
                                if (mousePos.Y - y > 3 || lastY - mousePos.Y > 3)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                if (y - mousePos.Y > 3 || mousePos.Y - lastY > 3)
                                {
                                    break;
                                }
                            }
                            double castX = MusicMath.InterpolateShapeX(lastX, x, lastY, y, mousePos.Y, lastShape) - mousePos.X;
                            double dis   = double.IsNaN(castX) ? Math.Abs(castY) : Math.Cos(Math.Atan2(Math.Abs(castY), Math.Abs(castX))) * Math.Abs(castY);
                            if (dis < 3)
                            {
                                double msX = DocManager.Inst.Project.TickToMillisecond(midiVM.CanvasToQuarter(mousePos.X) * DocManager.Inst.Project.Resolution - note.PosTick);
                                double msY = (midiVM.CanvasToPitch(mousePos.Y) - note.NoteNum) * 10;
                                return(new PitchPointHitTestResult()
                                {
                                    Note = note, Index = i - 1, OnPoint = false, X = msX, Y = msY
                                });
                            }
                            else
                            {
                                break;
                            }
                        }
                        lastX     = x;
                        lastY     = y;
                        lastShape = pit.Shape;
                    }
                }
            }
            return(null);
        }
Exemple #29
0
        public PitchPointHitInfo HitTestPitchPoint(Point mousePos)
        {
            if (!midiVM.ShowPitch)
            {
                return(null);
            }
            foreach (var note in midiVM.Part.notes)
            {
                // FIXME pitch point maybe in view while note is not.
                if (midiVM.NoteIsInView(note) && !note.Error)
                {
                    double          lastX = 0, lastY = 0;
                    PitchPointShape lastShape = PitchPointShape.l;
                    for (int i = 0; i < note.pitch.data.Count; i++)
                    {
                        var    pit     = note.pitch.data[i];
                        int    posTick = note.position + Project.MillisecondToTick(pit.X);
                        double noteNum = note.tone + pit.Y / 10;
                        double x       = midiVM.TickToCanvas(posTick);
                        double y       = midiVM.NoteNumToCanvas(noteNum) + midiVM.TrackHeight / 2;
                        if (Math.Abs(mousePos.X - x) < 4 && Math.Abs(mousePos.Y - y) < 4)
                        {
                            return new PitchPointHitInfo()
                                   {
                                       Note = note, Index = i, OnPoint = true
                                   }
                        }
                        ;
                        else if (mousePos.X < x && i > 0 && mousePos.X > lastX)
                        {
                            // Hit test curve
                            double castY = MusicMath.InterpolateShape(lastX, x, lastY, y, mousePos.X, lastShape) - mousePos.Y;

                            if (y >= lastY)
                            {
                                if (mousePos.Y - y > 3 || lastY - mousePos.Y > 3)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                if (y - mousePos.Y > 3 || mousePos.Y - lastY > 3)
                                {
                                    break;
                                }
                            }
                            double castX = MusicMath.InterpolateShapeX(lastX, x, lastY, y, mousePos.Y, lastShape) - mousePos.X;
                            double dis   = double.IsNaN(castX) ? Math.Abs(castY) : Math.Cos(Math.Atan2(Math.Abs(castY), Math.Abs(castX))) * Math.Abs(castY);
                            if (dis < 3)
                            {
                                double msX = DocManager.Inst.Project.TickToMillisecond(midiVM.CanvasToQuarter(mousePos.X) * DocManager.Inst.Project.resolution - note.position);
                                double msY = (midiVM.CanvasToPitch(mousePos.Y) - note.tone) * 10;
                                return(new PitchPointHitInfo()
                                {
                                    Note = note, Index = i - 1, OnPoint = false, X = (float)msX, Y = (float)msY
                                });
                            }
                            else
                            {
                                break;
                            }
                        }
                        lastX     = x;
                        lastY     = y;
                        lastShape = pit.shape;
                    }
                }
            }
            return(null);
        }
Exemple #30
0
        private List <int> BuildPitchData(UPhoneme phoneme, UVoicePart part, UProject project)
        {
            int  leftBound  = phoneme.Parent.position + phoneme.position - project.MillisecondToTick(phoneme.preutter);
            int  rightBound = phoneme.Parent.position + phoneme.position + phoneme.Duration - project.MillisecondToTick(phoneme.tailIntrude - phoneme.tailOverlap);
            var  leftNote   = phoneme.Parent;
            var  rightNote  = phoneme.Parent;
            bool oneMore    = true;

            while ((leftBound < leftNote.RightBound || oneMore) && leftNote.Prev != null && leftNote.Prev.End == leftNote.position)
            {
                leftNote = leftNote.Prev;
                if (leftBound >= leftNote.RightBound)
                {
                    oneMore = false;
                }
            }
            oneMore = true;
            while ((rightBound > rightNote.LeftBound || oneMore) && rightNote.Next != null && rightNote.Next.position == rightNote.End)
            {
                rightNote = rightNote.Next;
                if (rightBound <= rightNote.LeftBound)
                {
                    oneMore = false;
                }
            }

            // Collect pitch curve and vibratos.
            var   points      = new List <PitchPoint>();
            var   vibratos    = new List <Tuple <double, double, UVibrato> >();
            var   note        = leftNote;
            float vel         = Velocity;
            var   strechRatio = Math.Pow(2, 1.0 - vel / 100);
            float correction  = (float)(phoneme.oto.Preutter * (strechRatio - 1));

            while (true)
            {
                var offsetMs = (float)project.TickToMillisecond(note.position - phoneme.Parent.position);
                foreach (var point in note.pitch.data)
                {
                    var newpp = point.Clone();
                    newpp.X += offsetMs + correction;
                    newpp.Y -= (phoneme.Parent.tone - note.tone) * 10;
                    points.Add(newpp);
                }
                if (note.vibrato.length != 0)
                {
                    double vibratoStartMs = project.TickToMillisecond(note.position + note.duration * (1 - note.vibrato.length / 100) - phoneme.Parent.position);
                    double vibratoEndMs   = project.TickToMillisecond(note.End - phoneme.Parent.position);
                    vibratos.Add(Tuple.Create(vibratoStartMs, vibratoEndMs, note.vibrato));
                }
                if (note == rightNote)
                {
                    break;
                }
                note = note.Next;
            }

            // Expand curve if necessary.
            float startMs = (float)(project.TickToMillisecond(phoneme.position) - phoneme.oto.Preutter);
            float endMs   = (float)(project.TickToMillisecond(phoneme.End) - phoneme.tailIntrude + phoneme.tailOverlap);

            if (points.First().X > startMs)
            {
                points.Insert(0, new PitchPoint(startMs, points.First().Y));
            }
            if (points.Last().X < endMs)
            {
                points.Add(new PitchPoint(endMs, points.Last().Y));
            }

            // Interpolation.
            var       pitches      = new List <int>();
            const int intervalTick = 5;
            float     intervalMs   = (float)project.TickToMillisecond(intervalTick);
            float     currMs       = startMs;
            int       i            = 0;
            int       vibrato      = 0;

            while (currMs < endMs)
            {
                while (points[i + 1].X < currMs)
                {
                    i++;
                }
                var pit = MusicMath.InterpolateShape(points[i].X, points[i + 1].X, points[i].Y, points[i + 1].Y, currMs, points[i].shape) * 10;
                while (vibrato < vibratos.Count - 1 && vibratos[vibrato].Item2 < currMs)
                {
                    vibrato++;
                }
                if (vibrato < vibratos.Count && vibratos[vibrato].Item1 <= currMs && currMs < vibratos[vibrato].Item2)
                {
                    pit += InterpolateVibrato(vibratos[vibrato].Item3, currMs - vibratos[vibrato].Item1, vibratos[vibrato].Item2 - vibratos[vibrato].Item1, project);
                }
                pitches.Add((int)pit);
                currMs += intervalMs;
            }

            return(pitches);
        }