Exemplo n.º 1
0
    void Awake()
    {
        var model       = NotesEditorModel.Instance;
        var waveData    = new float[500000];
        var skipSamples = 50;
        var lineColor   = Color.green * 0.6f;
        var lines       = Enumerable.Range(0, waveData.Length / skipSamples)
                          .Select(_ => new Line(Vector3.zero, Vector3.zero, lineColor))
                          .ToArray();


        this.LateUpdateAsObservable()
        .Where(_ => model.WaveformDisplayEnabled.Value)
        .SkipWhile(_ => model.Audio.clip == null)
        .Subscribe(_ =>
        {
            model.Audio.clip.GetData(waveData, model.Audio.timeSamples);
            var x       = (model.CanvasWidth.Value / model.Audio.clip.samples) / 2f;
            var offsetX = model.CanvasOffsetX.Value;
            var offsetY = 200;

            for (int li = 0, wi = skipSamples / 2, l = waveData.Length; wi < l; li++, wi += skipSamples)
            {
                lines[li].start.x = lines[li].end.x = wi * x + offsetX;
                lines[li].end.y   = waveData[wi] * 45 - offsetY;
                lines[li].start.y = waveData[wi - skipSamples / 2] * 45 - offsetY;
            }

            GLLineRenderer.RenderLines("waveform", lines);
        });
    }
Exemplo n.º 2
0
    void Awake()
    {
        model         = NotesEditorModel.Instance;
        rectTransform = GetComponent <RectTransform>();
        rectTransform.localPosition = model.NoteToScreenPosition(notePosition);


        var image = GetComponent <Image>();

        noteType.DistinctUntilChanged()
        .Select(type => type == NoteTypes.Long)
        .Subscribe(isLongNote => image.color = isLongNote ? Color.cyan : new Color(175 / 255f, 1, 78 / 255f));


        this.UpdateAsObservable()
        .Select(_ => model.NoteToScreenPosition(notePosition))
        .DistinctUntilChanged()
        .Subscribe(pos => rectTransform.localPosition = pos);


        var mouseDownObservable = onMouseDownObservable
                                  .Where(_ => model.ClosestNotePosition.Value.Equals(notePosition));

        var editObservable = mouseDownObservable
                             .Where(editType => editType == NoteTypes.Normal)
                             .Where(editType => noteType.Value == editType)
                             .Merge(mouseDownObservable
                                    .Where(editType => editType == NoteTypes.Long));

        editObservable.Where(editType => editType == NoteTypes.Normal)
        .Subscribe(_ => model.NormalNoteObservable.OnNext(notePosition));

        editObservable.Where(editType => editType == NoteTypes.Long)
        .Subscribe(_ => model.LongNoteObservable.OnNext(notePosition));


        var longNoteLateUpdateObservable = this.LateUpdateAsObservable()
                                           .Where(_ => noteType.Value == NoteTypes.Long);

        longNoteLateUpdateObservable
        .Where(_ => next != null)
        .Select(_ => model.NoteToScreenPosition(next.notePosition))
        .Merge(longNoteLateUpdateObservable
               .Where(_ => next == null)
               .Where(_ => model.EditType.Value == NoteTypes.Long)
               .Where(_ => model.LongNoteTailPosition.Value.Equals(notePosition))
               .Select(_ => model.ScreenToCanvasPosition(Input.mousePosition)))
        .Select(nextPosition => new Line[] { new Line(model.NoteToScreenPosition(notePosition), nextPosition, 0 < nextPosition.x - model.NoteToScreenPosition(notePosition).x ? Color.cyan : Color.red) })
        .Subscribe(lines => GLLineRenderer.RenderLines(notePosition.ToString(), lines));
    }
    void LateUpdate()
    {
        if (model.Audio == null || model.Audio.clip == null)
        {
            return;
        }

        var beatNum     = model.LPB.Value * Mathf.CeilToInt(model.Audio.clip.samples / (float)model.UnitBeatSamples.Value);
        var beatSamples = Enumerable.Range(0, beatNum)
                          .Select(i => i * model.UnitBeatSamples.Value / model.LPB.Value)
                          .ToArray();


        var beatLines = beatSamples
                        .Select(x => model.SamplesToScreenPositionX(x))
                        .Select((x, i) => new Line(
                                    new Vector3(x, 140, 0),
                                    new Vector3(x, -140, 0),
                                    i % model.LPB.Value == 0 ? Color.white : Color.white / 2))
                        .ToArray();


        var blockLines = Enumerable.Range(0, 5)
                         .Select(i => model.BlockNumToScreenPositionY(i))
                         .Select(i => i + Screen.height * 0.5f)
                         .Select((y, i) => new Line(
                                     model.ScreenToCanvasPosition(new Vector3(0, y, 0)),
                                     model.ScreenToCanvasPosition(new Vector3(Screen.width, y, 0)),
                                     Color.white / 2f))
                         .ToArray();


        // Highlighting closest line to mouse pointer
        if (model.IsMouseOverCanvas.Value)
        {
            var highlightColor   = new Color(253 / 255f, 230 / 255f, 3 / 255f) * 0.8f;
            var mouseX           = model.ScreenToCanvasPosition(Input.mousePosition).x;
            var closestLineIndex = GetClosestLineIndex(beatLines, c => Mathf.Abs(c.start.x - mouseX));
            var closestBeatLine  = beatLines[closestLineIndex];

            var mouseY             = model.ScreenToCanvasPosition(Input.mousePosition).y;
            var closestBlockLindex = GetClosestLineIndex(blockLines, c => Mathf.Abs(c.start.y - mouseY));
            var closestBlockLine   = blockLines[closestBlockLindex];

            var distance = Vector2.Distance(
                new Vector2(closestBeatLine.start.x, closestBlockLine.start.y),
                new Vector2(mouseX, mouseY));

            var threshold = Mathf.Min(
                Mathf.Abs(model.BlockNumToScreenPositionY(0) - model.BlockNumToScreenPositionY(1)),
                Mathf.Abs(model.SamplesToScreenPositionX(beatSamples[0]) - model.SamplesToScreenPositionX(beatSamples[1]))) / 3f;

            if (distance < threshold)
            {
                closestBlockLine.color          = highlightColor;
                closestBeatLine.color           = highlightColor;
                model.ClosestNotePosition.Value = new NotePosition(model.BPM.Value, model.LPB.Value, closestLineIndex, closestBlockLindex);
            }
            else
            {
                model.ClosestNotePosition.Value = new NotePosition(-1, -1, -1, -1);
            }
        }

        GLLineRenderer.RenderLines("beats", beatLines);
        GLLineRenderer.RenderLines("blocks", blockLines);
    }