Compare commits

...

50 Commits

Author SHA1 Message Date
Jade (Rose) Rowland 42d7781d44 Merge branch 'main' into ziglets 2024-02-25 21:49:18 -05:00
Felix Roos 0416e4d212 Merge pull request #960 from tidalcycles/reset-global-fx
fix: reset global fx on pattern change
2024-02-25 19:17:00 +01:00
Felix Roos b9247db001 fix: reset global fx on pattern change 2024-02-25 15:09:15 +01:00
Felix Roos 325152c782 Merge pull request #936 from Enelg52/midi-issues
fix midi issue on firefox and added quote error
2024-02-25 14:15:30 +01:00
Felix Roos c136d12194 Merge pull request #956 from eefano/bracketMatching
'Enable Bracket Matching' option in Codemirror
2024-02-25 13:19:46 +01:00
Felix Roos 7557952155 format 2024-02-25 13:17:52 +01:00
Felix Roos b0b41e6718 revert unintended change 2024-02-25 13:17:29 +01:00
Felix Roos 22e3067b8c set bracket matching true by default 2024-02-25 13:16:53 +01:00
Felix Roos e9ab01ab06 Merge pull request #957 from tidalcycles/web-iife
fix script importable packages (web + repl)
2024-02-23 14:37:45 +01:00
Felix Roos 058e554b0f update example 2024-02-23 14:33:07 +01:00
Felix Roos 6d9327aebc adapt repl package similar to web package 2024-02-23 14:30:29 +01:00
Felix Roos c23d7850c7 simplify web example 2024-02-23 14:30:07 +01:00
Felix Roos 2854f0cf34 try different main / module setting + bump 2024-02-23 14:28:43 +01:00
Felix Roos a89e87ca2e add web package example using script tag 2024-02-23 14:21:59 +01:00
Felix Roos 5419ca431b bump web package version 2024-02-23 14:17:11 +01:00
Felix Roos e8b674badd add iife build to web package 2024-02-23 14:16:54 +01:00
eefano 8af40a9c61 added <> for mininotation 2024-02-22 23:35:00 +01:00
eefano f54aa3d823 'Enable Bracket Matching' option in Codemirror 2024-02-22 22:04:57 +01:00
Jade (Rose) Rowland 5e91287e3e Merge pull request #954 from daslyfe/midi_duration_fix
account for cps in midi time duration
2024-02-21 10:17:36 -05:00
Felix Roos 4e3d4a7060 hotfix: some samples were broken 2024-02-21 15:35:59 +01:00
Felix Roos 3d80da9816 Merge pull request #955 from tidalcycles/auto-await-samples
Auto await samples
2024-02-21 10:27:12 +01:00
Felix Roos bf63b716af refactor: remove await before samples calls in docs etc..
+ remove /master from dirt-samples calls (there is now a main branch)
+ remove /main endings from some places
2024-02-21 10:17:45 +01:00
Felix Roos 38d389b838 add test 2024-02-21 09:50:21 +01:00
Felix Roos ebdca32c80 automatically add await to samples call 2024-02-21 09:48:26 +01:00
Jade (Rose) Rowland c06a3710c1 fixed 2024-02-19 23:43:35 -05:00
Felix Roos a468ddb85b Merge pull request #945 from tidalcycles/cjs-fixes
remove cjs builds
2024-02-08 13:16:15 +01:00
Felix Roos 051bdaccc7 Publish
- @strudel/codemirror@1.0.1
 - @strudel/core@1.0.1
 - @strudel/csound@1.0.1
 - @strudel/hydra@1.0.1
 - @strudel/midi@1.0.1
 - @strudel/mini@1.0.1
 - @strudel/osc@1.0.1
 - @strudel/repl@1.0.1
 - @strudel/serial@1.0.1
 - @strudel/soundfonts@1.0.1
 - superdough@1.0.1
 - @strudel/tonal@1.0.1
 - @strudel/transpiler@1.0.1
 - @strudel/web@1.0.1
 - @strudel/webaudio@1.0.1
 - @strudel/xen@1.0.1
