Merge branch 'main' into envelope_improvements
This commit is contained in:
commit
a800b32529
79 changed files with 4033 additions and 4306 deletions
|
|
@ -33,9 +33,9 @@
|
|||
},
|
||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||
"devDependencies": {
|
||||
"vite": "^4.3.3"
|
||||
"vite": "^5.0.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"nanostores": "^0.8.1"
|
||||
"nanostores": "^0.9.5"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { noteToMidi, valueToMidi, nanFallback } from './util.mjs';
|
||||
import { noteToMidi, valueToMidi, getSoundIndex } from './util.mjs';
|
||||
import { getAudioContext, registerSound } from './index.mjs';
|
||||
import { getADSRValues, getEnvelope } from './helpers.mjs';
|
||||
import { logger } from './logger.mjs';
|
||||
|
|
@ -31,10 +31,12 @@ export const getSampleBufferSource = async (s, n, note, speed, freq, bank, resol
|
|||
transpose = midi - 36; // C3 is middle C
|
||||
|
||||
const ac = getAudioContext();
|
||||
|
||||
let sampleUrl;
|
||||
let index = 0;
|
||||
if (Array.isArray(bank)) {
|
||||
n = nanFallback(n, 0);
|
||||
sampleUrl = bank[n % bank.length];
|
||||
index = getSoundIndex(n, bank.length);
|
||||
sampleUrl = bank[index];
|
||||
} else {
|
||||
const midiDiff = (noteA) => noteToMidi(noteA) - midi;
|
||||
// object format will expect keys as notes
|
||||
|
|
@ -45,12 +47,13 @@ export const getSampleBufferSource = async (s, n, note, speed, freq, bank, resol
|
|||
null,
|
||||
);
|
||||
transpose = -midiDiff(closest); // semitones to repitch
|
||||
sampleUrl = bank[closest][n % bank[closest].length];
|
||||
index = getSoundIndex(n, bank[closest].length);
|
||||
sampleUrl = bank[closest][index];
|
||||
}
|
||||
if (resolveUrl) {
|
||||
sampleUrl = await resolveUrl(sampleUrl);
|
||||
}
|
||||
let buffer = await loadBuffer(sampleUrl, ac, s, n);
|
||||
let buffer = await loadBuffer(sampleUrl, ac, s, index);
|
||||
if (speed < 0) {
|
||||
// should this be cached?
|
||||
buffer = reverseBuffer(buffer);
|
||||
|
|
|
|||
|
|
@ -28,11 +28,13 @@ export const resetLoadedSounds = () => soundMap.set({});
|
|||
|
||||
let audioContext;
|
||||
|
||||
export const setDefaultAudioContext = () => {
|
||||
audioContext = new AudioContext();
|
||||
};
|
||||
|
||||
export const getAudioContext = () => {
|
||||
if (!audioContext) {
|
||||
audioContext = new AudioContext();
|
||||
const maxChannelCount = audioContext.destination.maxChannelCount;
|
||||
audioContext.destination.channelCount = maxChannelCount;
|
||||
setDefaultAudioContext();
|
||||
}
|
||||
return audioContext;
|
||||
};
|
||||
|
|
@ -84,15 +86,22 @@ let delays = {};
|
|||
const maxfeedback = 0.98;
|
||||
|
||||
let channelMerger, destinationGain;
|
||||
//update the output channel configuration to match user's audio device
|
||||
export function initializeAudioOutput() {
|
||||
const audioContext = getAudioContext();
|
||||
const maxChannelCount = audioContext.destination.maxChannelCount;
|
||||
audioContext.destination.channelCount = maxChannelCount;
|
||||
channelMerger = new ChannelMergerNode(audioContext, { numberOfInputs: audioContext.destination.channelCount });
|
||||
destinationGain = new GainNode(audioContext);
|
||||
channelMerger.connect(destinationGain);
|
||||
destinationGain.connect(audioContext.destination);
|
||||
}
|
||||
|
||||
// input: AudioNode, channels: ?Array<int>
|
||||
export const connectToDestination = (input, channels = [0, 1]) => {
|
||||
const ctx = getAudioContext();
|
||||
if (channelMerger == null) {
|
||||
channelMerger = new ChannelMergerNode(ctx, { numberOfInputs: ctx.destination.channelCount });
|
||||
destinationGain = new GainNode(ctx);
|
||||
channelMerger.connect(destinationGain);
|
||||
destinationGain.connect(ctx.destination);
|
||||
initializeAudioOutput();
|
||||
}
|
||||
//This upmix can be removed if correct channel counts are set throughout the app,
|
||||
// and then strudel could theoretically support surround sound audio files
|
||||
|
|
@ -114,6 +123,7 @@ export const panic = () => {
|
|||
}
|
||||
destinationGain.gain.linearRampToValueAtTime(0, getAudioContext().currentTime + 0.01);
|
||||
destinationGain = null;
|
||||
channelMerger == null;
|
||||
};
|
||||
|
||||
function getDelay(orbit, delaytime, delayfeedback, t) {
|
||||
|
|
|
|||
|
|
@ -61,3 +61,10 @@ export function nanFallback(value, fallback) {
|
|||
}
|
||||
return value;
|
||||
}
|
||||
// modulo that works with negative numbers e.g. _mod(-1, 3) = 2. Works on numbers (rather than patterns of numbers, as @mod@ from pattern.mjs does)
|
||||
export const _mod = (n, m) => ((n % m) + m) % m;
|
||||
|
||||
// round to nearest int, negative numbers will output a subtracted index
|
||||
export const getSoundIndex = (n, numSounds) => {
|
||||
return _mod(Math.round(nanFallback(n, 0)), numSounds);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export default defineConfig({
|
|||
lib: {
|
||||
entry: resolve(__dirname, 'index.mjs'),
|
||||
formats: ['es', 'cjs'],
|
||||
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.cjs' }[ext]),
|
||||
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.cjs' })[ext],
|
||||
},
|
||||
rollupOptions: {
|
||||
external: [...Object.keys(dependencies)],
|
||||
|
|
|
|||
|
|
@ -78,13 +78,13 @@ export function buildSamples(
|
|||
(i < attack
|
||||
? i / attack // attack
|
||||
: i < attack + decay // decay
|
||||
? 1 - ((i - attack) / decay) * (1 - sustainVolume) // decay falloff
|
||||
: i < attack + decay + sustain // sustain
|
||||
? sustainVolume // sustain volume
|
||||
: i < length - delay // release
|
||||
? ((length - i - delay) / release) * // release falloff
|
||||
sustainVolume // release volume
|
||||
: 0); // post release
|
||||
? 1 - ((i - attack) / decay) * (1 - sustainVolume) // decay falloff
|
||||
: i < attack + decay + sustain // sustain
|
||||
? sustainVolume // sustain volume
|
||||
: i < length - delay // release
|
||||
? ((length - i - delay) / release) * // release falloff
|
||||
sustainVolume // release volume
|
||||
: 0); // post release
|
||||
|
||||
s = delay
|
||||
? s / 2 +
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue