mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-22 02:58:32 +00:00
Merge pull request #222 from tidalcycles/negative-speed
support negative speeds
This commit is contained in:
commit
852f01fddd
@ -16,6 +16,15 @@ export const loadBuffer = (url, ac) => {
|
|||||||
return loadCache[url];
|
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) => {
|
export const getLoadedBuffer = (url) => {
|
||||||
return bufferCache[url];
|
return bufferCache[url];
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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 * as strudel from '@strudel.cycles/core';
|
||||||
import { fromMidi, toMidi } from '@strudel.cycles/core';
|
import { fromMidi, toMidi } from '@strudel.cycles/core';
|
||||||
import './feedbackdelay.mjs';
|
import './feedbackdelay.mjs';
|
||||||
import { loadBuffer } from './sampler.mjs';
|
import { loadBuffer, reverseBuffer } from './sampler.mjs';
|
||||||
const { Pattern } = strudel;
|
const { Pattern } = strudel;
|
||||||
import './vowel.mjs';
|
import './vowel.mjs';
|
||||||
import workletsUrl from './worklets.mjs?url';
|
import workletsUrl from './worklets.mjs?url';
|
||||||
@ -97,7 +97,7 @@ const getSoundfontKey = (s) => {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSampleBufferSource = async (s, n, note) => {
|
const getSampleBufferSource = async (s, n, note, speed) => {
|
||||||
let transpose = 0;
|
let transpose = 0;
|
||||||
let midi;
|
let midi;
|
||||||
|
|
||||||
@ -137,7 +137,11 @@ const getSampleBufferSource = async (s, n, note) => {
|
|||||||
transpose = -midiDiff(closest); // semitones to repitch
|
transpose = -midiDiff(closest); // semitones to repitch
|
||||||
sampleUrl = bank[closest][n % bank[closest].length];
|
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();
|
const bufferSource = ac.createBufferSource();
|
||||||
bufferSource.buffer = buffer;
|
bufferSource.buffer = buffer;
|
||||||
const playbackRate = 1.0 * Math.pow(2, transpose / 12);
|
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);
|
bufferSource = await globalThis.getFontBufferSource(soundfont, note || n, ac);
|
||||||
} else {
|
} else {
|
||||||
// is sample from loaded samples(..)
|
// is sample from loaded samples(..)
|
||||||
bufferSource = await getSampleBufferSource(s, n, note);
|
bufferSource = await getSampleBufferSource(s, n, note, speed);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(err);
|
console.warn(err);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user