Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start time must be strictly greater #1256

Open
handeyeco opened this issue Jun 12, 2024 · 0 comments
Open

Start time must be strictly greater #1256

handeyeco opened this issue Jun 12, 2024 · 0 comments

Comments

@handeyeco
Copy link

Describe the bug

ToneJS keeps crashing:

Uncaught Error: Start time must be strictly greater than previous start time

When I log, Tone.now() is the same thing even when 30+ milliseconds have passed.

To Reproduce

This example crashes for me intermittently (code below): https://glitch.com/edit/#!/married-lean-castanet?path=src%2Fapp.jsx%3A59%3A8

Seems to be most consistent after doing a full page refresh. It also seems to be more of a problem that faster I run through the graph.

Expected behavior
ToneJS shouldn't crash, it should just keep on truckin'. It also shouldn't have the same value when running Tone.now() several milliseconds apart, but I could be wrong about that.

What I've tried
I have a workaround:

      try {
        const y = yFromX(playheadPosition);
        const freq = map(y, -10, 10, 200, 1000);
        synth.triggerAttackRelease(freq, 0.1);
      } catch (err) {}

Just drop the error and keep going.

Additional context

import { Mafs, Coordinates, Line, Theme, vec } from "mafs";
import { useState, useEffect } from "react";
import * as Tone from "tone";
import "mafs/core.css";

// min: inclusive
// max: exclusive
function getRandomInt(min, max) {
  const minCeiled = Math.ceil(min);
  const maxFloored = Math.floor(max);
  return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled);
}

function map(
  n,
  start1,
  stop1,
  start2,
  stop2
) {
  return ((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
}

const point1 = [getRandomInt(-9, 0), getRandomInt(-9, 0)];
const point2 = [getRandomInt(1, 10), getRandomInt(1, 10)];

function yFromX(x) {
  const gradient = (point2[1] - point1[1]) / (point2[0] - point1[0]);
  const intercept = point1[1] - gradient * point1[0];
  return gradient * x + intercept;
}

const synth = new Tone.Synth().toDestination();

export default function LineChart() {
  const [playheadPosition, setPlayheadPosition] = useState(-10);
  const [playing, setPlaying] = useState(false);

  useEffect(() => {
    if (!playing) {
      return;
    }

    if (playheadPosition > 10) {
      setPlaying(false);
      return;
    }

    if (playheadPosition > point1[0] && playheadPosition < point2[0]) {
      const y = yFromX(playheadPosition);
      const now = Tone.now();
      const freq = map(y, -10, 10, 200, 1000);
      synth.triggerAttack(freq, now);
      synth.triggerRelease(now + 0.001);
    }

    setTimeout(() => {
      setPlayheadPosition((prev) => prev + 0.1);
    }, 10);
  }, [playheadPosition, playing]);

  function handlePressPlay() {
    setPlayheadPosition(-10);
    setPlaying(true);
  }

  return (
    <>
      <Mafs
        preserveAspectRatio={false}
        viewBox={{
          x: [-10, 10],
          y: [-10, 10],
          padding: 0,
        }}
        width={600}
        height={600}
      >
        <Coordinates.Cartesian />
        <Line.Segment point1={point1} point2={point2} color={Theme.blue} />
        {playing && (
          <Line.Segment
            point1={[playheadPosition, -10]}
            point2={[playheadPosition, 10]}
            color={Theme.red}
          />
        )}
      </Mafs>
      <button onClick={handlePressPlay} disabled={playing}>
        Play
      </button>
    </>
  );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant