|
1 | 1 | import * as Tone from 'tone' |
2 | | -import { useRef } from 'react' |
| 2 | +import { useRef, useState, useEffect } from 'react' |
3 | 3 | import { LIMITS } from '../components/controller/Envelope/constants' |
4 | 4 | import type { EnvelopeData, EnvelopeLimits } from '../components/controller/Envelope' |
5 | 5 |
|
6 | 6 | export interface UseEnvelopeProps { |
7 | 7 | data: EnvelopeData |
8 | 8 | limits?: EnvelopeLimits |
9 | | - setData?: (data: EnvelopeData) => void |
10 | 9 | } |
11 | 10 |
|
12 | 11 | export const useEnvelope = (props: UseEnvelopeProps) => { |
13 | | - const { data, limits = LIMITS, setData } = props |
| 12 | + const { data: _data, limits = LIMITS } = props |
14 | 13 |
|
| 14 | + const [data, setData] = useState({ ..._data }) |
15 | 15 | const envelope = useRef<Tone.Envelope | null>(null) |
16 | 16 |
|
17 | | - const init = () => { |
18 | | - envelope.current = new Tone.Envelope() |
19 | | - |
20 | | - return () => {} |
21 | | - } |
| 17 | + const [delay, setDelay] = useState(_data.delay) |
| 18 | + const [attack, setAttack] = useState(_data.attack) |
| 19 | + const [hold, setHold] = useState(_data.hold) |
| 20 | + const [decay, setDecay] = useState(_data.decay) |
| 21 | + const [sustain, setSustain] = useState(_data.sustain) |
| 22 | + const [release, setRelease] = useState(_data.release) |
22 | 23 |
|
23 | | - const setAttack = (value: number) => { |
24 | | - if (setData) { |
25 | | - setData({ ...data, attack: value }) |
26 | | - } |
27 | | - } |
| 24 | + useEffect(() => { |
| 25 | + if (!envelope.current) return |
28 | 26 |
|
29 | | - const setDecay = (value: number) => { |
30 | | - if (setData) { |
31 | | - setData({ ...data, decay: value }) |
32 | | - } |
33 | | - } |
| 27 | + envelope.current.attack = attack |
| 28 | + envelope.current.decay = decay |
| 29 | + envelope.current.sustain = sustain |
| 30 | + envelope.current.release = release |
| 31 | + setData({ attack, decay, sustain, release }) |
34 | 32 |
|
35 | | - const setDelay = (value: number) => { |
36 | | - if (setData) { |
37 | | - setData({ ...data, delay: value }) |
38 | | - } |
39 | | - } |
| 33 | + if (_data.delay !== undefined) { |
| 34 | + envelope.current.triggerAttack(`+${delay || 0}`) |
| 35 | + setData({ delay, attack, decay, sustain, release }) |
40 | 36 |
|
41 | | - const setHold = (value: number) => { |
42 | | - if (setData) { |
43 | | - setData({ ...data, hold: value }) |
| 37 | + if (_data.hold !== undefined) { |
| 38 | + envelope.current.triggerRelease(`+${delay! + attack + hold! + decay}}`) |
| 39 | + setData({ delay, attack, decay, hold, sustain, release }) |
| 40 | + } |
44 | 41 | } |
45 | | - } |
| 42 | + }, [delay, attack, hold, decay, sustain, release]) |
46 | 43 |
|
47 | | - const setRelease = (value: number) => { |
48 | | - if (setData) { |
49 | | - setData({ ...data, release: value }) |
50 | | - } |
| 44 | + const init = () => { |
| 45 | + envelope.current = new Tone.AmplitudeEnvelope({ |
| 46 | + attack: data.attack, |
| 47 | + decay: data.decay, |
| 48 | + sustain: data.sustain, |
| 49 | + release: data.release, |
| 50 | + }) |
51 | 51 | } |
52 | 52 |
|
53 | 53 | return { |
54 | | - envelope: envelope.current, |
| 54 | + init, |
55 | 55 | data, |
| 56 | + envelope, |
56 | 57 | limits, |
57 | | - init, |
58 | 58 | setAttack, |
59 | 59 | setDecay, |
| 60 | + setSustain, |
| 61 | + setRelease, |
60 | 62 | setDelay, |
61 | 63 | setHold, |
62 | | - setRelease, |
63 | 64 | } |
64 | 65 | } |
0 commit comments