mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-28 15:46:51 -04:00
buffers can now be repitched (still with aliasing)
This commit is contained in:
@@ -10,10 +10,10 @@ class DoughProcessor extends AudioWorkletProcessor {
|
||||
if (event.data.spawn) {
|
||||
this.dough.scheduleSpawn(event.data.spawn);
|
||||
} else if (event.data.sample) {
|
||||
this.dough.loadSample(event.data.sample, event.data.channels);
|
||||
this.dough.loadSample(event.data.sample, event.data.channels, event.data.sampleRate);
|
||||
} else if (event.data.samples) {
|
||||
event.data.samples.forEach(([name, channels]) => {
|
||||
this.dough.loadSample(name, channels);
|
||||
event.data.samples.forEach(([name, channels, sampleRate]) => {
|
||||
this.dough.loadSample(name, channels, sampleRate);
|
||||
});
|
||||
} else {
|
||||
console.log('unrecognized event type', event.data);
|
||||
|
||||
@@ -385,14 +385,16 @@ export class Distort {
|
||||
|
||||
export class BufferPlayer {
|
||||
static samples = new Map();
|
||||
channels = [];
|
||||
buffer; // { channels: Float32Array, sampleRate: number }
|
||||
pos = 0;
|
||||
sampleFreq = 261.626; // middle c
|
||||
update(freq, channel = 0) {
|
||||
if (this.pos >= this.channels[channel].length) {
|
||||
if (this.pos >= this.buffer.channels[channel].length) {
|
||||
return 0;
|
||||
}
|
||||
let s = this.channels[channel][this.pos];
|
||||
this.pos++;
|
||||
const speed = ((freq / this.sampleFreq) * this.buffer.sampleRate) / SAMPLE_RATE;
|
||||
let s = this.buffer.channels[channel][Math.floor(this.pos)];
|
||||
this.pos = this.pos + speed;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -576,7 +578,8 @@ export class DoughVoice {
|
||||
this._sound = new SourceClass();
|
||||
} else if (BufferPlayer.samples.has(this.s)) {
|
||||
this._sample = new BufferPlayer();
|
||||
this._sample.channels = BufferPlayer.samples.get(this.s);
|
||||
const buffer = BufferPlayer.samples.get(this.s);
|
||||
this._sample.buffer = buffer;
|
||||
} else {
|
||||
console.warn('sound not found', this.s);
|
||||
}
|
||||
@@ -738,7 +741,10 @@ export class DoughVoice {
|
||||
const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release);
|
||||
s = s * env;
|
||||
|
||||
s = s * this.postgain * 0.2;
|
||||
s = s * this.postgain;
|
||||
if (!this._sample) {
|
||||
s = s * 0.2; // turn down waveforms
|
||||
}
|
||||
|
||||
if (this.pan === 0.5) {
|
||||
this.l = this.r = s; // mono
|
||||
@@ -770,8 +776,8 @@ export class Dough {
|
||||
this._delayL = new Delay();
|
||||
this._delayR = new Delay();
|
||||
}
|
||||
loadSample(name, channels) {
|
||||
BufferPlayer.samples.set(name, channels);
|
||||
loadSample(name, channels, sampleRate) {
|
||||
BufferPlayer.samples.set(name, { channels, sampleRate });
|
||||
}
|
||||
scheduleSpawn(value) {
|
||||
if (value._begin === undefined) {
|
||||
|
||||
@@ -118,7 +118,7 @@ let samples = {
|
||||
'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/7.wav',
|
||||
'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/8.wav',
|
||||
],
|
||||
piano: ['https://raw.githubusercontent.com/felixroos/dough-samples/refs/heads/main/piano/A3v8.mp3'],
|
||||
piano: ['https://raw.githubusercontent.com/felixroos/dough-samples/refs/heads/main/piano/C3v8.mp3'],
|
||||
flute: ['https://raw.githubusercontent.com/felixroos/samples/refs/heads/main/flute/c4.mp3'],
|
||||
bd: [
|
||||
'https://raw.githubusercontent.com/geikha/tidal-drum-machines/15eac73c5e878550f91d864a4863e014799403f1/machines/RolandTR909/rolandtr909-bd/Bassdrum-01.wav',
|
||||
@@ -126,7 +126,7 @@ let samples = {
|
||||
};
|
||||
// for some reason, only piano and flute work.. is it because mp3??
|
||||
|
||||
async function loadSampleChannels(url) {
|
||||
async function loadSampleChannels(key, url) {
|
||||
const buffer = await fetch(url)
|
||||
.then((res) => res.arrayBuffer())
|
||||
.then((buf) => getAudioContext().decodeAudioData(buf));
|
||||
@@ -134,7 +134,7 @@ async function loadSampleChannels(url) {
|
||||
for (let i = 0; i < buffer.numberOfChannels; i++) {
|
||||
channels.push(buffer.getChannelData(i));
|
||||
}
|
||||
return channels;
|
||||
return [key, channels, buffer.sampleRate];
|
||||
}
|
||||
|
||||
let loaded = false;
|
||||
@@ -147,9 +147,7 @@ export async function doughsample() {
|
||||
const sampleMap = await Promise.all(
|
||||
Object.entries(samples).map(async ([key, url]) => {
|
||||
url = url[0];
|
||||
const channels = await loadSampleChannels(url);
|
||||
// console.log(key, 'url', url, channels);
|
||||
return [key, channels];
|
||||
return loadSampleChannels(key, url);
|
||||
}),
|
||||
);
|
||||
console.log('sampleMap', sampleMap);
|
||||
|
||||
Reference in New Issue
Block a user