Skip to content

Commit

Permalink
Merge pull request #654 from hyoo-ru/audio-node
Browse files Browse the repository at this point in the history
$mol_audio refactor, added sample and instrument nodes, isomorphic context
  • Loading branch information
zerkalica authored Dec 30, 2023
2 parents e5b8da5 + fc89ecd commit ae5310c
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 94 deletions.
9 changes: 9 additions & 0 deletions audio/context/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace $ {
export class $mol_audio_context extends $mol_object2 {
@ $mol_memo.method
static context() {
const AudioContext = this.$.$mol_dom_context.AudioContext || this.$.$node['web-audio-api'].AudioContext
return new AudioContext()
}
}
}
4 changes: 2 additions & 2 deletions audio/demo/demo.web.view.tree → audio/demo/demo.view.tree
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ $mol_audio_demo $mol_example_small
title \WebAudio API example
Beep $mol_audio_room
play => beep_play
duration 100
duration 0.1
input /
<= Beep_vibe $mol_audio_vibe
freq 440
Noise $mol_audio_room
play => noise_play
duration 1000
duration 1
input /
<= Noise_vibe $mol_audio_vibe
freq <= noise_freq 440
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ $mol_audio_demo_vibe $mol_example_small
sub /
<= List $mol_list rows /
<= Duration $mol_labeler
title <= duration_label \Duration, ms
title <= duration_label \Duration, s
content /
<= Duration_num $mol_number
precision_change 50
value? <=> duration? 500
precision_change 0.05
value? <=> duration? 0.5
<= Frequency $mol_labeler
title <= frequency_label \Frequency, Hz
content /
Expand All @@ -28,7 +28,7 @@ $mol_audio_demo_vibe $mol_example_small
Filter null
value? <=> shape? null
options /$mol_audio_vibe_shape
\sine
\sine
\square
\sawtooth
\triangle
Expand Down
File renamed without changes.
20 changes: 20 additions & 0 deletions audio/gain/gain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace $ {

export class $mol_audio_gain extends $mol_audio_node {

@ $mol_mem
override node_raw() { return this.context().createGain() }

@ $mol_mem
override node() {
const node = super.node()
node.gain.setValueAtTime( this.gain(), this.time() )
return node
}

@ $mol_mem
gain( next = 1 ) { return next }

}

}
19 changes: 0 additions & 19 deletions audio/gain/gain.web.ts

This file was deleted.

59 changes: 59 additions & 0 deletions audio/instrument/instrument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
namespace $ {
export class $mol_audio_instrument extends $mol_audio_node {
override node_raw(): AudioScheduledSourceNode {
throw new Error('implement')
}

@ $mol_mem
override node() {
const node = super.node()
node.onended = $mol_wire_async((e: Event) => this.end(e))

return node
}

protected promise = $mol_promise<void>()

@ $mol_mem
wait() {
return this.promise
}

end(e: Event) {
this.active( false )
}

@ $mol_mem
active( next?: boolean ): boolean {

$mol_wire_solid()

const node = next === false ? this.node_raw() : this.node()

const prev = $mol_wire_probe( ()=> this.active() )
if( prev === next ) return next ?? false

if( next === true ) {
node.start()
} else if( prev === true ) {
node.stop()
this.promise.done()
this.promise = $mol_promise()
}

return next ?? false
}

override destructor() {
this.active( false )
super.destructor()
}

@ $mol_mem
override output() {
this.active( true )
return super.output()
}

}
}
27 changes: 18 additions & 9 deletions audio/node/node.web.ts → audio/node/node.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
namespace $ {
export class $mol_audio_node extends $mol_object2 {
context() { return this.$.$mol_audio_context.context() }

@ $mol_memo.method
static context() {
return new AudioContext
@ $mol_mem
node_raw() { return this.context().destination as AudioNode }

node() {
return this.node_raw() as ReturnType<this['node_raw']>
}

@ $mol_mem
node() { return $mol_audio_node.context().destination as AudioNode }
duration() {
let duration = 0
for (const input of this.input_connected()) duration = Math.max(duration, input.duration())

return duration
}


@ $mol_mem
input( next = [] as readonly $mol_audio_node[] ) { return next }

@ $mol_mem
input_connected() {

const node = this.node()
const node = this.node_raw()

const prev = $mol_mem_cached( ()=> this.input_connected() ) ?? []
const next = this.input()
Expand All @@ -35,14 +44,14 @@ namespace $ {
@ $mol_mem
output() {
this.input_connected()
return this.node()
return this.node_raw()
}

time() { return $mol_audio_node.context().currentTime }
time() { return this.context().currentTime }

destructor() {

const node = this.node()
const node = this.node_raw()

for( const src of this.input() ) {
src.output().disconnect( node )
Expand Down
6 changes: 1 addition & 5 deletions audio/room/room.web.ts → audio/room/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@ namespace $ {
*/
export class $mol_audio_room extends $mol_audio_node {

duration() {
return 1000
}

@ $mol_action
play() {
this.output()
this.$.$mol_wait_timeout( this.duration() )
this.$.$mol_wait_timeout( this.duration() * 1000 )
}

}
Expand Down
28 changes: 28 additions & 0 deletions audio/sample/sample.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace $ {
export class $mol_audio_sample extends $mol_audio_instrument {
@ $mol_mem
override node_raw() { return this.context().createBufferSource() }

override duration() {
return this.audio_buffer().duration
}

buffer() {
return new ArrayBuffer(0)
}

@ $mol_mem
audio_buffer() {
return $mol_wire_sync(this.context()).decodeAudioData(this.buffer())
}

@ $mol_mem
override node() {
const node = super.node()
node.buffer = this.audio_buffer()

return node
}

}
}
38 changes: 38 additions & 0 deletions audio/vibe/vibe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace $ {

export type $mol_audio_vibe_shape =
| 'sine'
| 'square'
| 'sawtooth'
| 'triangle'
| 'custom'

/**
* @see https://mol.hyoo.ru/#!section=demos/demo=mol_audio_demo_vibe
*/
export class $mol_audio_vibe extends $mol_audio_instrument {

@ $mol_mem
override node_raw() { return this.context().createOscillator() }

@ $mol_mem
freq( next = 440 ) { return next }

@ $mol_mem
shape( next: $mol_audio_vibe_shape = 'sine' ) { return next }

override duration() {
return 0.5
}

@ $mol_mem
override node() {
const node = super.node()
node.frequency.setValueAtTime( this.freq(), this.time() )
node.type = this.shape()

return node
}

}
}
55 changes: 0 additions & 55 deletions audio/vibe/vibe.web.ts

This file was deleted.

0 comments on commit ae5310c

Please sign in to comment.