support negative speeds

This commit is contained in:
Felix Roos 2022-09-24 23:14:43 +02:00
parent dbda70eee9
commit 9ebada63e9
2 changed files with 17 additions and 4 deletions

View File

@ -16,6 +16,15 @@ export const loadBuffer = (url, ac) => {
return loadCache[url];
};
export function reverseBuffer(buffer) {
const ac = getAudioContext();
const reversed = ac.createBuffer(buffer.numberOfChannels, buffer.length, ac.sampleRate);
for (let channel = 0; channel < buffer.numberOfChannels; channel++) {
reversed.copyToChannel(buffer.getChannelData(channel).slice().reverse(), channel, channel);
}
return reversed;
}
export const getLoadedBuffer = (url) => {
return bufferCache[url];
};

View File

@ -8,7 +8,7 @@ This program is free software: you can redistribute it and/or modify it under th
import * as strudel from '@strudel.cycles/core';
import { fromMidi, toMidi } from '@strudel.cycles/core';
import './feedbackdelay.mjs';
import { loadBuffer } from './sampler.mjs';
import { loadBuffer, reverseBuffer } from './sampler.mjs';
const { Pattern } = strudel;
import './vowel.mjs';
import workletsUrl from './worklets.mjs?url';
@ -97,7 +97,7 @@ const getSoundfontKey = (s) => {
return;
};
const getSampleBufferSource = async (s, n, note) => {
const getSampleBufferSource = async (s, n, note, speed) => {
let transpose = 0;
let midi;
@ -137,7 +137,11 @@ const getSampleBufferSource = async (s, n, note) => {
transpose = -midiDiff(closest); // semitones to repitch
sampleUrl = bank[closest][n % bank[closest].length];
}
const buffer = await loadBuffer(sampleUrl, ac);
let buffer = await loadBuffer(sampleUrl, ac);
if (speed < 0) {
// should this be cached?
buffer = reverseBuffer(buffer);
}
const bufferSource = ac.createBufferSource();
bufferSource.buffer = buffer;
const playbackRate = 1.0 * Math.pow(2, transpose / 12);
@ -305,7 +309,7 @@ export const webaudioOutput = async (hap, deadline, hapDuration) => {
bufferSource = await globalThis.getFontBufferSource(soundfont, note || n, ac);
} else {
// is sample from loaded samples(..)
bufferSource = await getSampleBufferSource(s, n, note);
bufferSource = await getSampleBufferSource(s, n, note, speed);
}
} catch (err) {
console.warn(err);