Skip to content

Commit

Permalink
Merge branch 'main' into origin/daslyfe/subcycle
Browse files Browse the repository at this point in the history
  • Loading branch information
daslyfe committed Jan 16, 2025
2 parents c33c8b5 + 55c226c commit 6e5d8ee
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 13 deletions.
12 changes: 12 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ pnpm --filter "./packages/**" publish --access public
To manually publish a single package, increase the version in the `package.json`, then run `pnpm publish`.
Important: Always publish with `pnpm`, as `npm` does not support overriding main files in `publishConfig`, which is done in all the packages.


## useful commands
```sh
#regenerate the test snapshots (ex: when updating or creating new pattern functions)
pnpm snapshot

#start the OSC server
pnpm run osc

#build the standalone version
pnpm tauri build
```
## Have Fun

Remember to have fun, and that this project is driven by the passion of volunteers!
12 changes: 12 additions & 0 deletions packages/core/pattern.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1491,6 +1491,14 @@ function _sequenceCount(x) {
export const mask = curry((a, b) => reify(b).mask(a));
export const struct = curry((a, b) => reify(b).struct(a));
export const superimpose = curry((a, b) => reify(b).superimpose(...a));
export const withValue = curry((a, b) => reify(b).withValue(a));

export const bind = curry((a, b) => reify(b).bind(a));
export const innerBind = curry((a, b) => reify(b).innerBind(a));
export const outerBind = curry((a, b) => reify(b).outerBind(a));
export const squeezeBind = curry((a, b) => reify(b).squeezeBind(a));
export const stepBind = curry((a, b) => reify(b).stepBind(a));
export const polyBind = curry((a, b) => reify(b).polyBind(a));

// operators
export const set = curry((a, b) => reify(b).set(a));
Expand Down Expand Up @@ -2539,6 +2547,10 @@ Pattern.prototype.stepJoin = function () {
return new Pattern(q, first_t);
};

Pattern.prototype.stepBind = function (func) {
return this.fmap(func).stepJoin();
};

export function _retime(timedHaps) {
const occupied_perc = timedHaps.filter((t, pat) => pat.hasTactus).reduce((a, b) => a.add(b), Fraction(0));
const occupied_tactus = removeUndefineds(timedHaps.map((t, pat) => pat.tactus)).reduce(
Expand Down
48 changes: 47 additions & 1 deletion packages/core/signal.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ This program is free software: you can redistribute it and/or modify it under th
import { Hap } from './hap.mjs';
import { Pattern, fastcat, reify, silence, stack, register } from './pattern.mjs';
import Fraction from './fraction.mjs';
import { id, _mod } from './util.mjs';

import { id, keyAlias, getCurrentKeyboardState } from './util.mjs';

export function steady(value) {
// A continuous value
Expand Down Expand Up @@ -639,3 +640,48 @@ export const never = register('never', function (_, pat) {
export const always = register('always', function (func, pat) {
return func(pat);
});

//keyname: string | Array<string>
//keyname reference: https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values
export function _keyDown(keyname) {
if (Array.isArray(keyname) === false) {
keyname = [keyname];
}
const keyState = getCurrentKeyboardState();
return keyname.every((x) => {
const keyName = keyAlias.get(x) ?? x;
return keyState[keyName];
});
}

/**
*
* Do something on a keypress, or array of keypresses
* [Key name reference](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values)
*
* @name whenKey
* @memberof Pattern
* @returns Pattern
* @example
* s("bd(5,8)").whenKey("Control:j", x => x.segment(16).color("red")).whenKey("Control:i", x => x.fast(2).color("blue"))
*/

export const whenKey = register('whenKey', function (input, func, pat) {
return pat.when(_keyDown(input), func);
});

/**
*
* returns true when a key or array of keys is held
* [Key name reference](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values)
*
* @name keyDown
* @memberof Pattern
* @returns Pattern
* @example
* keyDown("Control:j").pick([s("bd(5,8)"), s("cp(3,8)")])
*/

export const keyDown = register('keyDown', function (pat) {
return pat.fmap(_keyDown);
});
32 changes: 32 additions & 0 deletions packages/core/util.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,38 @@ function getUnixTimeSeconds() {
return Date.now() * 0.001;
}

export const keyAlias = new Map([
['control', 'Control'],
['ctrl', 'Control'],
['alt', 'Alt'],
['shift', 'Shift'],
['down', 'ArrowDown'],
['up', 'ArrowUp'],
['left', 'ArrowLeft'],
['right', 'ArrowRight'],
]);
let keyState;

export function getCurrentKeyboardState() {
if (keyState == null) {
if (typeof window === 'undefined') {
return;
}
keyState = {};
// Listen for the keydown event to mark the key as pressed
window.addEventListener('keydown', (event) => {
keyState[event.key] = true; // Mark the key as pressed
});

// Listen for the keyup event to mark the key as released
window.addEventListener('keyup', (event) => {
keyState[event.key] = false; // Mark the key as released
});
}

return { ...keyState }; // Return a shallow copy of the key state object
}

// Floating point versions, see Fraction for rational versions
// // greatest common divisor
// export const gcd = function (x, y, ...z) {
Expand Down
22 changes: 22 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions test/__snapshots__/examples.test.mjs.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4095,6 +4095,8 @@ exports[`runs examples > example "juxBy" example index 0 1`] = `
]
`;

exports[`runs examples > example "keyDown" example index 0 1`] = `[]`;

exports[`runs examples > example "lastOf" example index 0 1`] = `
[
"[ 0/1 → 1/4 | note:c3 ]",
Expand Down Expand Up @@ -8862,6 +8864,8 @@ exports[`runs examples > example "when" example index 0 1`] = `
]
`;

exports[`runs examples > example "whenKey" example index 0 1`] = `[]`;

exports[`runs examples > example "withValue" example index 0 1`] = `
[
"[ 0/1 → 1/3 | 10 ]",
Expand Down
13 changes: 1 addition & 12 deletions website/src/pages/functions/value-modifiers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,7 @@ To modify a parameter value, you can either:

<MiniRepl client:only="react" tune={`note("50 60 70").room(.1).add(note("<0 1 2>")).log()`} />

- Modify _all_ numeral params:

<MiniRepl client:only="react" tune={`note("50 60 70").room(.1).add("<0 1 2>").log()`} />

Which of these 3 ways to use strongly depends on the context!
Note that the order of chaining param functions also matters!
In the last example, the `room` value would not have changed if it was applied later:

<MiniRepl client:only="react" tune={`note("50 60 70").add("<0 1 2>").room(.1).log()`} />

This shows how the execution of the chained functions goes from left to right.
In this case, the `.add` will only modify what's on the left side.
Remember the execution of the chained functions goes from left to right.

# Operators

Expand Down

0 comments on commit 6e5d8ee

Please sign in to comment.