2024-02-08 13:04:25 +01:00
Felix Roos 5dc04d9574 make sure to overwrite main field 2024-02-08 12:36:04 +01:00
Felix Roos 60129413d3 remove cjs builds
+ add type module everywhere
2024-02-08 12:19:11 +01:00
Felix Roos d2bf9370ea Update README.md
add link to usage example for repl package
2024-02-04 23:24:43 +01:00
Felix Roos fd11aa5eec Merge pull request #941 from mhetrick/patch-1
Minor documentation error: Update first-sounds.mdx
2024-02-04 23:15:37 +01:00
Michael Hetrick fb7c2b61d3 Update first-sounds.mdx
Update the tutorial text to reflect that the default cpm setting has changed from 60 to 30.
2024-01-26 07:13:09 -08:00
Felix Roos dd64bf0fc9 Merge pull request #938 from tidalcycles/pianoroll-sorting
fix: pianoroll sorting
2024-01-24 16:48:57 +01:00
Felix Roos 434eb3b256 fix: pianoroll sorting 2024-01-24 16:40:26 +01:00
Enelg52 6da98a5f31 fix midi issue on firefox and quote error 2024-01-23 16:47:46 +01:00
Felix Roos 8fef75385a Update README.md 2024-01-23 01:35:28 +01:00
Felix Roos c66b9219a8 Update README.md 2024-01-23 01:31:11 +01:00
Felix Roos 2a1f8823e8 Merge pull request #935 from tidalcycles/v1-release-notes
V1 release notes
2024-01-23 00:04:03 +01:00
Felix Roos 3da65f90e3 shorter titles for release notes 2024-01-22 23:55:57 +01:00
Felix Roos a36cc24087 v1 release notes 2024-01-22 23:55:49 +01:00
Felix Roos a746bf5461 add assemblyscript version 2024-01-10 22:08:41 +01:00
Felix Roos 700f0be0ba optimize c output 2024-01-10 21:49:04 +01:00
Felix Roos cb59d632a8 add c info to readme 2024-01-10 21:45:21 +01:00
Felix Roos 9fd86458e6 add csaw 2024-01-10 21:44:16 +01:00
Felix Roos 3cd49065c8 prettierignore superdough-wasm 2024-01-10 21:32:20 +01:00
Felix Roos a7726e2334 add rust + shrink zig wasm file 2024-01-10 21:31:22 +01:00
Felix Roos 26793aec91 frequency control (bad) 2024-01-10 18:27:40 +01:00
Felix Roos 7c4ed7e05f cleanup 2024-01-10 18:14:49 +01:00
Felix Roos 93cfe9802c zig dsp poc 2024-01-10 18:11:05 +01:00
Felix Roos 0106a129c9 add minimal zig wasm testing ground 2024-01-10 17:04:10 +01:00
99 changed files with 902 additions and 172 deletions
+1
View File
@@ -10,4 +10,5 @@ paper
pnpm-lock.yaml
pnpm-workspace.yaml
**/dev-dist
superdough-wasm
website/.astro
+2 -1
View File
@@ -2,12 +2,13 @@
[![Strudel test status](https://github.com/tidalcycles/strudel/actions/workflows/test.yml/badge.svg)](https://github.com/tidalcycles/strudel/actions)
An experiment in making a [Tidal](https://github.com/tidalcycles/tidal/) using web technologies. This software is slowly stabilising, but please continue to tread carefully.
An experiment in making a [Tidal](https://github.com/tidalcycles/tidal/) using web technologies. This software is a bit more stable now, but please continue to tread carefully.
- Try it here: <https://strudel.cc>
- Docs: <https://strudel.cc/learn>
- Technical Blog Post: <https://loophole-letters.vercel.app/strudel>
- 1 Year of Strudel Blog Post: <https://loophole-letters.vercel.app/strudel1year>
- 2 Years of Strudel Blog Post: <https://strudel.cc/blog/#year-2>
## Running Locally
@@ -6,7 +6,7 @@
<script type="module">
import { initStrudel } from 'https://cdn.skypack.dev/@strudel/web@0.8.2';
initStrudel({
prebake: () => samples('github:tidalcycles/Dirt-Samples/master'),
prebake: () => samples('github:tidalcycles/dirt-samples'),
});
const click = (id, action) => document.getElementById(id).addEventListener('click', action);
click('a', () => evaluate(`s('bd,jvbass(3,8)').jux(rev)`));
+1 -1
View File
@@ -52,7 +52,7 @@
});
function getTune() {
return `await samples('github:tidalcycles/Dirt-Samples/master')
return `samples('github:tidalcycles/dirt-samples')
stack(
// amen
@@ -1,4 +1,4 @@
<script src="https://unpkg.com/@strudel/repl@0.9.4"></script>
<script src="https://unpkg.com/@strudel/repl@1.0.2"></script>
<strudel-editor>
<!--
// @date 23-08-15
+8
View File
@@ -0,0 +1,8 @@
<script src="https://unpkg.com/@strudel/web@1.0.3"></script>
<button id="play">PLAY</button>
<script>
initStrudel({
prebake: () => samples('github:tidalcycles/dirt-samples'),
});
document.getElementById('play').addEventListener('click', () => s('bd sd').play());
</script>
+6 -6
View File
@@ -1,6 +1,6 @@
export const bumpStreet = `// froos - "22 bump street", licensed with CC BY-NC-SA 4.0
await samples('github:felixroos/samples/main')
await samples('https://strudel.cc/tidal-drum-machines.json', 'github:ritchse/tidal-drum-machines/main/machines/')
samples('github:felixroos/samples')
samples('https://strudel.cc/tidal-drum-machines.json', 'github:ritchse/tidal-drum-machines/main/machines/')
"<[0,<6 7 9>,13,<17 20 22 26>]!2>/2"
// make it 22 edo
@@ -33,8 +33,8 @@ await samples('https://strudel.cc/tidal-drum-machines.json', 'github:ritchse/tid
export const trafficFlam = `// froos - "traffic flam", licensed with CC BY-NC-SA 4.0
await samples('github:felixroos/samples/main')
await samples('https://strudel.cc/tidal-drum-machines.json', 'github:ritchse/tidal-drum-machines/main/machines/')
samples('github:felixroos/samples')
samples('https://strudel.cc/tidal-drum-machines.json', 'github:ritchse/tidal-drum-machines/main/machines/')
addVoicings('hip', {
m11: ['2M 3m 4P 7m'],
@@ -69,8 +69,8 @@ export const funk42 = `// froos - how to funk in 42 lines of code
// adapted from "how to funk in two minutes" by marc rebillet https://www.youtube.com/watch?v=3vBwRfQbXkg
// thanks to peach for the transcription: https://www.youtube.com/watch?v=8eiPXvIgda4
await samples('github:felixroos/samples/main')
await samples('https://strudel.cc/tidal-drum-machines.json', 'github:ritchse/tidal-drum-machines/main/machines/')
samples('github:felixroos/samples')
samples('https://strudel.cc/tidal-drum-machines.json', 'github:ritchse/tidal-drum-machines/main/machines/')
setcps(.5)
+1 -1
View File
@@ -15,7 +15,7 @@
<script type="module">
import { initStrudel } from '@strudel/web';
initStrudel({
prebake: () => samples('github:tidalcycles/Dirt-Samples/master'),
prebake: () => samples('github:tidalcycles/dirt-samples'),
});
const click = (id, action) => document.getElementById(id).addEventListener('click', action);
+1 -1
View File
@@ -1,4 +1,4 @@
export default `await samples('github:tidalcycles/Dirt-Samples/master')
export default `samples('github:tidalcycles/dirt-samples')
stack(
// amen
+1 -1
View File
@@ -12,7 +12,7 @@
const init = Promise.all([
initAudioOnFirstClick(),
samples('github:tidalcycles/Dirt-Samples/master'),
samples('github:tidalcycles/dirt-samples'),
registerSynthSounds(),
]);
+6 -1
View File
@@ -2,7 +2,7 @@ import { closeBrackets } from '@codemirror/autocomplete';
// import { search, highlightSelectionMatches } from '@codemirror/search';
import { history } from '@codemirror/commands';
import { javascript } from '@codemirror/lang-javascript';
import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language';
import { defaultHighlightStyle, syntaxHighlighting, bracketMatching } from '@codemirror/language';
import { Compartment, EditorState, Prec } from '@codemirror/state';
import {
EditorView,
@@ -24,6 +24,7 @@ import { persistentAtom } from '@nanostores/persistent';
const extensions = {
isLineWrappingEnabled: (on) => (on ? EditorView.lineWrapping : []),
isBracketMatchingEnabled: (on) => (on ? bracketMatching({ brackets: '()[]{}<>' }) : []),
isLineNumbersDisplayed: (on) => (on ? lineNumbers() : []),
theme,
isAutoCompletionEnabled,
@@ -37,6 +38,7 @@ const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [ke
export const defaultSettings = {
keybindings: 'codemirror',
isBracketMatchingEnabled: false,
isLineNumbersDisplayed: true,
isActiveLineHighlighted: false,
isAutoCompletionEnabled: false,
@@ -290,6 +292,9 @@ export class StrudelMirror {
setLineWrappingEnabled(enabled) {
this.reconfigureExtension('isLineWrappingEnabled', enabled);
}
setBracketMatchingEnabled(enabled) {
this.reconfigureExtension('isBracketMatchingEnabled', enabled);
}
setLineNumbersDisplayed(enabled) {
this.reconfigureExtension('isLineNumbersDisplayed', enabled);
}
+2 -3
View File
@@ -1,11 +1,10 @@
{
"name": "@strudel/codemirror",
"version": "1.0.0",
"version": "1.0.1",
"description": "Codemirror Extensions for Strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+1 -1
View File
@@ -292,7 +292,7 @@ const generic_params = [
* @name begin
* @param {number | Pattern} amount between 0 and 1, where 1 is the length of the sample
* @example
* samples({ rave: 'rave/AREUREADY.wav' }, 'github:tidalcycles/Dirt-Samples/master/')
* samples({ rave: 'rave/AREUREADY.wav' }, 'github:tidalcycles/dirt-samples')
* s("rave").begin("<0 .25 .5 .75>").fast(2)
*
*/
+2 -3
View File
@@ -1,12 +1,11 @@
{
"name": "@strudel/core",
"version": "1.0.0",
"version": "1.0.1",
"description": "Port of Tidal Cycles to JavaScript",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"test": "vitest run",
+3 -3
View File
@@ -2322,10 +2322,10 @@ const _loopAt = function (factor, pat, cps = 0.5) {
* @memberof Pattern
* @returns Pattern
* @example
* await samples('github:tidalcycles/Dirt-Samples/master')
* samples('github:tidalcycles/dirt-samples')
* s("breaks165").slice(8, "0 1 <2 2*2> 3 [4 0] 5 6 7".every(3, rev)).slow(0.75)
* @example
* await samples('github:tidalcycles/Dirt-Samples/master')
* samples('github:tidalcycles/dirt-samples')
* s("breaks125").fit().slice([0,.25,.5,.75], "0 1 1 <2 3>")
*/
@@ -2351,7 +2351,7 @@ export const slice = register(
* Works the same as slice, but changes the playback speed of each slice to match the duration of its step.
* @name splice
* @example
* await samples('github:tidalcycles/Dirt-Samples/master')
* samples('github:tidalcycles/dirt-samples')
* s("breaks165")
* .splice(8, "0 1 [2 3 0]@2 3 0@2 7")
*/
+7 -2
View File
@@ -160,8 +160,13 @@ export function pianoroll({
maxMidi = max;
valueExtent = maxMidi - minMidi + 1;
}
// foldValues = values.sort((a, b) => a - b);
foldValues = values.sort((a, b) => String(a).localeCompare(String(b)));
foldValues = values.sort((a, b) =>
typeof a === 'number' && typeof b === 'number'
? a - b
: typeof a === 'number'
? 1
: String(a).localeCompare(String(b)),
);
barThickness = fold ? valueAxis / foldValues.length : valueAxis / valueExtent;
ctx.fillStyle = background;
ctx.globalAlpha = 1; // reset!
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/csound",
"version": "1.0.0",
"version": "1.0.1",
"description": "csound bindings for strudel",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2 -2
View File
@@ -6,11 +6,11 @@ const OFF_MESSAGE = 0x80;
const CC_MESSAGE = 0xb0;
Pattern.prototype.midi = function (output) {
return this.onTrigger((time, hap, currentTime) => {
return this.onTrigger((time, hap, currentTime, cps) => {
const { note, nrpnn, nrpv, ccn, ccv } = hap.value;
const offset = (time - currentTime) * 1000;
const velocity = Math.floor((hap.context?.velocity ?? 0.9) * 100); // TODO: refactor velocity
const duration = Math.floor(hap.duration.valueOf() * 1000 - 10);
const duration = Math.floor((hap.duration.valueOf() / cps) * 1000 - 10);
const roundedOffset = Math.round(offset);
const midichan = (hap.value.midichan ?? 1) - 1;
const requestedport = output ?? 'IAC';
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/hydra",
"version": "1.0.0",
"version": "1.0.1",
"description": "Hydra integration for strudel",
"main": "hydra.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"server": "node server.js",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'hydra.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+9 -3
View File
@@ -129,7 +129,7 @@ Pattern.prototype.midi = function (output) {
const velocity = hap.context?.velocity ?? 0.9; // TODO: refactor velocity
// note off messages will often a few ms arrive late, try to prevent glitching by subtracting from the duration length
const duration = Math.floor(hap.duration.valueOf() * 1000 - 10);
const duration = Math.floor((hap.duration.valueOf() / cps) * 1000 - 10);
if (note != null) {
const midiNumber = typeof note === 'number' ? note : noteToMidi(note);
const midiNote = new Note(midiNumber, { attack: velocity, duration });
@@ -167,10 +167,16 @@ let listeners = {};
const refs = {};
export async function midin(input) {
if (isPattern(input)) {
throw new Error(
`.midi does not accept Pattern input. Make sure to pass device name with single quotes. Example: .midi('${
WebMidi.outputs?.[0]?.name || 'IAC Driver Bus 1'
}')`,
);
}
const initial = await enableWebMidi(); // only returns on first init
const device = getDevice(input, WebMidi.inputs);
if (initial) {
if (initial || WebMidi.enabled) {
const otherInputs = WebMidi.inputs.filter((o) => o.name !== device.name);
logger(
`Midi enabled! Using "${device.name}". ${
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/midi",
"version": "1.0.0",
"version": "1.0.1",
"description": "Midi API for strudel",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2 -3
View File
@@ -1,12 +1,11 @@
{
"name": "@strudel/mini",
"version": "1.0.0",
"version": "1.0.1",
"description": "Mini notation for strudel",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"test": "vitest run",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/osc",
"version": "1.0.0",
"version": "1.0.1",
"description": "OSC messaging for strudel",
"main": "osc.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"server": "node server.js",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'osc.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2
View File
@@ -1,3 +1,5 @@
# @strudel/repl
The Strudel REPL as a web component.
[Usage example](https://github.com/tidalcycles/strudel/blob/main/examples/buildless/web-component-no-iframe.html)
+2 -2
View File
@@ -1,8 +1,8 @@
{
"name": "@strudel/repl",
"version": "1.0.0",
"version": "1.0.2",
"description": "Strudel REPL as a Web Component",
"main": "index.mjs",
"module": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/serial",
"version": "1.0.0",
"version": "1.0.1",
"description": "Webserial API for strudel",
"main": "serial.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'serial.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+2 -3
View File
@@ -1,11 +1,10 @@
{
"name": "@strudel/soundfonts",
"version": "1.0.0",
"version": "1.0.1",
"description": "Soundsfont support for strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+1
View File
@@ -0,0 +1 @@
rustsaw/target
+57
View File
@@ -0,0 +1,57 @@
# superdough-wasm
This is just a very early experiment to find out how to run wasm in an AudioWorklet.
WASM can be compiled from several languages, which are tested here..
## zig
<https://dev.to/sleibrock/webassembly-with-zig-part-1-4onm>
```sh
# (re)compile dsp.zig
brew install zig # prequisite
cd zigsaw
zig build-lib zigsaw.zig -target wasm32-freestanding -dynamic -rdynamic -O ReleaseSmall # build
npx http-server .. -o # run
```
wasm file size: 690B
## rust
<https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_Wasm>
```sh
# https://www.rust-lang.org/tools/install
cargo install wasm-pack # prequisite
cd rustsaw
wasm-pack build --target bundler # build
npx http-server .. -o # run
```
wasm file size: 653B
## c
<https://emscripten.org/docs/getting_started/Tutorial.html>
```sh
# brew install emscripten
cd csaw
emcc -O2 csaw.c -o csaw # build
npx http-server .. -o
```
wasm file size: 680B
## assemblyscript
<https://www.assemblyscript.org/getting-started.html#setting-up-a-new-project>
```sh
cd ascsaw
# npm i
npm run asbuild # build
```
wasm file size: 122B !
@@ -0,0 +1,22 @@
{
"targets": {
"debug": {
"outFile": "build/debug.wasm",
"textFile": "build/debug.wat",
"sourceMap": true,
"debug": true
},
"release": {
"outFile": "build/release.wasm",
"textFile": "build/release.wat",
"sourceMap": true,
"optimizeLevel": 3,
"shrinkLevel": 2,
"converge": false,
"noAssert": false
}
},
"options": {
"bindings": "esm"
}
}
@@ -0,0 +1,3 @@
export function saw(t: f64, f: f64): f64 {
return (((f * t * 1.0) % 1.0) - 0.5) * 2.0;
}
@@ -0,0 +1,6 @@
{
"extends": "assemblyscript/std/assembly.json",
"include": [
"./**/*.ts"
]
}
@@ -0,0 +1,2 @@
*
!.gitignore
+54
View File
@@ -0,0 +1,54 @@
{
"name": "ascsaw",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ascsaw",
"version": "1.0.0",
"license": "ISC",
"devDependencies": {
"assemblyscript": "^0.27.22"
}
},
"node_modules/assemblyscript": {
"version": "0.27.22",
"resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.27.22.tgz",
"integrity": "sha512-6ClobsR4Hxn6K0daYp/+n9qWTqVbpdVeSGSVDqRvUEz66vvFb8atS6nLm+fnQ54JXuXmzLQy0uWYYgB8G59btQ==",
"dev": true,
"dependencies": {
"binaryen": "116.0.0-nightly.20231102",
"long": "^5.2.1"
},
"bin": {
"asc": "bin/asc.js",
"asinit": "bin/asinit.js"
},
"engines": {
"node": ">=16",
"npm": ">=7"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/assemblyscript"
}
},
"node_modules/binaryen": {
"version": "116.0.0-nightly.20231102",
"resolved": "https://registry.npmjs.org/binaryen/-/binaryen-116.0.0-nightly.20231102.tgz",
"integrity": "sha512-aPU9tlKdw/gcXx6u4PxtDgOtGjg/ZKnYdk23ctYb70GxZgPhWnGWmnBt01aV5dt5yFFo2V4rbB7SzpSFhViFQA==",
"dev": true,
"bin": {
"wasm-opt": "bin/wasm-opt",
"wasm2js": "bin/wasm2js"
}
},
"node_modules/long": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
"integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==",
"dev": true
}
}
}
@@ -0,0 +1,25 @@
{
"name": "ascsaw",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "node tests",
"asbuild:debug": "asc assembly/index.ts --target debug",
"asbuild:release": "asc assembly/index.ts --target release",
"asbuild": "npm run asbuild:debug && npm run asbuild:release",
"start": "npx serve ."
},
"author": "",
"license": "ISC",
"devDependencies": {
"assemblyscript": "^0.27.22"
},
"type": "module",
"exports": {
".": {
"import": "./build/release.js",
"types": "./build/release.d.ts"
}
}
}
+1
View File
@@ -0,0 +1 @@
csaw
+7
View File
@@ -0,0 +1,7 @@
#include <math.h>
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
double saw(double t, double f) {
return fmod((f * t * 1.0), 1.0) - 0.5 * 2.0;
}
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
<!doctype html>
<html>
<head>
<title>WASM AudioWorklet Demo</title>
</head>
<body>
<button id="play">play</button>
<input type="range" min="55" max="880" id="freq" />
</body>
<script src="./main.js"></script>
</html>
+24
View File
@@ -0,0 +1,24 @@
let ac;
document.getElementById('play').addEventListener('click', async () => {
ac = ac || new AudioContext();
await ac.resume();
await ac.audioWorklet.addModule('./worklet.js');
const node = new AudioWorkletNode(ac, 'saw-processor');
//let res = await fetch('./zigsaw/zigsaw.wasm');
// let res = await fetch('./csaw/csaw.wasm');
let res = await fetch('./ascsaw/build/release.wasm');
//let res = await fetch('./rustsaw/pkg/rustsaw_bg.wasm');
const buffer = await res.arrayBuffer();
node.port.onmessage = (e) => {
if (e.data === 'OK') {
console.log('worklet ready');
}
};
node.port.postMessage({ webassembly: buffer });
node.connect(ac.destination);
document.getElementById('freq').addEventListener('input', async (e) => {
node.port.postMessage({ frequency: e.target.value });
});
});
+123
View File
@@ -0,0 +1,123 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bumpalo"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "proc-macro2"
version = "1.0.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustsaw"
version = "0.1.0"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "syn"
version = "2.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "wasm-bindgen"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
@@ -0,0 +1,13 @@
[package]
name = "rustsaw"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
description = "A sample project with wasm-pack"
license = "MIT/Apache-2.0"
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
@@ -0,0 +1,6 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn saw(t: f64, f: f64) -> f64 {
return (((f * t * 1.0) % 1.0) - 0.5) * 2.0;
}
+38
View File
@@ -0,0 +1,38 @@
class SawProcessor extends AudioWorkletProcessor {
constructor() {
super();
this.t = 0; // samples passed
this.f = 110;
this.port.onmessage = (e) => {
const key = Object.keys(e.data)[0];
const value = e.data[key];
switch (key) {
case 'webassembly':
WebAssembly.instantiate(value, this.importObject).then((result) => {
this.api = result.instance.exports;
this.port.postMessage('OK');
});
break;
case 'frequency':
this.f = value;
}
};
}
process(inputs, outputs, parameters) {
if (this.api) {
const output = outputs[0];
for (let i = 0; i < output[0].length; i++) {
let t = this.t;
let out = 0;
out = this.api.saw(t / 44100, this.f);
output.forEach((channel) => {
channel[i] = out;
});
this.t++;
}
}
return true;
}
}
registerProcessor('saw-processor', SawProcessor);
Binary file not shown.
@@ -0,0 +1,5 @@
const std = @import("std");
export fn saw(t: f64, f: f64) f64 {
return ((@mod(f * t, 1.0)) - 0.5) * 2.0;
}
+2 -2
View File
@@ -19,7 +19,7 @@ import { superdough, samples, initAudioOnFirstClick, registerSynthSounds } from
const init = Promise.all([
initAudioOnFirstClick(),
samples('github:tidalcycles/Dirt-Samples/master'),
samples('github:tidalcycles/dirt-samples'),
registerSynthSounds(),
]);
@@ -148,7 +148,7 @@ The json file is expected to have the same format as described above.
Because it is common to use github for samples, there is a short way to load a sample map from github:
```js
samples('github:tidalcycles/Dirt-Samples/master')
samples('github:tidalcycles/dirt-samples')
```
The format is `github:<user>/<repo>/<branch>`.
+2 -3
View File
@@ -1,12 +1,11 @@
{
"name": "superdough",
"version": "1.0.0",
"version": "1.0.1",
"description": "simple web audio synth and sampler intended for live coding. inspired by superdirt and webdirt.",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.cjs",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"directories": {
"example": "examples"
+31 -15
View File
@@ -99,6 +99,27 @@ export const getLoadedBuffer = (url) => {
return bufferCache[url];
};
function resolveSpecialPaths(base) {
if (base.startsWith('bubo:')) {
const [_, repo] = base.split(':');
base = `github:Bubobubobubobubo/dough-${repo}`;
}
return base;
}
function githubPath(base, subpath = '') {
if (!base.startsWith('github:')) {
throw new Error('expected "github:" at the start of pseudoUrl');
}
let [_, path] = base.split('github:');
path = path.endsWith('/') ? path.slice(0, -1) : path;
if (path.split('/').length === 2) {
// assume main as default branch if none set
path += '/main';
}
return `https://raw.githubusercontent.com/${path}/${subpath}`;
}
export const processSampleMap = (sampleMap, fn, baseUrl = sampleMap._base || '') => {
return Object.entries(sampleMap).forEach(([key, value]) => {
if (typeof value === 'string') {
@@ -108,15 +129,19 @@ export const processSampleMap = (sampleMap, fn, baseUrl = sampleMap._base || '')
throw new Error('wrong sample map format for ' + key);
}
baseUrl = value._base || baseUrl;
const replaceUrl = (v) => (baseUrl + v).replace('github:', 'https://raw.githubusercontent.com/');
baseUrl = resolveSpecialPaths(baseUrl);
if (baseUrl.startsWith('github:')) {
baseUrl = githubPath(baseUrl, '');
}
const fullUrl = (v) => baseUrl + v;
if (Array.isArray(value)) {
//return [key, value.map(replaceUrl)];
value = value.map(replaceUrl);
value = value.map(fullUrl);
} else {
// must be object
value = Object.fromEntries(
Object.entries(value).map(([note, samples]) => {
return [note, (typeof samples === 'string' ? [samples] : samples).map(replaceUrl)];
return [note, (typeof samples === 'string' ? [samples] : samples).map(fullUrl)];
}),
);
}
@@ -142,7 +167,7 @@ function getSamplesPrefixHandler(url) {
/**
* Loads a collection of samples to use with `s`
* @example
* samples('github:tidalcycles/Dirt-Samples/master');
* samples('github:tidalcycles/dirt-samples');
* s("[bd ~]*2, [~ hh]*2, ~ sd")
* @example
* samples({
@@ -165,18 +190,9 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option
if (handler) {
return handler(sampleMap);
}
if (sampleMap.startsWith('bubo:')) {
const [_, repo] = sampleMap.split(':');
sampleMap = `github:Bubobubobubobubo/dough-${repo}`;
}
sampleMap = resolveSpecialPaths(sampleMap);
if (sampleMap.startsWith('github:')) {
let [_, path] = sampleMap.split('github:');
path = path.endsWith('/') ? path.slice(0, -1) : path;
if (path.split('/').length === 2) {
// assume main as default branch if none set
path += '/main';
}
sampleMap = `https://raw.githubusercontent.com/${path}/strudel.json`;
sampleMap = githubPath(sampleMap, 'strudel.json');
}
if (sampleMap.startsWith('shabda:')) {
let [_, path] = sampleMap.split('shabda:');
+5
View File
@@ -253,6 +253,11 @@ function effectSend(input, effect, wet) {
return send;
}
export function resetGlobalEffects() {
delays = {};
reverbs = {};
}
export const superdough = async (value, deadline, hapDuration) => {
const ac = getAudioContext();
if (typeof value !== 'object') {
+1 -1
View File
@@ -8,7 +8,7 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.cjs' })[ext],
},
rollupOptions: {
+2 -3
View File
@@ -1,11 +1,10 @@
{
"name": "@strudel/tonal",
"version": "1.0.0",
"version": "1.0.1",
"description": "Tonal functions for strudel",
"main": "index.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/transpiler",
"version": "1.0.0",
"version": "1.0.1",
"description": "Transpiler for strudel user code. Converts syntactically correct but semantically meaningless JS into evaluatable strudel code.",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
@@ -23,6 +23,9 @@ describe('transpiler', () => {
it('supports top level await', () => {
expect(transpiler("await samples('xxx');", simple).output).toEqual("await samples('xxx');");
});
it('adds await to bare samples call', () => {
expect(transpiler("samples('xxx');", simple).output).toEqual("await samples('xxx');");
});
/* it('parses dynamic imports', () => {
expect(
transpiler("const { default: foo } = await import('https://bar.com/foo.js');", {
+17 -4
View File
@@ -1,8 +1,7 @@
import escodegen from 'escodegen';
import { parse } from 'acorn';
import { walk } from 'estree-walker';
import { isNoteWithOctave } from '@strudel/core';
import { getLeafLocations } from '@strudel/mini';
import { parse } from 'acorn';
import escodegen from 'escodegen';
import { walk } from 'estree-walker';
export function transpiler(input, options = {}) {
const { wrapAsync = false, addReturn = true, emitMiniLocations = true, emitWidgets = true } = options;
@@ -47,6 +46,9 @@ export function transpiler(input, options = {}) {
});
return this.replace(widgetWithLocation(node));
}
if (isBareSamplesCall(node, parent)) {
return this.replace(withAwait(node));
}
},
leave(node, parent, prop, index) {},
});
@@ -119,3 +121,14 @@ function widgetWithLocation(node) {
node.callee.name = 'sliderWithID';
return node;
}
function isBareSamplesCall(node, parent) {
return node.type === 'CallExpression' && node.callee.name === 'samples' && parent.type !== 'AwaitExpression';
}
function withAwait(node) {
return {
type: 'AwaitExpression',
argument: node,
};
}
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+1 -1
View File
@@ -43,7 +43,7 @@ By default, no external samples are loaded, but you can add them like this:
```js
initStrudel({
prebake: () => samples('github:tidalcycles/Dirt-Samples/master'),
prebake: () => samples('github:tidalcycles/dirt-samples'),
});
document.getElementById('play').addEventListener('click',
+4 -3
View File
@@ -1,8 +1,8 @@
{
"name": "@strudel/web",
"version": "1.0.0",
"version": "1.0.3",
"description": "Easy to setup, opiniated bundle of Strudel for the browser.",
"main": "web.mjs",
"module": "web.mjs",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
@@ -37,7 +37,8 @@
"@strudel/mini": "workspace:*",
"@strudel/tonal": "workspace:*",
"@strudel/transpiler": "workspace:*",
"@strudel/webaudio": "workspace:*"
"@strudel/webaudio": "workspace:*",
"@rollup/plugin-replace": "^5.0.5"
},
"devDependencies": {
"vite": "^5.0.10"
+11 -3
View File
@@ -1,6 +1,7 @@
import { defineConfig } from 'vite';
import { dependencies } from './package.json';
import { resolve } from 'path';
import replace from '@rollup/plugin-replace';
// https://vitejs.dev/config/
export default defineConfig({
@@ -8,11 +9,18 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'web.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
name: 'strudel',
formats: ['es', 'iife'],
fileName: (ext) => ({ es: 'index.mjs', iife: 'index.js' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
// external: [...Object.keys(dependencies)],
plugins: [
replace({
'process.env.NODE_ENV': JSON.stringify('production'),
preventAssignment: true,
}),
],
},
target: 'esnext',
},
+2 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel/webaudio",
"version": "1.0.0",
"version": "1.0.1",
"description": "Web Audio helpers for Strudel",
"main": "index.mjs",
"type": "module",
@@ -8,8 +8,7 @@
"example": "examples"
},
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"example": "npx parcel examples/repl.html",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@strudel/xen",
"version": "1.0.0",
"version": "1.0.1",
"description": "Xenharmonic API for strudel",
"main": "index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
"main": "dist/index.mjs"
},
"scripts": {
"build": "vite build",
+2 -2
View File
@@ -8,8 +8,8 @@ export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'index.mjs'),
formats: ['es', 'cjs'],
fileName: (ext) => ({ es: 'index.mjs', cjs: 'index.js' })[ext],
formats: ['es'],
fileName: (ext) => ({ es: 'index.mjs' })[ext],
},
rollupOptions: {
external: [...Object.keys(dependencies)],
+3 -3
View File
@@ -430,6 +430,9 @@ importers:
packages/web:
dependencies:
'@rollup/plugin-replace':
specifier: ^5.0.5
version: 5.0.5
'@strudel/core':
specifier: workspace:*
version: link:../core
@@ -3691,7 +3694,6 @@ packages:
dependencies:
'@rollup/pluginutils': 5.1.0
magic-string: 0.30.5
dev: true
/@rollup/pluginutils@3.1.0(rollup@2.79.1):
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
@@ -3717,7 +3719,6 @@ packages:
'@types/estree': 1.0.0
estree-walker: 2.0.2
picomatch: 2.3.1
dev: true
/@rollup/rollup-android-arm-eabi@4.9.2:
resolution: {integrity: sha512-RKzxFxBHq9ysZ83fn8Iduv3A283K7zPPYuhL/z9CQuyFrjwpErJx0h4aeb/bnJ+q29GRLgJpY66ceQ/Wcsn3wA==}
@@ -7118,7 +7119,6 @@ packages:
/estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
dev: true
/estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+7
View File
@@ -262,6 +262,13 @@ declare module 'astro:content' {
collection: "blog";
data: InferEntrySchema<"blog">
} & { render(): Render[".mdx"] };
"release-1.0.0-geburtstagskuchen.mdx": {
id: "release-1.0.0-geburtstagskuchen.mdx";
slug: "release-100-geburtstagskuchen";
body: string;
collection: "blog";
data: InferEntrySchema<"blog">
} & { render(): Render[".mdx"] };
"year-2.mdx": {
id: "year-2.mdx";
slug: "year-2";
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.0.2 Schwindlig'
title: 'Release Notes v0.0.2'
description: ''
date: '2022-03-28'
tags: ['meta']
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.0.3 Stürmisch'
title: 'Release Notes v0.0.3'
date: '2022-05-20'
tags: ['meta']
author: froos
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.0.3 Maelstrom'
title: 'Release Notes v0.0.3'
description: ''
date: '2022-06-18'
tags: ['meta']
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.0.4 Gischt'
title: 'Release Notes v0.0.4'
description: ''
date: '2022-08-14'
tags: ['meta']
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.3.0 Donauwelle'
title: 'Release Notes v0.3.0'
description: ''
date: '2022-11-06'
tags: ['meta']
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.4.0 Brandung'
title: 'Release Notes v0.4.0'
description: ''
date: '2022-11-13'
tags: ['meta']
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.5.0 Wirbel'
title: 'Release Notes v0.5.0'
description: ''
date: '2022-12-13'
tags: ['meta']
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.6.0 Zimtschnecke'
title: 'Release Notes v0.6.0'
description: ''
date: '2023-02-01'
tags: ['meta']
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.7.0 Zuckerguss'
title: 'Release Notes v0.7.0'
description: ''
date: '2023-03-23'
tags: ['meta']
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.8.0 Himbeermuffin'
title: 'Release Notes v0.8.0'
description: ''
date: '2023-06-30'
tags: ['meta']
@@ -29,7 +29,7 @@ edit: the desktop app performance on linux is currently not that great.. the web
The desktop App has the same features as the webapp, with the additional ability to load samples from disk. It is currently not documented yet, but you can do something like
```js
await samples('~/music/xxx');
samples('~/music/xxx');
s('my_sound');
```
@@ -1,5 +1,5 @@
---
title: 'Release Notes v0.9.0 Bananenbrot'
title: 'Release Notes v0.9.0'
description: ''
date: '2023-09-17'
tags: ['meta']
@@ -0,0 +1,238 @@
---
title: 'Release Notes v1.0.0'
description: ''
date: '2024-01-22'
tags: ['meta']
author: froos
---
import BlogVideo from '../../components/BlogVideo.astro';
These are the release notes for Strudel 1.0.0 aka "Geburtstagskuchen"
This release marks the 2 year anniversary of the project, the first commit was on the 22nd January 2022 by Alex McLean.
If you generally need a heads up on what happened to Strudel in the last year, read the [2023 recap](/blog/#year-2)
import { Youtube } from '@src/components/Youtube';
<Youtube client:only="react" id="ByPFmSBqQk0" />
A lot has happened since then, and also since the last release 16 weeks ago.
Let me write up some of the highlights:
## Breaking Change
This version changes the default cps value from 1 to 0.5 to give patterns a little bit more time by default.
If you find your existing patterns to be suddenly half the speed, just add a `setcps(1)` to the top and it should sound as it did before!
- make 0.5hz cps the default by @yaxu in https://github.com/tidalcycles/strudel/pull/931
## New Domain
Strudel is now available under [strudel.cc](https://strudel.cc/). The old domain still works but you might not get the most recent version.
- replace strudel.tidalcycles.org with strudel.cc by @felixroos in https://github.com/tidalcycles/strudel/pull/768
## Strudel on Mastodon
Strudel now has a mastodon presence: https://social.toplap.org/@strudel
## New Audio Engine Features
superdough, the audio engine of strudel has gotten some new features:
- Create phaser effect by @daslyfe in https://github.com/tidalcycles/strudel/pull/798
- Multichannel audio by @daslyfe in https://github.com/tidalcycles/strudel/pull/820
- Audio device selection by @daslyfe in https://github.com/tidalcycles/strudel/pull/854
- Better convolution reverb by generating impulse responses by @Bubobubobubobubo and @felixroos in https://github.com/tidalcycles/strudel/pull/718
- Add 'white', 'pink' and 'brown' oscillators + refactor synth by @Bubobubobubobubo and @felixroos in https://github.com/tidalcycles/strudel/pull/713
- New noise type: "crackle" by @Bubobubobubobubo in https://github.com/tidalcycles/strudel/pull/806
- Add support for using samples as impulse response buffers for the reverb by @vasilymilovidov in https://github.com/tidalcycles/strudel/pull/717
- Compressor by @felixroos in https://github.com/tidalcycles/strudel/pull/729
- Adding vibrato to Superdough sampler by @Bubobubobubobubo and @felixroos in https://github.com/tidalcycles/strudel/pull/706
- Further Envelope improvements by @daslyfe in https://github.com/tidalcycles/strudel/pull/868
- Add more vowel qualities for the vowels function by @fnordomat in https://github.com/tidalcycles/strudel/pull/907
- pitch envelope by @felixroos in https://github.com/tidalcycles/strudel/pull/913
## Slider Controls
The new `slider` function inlines a draggable slider element into the code, bridging the gap between code and GUI.
- widgets by @felixroos in https://github.com/tidalcycles/strudel/pull/714
- Slider afterthoughts by @felixroos in https://github.com/tidalcycles/strudel/pull/723
- add xfade by @felixroos in https://github.com/tidalcycles/strudel/pull/780
## Improved MIDI integration
Pattern params [can now be controlled with cc messages](https://www.youtube.com/watch?v=e2-Sv_jjDQk) + you can now send a MIDI clock to sync your DAW with strudel.
- Midi in by @felixroos in https://github.com/tidalcycles/strudel/pull/699
- add midi clock support by @felixroos in https://github.com/tidalcycles/strudel/pull/710
## hydra
[hydra](https://hydra.ojack.xyz), the live coding video synth [can now be used directly inside the strudel REPL](https://strudel.cc/learn/hydra/).
- Hydra integration by @felixroos in https://github.com/tidalcycles/strudel/pull/759
- add options param to initHydra by @kasparsj in https://github.com/tidalcycles/strudel/pull/808
- Hydra fixes and improvements by @atfornes in https://github.com/tidalcycles/strudel/pull/818
## Vanilla REPL
The codemirror editor and the repl abstraction have been refactored from react to vanilla JS!
This should give some performance improvements and less dependency / maintenance burden:
- Vanilla repl 2 by @felixroos in https://github.com/tidalcycles/strudel/pull/863
- Vanilla repl 3 by @felixroos in https://github.com/tidalcycles/strudel/pull/865
- more work on vanilla repl: repl web component + package + MicroRepl by @felixroos in https://github.com/tidalcycles/strudel/pull/866
- main repl vanillification by @felixroos in https://github.com/tidalcycles/strudel/pull/873
- final vanillification by @felixroos in https://github.com/tidalcycles/strudel/pull/876
## Doc Changes
Plenty of things have been added to the docs, including a [showcase of what people have been done with strudel](https://strudel.cc/intro/showcase/) and the new [Community Bakery](/bakery/)!
<details>
<summary>show PRs</summary>
- Showcase by @felixroos in https://github.com/tidalcycles/strudel/pull/885
- Recipes by @felixroos in https://github.com/tidalcycles/strudel/pull/742
- Document striate function by @ilesinge in https://github.com/tidalcycles/strudel/pull/766
- Document adsr function by @ilesinge in https://github.com/tidalcycles/strudel/pull/767
- Add function params in reference tab by @ilesinge in https://github.com/tidalcycles/strudel/pull/785
- Update first-sounds.mdx by @bwagner in https://github.com/tidalcycles/strudel/pull/794
- Update recap.mdx by @bwagner in https://github.com/tidalcycles/strudel/pull/797
- Update pattern-effects.mdx by @bwagner in https://github.com/tidalcycles/strudel/pull/796
- Update first-effects.mdx by @bwagner in https://github.com/tidalcycles/strudel/pull/795
- Document pianoroll by @ilesinge in https://github.com/tidalcycles/strudel/pull/784
- Add doc for euclidLegatoRot, wordfall and slider by @ilesinge in https://github.com/tidalcycles/strudel/pull/801
- Improve documentation for synonym functions by @ilesinge in https://github.com/tidalcycles/strudel/pull/800
- Add and style algolia search by @ilesinge in https://github.com/tidalcycles/strudel/pull/827
- Fix a typo by @drewgbarnes in https://github.com/tidalcycles/strudel/pull/830
- add mastodon link by @felixroos in https://github.com/tidalcycles/strudel/pull/884
- adds a blog by @felixroos in https://github.com/tidalcycles/strudel/pull/911
- community bakery by @felixroos in https://github.com/tidalcycles/strudel/pull/923
- Blog improvements by @felixroos in https://github.com/tidalcycles/strudel/pull/919
- 2 years blog post by @felixroos in https://github.com/tidalcycles/strudel/pull/929
</details>
## Other Features
<details>
<summary>There is a lot more</summary>
- mini notation: international alphabets support by @ilesinge in https://github.com/tidalcycles/strudel/pull/751
- Add shabda shortcut by @ilesinge in https://github.com/tidalcycles/strudel/pull/740
- add play function by @felixroos in https://github.com/tidalcycles/strudel/pull/758 (superseded by next)
- tidal style d1 ... d9 functions + more by @felixroos in https://github.com/tidalcycles/strudel/pull/805
- add vscode bindings by @Dsm0 in https://github.com/tidalcycles/strudel/pull/773
- Implement optional hover tooltip with function documentation by @ilesinge in https://github.com/tidalcycles/strudel/pull/783
- samples loading shortcuts: by @felixroos in https://github.com/tidalcycles/strudel/pull/788
- add option to disable active line highlighting in Code Settings by @kasparsj in https://github.com/tidalcycles/strudel/pull/804
- Color hsl by @felixroos in https://github.com/tidalcycles/strudel/pull/815
- Patterns tab + Refactor Panel by @felixroos in https://github.com/tidalcycles/strudel/pull/769
- patterns tab: import patterns + style by @felixroos in https://github.com/tidalcycles/strudel/pull/852
- Export patterns + ui tweaks by @felixroos in https://github.com/tidalcycles/strudel/pull/855
- Pattern organization by @felixroos in https://github.com/tidalcycles/strudel/pull/858
- Sound Import from local file system by @daslyfe in https://github.com/tidalcycles/strudel/pull/839
- bugfix: suspend and close exisiting audio context when changing interface by @daslyfe in https://github.com/tidalcycles/strudel/pull/882
- add root mode for voicings by @felixroos in https://github.com/tidalcycles/strudel/pull/887
- scales can now be anchored by @felixroos in https://github.com/tidalcycles/strudel/pull/888
- add dough function for raw dsp by @felixroos in https://github.com/tidalcycles/strudel/pull/707 (experimental)
- support mininotation '..' range operator, fixes #715 by @yaxu in https://github.com/tidalcycles/strudel/pull/716
- Add pick and squeeze functions by @daslyfe in https://github.com/tidalcycles/strudel/pull/771
- support , in < > by @felixroos in https://github.com/tidalcycles/strudel/pull/886
- public sharing by @felixroos in https://github.com/tidalcycles/strudel/pull/910
- pick, pickmod, inhabit, inhabitmod by @yaxu in https://github.com/tidalcycles/strudel/pull/921
- Mini-notation additions towards tidal compatibility by @yaxu in https://github.com/tidalcycles/strudel/pull/926
- add pickF and pickmodF by @geikha in https://github.com/tidalcycles/strudel/pull/924
- Make splice cps-aware by @yaxu in https://github.com/tidalcycles/strudel/pull/932
- Refactor cps functions by @felixroos in https://github.com/tidalcycles/strudel/pull/933
- Add useful pattern selection behavior for performing. by @daslyfe in https://github.com/tidalcycles/strudel/pull/897
</details>
## Other Fixes
<details>
<summary>show</summary>
- fix: finally repair envelopes by @felixroos in https://github.com/tidalcycles/strudel/pull/861
- fix: reverb regenerate loophole by @felixroos in https://github.com/tidalcycles/strudel/pull/726
- fix: reverb roomsize not required by @felixroos in https://github.com/tidalcycles/strudel/pull/731
- fix: reverb sampleRate by @felixroos in https://github.com/tidalcycles/strudel/pull/732
- consume n with scale by @felixroos in https://github.com/tidalcycles/strudel/pull/727
- fix: hashes in urls by @felixroos in https://github.com/tidalcycles/strudel/pull/728
- [Bug Fix] chooseWith: prevent pattern from stopping audio when selection is >= 1 or < 0 by @daslyfe in https://github.com/tidalcycles/strudel/pull/741
- Fix addivite synthesis phases by @felixroos in https://github.com/tidalcycles/strudel/pull/762
- fix: scale offset by @felixroos in https://github.com/tidalcycles/strudel/pull/764
- fix zen mode logo overlap by @felixroos in https://github.com/tidalcycles/strudel/pull/760
- fix: share copy to clipboard + alert by @felixroos in https://github.com/tidalcycles/strudel/pull/774
- fix: style issues by @felixroos in https://github.com/tidalcycles/strudel/pull/781
- Fix scope pos + document by @felixroos in https://github.com/tidalcycles/strudel/pull/786
- don't use anchor links for reference by @felixroos in https://github.com/tidalcycles/strudel/pull/791
- remove unwanted cm6 outline for strudelTheme by @kasparsj in https://github.com/tidalcycles/strudel/pull/802
- FIXES: palindrome abc -> abccba by @bwagner in https://github.com/tidalcycles/strudel/pull/831
- Bug Fix #119: Clock drift by @daslyfe in https://github.com/tidalcycles/strudel/pull/874
- bugfix: sound select indexes out of bounds by @daslyfe in https://github.com/tidalcycles/strudel/pull/871
- Error tolerance by @felixroos in https://github.com/tidalcycles/strudel/pull/880
- fix: make sure n is never undefined before nanFallback by @felixroos in https://github.com/tidalcycles/strudel/pull/881
- fix: invisible selection on vim + emacs mode by @felixroos in https://github.com/tidalcycles/strudel/pull/889
- fix: autocomplete / tooltip code example bug by @felixroos in https://github.com/tidalcycles/strudel/pull/898
- Fix examples page, piano() and a few workshop imgs by @shiyouganai in https://github.com/tidalcycles/strudel/pull/848
- fix: trailing slash confusion by @felixroos in https://github.com/tidalcycles/strudel/pull/743
- fix: try different trailing slash behavior by @felixroos in https://github.com/tidalcycles/strudel/pull/744
- Fix krill build command in README by @ilesinge in https://github.com/tidalcycles/strudel/pull/748
- Fix for #1. Enables named instruments for csoundm. by @gogins in https://github.com/tidalcycles/strudel/pull/662
- fix: missing hash for links starting with / by @felixroos in https://github.com/tidalcycles/strudel/pull/845
- fix: swatch png src by @felixroos in https://github.com/tidalcycles/strudel/pull/846
- Fix edge case with rehype-urls and trailing slashes in image file paths by @shiyouganai in https://github.com/tidalcycles/strudel/pull/849
- fix: multiple repls by @felixroos in https://github.com/tidalcycles/strudel/pull/813
- Fix chunk, add fastChunk and repeatCycles by @yaxu in https://github.com/tidalcycles/strudel/pull/712
- Update tauri.yml workflow file by @vasilymilovidov in https://github.com/tidalcycles/strudel/pull/705
- vite-vanilla-repl readme fix by @felixroos in https://github.com/tidalcycles/strudel/pull/737
- completely revert config mess by @felixroos in https://github.com/tidalcycles/strudel/pull/745
- hopefully fix trainling slashes bug by @felixroos in https://github.com/tidalcycles/strudel/pull/753
- Update vite pwa by @felixroos in https://github.com/tidalcycles/strudel/pull/772
- Update to Astro 3 by @felixroos in https://github.com/tidalcycles/strudel/pull/775
- support multiple named serial connections, change default baudrate by @yaxu in https://github.com/tidalcycles/strudel/pull/551
- CHANGES: github action checkout v2 -> v4 by @bwagner in https://github.com/tidalcycles/strudel/pull/837
- CHANGES: pin pnpm to version 8.3.1 by @bwagner in https://github.com/tidalcycles/strudel/pull/834
- CHANGES: github action pnpm version from 7 to 8.3.1 by @bwagner in https://github.com/tidalcycles/strudel/pull/835
- ADDS: JetBrains IDE files and directories to .gitignore by @bwagner in https://github.com/tidalcycles/strudel/pull/840
- Prevent 404 on Algolia crawls by @ilesinge in https://github.com/tidalcycles/strudel/pull/838
- Add in fixes from my fork to slashocalypse branch by @shiyouganai in https://github.com/tidalcycles/strudel/pull/843
- improve slashing + base href behavior by @felixroos in https://github.com/tidalcycles/strudel/pull/842
- CHANGES: pnpm 8.1.3 to 8.11.0 by @bwagner in https://github.com/tidalcycles/strudel/pull/850
- add missing trailing slashes by @felixroos in https://github.com/tidalcycles/strudel/pull/860
- move all examples to separate examples folder by @felixroos in https://github.com/tidalcycles/strudel/pull/878
- Dependency update by @felixroos in https://github.com/tidalcycles/strudel/pull/879
- Update Vite version so hot reload works properly with newest pnpm version by @daslyfe in https://github.com/tidalcycles/strudel/pull/892
- prevent vite from complaining about additional exports in jsx files by @daslyfe in https://github.com/tidalcycles/strudel/pull/891
- fix some build warnings by @felixroos in https://github.com/tidalcycles/strudel/pull/902
- Remove hideHeader for better mobile UI and consistency by @rjulian in https://github.com/tidalcycles/strudel/pull/894
- Fix: swatch/[name].png.js static path by @oscarbyrne in https://github.com/tidalcycles/strudel/pull/916
- rename @strudel.cycles/_ packages to @strudel/_ by @felixroos in https://github.com/tidalcycles/strudel/pull/917
- `pick` now accepts lookup tables, with alternate cycle squeezing behaviour as new `inhabit` function by @yaxu in https://github.com/tidalcycles/strudel/pull/918
- Revert "`pick` now accepts lookup tables, with alternate cycle squeezing behaviour as new `inhabit` function" by @yaxu in https://github.com/tidalcycles/strudel/pull/920
- Fix pattern tab not showing patterns without created date by @daslyfe in https://github.com/tidalcycles/strudel/pull/934
</details>
## New Contributors
- @ilesinge made their first contribution in https://github.com/tidalcycles/strudel/pull/748
- @Dsm0 made their first contribution in https://github.com/tidalcycles/strudel/pull/773
- @kasparsj made their first contribution in https://github.com/tidalcycles/strudel/pull/802
- @atfornes made their first contribution in https://github.com/tidalcycles/strudel/pull/818
- @drewgbarnes made their first contribution in https://github.com/tidalcycles/strudel/pull/830
- @shiyouganai made their first contribution in https://github.com/tidalcycles/strudel/pull/843
- @rjulian made their first contribution in https://github.com/tidalcycles/strudel/pull/894
- @fnordomat made their first contribution in https://github.com/tidalcycles/strudel/pull/907
- @oscarbyrne made their first contribution in https://github.com/tidalcycles/strudel/pull/916
- @geikha made their first contribution in https://github.com/tidalcycles/strudel/pull/924
**Full Changelog**: https://github.com/tidalcycles/strudel/compare/v0.9.0...v1.0.0
+2 -2
View File
@@ -1,6 +1,6 @@
export const examples = [
`// "coastline" @by eddyflux
await samples('github:eddyflux/crate')
samples('github:eddyflux/crate')
setcps(.75)
let chords = chord("<Bbm9 Fm9>/4").dict('ireal')
stack(
@@ -30,7 +30,7 @@ stack(
.late("[0 .01]*4").late("[0 .01]*2").size(4)`,
`// "broken cut 1" @by froos
await samples('github:tidalcycles/Dirt-Samples/master')
samples('github:tidalcycles/dirt-samples')
samples({
'slap': 'https://cdn.freesound.org/previews/495/495416_10350281-lq.mp3',
'whirl': 'https://cdn.freesound.org/previews/495/495313_10350281-lq.mp3',
+1 -1
View File
@@ -51,7 +51,7 @@ Alternatively, you can get a taste of what Strudel can do by clicking play on th
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0A0D0.wav','bd/BT0A0A7.wav'],
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
}, 'github:tidalcycles/dirt-samples');
stack(
s("bd,[~ <sd!3 sd(3,4,2)>],hh*8") // drums
.speed(perlin.range(.7,.9)) // random sample speed variation
+10 -10
View File
@@ -143,7 +143,7 @@ Because GitHub is a popular place for uploading open source samples, it has its
bd: 'bd/BT0AADA.wav',
sd: 'sd/rytm-01-classic.wav',
hh: 'hh27/000_hh27closedhh.wav',
}, 'github:tidalcycles/Dirt-Samples/master/');
}, 'github:tidalcycles/dirt-samples');
s("bd sd bd sd,hh*16")`}
/>
@@ -174,7 +174,7 @@ It is also possible, to declare multiple files for one sound, using the array no
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav'],
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
}, 'github:tidalcycles/dirt-samples');
s("bd:0 bd:1,~ <sd:0 sd:1> ~ sd:0,[hh:0 hh:1]*4")`}
/>
@@ -187,7 +187,7 @@ The sample number can also be set using `n`:
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav'],
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
}, 'github:tidalcycles/dirt-samples');
s("bd bd,~ sd ~ sd,hh*8").n("<0 1>")`}
/>
@@ -231,7 +231,7 @@ For pitched sounds, you can use `note`, just like with synths:
client:idle
tune={`samples({
'gtr': 'gtr/0001_cleanC.wav',
}, 'github:tidalcycles/Dirt-Samples/master/');
}, 'github:tidalcycles/dirt-samples');
note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s('gtr').gain(.5)`}
/>
@@ -242,7 +242,7 @@ If we want them to behave more like a synth, we can add `clip(1)`:
client:idle
tune={`samples({
'gtr': 'gtr/0001_cleanC.wav',
}, 'github:tidalcycles/Dirt-Samples/master/');
}, 'github:tidalcycles/dirt-samples');
note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s('gtr').clip(1)
.gain(.5)`}
/>
@@ -256,7 +256,7 @@ If we have 2 samples with different base pitches, we can make them in tune by sp
tune={`samples({
'gtr': 'gtr/0001_cleanC.wav',
'moog': { 'g3': 'moog/005_Mighty%20Moog%20G3.wav' },
}, 'github:tidalcycles/Dirt-Samples/master/');
}, 'github:tidalcycles/dirt-samples');
note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s("gtr,moog").clip(1)
.gain(.5)`}
/>
@@ -272,7 +272,7 @@ We can also declare different samples for different regions of the keyboard:
'g2': 'moog/004_Mighty%20Moog%20G2.wav',
'g3': 'moog/005_Mighty%20Moog%20G3.wav',
'g4': 'moog/006_Mighty%20Moog%20G4.wav',
}}, 'github:tidalcycles/Dirt-Samples/master/');
}}, 'github:tidalcycles/dirt-samples');
note("g2!2 <bb2 c3>!2, <c4@3 [<eb4 bb3> g4 f4]>")
.s('moog').clip(1)
.gain(.5).cpm(60)`}
@@ -287,7 +287,7 @@ With it, you can enter any sample name(s) to query from [freesound.org](https://
<MiniRepl
client:idle
tune={`await samples('shabda:bass:4,hihat:4,rimshot:2')
tune={`samples('shabda:bass:4,hihat:4,rimshot:2')
stack(
n("0 1 2 3 0 1 2 3").s('bass'),
n("0 1*2 2 3*2").s('hihat'),
@@ -300,8 +300,8 @@ Note that the language code and the gender parameters are optional and default t
<MiniRepl
client:idle
tune={`await samples('shabda/speech:the_drum,forever')
await samples('shabda/speech/fr-FR/m:magnifique')
tune={`samples('shabda/speech:the_drum,forever')
samples('shabda/speech/fr-FR/m:magnifique')
stack(
s("the_drum*2").chop(16).speed(rand.range(0.85,1.1)),
s("forever magnifique").slow(4).late(0.125)
+10 -10
View File
@@ -60,7 +60,7 @@ A sample can be looped and chopped like this:
<MiniRepl
client:visible
tune={`await samples('github:yaxu/clean-breaks/main')
tune={`samples('github:yaxu/clean-breaks')
s("amen/4").fit().chop(32)`}
punchcard
/>
@@ -71,7 +71,7 @@ Let's add randmized doubling + reversing:
<MiniRepl
client:visible
tune={`await samples('github:yaxu/clean-breaks/main')
tune={`samples('github:yaxu/clean-breaks')
s("amen/4").fit().chop(16).cut(1)
.sometimesBy(.5, ply("2"))
.sometimesBy(.25, mul(speed("-1")))`}
@@ -82,7 +82,7 @@ If we want to specify the order of samples, we can replace `chop` with `slice`:
<MiniRepl
client:visible
tune={`await samples('github:yaxu/clean-breaks/main')
tune={`samples('github:yaxu/clean-breaks')
s("amen/4").fit()
.slice(8, "<0 1 2 3 4*2 5 6 [6 7]>*2")
.cut(1).rarely(ply("2"))`}
@@ -93,7 +93,7 @@ If we use `splice` instead of `slice`, the speed adjusts to the duration of the
<MiniRepl
client:visible
tune={`await samples('github:yaxu/clean-breaks/main')
tune={`samples('github:yaxu/clean-breaks')
s("amen")
.splice(8, "<0 1 2 3 4*2 5 6 [6 7]>*2")
.cut(1).rarely(ply("2"))`}
@@ -213,7 +213,7 @@ Using `run` with `n`, we can rush through a sample bank:
<MiniRepl
client:visible
tune={`await samples('bubo:fox')
tune={`samples('bubo:fox')
n(run(8)).s("ftabla")`}
punchcard
/>
@@ -224,7 +224,7 @@ In this case, I hear the beginning at the third sample, which can be accounted f
<MiniRepl
client:visible
tune={`await samples('bubo:fox')
tune={`samples('bubo:fox')
n(run(8)).s("ftabla").early(2/8)`}
/>
@@ -232,7 +232,7 @@ Let's add some randomness:
<MiniRepl
client:visible
tune={`await samples('bubo:fox')
tune={`samples('bubo:fox')
n(run(8)).s("ftabla").early(2/8)
.sometimes(mul(speed("1.5")))`}
/>
@@ -299,7 +299,7 @@ To simplify loading wavetables, any sample that starts with `wt_` will be looped
<MiniRepl
client:visible
tune={`await samples('github:bubobubobubobubo/dough-waveforms/main')
tune={`samples('github:bubobubobubobubo/dough-waveforms')
note("c eb g bb").s("wt_dbass").clip(2)`}
/>
@@ -307,7 +307,7 @@ Running through different wavetables can also give interesting variations:
<MiniRepl
client:visible
tune={`await samples('github:bubobubobubobubo/dough-waveforms/main')
tune={`samples('github:bubobubobubobubo/dough-waveforms')
note("c2*8").s("wt_dbass").n(run(8))`}
/>
@@ -315,7 +315,7 @@ note("c2*8").s("wt_dbass").n(run(8))`}
<MiniRepl
client:visible
tune={`await samples('github:bubobubobubobubo/dough-waveforms/main')
tune={`samples('github:bubobubobubobubo/dough-waveforms')
note("c2*8").s("wt_dbass").n(run(8))
.lpf(perlin.range(200,2000).slow(8))
.lpenv(-3).lpa(.1).room(.5)`}
+1 -1
View File
@@ -8,7 +8,7 @@ import { MiniRepl } from '../../docs/MiniRepl';
Note:
- this has been (partly) translated from https://tidalcycles.org/docs/patternlib/howtos/buildrhythms
- this only sounds good with `samples('github:tidalcycles/Dirt-Samples/master')` in prebake
- this only sounds good with `samples('github:tidalcycles/dirt-samples')` in prebake
# Build Rhythms
+1 -1
View File
@@ -139,7 +139,7 @@ The content of a sequence will be squished into what's called a cycle.
cpm = cycles per minute
By default, the tempo is 60 cycles per minute = 1 cycle per second.
By default, the tempo is 30 cycles per minute = 1 half cycle per second.
</Box>
+5
View File
@@ -64,3 +64,8 @@
#code .cm-focused {
outline: none;
}
#code .cm-matchingBracket {
text-decoration: underline 0.18rem;
text-underline-offset: 0.22rem;
}
+9 -1
View File
@@ -7,7 +7,13 @@ This program is free software: you can redistribute it and/or modify it under th
import { code2hash, getDrawContext, logger, silence } from '@strudel/core';
import cx from '@src/cx.mjs';
import { transpiler } from '@strudel/transpiler';
import { getAudioContext, initAudioOnFirstClick, webaudioOutput } from '@strudel/webaudio';
import {
getAudioContext,
initAudioOnFirstClick,
webaudioOutput,
resetGlobalEffects,
resetLoadedSounds,
} from '@strudel/webaudio';
import { defaultAudioDeviceName } from '../settings.mjs';
import { getAudioDevices, setAudioDevice } from './util.mjs';
import { StrudelMirror, defaultSettings } from '@strudel/codemirror';
@@ -157,6 +163,7 @@ export function Repl({ embedded = false }) {
};
const resetEditor = async () => {
resetGlobalEffects();
clearCanvas();
resetLoadedSounds();
editorRef.current.repl.setCps(0.5);
@@ -183,6 +190,7 @@ export function Repl({ embedded = false }) {
setViewingPatternData(patternData);
clearCanvas();
resetLoadedSounds();
resetGlobalEffects();
await prebake(); // declare default samples
editorRef.current.setCode(code);
editorRef.current.repl.evaluate(code);
+6
View File
@@ -77,6 +77,7 @@ export function SettingsTab({ started }) {
const {
theme,
keybindings,
isBracketMatchingEnabled,
isLineNumbersDisplayed,
isPatternHighlightingEnabled,
isActiveLineHighlighted,
@@ -137,6 +138,11 @@ export function SettingsTab({ started }) {
></ButtonGroup>
</FormItem>
<FormItem label="Code Settings">
<Checkbox
label="Enable bracket matching"
onChange={(cbEvent) => settingsMap.setKey('isBracketMatchingEnabled', cbEvent.target.checked)}
value={isBracketMatchingEnabled}
/>
<Checkbox
label="Display line numbers"
onChange={(cbEvent) => settingsMap.setKey('isLineNumbersDisplayed', cbEvent.target.checked)}
+1 -2
View File
@@ -115,13 +115,12 @@ export async function prebake() {
'numbers/8.wav',
],
},
'github:tidalcycles/Dirt-Samples/master/',
'github:tidalcycles/dirt-samples',
{
prebake: true,
},
),
]);
// await samples('github:tidalcycles/Dirt-Samples/master');
}
const maxPan = noteToMidi('C8');
+5 -5
View File
@@ -527,7 +527,7 @@ export const meltingsubmarine = `// "Melting submarine"
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
// @by Felix Roos
await samples('github:tidalcycles/Dirt-Samples/master/')
samples('github:tidalcycles/dirt-samples')
stack(
s("bd:5,[~ <sd:1!3 sd:1(3,4,3)>],hh27(3,4,1)") // drums
.speed(perlin.range(.7,.9)) // random sample speed variation
@@ -574,7 +574,7 @@ samples({
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
perc: ['perc/002_perc2.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
}, 'github:tidalcycles/dirt-samples');
chord("<C^7 Am7 Dm7 G7>*2").dict('lefthand').anchor("G4").voicing()
.stack(n("0@6 [<1 2> <2 0> 1]@2").scale('C5 major'))
@@ -608,7 +608,7 @@ samples({
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0A0D0.wav','bd/BT0A0A7.wav'],
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
}, 'github:tidalcycles/dirt-samples');
note("<8(3,8) <7 7*2> [4 5@3] 8>".sub(1) // sub 1 -> 1-indexed
.layer(
@@ -797,7 +797,7 @@ export const amensister = `// "Amensister"
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
// @by Felix Roos
await samples('github:tidalcycles/Dirt-Samples/master')
samples('github:tidalcycles/dirt-samples')
stack(
// amen
@@ -906,7 +906,7 @@ export const arpoon = `// "Arpoon"
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
// @by Felix Roos
await samples('github:tidalcycles/Dirt-Samples/master')
samples('github:tidalcycles/dirt-samples')
n("[0,3] 2 [1,3] 2".fast(3).lastOf(4, fast(2))).clip(2)
.offset("<<1 2> 2 1 1>")
+2
View File
@@ -7,6 +7,7 @@ export const defaultAudioDeviceName = 'System Standard';
export const defaultSettings = {
activeFooter: 'intro',
keybindings: 'codemirror',
isBracketMatchingEnabled: true,
isLineNumbersDisplayed: true,
isActiveLineHighlighted: true,
isAutoCompletionEnabled: false,
@@ -40,6 +41,7 @@ export function useSettings() {
return {
...state,
isZen: [true, 'true'].includes(state.isZen) ? true : false,
isBracketMatchingEnabled: [true, 'true'].includes(state.isBracketMatchingEnabled) ? true : false,
isLineNumbersDisplayed: [true, 'true'].includes(state.isLineNumbersDisplayed) ? true : false,
isActiveLineHighlighted: [true, 'true'].includes(state.isActiveLineHighlighted) ? true : false,
isAutoCompletionEnabled: [true, 'true'].includes(state.isAutoCompletionEnabled) ? true : false,