mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-22 05:05:26 -04:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a0c35e943f | |||
| 8b26f784d7 | |||
| 04df4a31af | |||
| 077ef0f083 | |||
| 5c4b6cda71 | |||
| 4553408b28 | |||
| 42eb33440c | |||
| 87768198a0 | |||
| c24a87df48 | |||
| 2d63f36201 | |||
| 43ac2d3d72 |
@@ -10,7 +10,7 @@ function getExports(code) {
|
||||
let ast;
|
||||
try {
|
||||
ast = parse(code, {
|
||||
ecmaVersion: 'latest',
|
||||
ecmaVersion: 11,
|
||||
sourceType: 'module',
|
||||
});
|
||||
} catch (err) {
|
||||
@@ -49,7 +49,9 @@ function getExports(code) {
|
||||
}
|
||||
|
||||
function isDocumented(name, docs) {
|
||||
return docs.find((d) => d.name === name || d.synonyms?.includes(name));
|
||||
return docs.find(
|
||||
(d) => d.name === name || d.tags?.find((t) => t.title === 'synonyms' && t.value.split(', ').includes(name)),
|
||||
);
|
||||
}
|
||||
|
||||
async function getUndocumented(path, docs) {
|
||||
|
||||
@@ -3289,7 +3289,6 @@ export const striate = register('striate', function (n, pat) {
|
||||
/**
|
||||
* Makes the sample fit the given number of cycles by changing the speed.
|
||||
* @name loopAt
|
||||
* @synonyms loopat
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
@@ -3422,7 +3421,6 @@ export const fit = register('fit', (pat) =>
|
||||
* given by a global clock and this function will be
|
||||
* deprecated/removed.
|
||||
* @name loopAtCps
|
||||
* @synonyms loopatcps
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
|
||||
@@ -10,27 +10,11 @@ import Fraction from './fraction.mjs';
|
||||
|
||||
import { id, keyAlias, getCurrentKeyboardState } from './util.mjs';
|
||||
|
||||
/**
|
||||
* A `signal` consisting of a constant value. Similar to `pure`, except that function
|
||||
* creates a pattern with one event per cycle, whereas this pattern doesn't have an intrinsic
|
||||
* structure.
|
||||
*
|
||||
* @param {*} value The constant value of the resulting pattern
|
||||
* @returns Pattern
|
||||
*/
|
||||
export function steady(value) {
|
||||
// A continuous value
|
||||
return new Pattern((state) => [new Hap(undefined, state.span, value)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a "signal", an unstructured pattern consisting of a single value that changes
|
||||
* over time.
|
||||
*
|
||||
*
|
||||
* @param {*} func
|
||||
* @returns Pattern
|
||||
*/
|
||||
export const signal = (func) => {
|
||||
const query = (state) => [new Hap(undefined, state.span, func(state.span.begin))];
|
||||
return new Pattern(query);
|
||||
@@ -39,7 +23,7 @@ export const signal = (func) => {
|
||||
/**
|
||||
* A sawtooth signal between 0 and 1.
|
||||
*
|
||||
* @type {Pattern}
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* note("<c3 [eb3,g3] g2 [g3,bb3]>*8")
|
||||
* .clip(saw.slow(2))
|
||||
@@ -173,7 +157,6 @@ export const time = signal(id);
|
||||
/**
|
||||
* The mouse's x position value ranges from 0 to 1.
|
||||
* @name mousex
|
||||
* @synonyms mouseX
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* n(mousex.segment(4).range(0,7)).scale("C:minor")
|
||||
@@ -183,7 +166,6 @@ export const time = signal(id);
|
||||
/**
|
||||
* The mouse's y position value ranges from 0 to 1.
|
||||
* @name mousey
|
||||
* @synonyms mouseY
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* n(mousey.segment(4).range(0,7)).scale("C:minor")
|
||||
@@ -233,6 +215,10 @@ const timeToRandsPrime = (seed, n) => {
|
||||
|
||||
const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* A discrete pattern of numbers from 0 to n-1
|
||||
* @example
|
||||
@@ -403,22 +389,16 @@ export const chooseInWith = (pat, xs) => {
|
||||
|
||||
/**
|
||||
* Chooses randomly from the given list of elements.
|
||||
* @synonyms chooseOut
|
||||
* @param {...any} xs values / patterns to choose from.
|
||||
* @returns {Pattern} - a continuous pattern.
|
||||
* @example
|
||||
* note("c2 g2!2 d2 f1").s(choose("sine", "triangle", "bd:6"))
|
||||
*/
|
||||
export const choose = (...xs) => chooseWith(rand, xs);
|
||||
export const chooseOut = choose;
|
||||
|
||||
/**
|
||||
* As with {choose}, but the structure comes from the chosen values, rather
|
||||
* than the pattern you're using to choose with.
|
||||
* @param {...any} xs
|
||||
* @returns
|
||||
*/
|
||||
// todo: doc
|
||||
export const chooseIn = (...xs) => chooseInWith(rand, xs);
|
||||
export const chooseOut = choose;
|
||||
|
||||
/**
|
||||
* Chooses from the given list of values (or patterns of values), according
|
||||
@@ -516,7 +496,6 @@ function _perlin(t) {
|
||||
const v = interp(t - ta)(timeToRand(ta))(timeToRand(tb));
|
||||
return v;
|
||||
}
|
||||
|
||||
export const perlinWith = (tpat) => {
|
||||
return tpat.fmap(_perlin);
|
||||
};
|
||||
@@ -562,15 +541,6 @@ export const perlin = perlinWith(time.fmap((v) => Number(v)));
|
||||
*/
|
||||
export const berlin = berlinWith(time.fmap((v) => Number(v)));
|
||||
|
||||
/**
|
||||
* Removes events from a pattern given a signal of numbers and a cutoff
|
||||
* value for interpreting that pattern as true or false.
|
||||
* @param {number} withPat - A numeric pattern for comparing the main pattern
|
||||
* against. Values higher than the cutoff will let events through and lower
|
||||
* values will remove events from the main pattern
|
||||
* @param {number} cutoff - The threshold value to use when interpreting the
|
||||
* `withPat`
|
||||
*/
|
||||
export const degradeByWith = register(
|
||||
'degradeByWith',
|
||||
(withPat, x, pat) => pat.fmap((a) => (_) => a).appLeft(withPat.filterValues((v) => v > x)),
|
||||
|
||||
@@ -14,7 +14,12 @@ npm i @strudel/gamepad --save
|
||||
import { gamepad } from '@strudel/gamepad';
|
||||
|
||||
// Initialize gamepad (optional index parameter, defaults to 0)
|
||||
const pad = gamepad(0);
|
||||
const pad = gamepad(0); // Default mapping is XBOX {a: 0, b: 1, x: 2, y: 3}
|
||||
|
||||
//const pad = gamepad(0, 'XBOX'); // XBOX button mapping {a: 0, b: 1, x: 2, y: 3}
|
||||
//const pad = gamepad(0, 'NES'); // Nintendo button mapping {a: 1, b: 0, x: 3, y: 2}
|
||||
//const pad = gamepad(0, {a: 0, b: 1, x: 2, y: 3}); // Custom mapping
|
||||
|
||||
|
||||
// Use gamepad inputs in patterns
|
||||
const pattern = sequence([
|
||||
@@ -86,8 +91,35 @@ $: sound("hadoken").gain(pad.checkSequence(HADOKEN))
|
||||
## Multiple Gamepads
|
||||
|
||||
You can connect multiple gamepads by specifying the gamepad index:
|
||||
Make sure to press buttons on all connected gamepads before hitting play, so the browser can properly detect them.
|
||||
|
||||
```javascript
|
||||
const pad1 = gamepad(0); // First gamepad
|
||||
const pad2 = gamepad(1); // Second gamepad
|
||||
```
|
||||
|
||||
## Vibration
|
||||
|
||||
You can use the `vibrate` control to provide haptic feedback to the gamepad.
|
||||
The `vibrate` control is a patternable control, so you can use it to control the vibration of the gamepad.
|
||||
|
||||
The vibrate control has several parameters:
|
||||
|
||||
- `vibGamepadIndex` - Index of the gamepad to vibrate (0-3)
|
||||
- `vibStrong` - Intensity of the strong/left motor (0-1)
|
||||
- `vibWeak` - Intensity of the weak/right motor (0-1)
|
||||
- `vibDuration` - Duration of vibration in milliseconds
|
||||
- `vibEnable` - Enable/disable vibration (0 or 1)
|
||||
|
||||
```javascript
|
||||
// Vibration with gamepad
|
||||
// vibrate(gamepadId, { strong: 1, weak: 0.5, duration: 100 })
|
||||
// vibrate("gamepadId")
|
||||
// vibrate(gamepadId)
|
||||
|
||||
$: note("c4*4").vibrate(0, { strong: 1, weak: 0.5, duration: 100 }) // gamepad index 0
|
||||
$: note("c4*4").vibrate("0:1:0.5:200") // Array format
|
||||
$: note("c4*4").vibrate("<0 1 0 1>") // select gamepad index
|
||||
|
||||
$: note("c4*4").vibStrong("<0.1 0.2 0.5 1>").vibWeak("<0.1 0.2 0.5 1>").vibDuration("<10 20 50 100>").vibrate(0) // gamepad index 0
|
||||
```
|
||||
|
||||
@@ -107,9 +107,32 @@ $: s("free_hadouken -").slow(2)
|
||||
samples({free_hadouken: 'https://cdn.freesound.org/previews/67/67674_111920-lq.mp3'})
|
||||
`} />
|
||||
|
||||
## Multiple Gamepads
|
||||
### Button Sequences
|
||||
|
||||
### Button Mappings
|
||||
|
||||
The gamepad module supports different button mapping configurations to accommodate various gamepad layouts:
|
||||
|
||||
- **XBOX** (Default): Standard Xbox-style mapping where A=0, B=1, X=2, Y=3
|
||||
- **NES**: Nintendo-style mapping where B=0, A=1, Y=2, X=3
|
||||
- **Custom**: Define your own button mapping by passing an object with button assignments
|
||||
|
||||
You can specify the mapping when initializing the gamepad:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`
|
||||
const pad1 = gamepad(0); // Default mapping is XBOX {a: 0, b: 1, x: 2, y: 3}
|
||||
const pad2 = gamepad(1, 'XBOX'); // XBOX button mapping {a: 0, b: 1, x: 2, y: 3}
|
||||
const pad3 = gamepad(2, 'NES'); // Nintendo button mapping {a: 1, b: 0, x: 3, y: 2}
|
||||
const pad4 = gamepad(3, {a: 0, b: 1, x: 2, y: 3}); // Custom mapping
|
||||
`}
|
||||
/>
|
||||
|
||||
### Multiple Gamepads
|
||||
|
||||
Strudel supports multiple gamepads. You can specify the gamepad index to connect to different devices.
|
||||
Make sure to press buttons on all connected gamepads before hitting play, so the browser can properly detect them.
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
|
||||
+147
-32
@@ -1,35 +1,77 @@
|
||||
// @strudel/gamepad/index.mjs
|
||||
|
||||
import { signal } from '@strudel/core';
|
||||
import { signal, Pattern, logger, registerControl, register, isPattern } from '@strudel/core';
|
||||
import { vibrationSupported, getGamepadVibrationActuator } from './vibration.mjs';
|
||||
|
||||
// Button mapping for Logitech Dual Action (STANDARD GAMEPAD Vendor: 046d Product: c216)
|
||||
export const buttonMap = {
|
||||
a: 0,
|
||||
b: 1,
|
||||
x: 2,
|
||||
y: 3,
|
||||
lb: 4,
|
||||
rb: 5,
|
||||
lt: 6,
|
||||
rt: 7,
|
||||
back: 8,
|
||||
start: 9,
|
||||
u: 12,
|
||||
up: 12,
|
||||
d: 13,
|
||||
down: 13,
|
||||
l: 14,
|
||||
left: 14,
|
||||
r: 15,
|
||||
right: 15,
|
||||
|
||||
export const buttonMapSettings = {
|
||||
XBOX: {
|
||||
// XBOX mapping default
|
||||
a: 0,
|
||||
b: 1,
|
||||
x: 2,
|
||||
y: 3,
|
||||
lb: 4,
|
||||
rb: 5,
|
||||
lt: 6,
|
||||
rt: 7,
|
||||
back: 8,
|
||||
start: 9,
|
||||
lstick: 10,
|
||||
rstick: 11,
|
||||
ls: 10,
|
||||
rs: 11,
|
||||
u: 12,
|
||||
up: 12,
|
||||
d: 13,
|
||||
down: 13,
|
||||
l: 14,
|
||||
left: 14,
|
||||
r: 15,
|
||||
right: 15,
|
||||
xbox: 16,
|
||||
},
|
||||
NES: {
|
||||
// Nintendo mapping
|
||||
a: 1,
|
||||
b: 0,
|
||||
x: 3,
|
||||
y: 2,
|
||||
lb: 4,
|
||||
rb: 5,
|
||||
zl: 6,
|
||||
zr: 7,
|
||||
lt: 6,
|
||||
rt: 7,
|
||||
back: 8,
|
||||
minus: 8,
|
||||
start: 9,
|
||||
plus: 9,
|
||||
lstick: 10,
|
||||
rstick: 11,
|
||||
ls: 10,
|
||||
rs: 11,
|
||||
u: 12,
|
||||
up: 12,
|
||||
d: 13,
|
||||
down: 13,
|
||||
l: 14,
|
||||
left: 14,
|
||||
r: 15,
|
||||
right: 15,
|
||||
home: 16,
|
||||
select: 17,
|
||||
},
|
||||
};
|
||||
|
||||
class ButtonSequenceDetector {
|
||||
constructor(timeWindow = 1000) {
|
||||
constructor(timeWindow = 1000, mapping) {
|
||||
this.sequence = [];
|
||||
this.timeWindow = timeWindow;
|
||||
this.lastInputTime = 0;
|
||||
this.buttonStates = Array(16).fill(0); // Track previous state of each button
|
||||
this.buttonStates = Array(Object.keys(mapping).length).fill(0); // Track previous state of each button
|
||||
this.buttonMap = mapping;
|
||||
// Button mapping for character inputs
|
||||
}
|
||||
|
||||
@@ -44,7 +86,8 @@ class ButtonSequenceDetector {
|
||||
}
|
||||
|
||||
// Store the button name instead of index
|
||||
const buttonName = Object.keys(buttonMap).find((key) => buttonMap[key] === buttonIndex) || buttonIndex.toString();
|
||||
const buttonName =
|
||||
Object.keys(this.buttonMap).find((key) => this.buttonMap[key] === buttonIndex) || buttonIndex.toString();
|
||||
|
||||
this.sequence.push({
|
||||
input: buttonName,
|
||||
@@ -87,9 +130,9 @@ class ButtonSequenceDetector {
|
||||
// Check if either the input matches directly or they refer to the same button in the map
|
||||
return (
|
||||
input === target ||
|
||||
buttonMap[input] === buttonMap[target] ||
|
||||
this.buttonMap[input] === this.buttonMap[target] ||
|
||||
// Also check if the numerical index matches
|
||||
buttonMap[input] === parseInt(target)
|
||||
this.buttonMap[input] === parseInt(target)
|
||||
);
|
||||
})
|
||||
? 1
|
||||
@@ -98,12 +141,13 @@ class ButtonSequenceDetector {
|
||||
}
|
||||
|
||||
class GamepadHandler {
|
||||
constructor(index = 0) {
|
||||
constructor(index = 0, mapping) {
|
||||
// Add index parameter
|
||||
this._gamepads = {};
|
||||
this._mapping = mapping;
|
||||
this._activeGamepad = index; // Use provided index
|
||||
this._axes = [0, 0, 0, 0];
|
||||
this._buttons = Array(16).fill(0);
|
||||
this._buttons = Array(Object.keys(mapping).length).fill(0);
|
||||
this.setupEventListeners();
|
||||
}
|
||||
|
||||
@@ -143,12 +187,66 @@ class GamepadHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Add utility function to list all connected gamepads
|
||||
export const listGamepads = () => {
|
||||
const gamepads = navigator.getGamepads();
|
||||
const connectedGamepads = Array.from(gamepads)
|
||||
.filter((gp) => gp !== null)
|
||||
.map((gp) => ({
|
||||
index: gp.index,
|
||||
id: gp.id,
|
||||
mapping: gp.mapping,
|
||||
buttons: gp.buttons.length,
|
||||
axes: gp.axes.length,
|
||||
connected: gp.connected,
|
||||
timestamp: gp.timestamp,
|
||||
}));
|
||||
// Format the gamepads info into a readable string
|
||||
const gamepadsInfo = connectedGamepads.map((gp) => `${gp.index}: ${gp.id}`).join('\n');
|
||||
|
||||
logger(`[gamepad] available gamepads:\n${gamepadsInfo}`);
|
||||
return connectedGamepads;
|
||||
};
|
||||
|
||||
// Module-level state store for toggle states
|
||||
const gamepadStates = new Map();
|
||||
|
||||
export const gamepad = (index = 0) => {
|
||||
const handler = new GamepadHandler(index);
|
||||
const sequenceDetector = new ButtonSequenceDetector(2000);
|
||||
export const gamepad = (index = 0, mapping = 'XBOX') => {
|
||||
// list connected gamepads
|
||||
const connectedGamepads = listGamepads();
|
||||
|
||||
// Check if the requested gamepad index exists
|
||||
const requestedGamepad = connectedGamepads.find((gp) => gp.index === index);
|
||||
if (!requestedGamepad) {
|
||||
throw new Error(
|
||||
`[gamepad] gamepad at index ${index} not found. available gamepads: ${connectedGamepads.map((gp) => gp.index).join(', ')}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Handle button mapping
|
||||
let buttonMap = buttonMapSettings.XBOX;
|
||||
|
||||
if (typeof mapping === 'string') {
|
||||
buttonMap = buttonMapSettings[mapping.toUpperCase()];
|
||||
} else if (typeof mapping === 'object') {
|
||||
buttonMap = { ...buttonMapSettings.XBOX, ...mapping };
|
||||
// Check that all mapping values are valid button indices
|
||||
const maxButtons = requestedGamepad.buttons;
|
||||
for (const [key, value] of Object.entries(mapping)) {
|
||||
if (typeof value !== 'number' || value < 0 || value >= maxButtons) {
|
||||
throw new Error(
|
||||
`[gamepad] invalid button mapping for '${key}': ${value}. Must be a number between 0 and ${maxButtons - 1}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!buttonMap) {
|
||||
throw new Error(`[gamepad] button mapping '${mapping}' not found`);
|
||||
}
|
||||
|
||||
const handler = new GamepadHandler(index, buttonMap);
|
||||
const sequenceDetector = new ButtonSequenceDetector(2000, buttonMap);
|
||||
|
||||
// Base signal that polls gamepad state and handles sequence detection
|
||||
const baseSignal = signal((t) => {
|
||||
@@ -179,7 +277,7 @@ export const gamepad = (index = 0) => {
|
||||
axes.y2_2 = axes.y2.toBipolar();
|
||||
|
||||
// Create button patterns
|
||||
const buttons = Array(16)
|
||||
const buttons = Array(Object.keys(buttonMap).length)
|
||||
.fill(null)
|
||||
.map((_, i) => {
|
||||
// Create unique key for this gamepad+button combination
|
||||
@@ -218,8 +316,22 @@ export const gamepad = (index = 0) => {
|
||||
return baseSignal.fmap(() => sequenceDetector.checkSequence(sequence));
|
||||
};
|
||||
const checkSequence = btnSequence;
|
||||
const sequence = btnSequence;
|
||||
const btnSeq = btnSequence;
|
||||
const btnseq = btnSeq;
|
||||
const btnseq = btnSequence;
|
||||
const seq = btnSequence;
|
||||
|
||||
// Create vibration pattern
|
||||
const vibration = (pattern) => {
|
||||
return signal(() => {
|
||||
// Return vibration enable/disable pattern
|
||||
return pattern;
|
||||
});
|
||||
};
|
||||
|
||||
logger(
|
||||
`[gamepad] connected to gamepad ${index} (${requestedGamepad.id}) with ${typeof mapping === 'object' ? 'custom' : mapping} mapping${vibrationSupported(index) ? ' (vibration supported)' : ''}`,
|
||||
);
|
||||
|
||||
// Return an object with all controls
|
||||
return {
|
||||
@@ -234,9 +346,12 @@ export const gamepad = (index = 0) => {
|
||||
]),
|
||||
),
|
||||
checkSequence,
|
||||
sequence,
|
||||
btnSequence,
|
||||
btnSeq,
|
||||
btnseq,
|
||||
seq,
|
||||
vibration,
|
||||
raw: baseSignal,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
// Gamepad Vibration Controls
|
||||
|
||||
import { registerControl, register, logger, isPattern } from '@strudel/core';
|
||||
import { Pattern } from '@strudel/core';
|
||||
|
||||
/**
|
||||
* Controls the strong motor intensity for gamepad vibration.
|
||||
*
|
||||
* @name vibStrong
|
||||
* @param {number | Pattern} intensity between 0 and 1
|
||||
* @synonyms vibS
|
||||
* @example
|
||||
* s("bd hh sd hh").vibStrong("1 0 0.5 0").vibrate(0)
|
||||
*/
|
||||
export const { vibStrong, vibS } = registerControl('vibStrong', 'vibS');
|
||||
|
||||
/**
|
||||
* Controls the weak motor intensity for gamepad vibration.
|
||||
*
|
||||
* @name vibWeak
|
||||
* @param {number | Pattern} intensity between 0 and 1
|
||||
* @synonyms vibW
|
||||
* @example
|
||||
* s("bd hh sd hh").vibWeak("0.5 0 0.8 0").vibrate(0)
|
||||
*/
|
||||
export const { vibWeak, vibW } = registerControl('vibWeak', 'vibW');
|
||||
|
||||
/**
|
||||
* Controls the duration of gamepad vibration in milliseconds.
|
||||
*
|
||||
* @name vibDuration
|
||||
* @param {number | Pattern} duration in milliseconds
|
||||
* @synonyms vibDur
|
||||
* @example
|
||||
* s("bd hh sd hh").vibDuration("200 0 100 0").vibrate(0)
|
||||
*/
|
||||
export const { vibDuration, vibDur } = registerControl('vibDuration', 'vibDur');
|
||||
|
||||
/**
|
||||
* Enables or disables gamepad vibration for individual events.
|
||||
*
|
||||
* @name vibEnable
|
||||
* @param {number | Pattern} enable 1 to enable, 0 to disable
|
||||
* @synonyms vibE
|
||||
* @example
|
||||
* s("bd hh sd hh").vibEnable("1 0 1 0").vibrate(0)
|
||||
*/
|
||||
export const { vibEnable, vibEn } = registerControl('vibEnable', 'vibEn');
|
||||
|
||||
/**
|
||||
* Sets the gamepad index for vibration events.
|
||||
*
|
||||
* @name vibGamepadIndex
|
||||
* @param {number | Pattern} index gamepad index (0-3)
|
||||
* @synonyms vibGpId, vibGamepadIndex, vibGamepadId
|
||||
* @example
|
||||
* s("bd hh sd hh").vibGamepadIndex("0 1 0 1").vibrate()
|
||||
*/
|
||||
export const { vibGamepadIndex, vibGpId, vibGamepadId } = registerControl('vibGamepadIndex', 'vibGpId', 'vibGamepadId');
|
||||
|
||||
/**
|
||||
* Sets both strong and weak vibration intensity at once.
|
||||
*
|
||||
* @name vibIntensity
|
||||
* @param {number | Pattern} intensity between 0 and 1, applied to both motors
|
||||
* @example
|
||||
* s("bd*4").vibIntensity(sine.slow(2).range(0, 1)).vibrate(0)
|
||||
*/
|
||||
export const vibIntensity = register('vibIntensity', (intensity, pat) => {
|
||||
return pat.vibStrong(intensity).vibWeak(intensity);
|
||||
});
|
||||
|
||||
export const vibrationSupported = (index) => {
|
||||
const gamepad = navigator.getGamepads()[index];
|
||||
return gamepad?.vibrationActuator?.type === 'dual-rumble';
|
||||
};
|
||||
|
||||
export const getGamepadVibrationActuator = (index) => {
|
||||
const gamepad = navigator.getGamepads()[index];
|
||||
if (!gamepad) {
|
||||
throw new Error(`[gamepad] gamepad at index ${index} not found`);
|
||||
}
|
||||
if (!gamepad.vibrationActuator) {
|
||||
throw new Error(`[gamepad] gamepad at index ${index} does not support vibration`);
|
||||
}
|
||||
return gamepad.vibrationActuator;
|
||||
};
|
||||
|
||||
// Default vibration latency in milliseconds
|
||||
const DEFAULT_VIBRATION_LATENCY = 10;
|
||||
|
||||
/**
|
||||
* Parses vibration string format "id:strong:weak:duration"
|
||||
* @param {string} vibString - The vibration string to parse
|
||||
* @returns {object} Parsed vibration parameters
|
||||
*/
|
||||
function parseVibrationString(vibString) {
|
||||
if (typeof vibString !== 'string') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parts = vibString.split(':');
|
||||
if (parts.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [id, strong, weak, duration] = parts;
|
||||
|
||||
return {
|
||||
vibGamepadIndex: parseInt(id) || 0,
|
||||
vibStrong: parseFloat(strong) || 0.8,
|
||||
vibWeak: parseFloat(weak) || 0.4,
|
||||
vibDuration: parseInt(duration) || 100,
|
||||
vibEnable: 1,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends vibration commands to a gamepad based on pattern events.
|
||||
*
|
||||
* @name vibrate
|
||||
* @memberof Pattern
|
||||
* @param {number | string | Pattern} gamepadIndex - Index of the gamepad to vibrate (0-3), can be patterned, or vibration string
|
||||
* @param {object} options - Default vibration options
|
||||
* @param {number} options.strong - Default strong motor intensity (0-1)
|
||||
* @param {number} options.weak - Default weak motor intensity (0-1)
|
||||
* @param {number} options.duration - Default duration in milliseconds
|
||||
* @param {number} options.latency - Latency compensation in milliseconds
|
||||
* @returns {Pattern}
|
||||
* @example
|
||||
* // Basic vibration on beat
|
||||
* s("bd hh sd hh").vibrate(0)
|
||||
*
|
||||
* @example
|
||||
* // Using hap values for vibration control
|
||||
* s("<bd hh sd hh>").vibStrong("<1 0.1 0.5 0>").vibWeak("<0.5 0 0.8 0>").vibrate(0)
|
||||
*
|
||||
* @example
|
||||
* // With default options
|
||||
* s("bd*4").vibrate(0, { strong: 1, weak: 0.5, duration: 100 })
|
||||
*
|
||||
* @example
|
||||
* // Using gamepad input to control vibration
|
||||
* let gp = gamepad(0);
|
||||
* note("c a f e").gain(gp.a).vibrate(0, { strong: gp.x1, duration: 200 })
|
||||
*
|
||||
* @example
|
||||
* // Patternable gamepad index - alternate between gamepads
|
||||
* s("bd hh sd hh").vibrate("<0 1 0 1>")
|
||||
*
|
||||
* @example
|
||||
* // Complex gamepad switching pattern
|
||||
* s("bd*8").vibrate("0 1 0 [1 0] 1 0 1 0")
|
||||
*
|
||||
* @example
|
||||
* // Using control parameter for gamepad index
|
||||
* s("bd hh sd hh").vibGamepad("<0 1 0 1>").vibrate()
|
||||
*
|
||||
* @example
|
||||
* // Assignable vibration syntax: "id:strong:weak:duration"
|
||||
* s("bd hh sd hh").vibrate("0:1:0.5:200 1:0.8:0.3:150")
|
||||
*
|
||||
* @example
|
||||
* // Complex assignable patterns
|
||||
* s("bd*8").vibrate("0:0.2:0.4:100 0:0.2:1:100 1:1:0.5:200 1:0.5:1:150")
|
||||
*/
|
||||
|
||||
export const { vibrate } = registerControl(['vibGamepad', 'vibStrong', 'vibWeak', 'vibDuration']);
|
||||
|
||||
Pattern.prototype.vibrate = function (gamepadIndex, options = {}) {
|
||||
// Default options
|
||||
const defaultOptions = {
|
||||
strong: 0.8,
|
||||
weak: 0.4,
|
||||
duration: 100,
|
||||
latency: DEFAULT_VIBRATION_LATENCY,
|
||||
...options,
|
||||
};
|
||||
|
||||
// If gamepadIndex is a pattern, handle it based on its content
|
||||
if (isPattern(gamepadIndex)) {
|
||||
return this.set(
|
||||
gamepadIndex.fmap((value) => {
|
||||
// Simple gamepad index pattern
|
||||
return { vibGamepadIndex: value };
|
||||
}),
|
||||
).onTrigger((time_deprecate, hap, currentTime, cps, targetTime) => {
|
||||
return vibrateHandler(hap, currentTime, cps, targetTime, defaultOptions);
|
||||
}, false);
|
||||
}
|
||||
|
||||
// If gamepadIndex is provided as static value, use it directly
|
||||
// If undefined, will be handled in vibrateHandler (using vibGamepad control or default 0)
|
||||
return this.onTrigger((time_deprecate, hap, currentTime, cps, targetTime) => {
|
||||
return vibrateHandler(hap, currentTime, cps, targetTime, defaultOptions, gamepadIndex);
|
||||
}, false);
|
||||
};
|
||||
|
||||
// Helper function to handle the actual vibration logic
|
||||
function vibrateHandler(hap, currentTime, cps, targetTime, defaultOptions, staticGamepadIndex = null) {
|
||||
try {
|
||||
// Determine gamepad index - from hap value or static parameter
|
||||
let gamepadIndex;
|
||||
if (staticGamepadIndex !== null && staticGamepadIndex !== undefined) {
|
||||
gamepadIndex = staticGamepadIndex;
|
||||
} else if (typeof hap.value === 'object' && ('vibGamepadIndex' in hap.value || 'vibGamepad' in hap.value)) {
|
||||
const vibGamepadValue = hap.value.vibGamepadIndex;
|
||||
gamepadIndex = Array.isArray(vibGamepadValue) ? vibGamepadValue[0] : vibGamepadValue;
|
||||
} else {
|
||||
gamepadIndex = 0; // fallback default
|
||||
}
|
||||
|
||||
// Validate gamepad index
|
||||
gamepadIndex = Math.max(0, Math.min(3, Math.floor(Number(gamepadIndex) || 0)));
|
||||
|
||||
// Check if vibration is supported
|
||||
if (!vibrationSupported(gamepadIndex)) {
|
||||
logger(`[gamepad] vibration not supported on gamepad ${gamepadIndex}`, 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const vibrationActuator = getGamepadVibrationActuator(gamepadIndex);
|
||||
|
||||
// Extract vibration parameters from hap value or use defaults
|
||||
let vibStrong, vibWeak, vibDuration, vibEnable;
|
||||
|
||||
if (typeof hap.value === 'object') {
|
||||
const vibGamepadValue = hap.value.vibGamepadIndex;
|
||||
|
||||
// Handle array format: [index, strong, weak, duration]
|
||||
if (Array.isArray(vibGamepadValue)) {
|
||||
vibStrong = vibGamepadValue[1] !== undefined ? vibGamepadValue[1] : defaultOptions.strong;
|
||||
vibWeak = vibGamepadValue[2] !== undefined ? vibGamepadValue[2] : defaultOptions.weak;
|
||||
vibDuration = vibGamepadValue[3] !== undefined ? vibGamepadValue[3] : defaultOptions.duration;
|
||||
vibEnable = 1;
|
||||
} else {
|
||||
// Regular object destructuring for non-array values
|
||||
({
|
||||
vibStrong = defaultOptions.strong,
|
||||
vibWeak = defaultOptions.weak,
|
||||
vibDuration = defaultOptions.duration,
|
||||
vibEnable = 1,
|
||||
} = hap.value);
|
||||
}
|
||||
} else {
|
||||
// If hap.value is a primitive, use it as vibEnable (0 = off, 1 = on)
|
||||
vibEnable = hap.value;
|
||||
vibStrong = defaultOptions.strong;
|
||||
vibWeak = defaultOptions.weak;
|
||||
vibDuration = defaultOptions.duration;
|
||||
}
|
||||
|
||||
// Skip vibration if disabled
|
||||
if (!vibEnable || vibEnable === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate parameters
|
||||
vibStrong = Math.max(0, Math.min(1, Number(vibStrong) || 0));
|
||||
vibWeak = Math.max(0, Math.min(1, Number(vibWeak) || 0));
|
||||
vibDuration = Math.max(0, Number(vibDuration) || defaultOptions.duration);
|
||||
|
||||
// Calculate timing offset
|
||||
const offset = (targetTime - currentTime + defaultOptions.latency / 1000) * 1000;
|
||||
|
||||
// Schedule vibration
|
||||
window.setTimeout(
|
||||
() => {
|
||||
try {
|
||||
vibrationActuator
|
||||
.playEffect('dual-rumble', {
|
||||
duration: vibDuration,
|
||||
strongMagnitude: vibStrong,
|
||||
weakMagnitude: vibWeak,
|
||||
})
|
||||
.catch((err) => {
|
||||
logger(`[gamepad] vibration failed: ${err.message}`, 'warning');
|
||||
});
|
||||
} catch (err) {
|
||||
logger(`[gamepad] vibration error: ${err.message}`, 'warning');
|
||||
}
|
||||
},
|
||||
Math.max(0, offset),
|
||||
);
|
||||
} catch (err) {
|
||||
logger(`[gamepad] vibration setup failed: ${err.message}`, 'warning');
|
||||
}
|
||||
}
|
||||
@@ -11780,6 +11780,279 @@ exports[`runs examples > example "vib" example index 1 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibDuration" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibDuration:200 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibDuration:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibDuration:100 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibDuration:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibDuration:200 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibDuration:0 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibDuration:100 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibDuration:0 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibDuration:200 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibDuration:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibDuration:100 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibDuration:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibDuration:200 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibDuration:0 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibDuration:100 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibDuration:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibDuration" example index 0 2`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibDuration:200 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibDuration:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibDuration:100 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibDuration:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibDuration:200 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibDuration:0 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibDuration:100 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibDuration:0 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibDuration:200 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibDuration:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibDuration:100 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibDuration:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibDuration:200 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibDuration:0 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibDuration:100 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibDuration:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibEnable" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibEnable:1 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibEnable:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibEnable:1 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibEnable:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibEnable:1 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibEnable:0 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibEnable:1 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibEnable:0 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibEnable:1 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibEnable:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibEnable:1 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibEnable:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibEnable:1 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibEnable:0 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibEnable:1 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibEnable:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibEnable" example index 0 2`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibEnable:1 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibEnable:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibEnable:1 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibEnable:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibEnable:1 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibEnable:0 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibEnable:1 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibEnable:0 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibEnable:1 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibEnable:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibEnable:1 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibEnable:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibEnable:1 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibEnable:0 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibEnable:1 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibEnable:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibGamepad" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibGamepad:1 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibGamepad:1 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibGamepad:1 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibGamepad:1 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibGamepad" example index 0 2`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibGamepad:1 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibGamepad:1 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibGamepad:1 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibGamepad:1 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibGamepadIndex" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibGamepadIndex:0 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibGamepadIndex:0 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibGamepadIndex:0 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibGamepadIndex:0 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibGamepadIndex:1 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibIntensity" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 1/4 → 1/2 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 1/2 → 3/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 3/4 → 1/1 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 5/4 → 3/2 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 3/2 → 7/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 7/4 → 2/1 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 9/4 → 5/2 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 5/2 → 11/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 11/4 → 3/1 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 13/4 → 7/2 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 7/2 → 15/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 15/4 → 4/1 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibIntensity" example index 0 2`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 1/4 → 1/2 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 1/2 → 3/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 3/4 → 1/1 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 5/4 → 3/2 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 3/2 → 7/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 7/4 → 2/1 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 9/4 → 5/2 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 5/2 → 11/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 11/4 → 3/1 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 13/4 → 7/2 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 7/2 → 15/4 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
"[ 15/4 → 4/1 | s:bd vibStrong:0.4999999999999999 vibWeak:0.4999999999999999 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibStrong" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibStrong:1 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibStrong:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibStrong:0.5 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibStrong:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibStrong:1 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibStrong:0 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibStrong:0.5 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibStrong:0 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibStrong:1 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibStrong:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibStrong:0.5 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibStrong:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibStrong:1 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibStrong:0 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibStrong:0.5 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibStrong:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibStrong" example index 0 2`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibStrong:1 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibStrong:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibStrong:0.5 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibStrong:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibStrong:1 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibStrong:0 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibStrong:0.5 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibStrong:0 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibStrong:1 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibStrong:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibStrong:0.5 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibStrong:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibStrong:1 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibStrong:0 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibStrong:0.5 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibStrong:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibWeak" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibWeak:0.5 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibWeak:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibWeak:0.8 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibWeak:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibWeak:0.5 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibWeak:0 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibWeak:0.8 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibWeak:0 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibWeak:0.5 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibWeak:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibWeak:0.8 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibWeak:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibWeak:0.5 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibWeak:0 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibWeak:0.8 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibWeak:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibWeak" example index 0 2`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibWeak:0.5 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibWeak:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibWeak:0.8 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibWeak:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibWeak:0.5 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibWeak:0 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibWeak:0.8 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibWeak:0 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibWeak:0.5 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibWeak:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibWeak:0.8 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibWeak:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibWeak:0.5 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibWeak:0 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibWeak:0.8 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibWeak:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibmod" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | note:a vib:4 vibmod:0.25 ]",
|
||||
@@ -11806,6 +12079,198 @@ exports[`runs examples > example "vibmod" example index 1 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibrate" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd ]",
|
||||
"[ 1/4 → 1/2 | s:hh ]",
|
||||
"[ 1/2 → 3/4 | s:sd ]",
|
||||
"[ 3/4 → 1/1 | s:hh ]",
|
||||
"[ 1/1 → 5/4 | s:bd ]",
|
||||
"[ 5/4 → 3/2 | s:hh ]",
|
||||
"[ 3/2 → 7/4 | s:sd ]",
|
||||
"[ 7/4 → 2/1 | s:hh ]",
|
||||
"[ 2/1 → 9/4 | s:bd ]",
|
||||
"[ 9/4 → 5/2 | s:hh ]",
|
||||
"[ 5/2 → 11/4 | s:sd ]",
|
||||
"[ 11/4 → 3/1 | s:hh ]",
|
||||
"[ 3/1 → 13/4 | s:bd ]",
|
||||
"[ 13/4 → 7/2 | s:hh ]",
|
||||
"[ 7/2 → 15/4 | s:sd ]",
|
||||
"[ 15/4 → 4/1 | s:hh ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibrate" example index 1 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | s:bd vibStrong:1 vibWeak:0.5 ]",
|
||||
"[ 1/1 → 2/1 | s:hh vibStrong:0.1 vibWeak:0 ]",
|
||||
"[ 2/1 → 3/1 | s:sd vibStrong:0.5 vibWeak:0.8 ]",
|
||||
"[ 3/1 → 4/1 | s:hh vibStrong:0 vibWeak:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibrate" example index 2 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd ]",
|
||||
"[ 1/4 → 1/2 | s:bd ]",
|
||||
"[ 1/2 → 3/4 | s:bd ]",
|
||||
"[ 3/4 → 1/1 | s:bd ]",
|
||||
"[ 1/1 → 5/4 | s:bd ]",
|
||||
"[ 5/4 → 3/2 | s:bd ]",
|
||||
"[ 3/2 → 7/4 | s:bd ]",
|
||||
"[ 7/4 → 2/1 | s:bd ]",
|
||||
"[ 2/1 → 9/4 | s:bd ]",
|
||||
"[ 9/4 → 5/2 | s:bd ]",
|
||||
"[ 5/2 → 11/4 | s:bd ]",
|
||||
"[ 11/4 → 3/1 | s:bd ]",
|
||||
"[ 3/1 → 13/4 | s:bd ]",
|
||||
"[ 13/4 → 7/2 | s:bd ]",
|
||||
"[ 7/2 → 15/4 | s:bd ]",
|
||||
"[ 15/4 → 4/1 | s:bd ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibrate" example index 4 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibGamepadIndex:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibGamepadIndex:0 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibGamepadIndex:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibGamepadIndex:1 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibGamepadIndex:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibGamepadIndex:0 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibGamepadIndex:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibGamepadIndex:1 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibGamepadIndex:1 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibGamepadIndex:1 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibrate" example index 5 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 1/8 → 1/4 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 1/4 → 3/8 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ (3/8 → 7/16) ⇝ 1/2 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 3/8 ⇜ (7/16 → 1/2) | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 1/2 → 5/8 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 5/8 → 3/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 3/4 → 7/8 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 7/8 → 1/1 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 1/1 → 9/8 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 9/8 → 5/4 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 5/4 → 11/8 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ (11/8 → 23/16) ⇝ 3/2 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 11/8 ⇜ (23/16 → 3/2) | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 3/2 → 13/8 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 13/8 → 7/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 7/4 → 15/8 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 15/8 → 2/1 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 2/1 → 17/8 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 17/8 → 9/4 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 9/4 → 19/8 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ (19/8 → 39/16) ⇝ 5/2 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 19/8 ⇜ (39/16 → 5/2) | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 5/2 → 21/8 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 21/8 → 11/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 11/4 → 23/8 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 23/8 → 3/1 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 3/1 → 25/8 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 25/8 → 13/4 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 13/4 → 27/8 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ (27/8 → 55/16) ⇝ 7/2 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 27/8 ⇜ (55/16 → 7/2) | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 7/2 → 29/8 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 29/8 → 15/4 | s:bd vibGamepadIndex:0 ]",
|
||||
"[ 15/4 → 31/8 | s:bd vibGamepadIndex:1 ]",
|
||||
"[ 31/8 → 4/1 | s:bd vibGamepadIndex:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibrate" example index 6 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibGamepad:0 ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibGamepad:0 ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibGamepad:1 ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibGamepad:1 ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibGamepad:1 ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibGamepad:0 ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibGamepad:0 ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibGamepad:0 ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibGamepad:0 ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibGamepad:1 ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibGamepad:1 ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibGamepad:1 ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibGamepad:1 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibrate" example index 7 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd vibGamepadIndex:[0 1 0.5 200] ]",
|
||||
"[ 1/4 → 1/2 | s:hh vibGamepadIndex:[0 1 0.5 200] ]",
|
||||
"[ 1/2 → 3/4 | s:sd vibGamepadIndex:[1 0.8 0.3 150] ]",
|
||||
"[ 3/4 → 1/1 | s:hh vibGamepadIndex:[1 0.8 0.3 150] ]",
|
||||
"[ 1/1 → 5/4 | s:bd vibGamepadIndex:[0 1 0.5 200] ]",
|
||||
"[ 5/4 → 3/2 | s:hh vibGamepadIndex:[0 1 0.5 200] ]",
|
||||
"[ 3/2 → 7/4 | s:sd vibGamepadIndex:[1 0.8 0.3 150] ]",
|
||||
"[ 7/4 → 2/1 | s:hh vibGamepadIndex:[1 0.8 0.3 150] ]",
|
||||
"[ 2/1 → 9/4 | s:bd vibGamepadIndex:[0 1 0.5 200] ]",
|
||||
"[ 9/4 → 5/2 | s:hh vibGamepadIndex:[0 1 0.5 200] ]",
|
||||
"[ 5/2 → 11/4 | s:sd vibGamepadIndex:[1 0.8 0.3 150] ]",
|
||||
"[ 11/4 → 3/1 | s:hh vibGamepadIndex:[1 0.8 0.3 150] ]",
|
||||
"[ 3/1 → 13/4 | s:bd vibGamepadIndex:[0 1 0.5 200] ]",
|
||||
"[ 13/4 → 7/2 | s:hh vibGamepadIndex:[0 1 0.5 200] ]",
|
||||
"[ 7/2 → 15/4 | s:sd vibGamepadIndex:[1 0.8 0.3 150] ]",
|
||||
"[ 15/4 → 4/1 | s:hh vibGamepadIndex:[1 0.8 0.3 150] ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "vibrate" example index 8 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | s:bd vibGamepadIndex:[0 0.2 0.4 100] ]",
|
||||
"[ 1/8 → 1/4 | s:bd vibGamepadIndex:[0 0.2 0.4 100] ]",
|
||||
"[ 1/4 → 3/8 | s:bd vibGamepadIndex:[0 0.2 1 100] ]",
|
||||
"[ 3/8 → 1/2 | s:bd vibGamepadIndex:[0 0.2 1 100] ]",
|
||||
"[ 1/2 → 5/8 | s:bd vibGamepadIndex:[1 1 0.5 200] ]",
|
||||
"[ 5/8 → 3/4 | s:bd vibGamepadIndex:[1 1 0.5 200] ]",
|
||||
"[ 3/4 → 7/8 | s:bd vibGamepadIndex:[1 0.5 1 150] ]",
|
||||
"[ 7/8 → 1/1 | s:bd vibGamepadIndex:[1 0.5 1 150] ]",
|
||||
"[ 1/1 → 9/8 | s:bd vibGamepadIndex:[0 0.2 0.4 100] ]",
|
||||
"[ 9/8 → 5/4 | s:bd vibGamepadIndex:[0 0.2 0.4 100] ]",
|
||||
"[ 5/4 → 11/8 | s:bd vibGamepadIndex:[0 0.2 1 100] ]",
|
||||
"[ 11/8 → 3/2 | s:bd vibGamepadIndex:[0 0.2 1 100] ]",
|
||||
"[ 3/2 → 13/8 | s:bd vibGamepadIndex:[1 1 0.5 200] ]",
|
||||
"[ 13/8 → 7/4 | s:bd vibGamepadIndex:[1 1 0.5 200] ]",
|
||||
"[ 7/4 → 15/8 | s:bd vibGamepadIndex:[1 0.5 1 150] ]",
|
||||
"[ 15/8 → 2/1 | s:bd vibGamepadIndex:[1 0.5 1 150] ]",
|
||||
"[ 2/1 → 17/8 | s:bd vibGamepadIndex:[0 0.2 0.4 100] ]",
|
||||
"[ 17/8 → 9/4 | s:bd vibGamepadIndex:[0 0.2 0.4 100] ]",
|
||||
"[ 9/4 → 19/8 | s:bd vibGamepadIndex:[0 0.2 1 100] ]",
|
||||
"[ 19/8 → 5/2 | s:bd vibGamepadIndex:[0 0.2 1 100] ]",
|
||||
"[ 5/2 → 21/8 | s:bd vibGamepadIndex:[1 1 0.5 200] ]",
|
||||
"[ 21/8 → 11/4 | s:bd vibGamepadIndex:[1 1 0.5 200] ]",
|
||||
"[ 11/4 → 23/8 | s:bd vibGamepadIndex:[1 0.5 1 150] ]",
|
||||
"[ 23/8 → 3/1 | s:bd vibGamepadIndex:[1 0.5 1 150] ]",
|
||||
"[ 3/1 → 25/8 | s:bd vibGamepadIndex:[0 0.2 0.4 100] ]",
|
||||
"[ 25/8 → 13/4 | s:bd vibGamepadIndex:[0 0.2 0.4 100] ]",
|
||||
"[ 13/4 → 27/8 | s:bd vibGamepadIndex:[0 0.2 1 100] ]",
|
||||
"[ 27/8 → 7/2 | s:bd vibGamepadIndex:[0 0.2 1 100] ]",
|
||||
"[ 7/2 → 29/8 | s:bd vibGamepadIndex:[1 1 0.5 200] ]",
|
||||
"[ 29/8 → 15/4 | s:bd vibGamepadIndex:[1 1 0.5 200] ]",
|
||||
"[ 15/4 → 31/8 | s:bd vibGamepadIndex:[1 0.5 1 150] ]",
|
||||
"[ 31/8 → 4/1 | s:bd vibGamepadIndex:[1 0.5 1 150] ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "voicing" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:52 ]",
|
||||
|
||||
@@ -18,6 +18,14 @@ const skippedExamples = [
|
||||
'accelerationZ',
|
||||
'accelerationY',
|
||||
'accelerationX',
|
||||
'vibrate',
|
||||
'vibGamepadIndex',
|
||||
'vibGamepadId',
|
||||
'vibEnable',
|
||||
'vibWeak',
|
||||
'vibStrong',
|
||||
'vibDuration',
|
||||
'vibIntensity',
|
||||
'defaultmidimap',
|
||||
'midimaps',
|
||||
];
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ import '@strudel/xen/xen.mjs';
|
||||
import '../website/src/repl/piano';
|
||||
//import * as motionHelpers from '../packages/motion/index.mjs';
|
||||
//import * as geolocationHelpers from '../packages/geolocation/index.mjs';
|
||||
import * as gamepadHelpers from '../packages/gamepad/index.mjs';
|
||||
//import * as gamepadHelpers from '../packages/gamepad/index.mjs';
|
||||
|
||||
class MockedNode {
|
||||
chain() {
|
||||
@@ -141,8 +141,8 @@ evalScope(
|
||||
uiHelpersMocked,
|
||||
webaudio,
|
||||
tonalHelpers,
|
||||
gamepadHelpers,
|
||||
/*
|
||||
gamepadHelpers,
|
||||
toneHelpers,
|
||||
voicingHelpers,
|
||||
drawHelpers,
|
||||
|
||||
+171
-250
@@ -32,12 +32,7 @@
|
||||
"/packages/codemirror/keybindings.mjs": [
|
||||
"keybindings"
|
||||
],
|
||||
"/packages/codemirror/themes/theme-helper.mjs": [
|
||||
"createTheme"
|
||||
],
|
||||
"/packages/codemirror/themes/strudel-theme.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/strudel-theme.mjs": [],
|
||||
"/packages/codemirror/themes/bluescreen.mjs": [
|
||||
"settings"
|
||||
],
|
||||
@@ -53,103 +48,7 @@
|
||||
"/packages/codemirror/themes/algoboy.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/CutiePi.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/sonic-pink.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/red-text.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/green-text.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/archBtw.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/fruitDaw.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/bluescreenlight.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/androidstudio.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/atomone.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/aura.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/darcula.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/dracula.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/duotoneDark.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/eclipse.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/githubDark.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/githubLight.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/gruvboxDark.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/gruvboxLight.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/materialDark.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/materialLight.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/nord.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/monokai.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/solarizedDark.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/solarizedLight.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/sublime.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/tokyoNight.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/tokioNightStorm.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/tokyoNightDay.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/vscodeDark.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/vscodeLight.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/xcodeLight.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/bbedit.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes/noctisLilac.mjs": [
|
||||
"/packages/codemirror/themes/terminal.mjs": [
|
||||
"settings"
|
||||
],
|
||||
"/packages/codemirror/themes.mjs": [
|
||||
@@ -162,12 +61,7 @@
|
||||
"activateTheme"
|
||||
],
|
||||
"/packages/codemirror/slider.mjs": [
|
||||
"sliderValues",
|
||||
"SliderWidget",
|
||||
"setSliderWidgets",
|
||||
"updateSliderWidgets",
|
||||
"sliderPlugin",
|
||||
"sliderWithID"
|
||||
"acorn parse error: SyntaxError: undefined"
|
||||
],
|
||||
"/packages/codemirror/widget.mjs": [
|
||||
"addWidget",
|
||||
@@ -184,59 +78,6 @@
|
||||
"StrudelMirror"
|
||||
],
|
||||
"/packages/codemirror/index.mjs": [],
|
||||
"/packages/core/logger.mjs": [
|
||||
"logKey",
|
||||
"errorLogger",
|
||||
"logger"
|
||||
],
|
||||
"/packages/core/util.mjs": [
|
||||
"isNoteWithOctave",
|
||||
"isNote",
|
||||
"tokenizeNote",
|
||||
"noteToMidi",
|
||||
"midiToFreq",
|
||||
"freqToMidi",
|
||||
"valueToMidi",
|
||||
"getEventOffsetMs",
|
||||
"_mod",
|
||||
"averageArray",
|
||||
"nanFallback",
|
||||
"getSoundIndex",
|
||||
"getPlayableNoteValue",
|
||||
"getFrequency",
|
||||
"rotate",
|
||||
"pipe",
|
||||
"compose",
|
||||
"flatten",
|
||||
"id",
|
||||
"constant",
|
||||
"listRange",
|
||||
"curry",
|
||||
"parseNumeral",
|
||||
"mapArgs",
|
||||
"numeralArgs",
|
||||
"parseFractional",
|
||||
"fractionalArgs",
|
||||
"splitAt",
|
||||
"zipWith",
|
||||
"pairs",
|
||||
"clamp",
|
||||
"sol2note",
|
||||
"uniq",
|
||||
"uniqsort",
|
||||
"uniqsortr",
|
||||
"unicodeToBase64",
|
||||
"base64ToUnicode",
|
||||
"code2hash",
|
||||
"hash2code",
|
||||
"objectMap",
|
||||
"cycleToSeconds",
|
||||
"ClockCollator",
|
||||
"getPerformanceTimeSeconds",
|
||||
"keyAlias",
|
||||
"getCurrentKeyboardState",
|
||||
"stringifyValues"
|
||||
],
|
||||
"/packages/core/fraction.mjs": [
|
||||
"gcd",
|
||||
"lcm"
|
||||
@@ -250,6 +91,45 @@
|
||||
"/packages/core/state.mjs": [
|
||||
"State"
|
||||
],
|
||||
"/packages/core/logger.mjs": [
|
||||
"logKey",
|
||||
"logger"
|
||||
],
|
||||
"/packages/core/util.mjs": [
|
||||
"isNoteWithOctave",
|
||||
"isNote",
|
||||
"tokenizeNote",
|
||||
"noteToMidi",
|
||||
"midiToFreq",
|
||||
"freqToMidi",
|
||||
"valueToMidi",
|
||||
"_mod",
|
||||
"nanFallback",
|
||||
"getSoundIndex",
|
||||
"getPlayableNoteValue",
|
||||
"getFrequency",
|
||||
"rotate",
|
||||
"pipe",
|
||||
"compose",
|
||||
"flatten",
|
||||
"constant",
|
||||
"listRange",
|
||||
"curry",
|
||||
"parseNumeral",
|
||||
"mapArgs",
|
||||
"numeralArgs",
|
||||
"parseFractional",
|
||||
"fractionalArgs",
|
||||
"splitAt",
|
||||
"zipWith",
|
||||
"clamp",
|
||||
"sol2note",
|
||||
"unicodeToBase64",
|
||||
"base64ToUnicode",
|
||||
"code2hash",
|
||||
"hash2code",
|
||||
"objectMap"
|
||||
],
|
||||
"/packages/core/value.mjs": [
|
||||
"unionWithObj",
|
||||
"valued",
|
||||
@@ -258,8 +138,10 @@
|
||||
],
|
||||
"/packages/core/drawLine.mjs": [],
|
||||
"/packages/core/pattern.mjs": [
|
||||
"calculateSteps",
|
||||
"setStringParser",
|
||||
"polyrhythm",
|
||||
"pr",
|
||||
"pm",
|
||||
"nothing",
|
||||
"isPattern",
|
||||
"reify",
|
||||
@@ -267,12 +149,8 @@
|
||||
"stackRight",
|
||||
"stackCentre",
|
||||
"stackBy",
|
||||
"bind",
|
||||
"innerBind",
|
||||
"outerBind",
|
||||
"squeezeBind",
|
||||
"stepBind",
|
||||
"polyBind",
|
||||
"fastcat",
|
||||
"_polymeterListSteps",
|
||||
"set",
|
||||
"keep",
|
||||
"keepif",
|
||||
@@ -296,51 +174,96 @@
|
||||
"func",
|
||||
"compressSpan",
|
||||
"compressspan",
|
||||
"fastgap",
|
||||
"focusSpan",
|
||||
"focusspan",
|
||||
"density",
|
||||
"sparsity",
|
||||
"zoomArc",
|
||||
"zoomarc",
|
||||
"inv",
|
||||
"juxby",
|
||||
"echowith",
|
||||
"stutWith",
|
||||
"stutwith",
|
||||
"iterback",
|
||||
"slowchunk",
|
||||
"slowChunk",
|
||||
"chunkback",
|
||||
"fastchunk",
|
||||
"bypass",
|
||||
"hsla",
|
||||
"hsl",
|
||||
"_retime",
|
||||
"_slices",
|
||||
"_fitslice",
|
||||
"_match",
|
||||
"_polymeterListSteps",
|
||||
"shrinklist",
|
||||
"s_cat",
|
||||
"s_alt",
|
||||
"s_polymeter",
|
||||
"s_taper",
|
||||
"s_taperlist",
|
||||
"s_add",
|
||||
"s_sub",
|
||||
"s_expand",
|
||||
"s_extend",
|
||||
"s_contract",
|
||||
"s_tour",
|
||||
"s_zip",
|
||||
"steps",
|
||||
"_morph"
|
||||
"loopat",
|
||||
"loopatcps"
|
||||
],
|
||||
"/packages/core/controls.mjs": [
|
||||
"createParam",
|
||||
"isControlName",
|
||||
"registerControl",
|
||||
"sound",
|
||||
"src",
|
||||
"att",
|
||||
"fmi",
|
||||
"fmrelease",
|
||||
"fmvelocity",
|
||||
"analyze",
|
||||
"fft",
|
||||
"dec",
|
||||
"sus",
|
||||
"rel",
|
||||
"hold",
|
||||
"duck",
|
||||
"bandf",
|
||||
"bp",
|
||||
"bandq",
|
||||
"loopb",
|
||||
"loope",
|
||||
"ch",
|
||||
"phaserrate",
|
||||
"phasr",
|
||||
"ph",
|
||||
"phs",
|
||||
"phc",
|
||||
"phd",
|
||||
"phasdp",
|
||||
"cutoff",
|
||||
"ctf",
|
||||
"lp",
|
||||
"lpe",
|
||||
"hpe",
|
||||
"bpe",
|
||||
"lpa",
|
||||
"hpa",
|
||||
"bpa",
|
||||
"lpd",
|
||||
"hpd",
|
||||
"bpd",
|
||||
"lps",
|
||||
"hps",
|
||||
"bps",
|
||||
"lpr",
|
||||
"hpr",
|
||||
"bpr",
|
||||
"fanchor",
|
||||
"vibrato",
|
||||
"v",
|
||||
"vmod",
|
||||
"hcutoff",
|
||||
"hp",
|
||||
"hresonance",
|
||||
"resonance",
|
||||
"delayfb",
|
||||
"dfb",
|
||||
"delayt",
|
||||
"dt",
|
||||
"lock",
|
||||
"det",
|
||||
"fadeTime",
|
||||
"fadeOutTime",
|
||||
"fadeInTime",
|
||||
"patt",
|
||||
"pdec",
|
||||
"psustain",
|
||||
"psus",
|
||||
"prel",
|
||||
"gate",
|
||||
"gat",
|
||||
"activeLabel",
|
||||
@@ -368,13 +291,26 @@
|
||||
"offset",
|
||||
"octaves",
|
||||
"mode",
|
||||
"rlp",
|
||||
"rdim",
|
||||
"rfade",
|
||||
"ir",
|
||||
"size",
|
||||
"sz",
|
||||
"rsize",
|
||||
"dist",
|
||||
"compressorKnee",
|
||||
"compressorRatio",
|
||||
"compressorAttack",
|
||||
"compressorRelease",
|
||||
"waveloss",
|
||||
"density",
|
||||
"expression",
|
||||
"sustainpedal",
|
||||
"tremolodepth",
|
||||
"tremdp",
|
||||
"tremolorate",
|
||||
"tremr",
|
||||
"fshift",
|
||||
"fshiftnote",
|
||||
"fshiftphase",
|
||||
@@ -400,15 +336,27 @@
|
||||
"binshift",
|
||||
"hbrick",
|
||||
"lbrick",
|
||||
"midichan",
|
||||
"control",
|
||||
"ccn",
|
||||
"ccv",
|
||||
"polyTouch",
|
||||
"midibend",
|
||||
"miditouch",
|
||||
"ctlNum",
|
||||
"frameRate",
|
||||
"frames",
|
||||
"hours",
|
||||
"midicmd",
|
||||
"minutes",
|
||||
"progNum",
|
||||
"seconds",
|
||||
"songPtr",
|
||||
"uid",
|
||||
"val",
|
||||
"cps",
|
||||
"legato",
|
||||
"dur",
|
||||
"zrand",
|
||||
"curve",
|
||||
"deltaSlide",
|
||||
@@ -420,40 +368,44 @@
|
||||
"zmod",
|
||||
"zcrush",
|
||||
"zdelay",
|
||||
"tremolo",
|
||||
"zzfx",
|
||||
"colour",
|
||||
"createParams",
|
||||
"ad",
|
||||
"ds",
|
||||
"ar",
|
||||
"midimap",
|
||||
"ctlNum",
|
||||
"polyTouch",
|
||||
"getControlName"
|
||||
"ar"
|
||||
],
|
||||
"/packages/core/euclid.mjs": [
|
||||
"bjork",
|
||||
"e",
|
||||
"euclidrot"
|
||||
],
|
||||
"/packages/core/zyklus.mjs": [],
|
||||
"/packages/core/signal.mjs": [
|
||||
"randrun",
|
||||
"steady",
|
||||
"signal",
|
||||
"isaw",
|
||||
"isaw2",
|
||||
"saw2",
|
||||
"sine2",
|
||||
"cosine2",
|
||||
"square2",
|
||||
"tri2",
|
||||
"time",
|
||||
"_brandBy",
|
||||
"_irand",
|
||||
"pickSqueeze",
|
||||
"pickmodSqueeze",
|
||||
"__chooseWith",
|
||||
"chooseIn",
|
||||
"chooseOut",
|
||||
"randcat",
|
||||
"wrandcat",
|
||||
"perlinWith",
|
||||
"berlinWith",
|
||||
"degradeByWith",
|
||||
"_keyDown"
|
||||
"degradeByWith"
|
||||
],
|
||||
"/packages/core/pick.mjs": [],
|
||||
"/packages/core/speak.mjs": [
|
||||
"speak"
|
||||
],
|
||||
"/packages/core/evaluate.mjs": [
|
||||
"strudelScope",
|
||||
"evalScope",
|
||||
"evaluate"
|
||||
],
|
||||
@@ -488,18 +440,13 @@
|
||||
"isTauri"
|
||||
],
|
||||
"/packages/desktopbridge/midibridge.mjs": [],
|
||||
"/packages/desktopbridge/oscbridge.mjs": [
|
||||
"oscTriggerTauri"
|
||||
],
|
||||
"/packages/desktopbridge/oscbridge.mjs": [],
|
||||
"/packages/desktopbridge/index.mjs": [],
|
||||
"/packages/draw/draw.mjs": [
|
||||
"getDrawContext",
|
||||
"cleanupDraw",
|
||||
"Framer",
|
||||
"Drawer",
|
||||
"getComputedPropertyValue",
|
||||
"getTheme",
|
||||
"setTheme"
|
||||
"Drawer"
|
||||
],
|
||||
"/packages/draw/animate.mjs": [
|
||||
"x",
|
||||
@@ -520,19 +467,16 @@
|
||||
"convertHexToNumber"
|
||||
],
|
||||
"/packages/draw/pianoroll.mjs": [
|
||||
"__pianoroll",
|
||||
"getDrawOptions",
|
||||
"getPunchcardPainter",
|
||||
"drawPianoroll"
|
||||
],
|
||||
"/packages/draw/spiral.mjs": [],
|
||||
"/packages/draw/pitchwheel.mjs": [],
|
||||
"/packages/draw/index.mjs": [],
|
||||
"/packages/midi/midi.mjs": [
|
||||
"WebMidi",
|
||||
"enableWebMidi",
|
||||
"midicontrolMap",
|
||||
"midisoundMap"
|
||||
"midin"
|
||||
],
|
||||
"/packages/midi/index.mjs": [],
|
||||
"/packages/mini/krill-parser.js": [],
|
||||
@@ -552,11 +496,12 @@
|
||||
"/packages/repl/prebake.mjs": [
|
||||
"prebake"
|
||||
],
|
||||
"/packages/repl/repl-component.mjs": [],
|
||||
"/packages/repl/repl-component.mjs": [
|
||||
"acorn parse error: SyntaxError: undefined"
|
||||
],
|
||||
"/packages/repl/index.mjs": [],
|
||||
"/packages/soundfonts/gm.mjs": [],
|
||||
"/packages/soundfonts/fontloader.mjs": [
|
||||
"setSoundfontUrl",
|
||||
"getFontBufferSource",
|
||||
"getFontPitch",
|
||||
"registerSoundfonts"
|
||||
@@ -577,7 +522,6 @@
|
||||
"vowelFormant"
|
||||
],
|
||||
"/packages/superdough/logger.mjs": [
|
||||
"errorLogger",
|
||||
"logger",
|
||||
"setLogger"
|
||||
],
|
||||
@@ -590,19 +534,10 @@
|
||||
"valueToMidi",
|
||||
"nanFallback",
|
||||
"_mod",
|
||||
"getSoundIndex",
|
||||
"cycleToSeconds",
|
||||
"secondsToCycle"
|
||||
],
|
||||
"/packages/superdough/noise.mjs": [
|
||||
"getNoiseBuffer",
|
||||
"getNoiseOscillator",
|
||||
"getNoiseMix"
|
||||
"getSoundIndex"
|
||||
],
|
||||
"/packages/superdough/helpers.mjs": [
|
||||
"noises",
|
||||
"gainNode",
|
||||
"getWorklet",
|
||||
"getParamADSR",
|
||||
"getCompressor",
|
||||
"getADSRValues",
|
||||
@@ -615,8 +550,6 @@
|
||||
],
|
||||
"/packages/superdough/sampler.mjs": [
|
||||
"getCachedBuffer",
|
||||
"getSampleInfo",
|
||||
"getSampleBuffer",
|
||||
"getSampleBufferSource",
|
||||
"loadBuffer",
|
||||
"reverseBuffer",
|
||||
@@ -626,32 +559,18 @@
|
||||
"onTriggerSample"
|
||||
],
|
||||
"/packages/superdough/superdough.mjs": [
|
||||
"DEFAULT_MAX_POLYPHONY",
|
||||
"setMaxPolyphony",
|
||||
"setMultiChannelOrbits",
|
||||
"soundMap",
|
||||
"registerSound",
|
||||
"applyGainCurve",
|
||||
"setGainCurve",
|
||||
"getSound",
|
||||
"getAudioDevices",
|
||||
"setDefault",
|
||||
"resetDefaults",
|
||||
"setDefaultValue",
|
||||
"getDefaultValue",
|
||||
"setDefaultValues",
|
||||
"resetDefaultValues",
|
||||
"setVersionDefaults",
|
||||
"resetLoadedSounds",
|
||||
"setDefaultAudioContext",
|
||||
"getAudioContext",
|
||||
"getAudioContextCurrentTime",
|
||||
"getWorklet",
|
||||
"initAudio",
|
||||
"initAudioOnFirstClick",
|
||||
"initializeAudioOutput",
|
||||
"connectToDestination",
|
||||
"panic",
|
||||
"getLfo",
|
||||
"analysers",
|
||||
"analysersData",
|
||||
"getAnalyserById",
|
||||
@@ -660,13 +579,17 @@
|
||||
"superdough",
|
||||
"superdoughTrigger"
|
||||
],
|
||||
"/packages/superdough/noise.mjs": [
|
||||
"getNoiseOscillator",
|
||||
"getNoiseMix"
|
||||
],
|
||||
"/packages/superdough/synth.mjs": [
|
||||
"registerSynthSounds",
|
||||
"waveformN",
|
||||
"getOscillator"
|
||||
],
|
||||
"/packages/superdough/zzfx_fork.mjs": [
|
||||
"buildSamples"
|
||||
"acorn parse error: SyntaxError: undefined"
|
||||
],
|
||||
"/packages/superdough/zzfx.mjs": [
|
||||
"getZZFX",
|
||||
@@ -717,7 +640,6 @@
|
||||
],
|
||||
"/packages/transpiler/transpiler.mjs": [
|
||||
"registerWidgetType",
|
||||
"registerLanguage",
|
||||
"transpiler",
|
||||
"getWidgetID"
|
||||
],
|
||||
@@ -732,7 +654,6 @@
|
||||
"drawTimeScope",
|
||||
"drawFrequencyScope"
|
||||
],
|
||||
"/packages/webaudio/spectrum.mjs": [],
|
||||
"/packages/webaudio/index.mjs": [],
|
||||
"/packages/xen/xen.mjs": [
|
||||
"edo",
|
||||
|
||||
Reference in New Issue
Block a user