Skip to content

Commit 3b18bdd

Browse files
committed
refactor(synth): Signal.toggle
1 parent ea8b5ab commit 3b18bdd

5 files changed

Lines changed: 222 additions & 116 deletions

File tree

packages/synth/src/node/constant/constant-synth-node.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export class ConstantSynthNode extends SynthNode {
1919
automate: { param: constantSource.offset },
2020
})
2121

22-
constantSource.start()
22+
synth.playing.toggle(
23+
this.disposed,
24+
() => constantSource.start(),
25+
() => constantSource.stop(),
26+
)
2327
}
2428
}

packages/synth/src/node/generator/generator-synth-node.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -125,23 +125,30 @@ export class GeneratorSynthNode extends SynthNode {
125125
updateWaveShape()
126126
this.waveShape.changed.watch(updateWaveShape)
127127

128-
oscillator.start()
129-
this.disposed.watch(() => oscillator.stop())
128+
synth.playing.toggle(
129+
this.disposed,
130+
() => oscillator.start(),
131+
() => oscillator.stop(),
132+
)
130133

131134
return { frequency, adsr }
132135
})
133136

134-
const mute = () => {
135-
master.gain.value = 0
136-
}
137-
138-
const unmute = () => {
139-
master.gain.value = DEFAULT_SOURCE_GAIN
140-
}
141-
142-
mute()
143-
this.synth.playing.watchUntil(this.disposed, unmute)
144-
this.synth.stopped.watchUntil(this.disposed, mute)
137+
// this.synth.playing.watch(() => console.log('playing'))
138+
// this.synth.stopped.watch(() => console.log('stopped'))
139+
140+
master.gain.value = 0
141+
this.synth.playing.toggle(
142+
this.synth.stopped,
143+
() => {
144+
// console.log('master on')
145+
master.gain.value = DEFAULT_SOURCE_GAIN
146+
},
147+
() => {
148+
// console.log('master off')
149+
master.gain.value = 0
150+
},
151+
)
145152
}
146153

147154
attackAt(time: Time, frequency: Hertz) {

packages/synth/src/node/oscillator/oscillator-synth-node.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ export class OscillatorSynthNode extends SynthNode {
2222
oscillator.connect(merger, 0, 1)
2323
merger.connect(master)
2424

25-
oscillator.start()
26-
2725
super({ synth, inputs: [], outputs: [master] })
2826

2927
this.waveShape = new EnumSynthParam({
@@ -46,19 +44,21 @@ export class OscillatorSynthNode extends SynthNode {
4644
automate: { param: oscillator.frequency },
4745
})
4846

49-
const unmuteOscillator = () => {
50-
master.gain.value = DEFAULT_SOURCE_GAIN
51-
}
52-
53-
const muteOscillator = () => {
54-
master.gain.value = 0
55-
}
56-
57-
muteOscillator()
58-
59-
this.synth.playing.watchUntil(this.disposed, unmuteOscillator)
60-
this.synth.stopped.watchUntil(this.disposed, muteOscillator)
61-
62-
this.disposed.watch(() => oscillator.stop())
47+
synth.playing.toggle(
48+
this.disposed,
49+
() => oscillator.start(),
50+
() => oscillator.stop(),
51+
)
52+
53+
master.gain.value = 0
54+
synth.playing.toggle(
55+
synth.stopped,
56+
() => {
57+
master.gain.value = DEFAULT_SOURCE_GAIN
58+
},
59+
() => {
60+
master.gain.value = 0
61+
},
62+
)
6363
}
6464
}

packages/synth/src/signal/signal.ts

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,67 +30,88 @@ export class Signal<TParam> {
3030
}
3131
}
3232

33-
static combine<TParam>(signals: Signal<TParam>[]): Signal<TParam> {
34-
const { signal, emit } = Signal.controlled<TParam>()
35-
36-
for (const parentSignal of signals) {
37-
parentSignal.watch(emit)
38-
}
39-
40-
return signal
41-
}
42-
4333
get emitted() {
4434
return this.#emitted
4535
}
4636

37+
get watched() {
38+
return this.#listeners.length > 0
39+
}
40+
4741
watch(listener: (param: TParam) => void) {
48-
if (this.#once && this.#emitted) {
49-
return
42+
if (this.#active) {
43+
this.#listeners.push(listener)
5044
}
45+
}
5146

52-
this.#listeners.push(listener)
47+
cancel(listener: (param: TParam) => void) {
48+
const index = this.#listeners.indexOf(listener)
49+
if (index >= 0) {
50+
this.#listeners.splice(index, 1)
51+
}
5352
}
5453

5554
watchUntil(cancelSignal: Signal<any>, listener: (param: TParam) => void) {
56-
if ((cancelSignal.#once && cancelSignal.#emitted) || (this.#once && this.#emitted)) {
55+
if (!this.#active || !cancelSignal.#active) {
5756
return
5857
}
5958

59+
const cancel = () => {
60+
this.cancel(listener)
61+
cancelSignal.cancel(cancel)
62+
}
63+
6064
this.watch(listener)
61-
cancelSignal.watch(() => this.cancel(listener))
65+
cancelSignal.watch(cancel)
6266
}
6367

64-
chain(signal: SignalController<TParam>) {
65-
this.watch(param => signal.emit(param))
66-
}
68+
toggle<TUndoParam>(
69+
undoSignal: Signal<TUndoParam>,
70+
applyListener: (param: TParam) => void,
71+
undoListener: (param: TUndoParam) => void,
72+
) {
73+
if (!this.#active || !undoSignal.#active) {
74+
return
75+
}
6776

68-
cancel(listener: (param: TParam) => void) {
69-
const index = this.#listeners.indexOf(listener)
70-
if (index >= 0) {
71-
this.#listeners.splice(index, 1)
77+
const apply = (param: TParam) => {
78+
this.cancel(apply)
79+
if (undoSignal.#active) {
80+
applyListener(param)
81+
undoSignal.watch(undo)
82+
}
83+
}
84+
85+
const undo = (param: TUndoParam) => {
86+
undoSignal.cancel(undo)
87+
undoListener(param)
88+
if (this.#active) {
89+
this.watch(apply)
90+
}
7291
}
92+
93+
this.watch(apply)
94+
}
95+
96+
get #active() {
97+
return !(this.#once && this.#emitted)
7398
}
7499

75100
#cancelAll() {
76101
this.#listeners.length = 0
77102
}
78103

79104
#emit(param: TParam) {
80-
if (this.#once && this.#emitted) {
105+
if (!this.#active) {
81106
return
82107
}
83108

84109
this.#emitted = true
85110

86-
if (this.#reverseOrder) {
87-
for (let index = this.#listeners.length - 1; index >= 0; index--) {
88-
this.#listeners[index]?.(param)
89-
}
90-
} else {
91-
for (const listener of this.#listeners) {
92-
listener(param)
93-
}
111+
const listeners = this.#reverseOrder ? this.#listeners.toReversed() : this.#listeners.slice()
112+
113+
for (const listener of listeners) {
114+
listener(param)
94115
}
95116

96117
if (this.#once) {

0 commit comments

Comments
 (0)