@hlysine/piano
Version:
Web Audio instrument using Salamander Grand Piano samples
77 lines (61 loc) • 1.52 kB
text/typescript
import { Param, ToneAudioNode, Unit, Volume } from 'tone'
type ToneAudioNodeOptions = import('tone/build/esm/core/context/ToneAudioNode').ToneAudioNodeOptions
export interface PianoComponentOptions extends ToneAudioNodeOptions {
volume: Unit.Decibels
enabled: boolean
samples: string
}
export interface UrlsMap {
[note: string]: string
}
/**
* Base class for the other components
*/
export abstract class PianoComponent extends ToneAudioNode {
readonly name = 'PianoComponent'
readonly input = undefined
readonly output = new Volume({ context: this.context })
/**
* If the component is enabled or not
*/
protected _enabled: boolean = false
/**
* The volume output of the component
*/
readonly volume: Param<"decibels"> = this.output.volume
/**
* Boolean indication of if the component is loaded or not
*/
private _loaded: boolean = false
/**
* The directory to load the Salamander samples out of
*/
readonly samples: string
constructor(options: PianoComponentOptions) {
super(options)
this.volume.value = options.volume
this._enabled = options.enabled
this.samples = options.samples
}
/**
* Load the component internally
*/
protected abstract _internalLoad(): Promise<void>
/**
* If the samples are loaded or not
*/
get loaded(): boolean {
return this._loaded
}
/**
* Load the samples
*/
async load(): Promise<void> {
if (this._enabled) {
await this._internalLoad()
this._loaded = true
} else {
return Promise.resolve()
}
}
}