Merge branch 'main' into daslyfe/gainmod
This commit is contained in:
commit
3ea91adfd6
10 changed files with 125 additions and 37 deletions
|
|
@ -150,6 +150,7 @@ Important: Always publish with `pnpm`, as `npm` does not support overriding main
|
||||||
|
|
||||||
|
|
||||||
## useful commands
|
## useful commands
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
#regenerate the test snapshots (ex: when updating or creating new pattern functions)
|
#regenerate the test snapshots (ex: when updating or creating new pattern functions)
|
||||||
pnpm snapshot
|
pnpm snapshot
|
||||||
|
|
@ -160,6 +161,81 @@ pnpm run osc
|
||||||
#build the standalone version
|
#build the standalone version
|
||||||
pnpm tauri build
|
pnpm tauri build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## version tag patching
|
||||||
|
|
||||||
|
here's a little guide on how to patch patterns in the database to prevent breaking old patterns due to breaking changes in newer versions.
|
||||||
|
|
||||||
|
the general tactic is to use `// @version x.y` to tag a pattern with a specific strudel version. when a pattern is evaluated, this metadata will de-activate any breaking changes that came after the specified version.
|
||||||
|
for example, in version 1.1, the default value for `fanchor` was changed from `0.5` to `0`.
|
||||||
|
if play a pattern that was made before that change, sounds that use filter evenlopes can sound very different, so by adding `// @version 1.0` will make it sound like it used to.
|
||||||
|
before releasing a new version with breaking changes, we can edit all patterns in the database, inserting the version tag they were created under:
|
||||||
|
|
||||||
|
as an example, to release version 1.2, do the following:
|
||||||
|
|
||||||
|
1. get date range
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# get date of last version:
|
||||||
|
git log -1 --format=%aI @strudel/core@1.1.0
|
||||||
|
# 2024-05-31T23:07:26+02:00
|
||||||
|
|
||||||
|
# get date of current version:
|
||||||
|
git log -1 --format=%aI @strudel/core@1.2.0
|
||||||
|
# 2025-05-01T12:39:24+02:00
|
||||||
|
# might also use todays timestamp if version is not yet released
|
||||||
|
```
|
||||||
|
|
||||||
|
now we know, all patterns between these 2 dates have to receive a version tag (unless they already have one).
|
||||||
|
|
||||||
|
2. get patterns in question
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT *
|
||||||
|
FROM code_v1
|
||||||
|
WHERE code NOT LIKE '%@version%'
|
||||||
|
AND created_at > '2024-05-31T23:07:26+02:00'
|
||||||
|
AND created_at < '2025-05-01T12:39:24+02:00'
|
||||||
|
ORDER BY created_at ASC;
|
||||||
|
```
|
||||||
|
|
||||||
|
this gives us all unversioned patterns that were saved between 1.1.0 and 1.2.0. in this case, it's 9373 patterns!
|
||||||
|
|
||||||
|
3. insert version tags
|
||||||
|
|
||||||
|
we are now ready to insert the version tag to these patterns.
|
||||||
|
before updating thousands of patterns, it's probably a good idea to test if a single one gets udpated:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
UPDATE code_v1
|
||||||
|
SET code = code || E'\n// @version 1.1'
|
||||||
|
WHERE hash = 'Ns2sMB40yIw4';
|
||||||
|
```
|
||||||
|
|
||||||
|
after [verifying](https://strudel.cc/?Ns2sMB40yIw4) that the version tag has been added, let's insert it everywhere:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
UPDATE code_v1
|
||||||
|
SET code = code || E'\n// @version 1.1'
|
||||||
|
WHERE code NOT LIKE '%@version%'
|
||||||
|
AND created_at > '2024-05-31T23:07:26+02:00'
|
||||||
|
AND created_at < '2025-05-01T12:39:24+02:00'
|
||||||
|
```
|
||||||
|
|
||||||
|
4. verify
|
||||||
|
|
||||||
|
we can verify that the edits worked by querying all patterns that contain the new version tag:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT *
|
||||||
|
FROM code_v1
|
||||||
|
WHERE code LIKE '%@version 1.1%'
|
||||||
|
AND created_at > '2024-05-31T23:07:26+02:00'
|
||||||
|
AND created_at < '2025-05-01T12:39:24+02:00'
|
||||||
|
ORDER BY created_at ASC;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Have Fun
|
## Have Fun
|
||||||
|
|
||||||
Remember to have fun, and that this project is driven by the passion of volunteers!
|
Remember to have fun, and that this project is driven by the passion of volunteers!
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,7 @@ Licensing info for the default sound banks can be found over on the [dough-sampl
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
There are many ways to contribute to this project! See [contribution guide](./CONTRIBUTING.md).
|
There are many ways to contribute to this project! See [contribution guide](./CONTRIBUTING.md). You can find the full list of contributors [here](https://codeberg.org/uzu/strudel/activity/contributors).
|
||||||
|
|
||||||
<a href="https://codeberg.org/uzu/strudel/activity/contributors">
|
|
||||||
<img src="https://contrib.rocks/image?repo=tidalcycles/strudel" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
Made with [contrib.rocks](https://contrib.rocks).
|
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,7 @@ export const randrun = (n) => {
|
||||||
const rands = timeToRands(t.floor().add(0.5), n);
|
const rands = timeToRands(t.floor().add(0.5), n);
|
||||||
const nums = rands
|
const nums = rands
|
||||||
.map((n, i) => [n, i])
|
.map((n, i) => [n, i])
|
||||||
.sort((a, b) => a[0] > b[0] - a[0] < b[0])
|
.sort((a, b) => (a[0] > b[0]) - (a[0] < b[0]))
|
||||||
.map((x) => x[1]);
|
.map((x) => x[1]);
|
||||||
const i = t.cyclePos().mul(n).floor() % n;
|
const i = t.cyclePos().mul(n).floor() % n;
|
||||||
return nums[i];
|
return nums[i];
|
||||||
|
|
|
||||||
|
|
@ -537,7 +537,7 @@ export default {
|
||||||
],
|
],
|
||||||
gm_synth_bass_1: [
|
gm_synth_bass_1: [
|
||||||
// Synth Bass 1: Bass
|
// Synth Bass 1: Bass
|
||||||
'0380_Aspirin_sf2_file',
|
// '0380_Aspirin_sf2_file', // broken in safari https://codeberg.org/uzu/strudel/issues/1384
|
||||||
'0380_Chaos_sf2_file',
|
'0380_Chaos_sf2_file',
|
||||||
'0380_FluidR3_GM_sf2_file',
|
'0380_FluidR3_GM_sf2_file',
|
||||||
// 0380_GeneralUserGS_sf2_file // laut
|
// 0380_GeneralUserGS_sf2_file // laut
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ export const getAudioDevices = async () => {
|
||||||
return devicesMap;
|
return devicesMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultDefaultValues = {
|
let defaultDefaultValues = {
|
||||||
s: 'triangle',
|
s: 'triangle',
|
||||||
gain: 0.8,
|
gain: 0.8,
|
||||||
postgain: 1,
|
postgain: 1,
|
||||||
|
|
@ -150,6 +150,17 @@ const defaultDefaultValues = {
|
||||||
fft: 8,
|
fft: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const defaultDefaultDefaultValues = Object.freeze({ ...defaultDefaultValues });
|
||||||
|
|
||||||
|
export function setDefault(control, value) {
|
||||||
|
// const main = getControlName(control); // we cant do this because superdough is independent of strudel/core
|
||||||
|
defaultDefaultValues[control] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetDefaults() {
|
||||||
|
defaultDefaultValues = { ...defaultDefaultDefaultValues };
|
||||||
|
}
|
||||||
|
|
||||||
let defaultControls = new Map(Object.entries(defaultDefaultValues));
|
let defaultControls = new Map(Object.entries(defaultDefaultValues));
|
||||||
|
|
||||||
export function setDefaultValue(key, value) {
|
export function setDefaultValue(key, value) {
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,10 @@ export function registerSynthSounds() {
|
||||||
const gainAdjustment = 1 / Math.sqrt(voices);
|
const gainAdjustment = 1 / Math.sqrt(voices);
|
||||||
getPitchEnvelope(o.parameters.get('detune'), value, begin, holdend);
|
getPitchEnvelope(o.parameters.get('detune'), value, begin, holdend);
|
||||||
const vibratoOscillator = getVibratoOscillator(o.parameters.get('detune'), value, begin);
|
const vibratoOscillator = getVibratoOscillator(o.parameters.get('detune'), value, begin);
|
||||||
const fm = applyFM(o.parameters.get('frequency'), value, begin);
|
// const fm = applyFM(o.parameters.get('frequency'), value, begin);
|
||||||
|
// https://codeberg.org/uzu/strudel/issues/1428
|
||||||
|
// if you think about re-enabling this, please test with fm > 1 first
|
||||||
|
// it's like 10x gain, so it's really dangerous
|
||||||
let envGain = gainNode(1);
|
let envGain = gainNode(1);
|
||||||
envGain = o.connect(envGain);
|
envGain = o.connect(envGain);
|
||||||
|
|
||||||
|
|
@ -133,7 +136,7 @@ export function registerSynthSounds() {
|
||||||
destroyAudioWorkletNode(o);
|
destroyAudioWorkletNode(o);
|
||||||
envGain.disconnect();
|
envGain.disconnect();
|
||||||
onended();
|
onended();
|
||||||
fm?.stop();
|
// fm?.stop();
|
||||||
vibratoOscillator?.stop();
|
vibratoOscillator?.stop();
|
||||||
},
|
},
|
||||||
begin,
|
begin,
|
||||||
|
|
|
||||||
|
|
@ -9047,46 +9047,46 @@ exports[`runs examples > example "shrink" example index 3 1`] = `
|
||||||
|
|
||||||
exports[`runs examples > example "shuffle" example index 0 1`] = `
|
exports[`runs examples > example "shuffle" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/4 | note:c s:piano ]",
|
"[ 0/1 → 1/4 | note:e s:piano ]",
|
||||||
"[ 1/4 → 1/2 | note:d s:piano ]",
|
"[ 1/4 → 1/2 | note:d s:piano ]",
|
||||||
"[ 1/2 → 3/4 | note:e s:piano ]",
|
"[ 1/2 → 3/4 | note:f s:piano ]",
|
||||||
"[ 3/4 → 1/1 | note:f s:piano ]",
|
"[ 3/4 → 1/1 | note:c s:piano ]",
|
||||||
"[ 1/1 → 5/4 | note:c s:piano ]",
|
"[ 1/1 → 5/4 | note:e s:piano ]",
|
||||||
"[ 5/4 → 3/2 | note:d s:piano ]",
|
"[ 5/4 → 3/2 | note:c s:piano ]",
|
||||||
"[ 3/2 → 7/4 | note:e s:piano ]",
|
"[ 3/2 → 7/4 | note:f s:piano ]",
|
||||||
"[ 7/4 → 2/1 | note:f s:piano ]",
|
"[ 7/4 → 2/1 | note:d s:piano ]",
|
||||||
"[ 2/1 → 9/4 | note:c s:piano ]",
|
"[ 2/1 → 9/4 | note:d s:piano ]",
|
||||||
"[ 9/4 → 5/2 | note:d s:piano ]",
|
"[ 9/4 → 5/2 | note:c s:piano ]",
|
||||||
"[ 5/2 → 11/4 | note:e s:piano ]",
|
"[ 5/2 → 11/4 | note:e s:piano ]",
|
||||||
"[ 11/4 → 3/1 | note:f s:piano ]",
|
"[ 11/4 → 3/1 | note:f s:piano ]",
|
||||||
"[ 3/1 → 13/4 | note:c s:piano ]",
|
"[ 3/1 → 13/4 | note:c s:piano ]",
|
||||||
"[ 13/4 → 7/2 | note:d s:piano ]",
|
"[ 13/4 → 7/2 | note:e s:piano ]",
|
||||||
"[ 7/2 → 15/4 | note:e s:piano ]",
|
"[ 7/2 → 15/4 | note:f s:piano ]",
|
||||||
"[ 15/4 → 4/1 | note:f s:piano ]",
|
"[ 15/4 → 4/1 | note:d s:piano ]",
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`runs examples > example "shuffle" example index 1 1`] = `
|
exports[`runs examples > example "shuffle" example index 1 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/8 | note:c s:piano ]",
|
"[ 0/1 → 1/8 | note:e s:piano ]",
|
||||||
"[ 1/8 → 1/4 | note:d s:piano ]",
|
"[ 1/8 → 1/4 | note:d s:piano ]",
|
||||||
"[ 1/4 → 3/8 | note:e s:piano ]",
|
"[ 1/4 → 3/8 | note:f s:piano ]",
|
||||||
"[ 3/8 → 1/2 | note:f s:piano ]",
|
"[ 3/8 → 1/2 | note:c s:piano ]",
|
||||||
"[ 1/2 → 1/1 | note:g s:piano ]",
|
"[ 1/2 → 1/1 | note:g s:piano ]",
|
||||||
"[ 1/1 → 9/8 | note:c s:piano ]",
|
"[ 1/1 → 9/8 | note:e s:piano ]",
|
||||||
"[ 9/8 → 5/4 | note:d s:piano ]",
|
"[ 9/8 → 5/4 | note:c s:piano ]",
|
||||||
"[ 5/4 → 11/8 | note:e s:piano ]",
|
"[ 5/4 → 11/8 | note:f s:piano ]",
|
||||||
"[ 11/8 → 3/2 | note:f s:piano ]",
|
"[ 11/8 → 3/2 | note:d s:piano ]",
|
||||||
"[ 3/2 → 2/1 | note:g s:piano ]",
|
"[ 3/2 → 2/1 | note:g s:piano ]",
|
||||||
"[ 2/1 → 17/8 | note:c s:piano ]",
|
"[ 2/1 → 17/8 | note:d s:piano ]",
|
||||||
"[ 17/8 → 9/4 | note:d s:piano ]",
|
"[ 17/8 → 9/4 | note:c s:piano ]",
|
||||||
"[ 9/4 → 19/8 | note:e s:piano ]",
|
"[ 9/4 → 19/8 | note:e s:piano ]",
|
||||||
"[ 19/8 → 5/2 | note:f s:piano ]",
|
"[ 19/8 → 5/2 | note:f s:piano ]",
|
||||||
"[ 5/2 → 3/1 | note:g s:piano ]",
|
"[ 5/2 → 3/1 | note:g s:piano ]",
|
||||||
"[ 3/1 → 25/8 | note:c s:piano ]",
|
"[ 3/1 → 25/8 | note:c s:piano ]",
|
||||||
"[ 25/8 → 13/4 | note:d s:piano ]",
|
"[ 25/8 → 13/4 | note:e s:piano ]",
|
||||||
"[ 13/4 → 27/8 | note:e s:piano ]",
|
"[ 13/4 → 27/8 | note:f s:piano ]",
|
||||||
"[ 27/8 → 7/2 | note:f s:piano ]",
|
"[ 27/8 → 7/2 | note:d s:piano ]",
|
||||||
"[ 7/2 → 4/1 | note:g s:piano ]",
|
"[ 7/2 → 4/1 | note:g s:piano ]",
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ Diese Kombinationen von Buchstaben stehen für verschiedene Teile eines Schlagze
|
||||||
- `mt` = **m**iddle tom
|
- `mt` = **m**iddle tom
|
||||||
- `ht` = **h**igh tom
|
- `ht` = **h**igh tom
|
||||||
- `rd` = **r**i**d**e cymbal
|
- `rd` = **r**i**d**e cymbal
|
||||||
- `rd` = **cr**ash cymbal
|
- `cr` = **cr**ash cymbal
|
||||||
|
|
||||||
Probier verschiedene Sounds aus!
|
Probier verschiedene Sounds aus!
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@ Or using 2 beats per cycle:
|
||||||
s("bd sd, hh*4")`}
|
s("bd sd, hh*4")`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
You can use the `setcps` method to set the global tempo in cycles per second. `setcpm(x)` is the same as `setcps(x / 60)`.
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
|
|
||||||
To set a specific bpm, use `setcpm(bpm/bpc)`
|
To set a specific bpm, use `setcpm(bpm/bpc)`
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import {
|
||||||
resetGlobalEffects,
|
resetGlobalEffects,
|
||||||
resetLoadedSounds,
|
resetLoadedSounds,
|
||||||
initAudioOnFirstClick,
|
initAudioOnFirstClick,
|
||||||
|
resetDefaults,
|
||||||
} from '@strudel/webaudio';
|
} from '@strudel/webaudio';
|
||||||
import { setVersionDefaultsFrom } from './util.mjs';
|
import { setVersionDefaultsFrom } from './util.mjs';
|
||||||
import { StrudelMirror, defaultSettings } from '@strudel/codemirror';
|
import { StrudelMirror, defaultSettings } from '@strudel/codemirror';
|
||||||
|
|
@ -181,6 +182,7 @@ export function useReplContext() {
|
||||||
|
|
||||||
const resetEditor = async () => {
|
const resetEditor = async () => {
|
||||||
(await getModule('@strudel/tonal'))?.resetVoicings();
|
(await getModule('@strudel/tonal'))?.resetVoicings();
|
||||||
|
resetDefaults();
|
||||||
resetGlobalEffects();
|
resetGlobalEffects();
|
||||||
clearCanvas();
|
clearCanvas();
|
||||||
clearHydra();
|
clearHydra();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue