@hlysine/piano
Version:
Web Audio instrument using Salamander Grand Piano samples
57 lines (43 loc) • 1.2 kB
text/typescript
import { Sampler, ToneAudioNode } from 'tone'
import { PianoComponentOptions, UrlsMap } from './Component'
import { getNotesUrl } from './Salamander'
interface PianoStringOptions extends PianoComponentOptions {
notes: number[]
velocity: number
}
/**
* A single velocity of strings
*/
export class PianoString extends ToneAudioNode {
readonly name = 'PianoString'
private _sampler: Sampler
output: Sampler
input: undefined
private _urls: UrlsMap = {}
readonly samples: string
constructor(options: PianoStringOptions) {
super(options)
// create the urls
options.notes.forEach(note => this._urls[note] = getNotesUrl(note, options.velocity))
this.samples = options.samples
}
load(): Promise<void> {
return new Promise(onload => {
this._sampler = this.output = new Sampler({
attack: 0,
baseUrl: this.samples,
curve: 'exponential',
onload,
release: 0.4,
urls: this._urls,
volume: 3,
})
})
}
triggerAttack(note: string | number, time: number, velocity: number): void {
this._sampler.triggerAttack(note, time, velocity)
}
triggerRelease(note: string | number, time: number): void {
this._sampler.triggerRelease(note, time)
}
}