0

我正在尝试在我的 React 应用程序中使用 Tone.js 创建一个简单的节拍器。但我听不到任何声音。我究竟做错了什么?

练习.ts

import React, { useRef, useEffect, useState } from 'react'
import { exercises } from 'data/exercises.json'
import { Typography, Grid, Button } from '@material-ui/core'
import { useParams } from 'react-router-dom'
import { Sampler, Loop, Part, Transport } from 'tone'

let part: Part
let loop: Loop

export default function ExercisePage() {
  const [isLoaded, setIsLoaded] = useState(false)

  // find exercise
  let { id } = useParams()
  let exercise = exercises.find(e => e.id === id)

  const sampler = useRef<Sampler | null>(null)

  useEffect(() => {
    sampler.current = new Sampler(
      { A1: 'click_hi.ogg', B1: 'click_lo.ogg' },
      () => {
        setIsLoaded(true)
      },
      `${process.env.PUBLIC_URL}/audio/`
    ).toMaster()

    part = new Part(
      (time, note) => {
        // @ts-ignore
        sampler.current.triggerAttack(note.note, note.time, time, note.velocity)
      },
      [
        { time: '4n', note: 'A1', velocity: 1 },
        { time: '4n', note: 'B1', velocity: 0.5 },
        { time: '4n', note: 'B1', velocity: 0.5 },
        { time: '4n', note: 'B1', velocity: 0.5 },
      ]
    )

    loop = new Loop(() => {
      part.start(0)
    }, '1m')

    Transport.start()
  }, [])

  const startLoop = () => {
    loop.start(0)
  }

  return (
    <Grid container direction="column">
      <Grid item>
        <Typography variant="h4">Exercise: {id}</Typography>
        <Button
          variant="contained"
          color="secondary"
          onClick={() => startLoop()}
        >
          Start
        </Button>
      </Grid>
    </Grid>
  )
}
4

1 回答 1

0

将 Transport.start() 移动到 startLoop 函数

const startLoop = () => {
    Transport.start()
    loop.start(0)
}
于 2020-04-07T06:44:24.007 回答