Skip to content

Commit

Permalink
Merge pull request #222 from tidalcycles/negative-speed
Browse files Browse the repository at this point in the history
support negative speeds
  • Loading branch information
felixroos committed Sep 24, 2022
2 parents dbda70e + 9ebada6 commit 852f01f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
9 changes: 9 additions & 0 deletions packages/webaudio/sampler.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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];
};
Expand Down
12 changes: 8 additions & 4 deletions packages/webaudio/webaudio.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 852f01f

Please sign in to comment.