import Tone from 'tone' import { choice, clamp } from './util' import spectrum from './spectrum' const player_count = 1 export default class Sampler { constructor(path, count){ this.samples = (() => { let s = '', a = [] for (let i = 1; i < count; i++) { s = i < 10 ? '0' + i : i; a.push({ root: 100, fn: path.replace(/{}/, s) }) } return a })() this.length = this.samples.length this.samples.forEach((sample) => { sample.players = [] sample.index = -1 for (let i = 0; i < player_count; i++) { let fn = sample.fn if (window.location.href.match(/asdf.us/)) { fn = '//asdf.us/glass/' + fn.replace('wav','mp3') } let player = new Tone.Player({ url: fn, retrigger: true, playbackRate: 1, }) sample.players.push(player) } }) } choice(){ return choice(this.samples) } play(freq, time, output) { const { player, best } = this.getPlayer() freq = freq || best.root player.playbackRate = freq / best.root time = time || Tone.now() if (player.loaded) { player.stop() player.disconnect() player.connect(output) player.start(time) } else { // console.log('loading') } return player } getRandomPlayer(){ const best = this.choice() best.index = (best.index + 1) % player_count const player = best.players[ best.index ] return { player, best } } getPlayer(n){ n = n || 0 if (n < 1) n *= this.samples.length const best = this.samples[clamp(n|0, 0, this.samples.length-1)] best.index = (best.index + 1) % player_count const player = best.players[ best.index ] return { player, best } } getWaveAndSpectrum(n){ const { player } = this.getPlayer(n) const buf = player._buffer.get() if (! buf) return { pcm: null, spec: null } const pcm = buf.getChannelData(0) if (! player._spectrum) { const sr = buf.sampleRate player._spectrum = spectrum.toSpectrum(pcm, sr) } return { pcm: pcm, spec: player._spectrum, } } }