From 0bb89d1a9f26b6bcecae3bf4694731bc47965437 Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Wed, 19 Nov 2025 20:09:14 +0100 Subject: [PATCH 01/79] New page FAQ in "More" --- website/src/config.ts | 1 + website/src/pages/learn/faq.mdx | 403 ++++++++++++++++++++++++++++++++ 2 files changed, 404 insertions(+) create mode 100644 website/src/pages/learn/faq.mdx diff --git a/website/src/config.ts b/website/src/config.ts index f335b272e..eb39d2958 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -76,6 +76,7 @@ export const SIDEBAR: Sidebar = { { text: 'MIDI & OSC', link: 'learn/input-output' }, ], More: [ + { text: 'FAQ', link: 'learn/faq' }, { text: 'Recipes', link: 'recipes/recipes' }, { text: 'Mini-Notation', link: 'learn/mini-notation' }, { text: 'Visual Feedback', link: 'learn/visual-feedback' }, diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx new file mode 100644 index 000000000..30f2986bd --- /dev/null +++ b/website/src/pages/learn/faq.mdx @@ -0,0 +1,403 @@ +--- +title: Frequently Asked Questions +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; +import { JsDoc } from '../../docs/JsDoc'; + +# Frequently Asked Questions + +This page contains frequently asked questions. Usually, the topic is explained in more detail in a section which is linked in the answer. This page's aim is to give an overview over topics which are important to the users of strudel. + +## Is Strudel/Tidal free? + +Yes - there is no charge, this is a collective open source project, and the music you make with it is your own. + +However there are some caveats - the source code must stay free, i.e. you cannot distribute strudel or tidal as part of projects with incompatible licenses - see the [license]() for details. The contributed examples and tracks are also separately licensed, and must not e.g. be used to train AI models without permission. + +## How to record or export audio? + +There are multiple ways to record the audio -- and video -- output of Strudel: + - capture the raw stereo signal coming out of your web browser. + - use the alternative SuperDirt audio engine. Read [this page](/learn/input-output/#oscsuperdirtstrudeldirt) to know more about it. + - capture the audio/video stream using a capture tool such as [OBS](). + - don't record anything and code it again in front of your friends. + +You will need an external audio editor/DAW such as Reaper/Audacity/Ardour, etc. Strudel itself does not have functionality for exporting stems / individual tracks to an audio or midi file. Strudel is not a digital audio workstation and does not operate following the same principles shared by most traditional audio softwares. + +## Can I use strudel with my IDE? + +Yes you can. There are experimental modes, made by community members, for several IDEs such as: + - VS Code: [Strudel VS](): an experimental mode for Microsoft VSCode. A revived version of [TidalStrudel](), which is defunct. + - nvim: [strudel.nvim](https://github.com/gruvw/strudel.nvim) + +## How can I record samples? + +You can use your own samples with Strudel. There are multiple ways to load your sample collection. Some methods are good for quick experimentation, some others are good to share your audio collection with other musicians: + + - Import folders [from the interface](/learn/samples/#from-disk-via-import-sounds-folder) + - Host your sound library e.g. on github and [load them from an URL](/learn/samples/#loading-custom-samples) + +## Can I use Strudel with AI/LLM tools? + +You are free to do what you like with Strudel, within the terms of the free/open source AGPLv3 license. However as a community we are interested in exploring human creativity. AI is *way* over-hyped right now, including by people with very shady motives. Many in the community are very wary of people training models on their tunes that they've poured their love into. So please keep discussion and questions around AI and LLMs to channels dedicated to the topic and be fully respectful of other people's work. + +Furthermore, tools like ChatGPT generally give wrong answers. Please don't ask the community to fix those answers for you, as generally they will be timewasting nonsense. + +Human questions only! + +## How to run offline? + +Strudel works offline just fine! There are multiple techniques to run it yourself, see [this explanation](learn/pwa/#using-strudel-offline). + +## How to change tempo? How do I translate BPM to cpm? + +If you have your tempo in beats per minute and use 4 beats per cycle (e.g. if your track is in 4/4ths) then you can do `setcpm(BPM/4)` where BPM is your beats per minute. + +If you have a different number of beats per bar or are using more or less beats per cycle (e.g. If you want to put only half a bar or two bars into one cycle), adjust accordingly. + +## Where can I see all the functions? + +If you pop open the sidetab of strudel.cc (small white < on the right hand side), there is a tab "reference" which lists all the functions of strudel. + +## Where can I see all the samples and synths? + +If you pop open the sidetab of strudel.cc (small white < on the right hand side), there is a tab "sounds" which lists all the drum machines, samples and synths currently loaded. + +## How do I use this exactly like a DAW? + +Short answer: you don't. + +Long answer: you can use Strudel to work along your creative work in a DAW. There are many ways to do so. + +If you want to emulate the functionality of a DAW in a live coding language, you'll have to identify the operations executed by the DAW (sequencing, repeating, applying filters and envelopes) and write code that is equivalent to these operations. You might then find that the typical DAW workflow is not really adapted to live coding (because, despite both being ways of making music on the computer, they are two very different tools) and adapt your way of proceeding to the medium of code. This might mean leaving more place to serendipity and writing code that you don't predict the output of. + +## Why doesn't everyone just use a DAW? + +There is no easy answer to this question. Here are some thoughts: + - Live coding tools such as Strudel are excellent for improvising music and visuals using a computer. DAWs are valuable and robust companions for other activities such as producing, mastering and mixing audio, among other usages. Using a tool does not exclude from using any another tool, just build a toolbox. + - Live coding has been practiced for quite some time as a performative activity. Artists like to show their screens while playing in front of an audience. It is an essential part of what they do, of the way they share their activity with everybody. + - Code is a human language, it is made for other humans to read it. You can read the code and enjoy the music too. It has meaning, value, and there might even be something poetic/important about it! + - Strudel is free and open source, you can inspect the code, reshape it, contribute to it if you can/want. It is not opaque and this matters for many people. There is no black box, no obscure abstractions, no business model or hidden features. We need open tools in the arts! + - Live coders don't shy away from using DAWs. They use them all of the time, especially when it makes their life easier for... live coding! + - Code is an artistic material like any other. There is something valuable in the process of making music through code. More generally speaking, it is nice to tackle creative problems through the use of a programming language: creative thinking, building up your own solutions, DIY approach to music-making, unexpected outcome of algorithms, funny human errors, etc. + - There are pianos and trumpets in your DAW: why do people continue playing the piano or the trumpet? Think of live coding tools as instruments that you activate through the act of programming. + +## Is it more efficient to use Strudel than a DAW? + +Strudel was not build to be a DAW, yet it can still be used to make covers, arrange tracks, or prepare patterns for jamming. When playing concerts or jamming, some livecoders prepare their code, some perform from scratch. + +It might be interesting for you to check out for yourself how strudel can be used to express yourself creatively. Also you are free to combine a language like Strudel with a DAW. + +## How can I interface Strudel with my favorite music software? What can I do with it? + +Strudel can send [MIDI and OSC](/learn/input-output/), which are protocols for communicating musical information. + +Another music software (or hardware!) can then listen to these messages and process them according to its capabilities. + +A simple example would be to send livecoded audio to Ableton on different tracks and then use it to mix them. + +You could also send the MIDI of a sequenced pattern to Musescore and then have it transcribe your livecoded work as a musical score. + +You could also send MIDI to your hardware synths because you think they sound better than the software synths built-in Strudel. + +## How do I use this in my closed source webgame? + +You don't. You would need to re-license your game to AGPLv3 to fulfill the license Strudel is distributed under. + +## Where can I download loads of patterns to train my LLM? + +You cannot, as there is no such place. For details regarding our stance towards AI/LLM, see [above](/learn/faq/#can-i-use-strudel-with-aillm-tools) + +## How to play different patterns simultaneously? + +Using the $ operator, several patterns can be played at once: + + +See also [stack](intro/#combining-patterns) + +## Is it possible to mute a pattern? + +With an additional underscore, a pattern can be muted. + + + +See also [hush](/learn/conditional-modifiers/#hush) + +## How can I arrange in Strudel using `mask`? + +With mini-notation, using the `<>` and `!` operators, you can try something like +``` +.mask("<0!24 1!40>") +``` +It mutes a pattern for 24 cycles and plays it for 40. You would gain 64 cycles total, a multiple of 2/4/8 commonly used in western music. + +If each cycle is a bar, as a starting point, you could write a mask like that for any pattern: +``` +.mask("<0!16 0!16 0!16 0!16 0!16 0!10>") +``` +It mutes it throughout. + +For arranging, you could add the same mask to each part and replace some zeroes with ones in your different masks to make parts play. + +If you use `.mask()` on different patterns mess up your counting, then patterns do not align anymore. +On the other hand, doing that on purpose is one of the things that could be considered a strength of tidalcycles and Strudel. +You can make things quite lively and more organic with a little (controlled) interference, according to your own taste. +And you are free to arrange in cycles like 3, 6 or 9 too. + +To modify everything at once, you could try all and when, for example: + +``` +all(x=>x.when("<0!7 1>", x=>x.lpf(saw.range(200, 2000)))) +``` + +This would lowpass filter sweep everything every 8 cycles. + +## How can I arrange in Strudel using `arrange` or `pick`? + +Take [Pachelbel's Canon in D](https://en.wikipedia.org/wiki/Pachelbel%27s_Canon#Analysis) as an example which has 4 voices (one cello and 3 violins) which have repeating patterns, as seen in the link above. + +The following snipped defines the patterns as constants which can then be used for the different voices. `arrange` takes multiple arguments, which are each a number of cycles and a pattern which is played for the number of cycles, wrapped in `[]` If the pattern is shorter than the number, it is repeated. +") + .color("grey").sound("gm_tremolo_strings:3") + const violin_p1 = note( + "<[f#5 e5 d5 c#5] [b4 a4 b4 c#5]>") + .color("blue") + const violin_p2 = note( + "<[d5 c#5 b4 a4] [ g4 f#4 g4 f#4]>") + .color("green") + const violin_p3 = note( + "<[d4 f#4 a4 g4 f#4 d4 f#4 e4] [d4 b3 d4 a4 g4 b4 a4 g4]>") + .color("purple") + const violin_p4 = note( + "<[f#4 d4 e4 c#5 d5 f#5 a5 a4] [b4 g4 a4 f#4 d4 d5 [d5@3 c#5]@2]>") + .color("red") + + + cello$: arrange( + [2, silence], + [18,cello]) + violin1$: arrange( + [4,silence], + [2,violin_p1], [2,violin_p2], + [2,violin_p3], [2,violin_p4], + [2,violin_p1], [2,violin_p2], + [2,violin_p3], [2,violin_p4] + ).sound("gm_tremolo_strings:0") + violin2$: arrange( + [6,silence], [2,violin_p1], + [2,violin_p2], [2,violin_p3], + [2,violin_p4], [2,violin_p1], + [2,violin_p2], [2,violin_p3] + ).sound("gm_tremolo_strings:1") + violin3$: arrange( + [8,silence], + [2,violin_p1], [2,violin_p2], + [2,violin_p3], [2,violin_p4], + [2,violin_p1], [2,violin_p2] + ).sound("gm_tremolo_strings:2") + + all(x => x.release(.2)) +`} /> + +Alternatively, you can also put the different patterns for the violins into one single array (`const violins = [violin_p1, violin_p2, violin_p3, violin_p4]`) and use a pattern as an index to `pick` the nth element of that array. This replaces the voices defined above. Here you use `0@2` to specifiy that the first item (i.e. with index `0`) is played for `2` cycles. + +`pick` has better highlighting than `arrange`: + +") + .color("grey").sound("gm_tremolo_strings:3") + const violin_p1 = note( + "<[f#5 e5 d5 c#5] [b4 a4 b4 c#5]>") + .color("blue") + const violin_p2 = note( + "<[d5 c#5 b4 a4] [ g4 f#4 g4 f#4]>") + .color("green") + const violin_p3 = note( + "<[d4 f#4 a4 g4 f#4 d4 f#4 e4] [d4 b3 d4 a4 g4 b4 a4 g4]>") + .color("purple") + const violin_p4 = note( + "<[f#4 d4 e4 c#5 d5 f#5 a5 a4] [b4 g4 a4 f#4 d4 d5 [d5@3 c#5]@2]>") + .color("red") + +const violins = [violin_p1, violin_p2, violin_p3, violin_p4] + +cello$: "<~@2 0@18>".pick([cello]) +violin1$: "<~@4 0@2 1@2 2@2 3@2 0@2 1@2 2@2 3@2>".pick(violins) +.sound("gm_tremolo_strings:0") +violin2$: "<~@6 0@2 1@2 2@2 3@2 0@2 1@2 2@2>".pick(violins) +.sound("gm_tremolo_strings:1") +violin3$: "<~@8 0@2 1@2 2@2 3@2 0@2 1@2 >".pick(violins) +.sound("gm_tremolo_strings:2") +all(x => x.release(.2)) +`} /> + +The `pick` method also works with jsons which have named elements, which makes it easier to read, see the [here](/learn/conditional-modifiers/#pick). `pickRestart` restarts the pattern upon picking it which can make a difference if the duration of the pick indexes doesn't line up with the patterns which are picked - which is not the case here. + +Try adding `.punchcard()` after the `release(.2)` for a visualization. + +## I saw Switch Angel using functions which I cannot find in the reference (e.g. `trancegate`). How do I make it work? + +Methods like `trancegate()`, `rlpf()` and `acidenv()` are currently not pattern methods which come natively with strudel. + +It's part of a script for strudel which was written by Switch Angel and published [here](https://github.com/switchangel/strudel-scripts/blob/main/allscripts.js) + +Note that this script defines functions and registers methods which `trancegate()` will depend on so just pasting the `trancegate()` method from that script alone will not suffice, but you will also need the `fill` method. + +If you copy the full script into your strudel, be mindful of lines which try to load local samples - these should be deleted or prefixed with `//` as a comment. + +If you paste these functions into your strudel session, hit "Update" and delete the source of the functions, the functions will still be availabe until you do a browser refresh. + +## Is there difference between `n` and `note`? + +They are not aliases of each other, in contrast to `s` and `sound`. + +The method `note` is used to reference a certain note (either as its name, such as `c` or `b2` or the midi number `69`, for example `note("c3 e3 g3")`). + +On the other hand, `n` is a way to reference the nth index of something. This something can be a scale (eg `n("0 2 4").scale("C:major")`) , but it can also be a particular note in a chord (see https://strudel.cc/recipes/recipes/#arpeggios for an example) . + +The method `n` can also be used for something completely unrelated to notes like the nth sample from a sample map `s("hh*8").bank("RolandTR909").n("0 1 2 3")`. Note that `pick` does *not* use `n`. + +".pickRestart([ + n("0 1 2 0"), + n("2 3 4 ~"), + n("[4 5] [4 3] 2 0"), + n("0 -3 0 ~") + ]).scale("C:major").s("piano")`} /> + + +## Is there a cheat sheet for all symbols? + +Yes! + +``` +' marks start and end of strings, is different from " +" marks start and end of single line patterns in mini notation, is different from ' +` marks start and end of patterns with line breaks in mini notation, is different from ' +[] used for patterns, each item in it has the same length +<> used for patterns, alternates each item each cycle +{} historically used for polyrhythmic patterns. {a b c}%4 is the same as *4. +@3 elongates the item by a factor of 3 (other numbers work too) +@ after an item: elongates the item once (multiple @ work too c @ @ is the same as c@3) +_ after an item: also elongates an item once (multiple _ work too c _ _ is the same as c@3) +. this divides equal parts of a pattern and is called a foot. Can be used instead of [] like this: "1 6 7 8 . 2 . 3 . 4" is the same as "[1 6 7 8] 2 3 4" +- silence +~ also silence +x not silence (for the use in struct, same as 1) +s increase a note of a scale by one semitone, i.e. sharp +b decrease a note of a scale by one semitone, i.e. flat +# used in mondo notation +# also used for names of chords, like F# +*3 play the sample or pattern at thrice the speed, fast(3) +!3 play the sample or pattern three times +/2 play the sample or pattern at half speed, slow(2) +? play the pattern sometimes +| once per cycle, choose randomly a pattern of those separated by i.e. chooseCycles() +, play all items separated by it at the same time, i.e. stack() +: is used to separate multiple parameters, such as adsr(".1:.1:.5:.2") +$: at the start of a line, defines a member of the stack. is the only stack name that should occur multiple names +_ before a stack name: mutes the stack, i.e. hush(), for example _$: s("bd") +``` + +## Are there more FAQ items? + +These pages have been taken from [this pad](https://doc.patternclub.org/_CgofWouTciXXHexUP9AVg?both). Some of the items there have not been brushed up and brought here. + +These include the following items: 9, 11, 12 and 19 + +# Coding Syntax (old Content from code) + +Let's take a step back and understand how the syntax in Strudel works. + +Take a look at this simple example: + + + +- We have a word `note` which is followed by some brackets `()` with some words/letters/numbers inside, surrounded by quotes `"c a f e"` +- Then we have a dot `.` followed by another similar piece of code `s("piano")`. +- We can also see these texts are _highlighted_ using colours: word `note` is purple, the brackets `()` are grey, and the content inside the `""` are green. (The colors could be different if you've changed the default theme) + +What happens if we try to 'break' this pattern in different ways? + + + + + + + +Ok, none of these seem to work... + + + +This one does work, but now we only hear the first note... + +So what is going on here? + +# Functions, arguments and chaining + +So far, we've seen the following syntax: + +``` +xxx("foo").yyy("bar") +``` + +Generally, `xxx` and `yyy` are called [_functions_](), while `foo` and `bar` are called function [_arguments_ or _parameters_](). +So far, we've used the functions to declare which aspect of the sound we want to control, and their arguments for the actual data. +The `yyy` function is called a [_chained_ function](https://en.wikipedia.org/wiki/Method_chaining), because it is preceded with a dot (`.`). + +Generally, the idea with chaining is that code such as `a("this").b("that").c("other")` allows `a`, `b` and `c` functions to happen in a specified order, without needing to write them as three separate lines of code. +You can think of this as being similar to chaining audio effects together using guitar pedals or digital audio effects. + +Strudel makes heavy use of chained functions. Here is a more sophisticated example: + + + +## Write your own chained function + +You can write your own chained function using `register`. Here's the above chain but registered as a reusable, chained function. + + pat + .s("sawtooth") + .cutoff(500) + //.delay(0.5) + .room(0.5) + ) +note("a3 c#4 e4 a4").effectChain()`} +/> + +Try adding `.rev()` after `effectChain()` to hear further effects added. + +# Comments + +The `//` in the example above is a line comment, resulting in the `delay` function being ignored. +It is a handy way to quickly turn code on and off. +Try uncommenting this line by deleting `//` and refreshing the pattern. +You can also use the keyboard shortcut `cmd-/` to toggle comments on and off. + +You might noticed that some comments in the REPL samples include some words starting with a "@", like `@by` or `@license`. +Those are just a convention to define some information about the music. We will talk about it in the [Music metadata](/learn/metadata) section. + +# Strings + +Ok, so what about the content inside the quotes (e.g. `"c a f e"`)? +In JavaScript, as in most programming languages, this content is referred to as being a [_string_](). +A string is simply a sequence of individual characters. +In TidalCycles, double quoted strings are used to write _patterns_ using the mini-notation, and you may hear the phrase _pattern string_ from time to time. +If you want to create a regular string and not a pattern, you can use single quotes, e.g. `'C minor'` will not be parsed as Mini Notation. + +The good news is, that this covers most of the JavaScript syntax needed for Strudel! + +
From 371e6c7d6d4f1fdd780c6a07302049ae069c1a08 Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Wed, 19 Nov 2025 20:17:19 +0100 Subject: [PATCH 02/79] tidy up FAQ --- website/src/pages/learn/faq.mdx | 93 --------------------------------- 1 file changed, 93 deletions(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index 30f2986bd..dbce4c701 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -308,96 +308,3 @@ _ before a stack name: mutes the stack, i.e. hush(), for example _$: s("bd") These pages have been taken from [this pad](https://doc.patternclub.org/_CgofWouTciXXHexUP9AVg?both). Some of the items there have not been brushed up and brought here. These include the following items: 9, 11, 12 and 19 - -# Coding Syntax (old Content from code) - -Let's take a step back and understand how the syntax in Strudel works. - -Take a look at this simple example: - - - -- We have a word `note` which is followed by some brackets `()` with some words/letters/numbers inside, surrounded by quotes `"c a f e"` -- Then we have a dot `.` followed by another similar piece of code `s("piano")`. -- We can also see these texts are _highlighted_ using colours: word `note` is purple, the brackets `()` are grey, and the content inside the `""` are green. (The colors could be different if you've changed the default theme) - -What happens if we try to 'break' this pattern in different ways? - - - - - - - -Ok, none of these seem to work... - - - -This one does work, but now we only hear the first note... - -So what is going on here? - -# Functions, arguments and chaining - -So far, we've seen the following syntax: - -``` -xxx("foo").yyy("bar") -``` - -Generally, `xxx` and `yyy` are called [_functions_](), while `foo` and `bar` are called function [_arguments_ or _parameters_](). -So far, we've used the functions to declare which aspect of the sound we want to control, and their arguments for the actual data. -The `yyy` function is called a [_chained_ function](https://en.wikipedia.org/wiki/Method_chaining), because it is preceded with a dot (`.`). - -Generally, the idea with chaining is that code such as `a("this").b("that").c("other")` allows `a`, `b` and `c` functions to happen in a specified order, without needing to write them as three separate lines of code. -You can think of this as being similar to chaining audio effects together using guitar pedals or digital audio effects. - -Strudel makes heavy use of chained functions. Here is a more sophisticated example: - - - -## Write your own chained function - -You can write your own chained function using `register`. Here's the above chain but registered as a reusable, chained function. - - pat - .s("sawtooth") - .cutoff(500) - //.delay(0.5) - .room(0.5) - ) -note("a3 c#4 e4 a4").effectChain()`} -/> - -Try adding `.rev()` after `effectChain()` to hear further effects added. - -# Comments - -The `//` in the example above is a line comment, resulting in the `delay` function being ignored. -It is a handy way to quickly turn code on and off. -Try uncommenting this line by deleting `//` and refreshing the pattern. -You can also use the keyboard shortcut `cmd-/` to toggle comments on and off. - -You might noticed that some comments in the REPL samples include some words starting with a "@", like `@by` or `@license`. -Those are just a convention to define some information about the music. We will talk about it in the [Music metadata](/learn/metadata) section. - -# Strings - -Ok, so what about the content inside the quotes (e.g. `"c a f e"`)? -In JavaScript, as in most programming languages, this content is referred to as being a [_string_](). -A string is simply a sequence of individual characters. -In TidalCycles, double quoted strings are used to write _patterns_ using the mini-notation, and you may hear the phrase _pattern string_ from time to time. -If you want to create a regular string and not a pattern, you can use single quotes, e.g. `'C minor'` will not be parsed as Mini Notation. - -The good news is, that this covers most of the JavaScript syntax needed for Strudel! - -
From 69c5df67f5cb01ca372afc3d42f3cd23f2985d62 Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Wed, 19 Nov 2025 21:40:48 +0100 Subject: [PATCH 03/79] FAQ is now prettier --- website/src/pages/learn/faq.mdx | 134 +++++++++++++++++++------------- 1 file changed, 78 insertions(+), 56 deletions(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index dbce4c701..923bb5f66 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -12,16 +12,20 @@ This page contains frequently asked questions. Usually, the topic is explained i ## Is Strudel/Tidal free? -Yes - there is no charge, this is a collective open source project, and the music you make with it is your own. +Yes - there is no charge, this is a collective open source project, and the music you make with it is your own. -However there are some caveats - the source code must stay free, i.e. you cannot distribute strudel or tidal as part of projects with incompatible licenses - see the [license]() for details. The contributed examples and tracks are also separately licensed, and must not e.g. be used to train AI models without permission. +However there are some caveats - the source code must stay free, i.e. you cannot distribute strudel or tidal as part of projects with incompatible licenses - see the [license](https://www.gnu.org/licenses/agpl-3.0.en.html) for details. The contributed examples and tracks are also separately licensed, and must not e.g. be used to train AI models without permission. ## How to record or export audio? There are multiple ways to record the audio -- and video -- output of Strudel: + - capture the raw stereo signal coming out of your web browser. + - use the alternative SuperDirt audio engine. Read [this page](/learn/input-output/#oscsuperdirtstrudeldirt) to know more about it. + - capture the audio/video stream using a capture tool such as [OBS](). + - don't record anything and code it again in front of your friends. You will need an external audio editor/DAW such as Reaper/Audacity/Ardour, etc. Strudel itself does not have functionality for exporting stems / individual tracks to an audio or midi file. Strudel is not a digital audio workstation and does not operate following the same principles shared by most traditional audio softwares. @@ -29,9 +33,10 @@ You will need an external audio editor/DAW such as Reaper/Audacity/Ardour, etc. ## Can I use strudel with my IDE? Yes you can. There are experimental modes, made by community members, for several IDEs such as: - - VS Code: [Strudel VS](): an experimental mode for Microsoft VSCode. A revived version of [TidalStrudel](), which is defunct. - - nvim: [strudel.nvim](https://github.com/gruvw/strudel.nvim) - + +- VS Code: [Strudel VS](https://marketplace.visualstudio.com/items?itemName=cmillsdev.strudelvs): an experimental mode for Microsoft VSCode. A revived version of [TidalStrudel](https://marketplace.visualstudio.com/items?itemName=roipoussiere.tidal-strudel), which is defunct. +- nvim: [strudel.nvim](https://github.com/gruvw/strudel.nvim) + ## How can I record samples? You can use your own samples with Strudel. There are multiple ways to load your sample collection. Some methods are good for quick experimentation, some others are good to share your audio collection with other musicians: @@ -41,10 +46,10 @@ You can use your own samples with Strudel. There are multiple ways to load your ## Can I use Strudel with AI/LLM tools? -You are free to do what you like with Strudel, within the terms of the free/open source AGPLv3 license. However as a community we are interested in exploring human creativity. AI is *way* over-hyped right now, including by people with very shady motives. Many in the community are very wary of people training models on their tunes that they've poured their love into. So please keep discussion and questions around AI and LLMs to channels dedicated to the topic and be fully respectful of other people's work. +You are free to do what you like with Strudel, within the terms of the free/open source AGPLv3 license. However as a community we are interested in exploring human creativity. AI is _way_ over-hyped right now, including by people with very shady motives. Many in the community are very wary of people training models on their tunes that they've poured their love into. So please keep discussion and questions around AI and LLMs to channels dedicated to the topic and be fully respectful of other people's work. Furthermore, tools like ChatGPT generally give wrong answers. Please don't ask the community to fix those answers for you, as generally they will be timewasting nonsense. - + Human questions only! ## How to run offline? @@ -53,7 +58,7 @@ Strudel works offline just fine! There are multiple techniques to run it yoursel ## How to change tempo? How do I translate BPM to cpm? -If you have your tempo in beats per minute and use 4 beats per cycle (e.g. if your track is in 4/4ths) then you can do `setcpm(BPM/4)` where BPM is your beats per minute. +If you have your tempo in beats per minute and use 4 beats per cycle (e.g. if your track is in 4/4ths) then you can do `setcpm(BPM/4)` where BPM is your beats per minute. If you have a different number of beats per bar or are using more or less beats per cycle (e.g. If you want to put only half a bar or two bars into one cycle), adjust accordingly. @@ -68,21 +73,24 @@ If you pop open the sidetab of strudel.cc (small white < on the right hand side) ## How do I use this exactly like a DAW? Short answer: you don't. - + Long answer: you can use Strudel to work along your creative work in a DAW. There are many ways to do so. - + If you want to emulate the functionality of a DAW in a live coding language, you'll have to identify the operations executed by the DAW (sequencing, repeating, applying filters and envelopes) and write code that is equivalent to these operations. You might then find that the typical DAW workflow is not really adapted to live coding (because, despite both being ways of making music on the computer, they are two very different tools) and adapt your way of proceeding to the medium of code. This might mean leaving more place to serendipity and writing code that you don't predict the output of. ## Why doesn't everyone just use a DAW? -There is no easy answer to this question. Here are some thoughts: - - Live coding tools such as Strudel are excellent for improvising music and visuals using a computer. DAWs are valuable and robust companions for other activities such as producing, mastering and mixing audio, among other usages. Using a tool does not exclude from using any another tool, just build a toolbox. - - Live coding has been practiced for quite some time as a performative activity. Artists like to show their screens while playing in front of an audience. It is an essential part of what they do, of the way they share their activity with everybody. - - Code is a human language, it is made for other humans to read it. You can read the code and enjoy the music too. It has meaning, value, and there might even be something poetic/important about it! - - Strudel is free and open source, you can inspect the code, reshape it, contribute to it if you can/want. It is not opaque and this matters for many people. There is no black box, no obscure abstractions, no business model or hidden features. We need open tools in the arts! - - Live coders don't shy away from using DAWs. They use them all of the time, especially when it makes their life easier for... live coding! - - Code is an artistic material like any other. There is something valuable in the process of making music through code. More generally speaking, it is nice to tackle creative problems through the use of a programming language: creative thinking, building up your own solutions, DIY approach to music-making, unexpected outcome of algorithms, funny human errors, etc. - - There are pianos and trumpets in your DAW: why do people continue playing the piano or the trumpet? Think of live coding tools as instruments that you activate through the act of programming. +There is no easy answer to this question. Here are some thoughts: + +- Live coding tools such as Strudel are excellent for improvising music and visuals using a computer. DAWs are valuable and robust companions for other activities such as producing, mastering and mixing audio, among other usages. Using a tool does not exclude from using any another tool, just build a toolbox. + +- Live coding has been practiced for quite some time as a performative activity. Artists like to show their screens while playing in front of an audience. It is an essential part of what they do, of the way they share their activity with everybody. + +- Code is a human language, it is made for other humans to read it. You can read the code and enjoy the music too. It has meaning, value, and there might even be something poetic/important about it! - Strudel is free and open source, you can inspect the code, reshape it, contribute to it if you can/want. It is not opaque and this matters for many people. There is no black box, no obscure abstractions, no business model or hidden features. We need open tools in the arts! - Live coders don't shy away from using DAWs. They use them all of the time, especially when it makes their life easier for... live coding! + +- Code is an artistic material like any other. There is something valuable in the process of making music through code. More generally speaking, it is nice to tackle creative problems through the use of a programming language: creative thinking, building up your own solutions, DIY approach to music-making, unexpected outcome of algorithms, funny human errors, etc. + +- There are pianos and trumpets in your DAW: why do people continue playing the piano or the trumpet? Think of live coding tools as instruments that you activate through the act of programming. ## Is it more efficient to use Strudel than a DAW? @@ -96,11 +104,11 @@ Strudel can send [MIDI and OSC](/learn/input-output/), which are protocols for c Another music software (or hardware!) can then listen to these messages and process them according to its capabilities. -A simple example would be to send livecoded audio to Ableton on different tracks and then use it to mix them. +A simple example would be to send livecoded audio to Ableton on different tracks and then use it to mix them. You could also send the MIDI of a sequenced pattern to Musescore and then have it transcribe your livecoded work as a musical score. -You could also send MIDI to your hardware synths because you think they sound better than the software synths built-in Strudel. +You could also send MIDI to your hardware synths because you think they sound better than the software synths built-in Strudel. ## How do I use this in my closed source webgame? @@ -113,8 +121,12 @@ You cannot, as there is no such place. For details regarding our stance towards ## How to play different patterns simultaneously? Using the $ operator, several patterns can be played at once: - + + See also [stack](intro/#combining-patterns) @@ -122,29 +134,36 @@ See also [stack](intro/#combining-patterns) With an additional underscore, a pattern can be muted. - + See also [hush](/learn/conditional-modifiers/#hush) ## How can I arrange in Strudel using `mask`? -With mini-notation, using the `<>` and `!` operators, you can try something like +With mini-notation, using the `<>` and `!` operators, you can try something like + ``` .mask("<0!24 1!40>") ``` + It mutes a pattern for 24 cycles and plays it for 40. You would gain 64 cycles total, a multiple of 2/4/8 commonly used in western music. If each cycle is a bar, as a starting point, you could write a mask like that for any pattern: + ``` -.mask("<0!16 0!16 0!16 0!16 0!16 0!10>") +.mask("<0!16 0!16 0!16 0!16 0!16 0!10>") ``` + It mutes it throughout. For arranging, you could add the same mask to each part and replace some zeroes with ones in your different masks to make parts play. If you use `.mask()` on different patterns mess up your counting, then patterns do not align anymore. -On the other hand, doing that on purpose is one of the things that could be considered a strength of tidalcycles and Strudel. +On the other hand, doing that on purpose is one of the things that could be considered a strength of tidalcycles and Strudel. You can make things quite lively and more organic with a little (controlled) interference, according to your own taste. And you are free to arrange in cycles like 3, 6 or 9 too. @@ -159,8 +178,9 @@ This would lowpass filter sweep everything every 8 cycles. ## How can I arrange in Strudel using `arrange` or `pick`? Take [Pachelbel's Canon in D](https://en.wikipedia.org/wiki/Pachelbel%27s_Canon#Analysis) as an example which has 4 voices (one cello and 3 violins) which have repeating patterns, as seen in the link above. - + The following snipped defines the patterns as constants which can then be used for the different voices. `arrange` takes multiple arguments, which are each a number of cycles and a pattern which is played for the number of cycles, wrapped in `[]` If the pattern is shorter than the number, it is repeated. + ") .color("grey").sound("gm_tremolo_strings:3") @@ -177,34 +197,34 @@ The following snipped defines the patterns as constants which can then be used f "<[f#4 d4 e4 c#5 d5 f#5 a5 a4] [b4 g4 a4 f#4 d4 d5 [d5@3 c#5]@2]>") .color("red") - - cello$: arrange( +cello$: arrange( [2, silence], [18,cello]) violin1$: arrange( - [4,silence], - [2,violin_p1], [2,violin_p2], - [2,violin_p3], [2,violin_p4], - [2,violin_p1], [2,violin_p2], - [2,violin_p3], [2,violin_p4] - ).sound("gm_tremolo_strings:0") - violin2$: arrange( +[4,silence], +[2,violin_p1], [2,violin_p2], +[2,violin_p3], [2,violin_p4], +[2,violin_p1], [2,violin_p2], +[2,violin_p3], [2,violin_p4] +).sound("gm_tremolo_strings:0") +violin2$: arrange( [6,silence], [2,violin_p1], [2,violin_p2], [2,violin_p3], [2,violin_p4], [2,violin_p1], [2,violin_p2], [2,violin_p3] ).sound("gm_tremolo_strings:1") violin3$: arrange( - [8,silence], - [2,violin_p1], [2,violin_p2], - [2,violin_p3], [2,violin_p4], - [2,violin_p1], [2,violin_p2] - ).sound("gm_tremolo_strings:2") +[8,silence], +[2,violin_p1], [2,violin_p2], +[2,violin_p3], [2,violin_p4], +[2,violin_p1], [2,violin_p2] +).sound("gm_tremolo_strings:2") all(x => x.release(.2)) + `} /> -Alternatively, you can also put the different patterns for the violins into one single array (`const violins = [violin_p1, violin_p2, violin_p3, violin_p4]`) and use a pattern as an index to `pick` the nth element of that array. This replaces the voices defined above. Here you use `0@2` to specifiy that the first item (i.e. with index `0`) is played for `2` cycles. +Alternatively, you can also put the different patterns for the violins into one single array (`const violins = [violin_p1, violin_p2, violin_p3, violin_p4]`) and use a pattern as an index to `pick` the nth element of that array. This replaces the voices defined above. Here you use `0@2` to specifiy that the first item (i.e. with index `0`) is played for `2` cycles. `pick` has better highlighting than `arrange`: @@ -231,18 +251,18 @@ violin1$: "<~@4 0@2 1@2 2@2 3@2 0@2 1@2 2@2 3@2>".pick(violins) .sound("gm_tremolo_strings:0") violin2$: "<~@6 0@2 1@2 2@2 3@2 0@2 1@2 2@2>".pick(violins) .sound("gm_tremolo_strings:1") -violin3$: "<~@8 0@2 1@2 2@2 3@2 0@2 1@2 >".pick(violins) +violin3$: "<~@8 0@2 1@2 2@2 3@2 0@2 1@2 >".pick(violins) .sound("gm_tremolo_strings:2") all(x => x.release(.2)) -`} /> - +`} /> + The `pick` method also works with jsons which have named elements, which makes it easier to read, see the [here](/learn/conditional-modifiers/#pick). `pickRestart` restarts the pattern upon picking it which can make a difference if the duration of the pick indexes doesn't line up with the patterns which are picked - which is not the case here. Try adding `.punchcard()` after the `release(.2)` for a visualization. ## I saw Switch Angel using functions which I cannot find in the reference (e.g. `trancegate`). How do I make it work? -Methods like `trancegate()`, `rlpf()` and `acidenv()` are currently not pattern methods which come natively with strudel. +Methods like `trancegate()`, `rlpf()` and `acidenv()` are currently not pattern methods which come natively with strudel. It's part of a script for strudel which was written by Switch Angel and published [here](https://github.com/switchangel/strudel-scripts/blob/main/allscripts.js) @@ -255,20 +275,22 @@ If you paste these functions into your strudel session, hit "Update" and delete ## Is there difference between `n` and `note`? They are not aliases of each other, in contrast to `s` and `sound`. - -The method `note` is used to reference a certain note (either as its name, such as `c` or `b2` or the midi number `69`, for example `note("c3 e3 g3")`). - -On the other hand, `n` is a way to reference the nth index of something. This something can be a scale (eg `n("0 2 4").scale("C:major")`) , but it can also be a particular note in a chord (see https://strudel.cc/recipes/recipes/#arpeggios for an example) . -The method `n` can also be used for something completely unrelated to notes like the nth sample from a sample map `s("hh*8").bank("RolandTR909").n("0 1 2 3")`. Note that `pick` does *not* use `n`. +The method `note` is used to reference a certain note (either as its name, such as `c` or `b2` or the midi number `69`, for example `note("c3 e3 g3")`). -".pickRestart([ +On the other hand, `n` is a way to reference the nth index of something. This something can be a scale (eg `n("0 2 4").scale("C:major")`) , but it can also be a particular note in a chord (see https://strudel.cc/recipes/recipes/#arpeggios for an example) . + +The method `n` can also be used for something completely unrelated to notes like the nth sample from a sample map `s("hh*8").bank("RolandTR909").n("0 1 2 3")`. Note that `pick` does _not_ use `n`. + +".pickRestart([ n("0 1 2 0"), n("2 3 4 ~"), n("[4 5] [4 3] 2 0"), n("0 -3 0 ~") - ]).scale("C:major").s("piano")`} /> - + ]).scale("C:major").s("piano")`} +/>{' '} ## Is there a cheat sheet for all symbols? @@ -305,6 +327,6 @@ _ before a stack name: mutes the stack, i.e. hush(), for example _$: s("bd") ## Are there more FAQ items? -These pages have been taken from [this pad](https://doc.patternclub.org/_CgofWouTciXXHexUP9AVg?both). Some of the items there have not been brushed up and brought here. +These pages have been taken from [this pad](https://doc.patternclub.org/_CgofWouTciXXHexUP9AVg?both). Some of the items there have not been brushed up and brought here. These include the following items: 9, 11, 12 and 19 From 4504d1afd0f893f696600493c23dff122c06c6ca Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Wed, 19 Nov 2025 22:14:23 +0100 Subject: [PATCH 04/79] remove trailing spaces in FAQ --- website/src/pages/learn/faq.mdx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index 923bb5f66..2e4cb5c4b 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -42,6 +42,7 @@ Yes you can. There are experimental modes, made by community members, for severa You can use your own samples with Strudel. There are multiple ways to load your sample collection. Some methods are good for quick experimentation, some others are good to share your audio collection with other musicians: - Import folders [from the interface](/learn/samples/#from-disk-via-import-sounds-folder) + - - Host your sound library e.g. on github and [load them from an URL](/learn/samples/#loading-custom-samples) ## Can I use Strudel with AI/LLM tools? @@ -80,15 +81,15 @@ If you want to emulate the functionality of a DAW in a live coding language, you ## Why doesn't everyone just use a DAW? -There is no easy answer to this question. Here are some thoughts: +There is no easy answer to this question. Here are some thoughts: -- Live coding tools such as Strudel are excellent for improvising music and visuals using a computer. DAWs are valuable and robust companions for other activities such as producing, mastering and mixing audio, among other usages. Using a tool does not exclude from using any another tool, just build a toolbox. +- Live coding tools such as Strudel are excellent for improvising music and visuals using a computer. DAWs are valuable and robust companions for other activities such as producing, mastering and mixing audio, among other usages. Using a tool does not exclude from using any another tool, just build a toolbox. -- Live coding has been practiced for quite some time as a performative activity. Artists like to show their screens while playing in front of an audience. It is an essential part of what they do, of the way they share their activity with everybody. +- Live coding has been practiced for quite some time as a performative activity. Artists like to show their screens while playing in front of an audience. It is an essential part of what they do, of the way they share their activity with everybody. -- Code is a human language, it is made for other humans to read it. You can read the code and enjoy the music too. It has meaning, value, and there might even be something poetic/important about it! - Strudel is free and open source, you can inspect the code, reshape it, contribute to it if you can/want. It is not opaque and this matters for many people. There is no black box, no obscure abstractions, no business model or hidden features. We need open tools in the arts! - Live coders don't shy away from using DAWs. They use them all of the time, especially when it makes their life easier for... live coding! +- Code is a human language, it is made for other humans to read it. You can read the code and enjoy the music too. It has meaning, value, and there might even be something poetic/important about it! - Strudel is free and open source, you can inspect the code, reshape it, contribute to it if you can/want. It is not opaque and this matters for many people. There is no black box, no obscure abstractions, no business model or hidden features. We need open tools in the arts! - Live coders don't shy away from using DAWs. They use them all of the time, especially when it makes their life easier for... live coding! -- Code is an artistic material like any other. There is something valuable in the process of making music through code. More generally speaking, it is nice to tackle creative problems through the use of a programming language: creative thinking, building up your own solutions, DIY approach to music-making, unexpected outcome of algorithms, funny human errors, etc. +- Code is an artistic material like any other. There is something valuable in the process of making music through code. More generally speaking, it is nice to tackle creative problems through the use of a programming language: creative thinking, building up your own solutions, DIY approach to music-making, unexpected outcome of algorithms, funny human errors, etc. - There are pianos and trumpets in your DAW: why do people continue playing the piano or the trumpet? Think of live coding tools as instruments that you activate through the act of programming. From 4ec68fcd1de98ba0cd1d0fb22de84ecddfb15d1a Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Thu, 20 Nov 2025 00:07:44 +0100 Subject: [PATCH 05/79] a little prettier --- website/src/pages/learn/faq.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index 2e4cb5c4b..b16eb8cdd 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -42,7 +42,7 @@ Yes you can. There are experimental modes, made by community members, for severa You can use your own samples with Strudel. There are multiple ways to load your sample collection. Some methods are good for quick experimentation, some others are good to share your audio collection with other musicians: - Import folders [from the interface](/learn/samples/#from-disk-via-import-sounds-folder) - - + - - Host your sound library e.g. on github and [load them from an URL](/learn/samples/#loading-custom-samples) ## Can I use Strudel with AI/LLM tools? From 39bff8900f695b80e4c5a666a62a33a186e58ff0 Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Mon, 1 Dec 2025 18:22:26 +0100 Subject: [PATCH 06/79] website/src/pages/learn/faq.mdx aktualisiert updated the section on switch angel's prebake. Now refers to the readme for instructions. --- website/src/pages/learn/faq.mdx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index b16eb8cdd..c22391330 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -265,13 +265,9 @@ Try adding `.punchcard()` after the `release(.2)` for a visualization. Methods like `trancegate()`, `rlpf()` and `acidenv()` are currently not pattern methods which come natively with strudel. -It's part of a script for strudel which was written by Switch Angel and published [here](https://github.com/switchangel/strudel-scripts/blob/main/allscripts.js) +They are part of a script/prebake for strudel which was written by Switch Angel and published [here](https://github.com/switchangel/strudel-scripts) -Note that this script defines functions and registers methods which `trancegate()` will depend on so just pasting the `trancegate()` method from that script alone will not suffice, but you will also need the `fill` method. - -If you copy the full script into your strudel, be mindful of lines which try to load local samples - these should be deleted or prefixed with `//` as a comment. - -If you paste these functions into your strudel session, hit "Update" and delete the source of the functions, the functions will still be availabe until you do a browser refresh. +You can find the instructions how to use that script in the readme.md there. ## Is there difference between `n` and `note`? From b9fce1504276215bd9b280b69ab1214f6d341162 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 3 Dec 2025 15:18:32 -0500 Subject: [PATCH 07/79] working --- packages/codemirror/codemirror.mjs | 9 +++++++++ packages/codemirror/labelJump.mjs | 31 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 packages/codemirror/labelJump.mjs diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 69fce4b50..6643e400d 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -24,6 +24,7 @@ import { sliderPlugin, updateSliderWidgets } from './slider.mjs'; import { activateTheme, initTheme, theme } from './themes.mjs'; import { isTooltipEnabled } from './tooltip.mjs'; import { updateWidgets, widgetPlugin } from './widget.mjs'; +import { jumpToCharacter } from './labelJump.mjs'; export { toggleBlockComment, toggleBlockCommentByLine, toggleComment, toggleLineComment } from '@codemirror/commands'; @@ -119,6 +120,14 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, roo preventDefault: true, run: () => onStop?.(), }, + { + key: 'Alt-]', + run: (view) => jumpToCharacter(view, '$', 1), + }, + { + key: 'Alt-[', + run: (view) => jumpToCharacter(view, '$', -1), + }, /* { key: 'Ctrl-Shift-.', run: () => (onPanic ? onPanic() : onStop?.()), diff --git a/packages/codemirror/labelJump.mjs b/packages/codemirror/labelJump.mjs new file mode 100644 index 000000000..fcdb437f5 --- /dev/null +++ b/packages/codemirror/labelJump.mjs @@ -0,0 +1,31 @@ +import { EditorSelection } from '@codemirror/state'; +import { SearchCursor } from '@codemirror/search'; + +export function jumpToCharacter(view, character, direction = 1) { + const { state, dispatch } = view; + const pos = state.selection.main.head; + const cursor = new SearchCursor(state.doc, character); + + let characterPositions = []; + let jumpPos; + while (!cursor.next().done) { + characterPositions.push(cursor.value.to); + } + if (!characterPositions.length) { + return false; + } + if (direction > 0) { + jumpPos = characterPositions.find((x) => x > pos + 1) ?? characterPositions.at(0); // Loop back around for convenience + } else { + jumpPos = characterPositions.reverse().find((x) => x < pos + 1) ?? characterPositions.at(0); + } + + if (!jumpPos) { + return false; + } + dispatch({ + selection: EditorSelection.cursor(jumpPos - 1), + scrollIntoView: true, + }); + return true; +} From c1a185e852433d4469e25e6b07a2eec64b36d08d Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 3 Dec 2025 15:25:05 -0500 Subject: [PATCH 08/79] fix null case --- packages/codemirror/labelJump.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/codemirror/labelJump.mjs b/packages/codemirror/labelJump.mjs index fcdb437f5..0aced4eb5 100644 --- a/packages/codemirror/labelJump.mjs +++ b/packages/codemirror/labelJump.mjs @@ -20,7 +20,7 @@ export function jumpToCharacter(view, character, direction = 1) { jumpPos = characterPositions.reverse().find((x) => x < pos + 1) ?? characterPositions.at(0); } - if (!jumpPos) { + if (jumpPos == null) { return false; } dispatch({ From f0aac2098afba2ba10d1f8d88db70c988c6b3496 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 3 Dec 2025 22:59:20 -0500 Subject: [PATCH 09/79] update_shortcut --- packages/codemirror/codemirror.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 6643e400d..ba481d9ac 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -121,11 +121,11 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, roo run: () => onStop?.(), }, { - key: 'Alt-]', + key: 'Alt-w', run: (view) => jumpToCharacter(view, '$', 1), }, { - key: 'Alt-[', + key: 'Alt-q', run: (view) => jumpToCharacter(view, '$', -1), }, /* { From 600ab0a83e4edd4a8650ad44546de15448e82276 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 4 Dec 2025 12:17:07 -0600 Subject: [PATCH 10/79] WIP with compressors, filters, heavy worklets --- packages/superdough/audioContext.mjs | 9 +++ packages/superdough/nodePools.mjs | 70 ++++++++++++++++++++++++ packages/superdough/superdough.mjs | 7 ++- packages/superdough/superdoughoutput.mjs | 9 +++ packages/superdough/synth.mjs | 38 +++++++------ packages/superdough/wavetable.mjs | 46 +++++++++------- packages/superdough/worklets.mjs | 68 ++++++++++------------- 7 files changed, 166 insertions(+), 81 deletions(-) create mode 100644 packages/superdough/nodePools.mjs diff --git a/packages/superdough/audioContext.mjs b/packages/superdough/audioContext.mjs index 71e01d57d..3523f6dfe 100644 --- a/packages/superdough/audioContext.mjs +++ b/packages/superdough/audioContext.mjs @@ -1,3 +1,12 @@ +/* +audioContext.mjs - Audio Context manager + +Sets up a common and accessible audio context for all superdough operations + +Copyright (C) 2025 Strudel contributors - see +This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . +*/ + let audioContext; export const setDefaultAudioContext = () => { diff --git a/packages/superdough/nodePools.mjs b/packages/superdough/nodePools.mjs new file mode 100644 index 000000000..ae59a2ce9 --- /dev/null +++ b/packages/superdough/nodePools.mjs @@ -0,0 +1,70 @@ +/* +nodePools.mjs - Helper functions related to pooling and re-using audio nodes + +Copyright (C) 2025 Strudel contributors - see +This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . +*/ + +const nodePools = new Map(); +const POOL_KEY = Symbol('nodePoolKey'); +const IS_WORKLET_DEAD = Symbol('nodePoolIsWorkletDead'); +const MAX_POOL_SIZE = 64; + +export const isPoolable = (node) => !!node[POOL_KEY]; + +const getParams = (node) => { + const params = new Set(); + node.parameters?.forEach((param) => params.add(param)); + const visited = new Set(); // prioritize deepest definition + let proto = node; + // Move up the prototype chain + while (proto !== Object.prototype) { + for (const key of Object.getOwnPropertyNames(proto)) { + if (visited.has(key)) continue; + visited.add(key); + const value = node[key]; + if (value instanceof AudioParam) { + params.add(value); + } + } + proto = Object.getPrototypeOf(proto); + } + return params; +}; + +export const releaseNodeToPool = (node) => { + node.disconnect(); + if (node instanceof AudioScheduledSourceNode) { + // not reusable + return; + } + // Fallback to a type-based key if the node was not created via getNodeFromPool + const key = node[POOL_KEY]; + if (key == null) return; + const now = node.context?.currentTime ?? 0; + getParams(node).forEach((param) => param.cancelScheduledValues(now)); + const pool = nodePools.get(key) ?? []; + if (pool.length < MAX_POOL_SIZE) { + pool.push(new WeakRef(node)); + nodePools.set(key, pool); + } +}; + +export const markWorkletAsDead = (worklet) => (worklet[IS_WORKLET_DEAD] = true); + +// Attempt to get node from the pool. If this fails, fall back +// to building it with the factory +export const getNodeFromPool = (key, factory) => { + const pool = nodePools.get(key) ?? []; + let node; + while (pool.length) { + const ref = pool.pop(); + node = ref?.deref(); + if (node != null && !node[IS_WORKLET_DEAD]) break; + } + if (node == null || node[IS_WORKLET_DEAD]) { + node = factory(); + } + node[POOL_KEY] = key; + return node; +}; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 6f610d514..57279aac2 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -9,7 +9,8 @@ import './reverb.mjs'; import './vowel.mjs'; import { nanFallback, _mod, cycleToSeconds, pickAndRename } from './util.mjs'; import workletsUrl from './worklets.mjs?audioworklet'; -import { createFilter, gainNode, getCompressor, getDistortion, getLfo, getWorklet, effectSend } from './helpers.mjs'; +import { createFilter, effectSend, gainNode, getCompressor, getDistortion, getLfo, getWorklet } from './helpers.mjs'; +import { getNodeFromPool, isPoolable, releaseNodeToPool } from './nodePools.mjs'; import { map } from 'nanostores'; import { logger } from './logger.mjs'; import { loadBuffer } from './sampler.mjs'; @@ -294,7 +295,7 @@ function getPhaser(time, end, frequency = 1, depth = 0.5, centerFrequency = 1000 let fOffset = 0; const filterChain = []; for (let i = 0; i < numStages; i++) { - const filter = ac.createBiquadFilter(); + const filter = getNodeFromPool('filter', () => ac.createBiquadFilter()); filter.type = 'notch'; filter.gain.value = 1; filter.frequency.value = centerFrequency + fOffset; @@ -506,7 +507,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) } else if (getSound(s)) { const { onTrigger } = getSound(s); const onEnded = () => { - audioNodes.forEach((n) => n?.disconnect()); + audioNodes.forEach((n) => (isPoolable(n) ? releaseNodeToPool(n) : n?.disconnect())); activeSoundSources.delete(chainID); }; const soundHandle = await onTrigger(t, value, onEnded, cps); diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs index d8ead7d06..7bb4864f3 100644 --- a/packages/superdough/superdoughoutput.mjs +++ b/packages/superdough/superdoughoutput.mjs @@ -1,3 +1,12 @@ +/* +superdoughoutput.mjs - Output controller for superdough + +Handles setting up and mixing to the outputs as well as all global (orbit) effects + +Copyright (C) 2025 Strudel contributors - see +This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . +*/ + import { effectSend, getWorklet, webAudioTimeout } from './helpers.mjs'; import { errorLogger } from './logger.mjs'; import { clamp } from './util.mjs'; diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index b02354465..87b25ff22 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -17,6 +17,7 @@ import { } from './helpers.mjs'; import { logger } from './logger.mjs'; import { getNoiseMix, getNoiseOscillator } from './noise.mjs'; +import { getNodeFromPool, markWorkletAsDead, releaseNodeToPool } from './nodePools.mjs'; const waveforms = ['triangle', 'square', 'sawtooth', 'sine', 'user']; const waveformAliases = [ @@ -164,22 +165,25 @@ export function registerSynthSounds() { const end = holdend + release + 0.01; const voices = clamp(unison, 1, 100); let panspread = voices > 1 ? clamp(spread, 0, 1) : 0; - let o = getWorklet( - ac, - 'supersaw-oscillator', - { - frequency, - begin, - end, - freqspread: detune, - voices, - panspread, - }, - { - outputChannelCount: [2], - }, - ); - + const params = { + frequency, + begin, + end: end + 0.5, // add a grace period for pooling + freqspread: detune, + voices, + panspread, + }; + const factory = () => new AudioWorkletNode(ac, 'supersaw-oscillator', { outputChannelCount: [2] }); + const o = getNodeFromPool('supersaw', factory); + Object.entries(params).forEach(([key, value]) => { + if (value !== undefined) { + o.parameters.get(key).value = value; + } + }); + o.port.postMessage({ type: 'initialize' }); + o.port.onMessage = (e) => { + if (e.data.type === 'died') markWorkletAsDead(o); + }; const gainAdjustment = 1 / Math.sqrt(voices); getPitchEnvelope(o.parameters.get('detune'), value, begin, holdend); const vibratoOscillator = getVibratoOscillator(o.parameters.get('detune'), value, begin); @@ -192,7 +196,7 @@ export function registerSynthSounds() { let timeoutNode = webAudioTimeout( ac, () => { - releaseAudioNode(o); + releaseNodeToPool(o); onended(); fm?.stop(); vibratoOscillator?.stop(); diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index e9d810414..9545fa1bb 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -8,10 +8,9 @@ import { getParamADSR, getPitchEnvelope, getVibratoOscillator, - getWorklet, - releaseAudioNode, webAudioTimeout, } from './helpers.mjs'; +import { getNodeFromPool, markWorkletAsDead, releaseNodeToPool } from './nodePools.mjs'; import { logger } from './logger.mjs'; export const Warpmode = Object.freeze({ @@ -225,24 +224,29 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { } const endWithRelease = holdEnd + release; const envEnd = endWithRelease + 0.01; - const source = getWorklet( - ac, - 'wavetable-oscillator-processor', - { - begin: t, - end: envEnd, - frequency, - freqspread: value.detune, - position: value.wt, - warp: value.warp, - warpMode: warpmode, - voices: Math.max(value.unison ?? 1, 1), - panspread: value.spread, - phaserand: (value.wtphaserand ?? value.unison > 1) ? 1 : 0, - }, - { outputChannelCount: [2] }, - ); - source.port.postMessage({ type: 'table', payload }); + const params = { + begin: t, + end: envEnd + 0.5, // add a grace period for pooling + frequency, + freqspread: value.detune, + position: value.wt, + warp: value.warp, + warpMode: warpmode, + voices: Math.max(value.unison ?? 1, 1), + panspread: value.spread, + phaserand: (value.wtphaserand ?? value.unison > 1) ? 1 : 0, + }; + const factory = () => new AudioWorkletNode(ac, 'wavetable-oscillator-processor', { outputChannelCount: [2] }); + const source = getNodeFromPool('wavetable', factory); + Object.entries(params).forEach(([key, value]) => { + if (value !== undefined) { + source.parameters.get(key).value = value; + } + }); + source.port.postMessage({ type: 'initialize', payload }); + source.port.onMessage = (e) => { + if (e.data.type === 'died') markWorkletAsDead(source); + }; if (ac.currentTime > t) { logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight'); return; @@ -319,7 +323,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { const timeoutNode = webAudioTimeout( ac, () => { - releaseAudioNode(source); + releaseNodeToPool(source); vibratoOscillator?.stop(); fm?.stop(); wtPosModulators?.disconnect(); diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 2f75453b9..2a07e56ce 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -458,6 +458,15 @@ registerProcessor('distort-processor', DistortProcessor); class SuperSawOscillatorProcessor extends AudioWorkletProcessor { constructor() { super(); + this.port.onmessage = (e) => { + const { type, payload } = e.data || {}; + if (type === 'initialize') { + this.initialize(payload); + } + }; + this.initialize(); + } + initialize(_options) { this.phase = []; } static get parameterDescriptors() { @@ -1135,37 +1144,27 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { constructor(options) { super(options); + this.port.onmessage = (e) => { + const { type, payload } = e.data || {}; + if (type === 'initialize') { + this.initialize(payload); + } + }; + this.initialize(); + } + initialize(options) { this.frameLen = 0; this.numFrames = 0; this.phase = []; - - this.port.onmessage = (e) => { - const { type, payload } = e.data || {}; - if (type === 'table') { - const key = payload.key; - this.frameLen = payload.frameLen; - if (!tablesCache[key]) { - const tables = [payload.frames]; - let table = tables[0]; - for (let level = 1; level < 1; level++) { - const nextLen = table.length >> 1; - const nextTable = table.map((frame) => { - const avg = new Float32Array(nextLen); - for (let i = 0; i < nextLen; i++) { - avg[i] = (frame[2 * i] + frame[2 * i + 1]) / 2; - } - return avg; - }); - tables.push(nextTable); - table = nextTable; - if (nextLen <= 32) break; - } - tablesCache[key] = tables; - } - this.tables = tablesCache[key]; - this.numFrames = this.tables[0].length; + if (options?.frames) { + const key = options.key; + this.frameLen = options.frameLen; + if (!tablesCache[key]) { + tablesCache[key] = options.frames; } - }; + this.table = tablesCache[key]; + this.numFrames = this.table.length; + } } _mirror(x) { @@ -1310,15 +1309,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { return a + (b - a) * frac; } - _chooseMip(dphi) { - const approxHarm = clamp(dphi, 1e-6, 64); - let level = 0; - while (level + 1 < (this.tables?.length || 1) && approxHarm < this.tables[level][0].length / 8) { - level++; - } - return level; - } - process(_inputs, outputs, parameters) { if (currentTime >= parameters.end[0]) { return false; @@ -1362,14 +1352,12 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } const fVoice = applySemitoneDetuneToFrequency(f, detuner(n)); // voice detune const dPhase = fVoice * INVSR; - const level = this._chooseMip(dPhase); - const table = this.tables[level]; // warp phase then sample this.phase[n] = this.phase[n] ?? Math.random() * phaseRand; const ph = this._warpPhase(this.phase[n], warpAmount, warpMode); - const s0 = this._sampleFrame(table[fIdx], ph); - const s1 = this._sampleFrame(table[Math.min(this.numFrames - 1, fIdx + 1)], ph); + const s0 = this._sampleFrame(this.table[fIdx], ph); + const s1 = this._sampleFrame(this.table[Math.min(this.numFrames - 1, fIdx + 1)], ph); let s = lerp(s0, s1, interpT); if (warpMode === WarpMode.FLIP && this.phase[n] < warpAmount) { s = -s; From 66107130187ba248360a8381a5f1824fad5cd428 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 4 Dec 2025 12:40:28 -0600 Subject: [PATCH 11/79] Working version of supersaw, almost on wavetable --- packages/superdough/nodePools.mjs | 4 ++++ packages/superdough/synth.mjs | 3 ++- packages/superdough/wavetable.mjs | 3 ++- packages/superdough/worklets.mjs | 17 ++++++++++++++--- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/superdough/nodePools.mjs b/packages/superdough/nodePools.mjs index ae59a2ce9..08ec9ce51 100644 --- a/packages/superdough/nodePools.mjs +++ b/packages/superdough/nodePools.mjs @@ -38,6 +38,10 @@ export const releaseNodeToPool = (node) => { // not reusable return; } + if (node[IS_WORKLET_DEAD]) { + // Worklet already terminated, don't pool it + return; + } // Fallback to a type-based key if the node was not created via getNodeFromPool const key = node[POOL_KEY]; if (key == null) return; diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 87b25ff22..b10136abf 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -181,8 +181,9 @@ export function registerSynthSounds() { } }); o.port.postMessage({ type: 'initialize' }); - o.port.onMessage = (e) => { + o.port.onmessage = (e) => { if (e.data.type === 'died') markWorkletAsDead(o); + o.port.onmessage = null; }; const gainAdjustment = 1 / Math.sqrt(voices); getPitchEnvelope(o.parameters.get('detune'), value, begin, holdend); diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 9545fa1bb..a74b3747c 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -244,8 +244,9 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { } }); source.port.postMessage({ type: 'initialize', payload }); - source.port.onMessage = (e) => { + source.port.onmessage = (e) => { if (e.data.type === 'died') markWorkletAsDead(source); + source.port.onmessage = null; }; if (ac.currentTime > t) { logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight'); diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 2a07e56ce..73fbe9456 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -458,6 +458,7 @@ registerProcessor('distort-processor', DistortProcessor); class SuperSawOscillatorProcessor extends AudioWorkletProcessor { constructor() { super(); + this.isAlive = true; // used internally to prevent multiple death messages this.port.onmessage = (e) => { const { type, payload } = e.data || {}; if (type === 'initialize') { @@ -519,6 +520,10 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { process(_input, outputs, params) { if (currentTime >= params.end[0]) { // should terminate + if (this.isAlive) { + this.port.postMessage({ type: 'died' }); + this.isAlive = false; + } return false; } if (currentTime <= params.begin[0]) { @@ -1144,6 +1149,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { constructor(options) { super(options); + this.isAlive = true; // used internally to prevent multiple death messages this.port.onmessage = (e) => { const { type, payload } = e.data || {}; if (type === 'initialize') { @@ -1153,8 +1159,9 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { this.initialize(); } initialize(options) { - this.frameLen = 0; - this.numFrames = 0; + this.table = null; + this.frameLen = null; + this.numFrames = null; this.phase = []; if (options?.frames) { const key = options.key; @@ -1311,6 +1318,10 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { process(_inputs, outputs, parameters) { if (currentTime >= parameters.end[0]) { + if (this.isAlive) { + this.port.postMessage({ type: 'died' }); + this.isAlive = false; + } return false; } if (currentTime <= parameters.begin[0]) { @@ -1318,7 +1329,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } const outL = outputs[0][0]; const outR = outputs[0][1] || outputs[0][0]; - if (!this.tables) { + if (!this.table) { outL.fill(0); if (outR !== outL) outR.set(outL); return true; From 4321814d36cac20ae5625bbd813b25ea3048411d Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 4 Dec 2025 13:04:33 -0600 Subject: [PATCH 12/79] Working version for compressor, filter, supersaw, wavetable --- packages/superdough/helpers.mjs | 16 ++++++++++++---- packages/superdough/synth.mjs | 2 +- packages/superdough/wavetable.mjs | 2 +- packages/superdough/worklets.mjs | 16 +++++++++------- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 219c66d6f..c5c038312 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -1,7 +1,8 @@ import { getAudioContext } from './audioContext.mjs'; -import { clamp, nanFallback, midiToFreq, noteToMidi } from './util.mjs'; -import { getNoiseBuffer } from './noise.mjs'; import { logger } from './logger.mjs'; +import { getNoiseBuffer } from './noise.mjs'; +import { getNodeFromPool } from './nodePools.mjs'; +import { clamp, nanFallback, midiToFreq, noteToMidi } from './util.mjs'; export const noises = ['pink', 'white', 'brown', 'crackle']; @@ -128,6 +129,7 @@ export function getLfo(audioContext, begin, end, properties = {}) { } export function getCompressor(ac, threshold, ratio, knee, attack, release) { + const node = getNodeFromPool('compressor', () => new DynamicsCompressorNode(ac, {})); const options = { threshold: threshold ?? -3, ratio: ratio ?? 10, @@ -135,7 +137,12 @@ export function getCompressor(ac, threshold, ratio, knee, attack, release) { attack: attack ?? 0.005, release: release ?? 0.05, }; - return new DynamicsCompressorNode(ac, options); + node.threshold.value = options.threshold; + node.ratio.value = options.ratio; + node.knee.value = options.knee; + node.attack.value = options.attack; + node.release.value = options.release; + return node; } // changes the default values of the envelope based on what parameters the user has defined @@ -214,7 +221,8 @@ export function createFilter(context, start, end, params, cps, cycle) { filter = getWorklet(context, 'ladder-processor', { frequency, q, drive }); frequencyParam = filter.parameters.get('frequency'); } else { - filter = context.createBiquadFilter(); + const factory = () => context.createBiquadFilter(); + filter = getNodeFromPool('filter', factory); filter.type = type; filter.Q.value = q; filter.frequency.value = frequency; diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index b10136abf..6bf7a1379 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -168,7 +168,7 @@ export function registerSynthSounds() { const params = { frequency, begin, - end: end + 0.5, // add a grace period for pooling + end, freqspread: detune, voices, panspread, diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index a74b3747c..2cac9fac5 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -226,7 +226,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { const envEnd = endWithRelease + 0.01; const params = { begin: t, - end: envEnd + 0.5, // add a grace period for pooling + end: envEnd, frequency, freqspread: value.detune, position: value.wt, diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 73fbe9456..e6887a3f6 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -518,16 +518,16 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { ]; } process(_input, outputs, params) { - if (currentTime >= params.end[0]) { - // should terminate + if (currentTime >= params.end[0] + 0.5) { + // Outside of grace period - should terminate if (this.isAlive) { this.port.postMessage({ type: 'died' }); this.isAlive = false; } return false; } - if (currentTime <= params.begin[0]) { - // keep alive + if (currentTime >= params.end[0] || currentTime <= params.begin[0]) { + // Inside of grace period or not yet started return true; } const output = outputs[0]; @@ -1163,7 +1163,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { this.frameLen = null; this.numFrames = null; this.phase = []; - if (options?.frames) { + if (options?.key) { const key = options.key; this.frameLen = options.frameLen; if (!tablesCache[key]) { @@ -1317,14 +1317,16 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } process(_inputs, outputs, parameters) { - if (currentTime >= parameters.end[0]) { + if (currentTime >= parameters.end[0] + 0.5) { + // Outside of grace period - should terminate if (this.isAlive) { this.port.postMessage({ type: 'died' }); this.isAlive = false; } return false; } - if (currentTime <= parameters.begin[0]) { + if (currentTime >= parameters.end[0] || currentTime <= parameters.begin[0]) { + // Inside of grace period or not yet started return true; } const outL = outputs[0][0]; From 0664f90178610c3cb781eb478f68ebacbb49d9a8 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 4 Dec 2025 13:07:13 -0600 Subject: [PATCH 13/79] Remove old comment --- packages/superdough/nodePools.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/superdough/nodePools.mjs b/packages/superdough/nodePools.mjs index 08ec9ce51..205352247 100644 --- a/packages/superdough/nodePools.mjs +++ b/packages/superdough/nodePools.mjs @@ -42,7 +42,6 @@ export const releaseNodeToPool = (node) => { // Worklet already terminated, don't pool it return; } - // Fallback to a type-based key if the node was not created via getNodeFromPool const key = node[POOL_KEY]; if (key == null) return; const now = node.context?.currentTime ?? 0; From 4c99f4866b03ba5ad7498bfa11da6408e7609153 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 4 Dec 2025 22:50:28 -0600 Subject: [PATCH 14/79] Use setvalueattime to pin values and prevent bleed --- packages/superdough/helpers.mjs | 15 ++++++++------- packages/superdough/synth.mjs | 7 ++++--- packages/superdough/wavetable.mjs | 7 ++++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 1a9ed3797..1430b5642 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -137,11 +137,10 @@ export function getCompressor(ac, threshold, ratio, knee, attack, release) { attack: attack ?? 0.005, release: release ?? 0.05, }; - node.threshold.value = options.threshold; - node.ratio.value = options.ratio; - node.knee.value = options.knee; - node.attack.value = options.attack; - node.release.value = options.release; + const now = ac.currentTime; + Object.entries(options).forEach(([key, value]) => { + node[key].setValueAtTime(value, now); + }); return node; } @@ -224,8 +223,10 @@ export function createFilter(context, start, end, params, cps, cycle) { const factory = () => context.createBiquadFilter(); filter = getNodeFromPool('filter', factory); filter.type = type; - filter.Q.value = q; - filter.frequency.value = frequency; + const now = context.currentTime; + Object.entries({ Q: q, frequency }).forEach(([key, value]) => { + filter[key].setValueAtTime(value, now); + }); frequencyParam = filter.frequency; } const envelopeValues = [params.attack, params.decay, params.sustain, params.release]; diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 6bf7a1379..8f9efa40f 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -175,10 +175,11 @@ export function registerSynthSounds() { }; const factory = () => new AudioWorkletNode(ac, 'supersaw-oscillator', { outputChannelCount: [2] }); const o = getNodeFromPool('supersaw', factory); + const now = ac.currentTime; Object.entries(params).forEach(([key, value]) => { - if (value !== undefined) { - o.parameters.get(key).value = value; - } + const param = o.parameters.get(key); + const target = value !== undefined ? value : param.defaultValue; + param.setValueAtTime(target, now); }); o.port.postMessage({ type: 'initialize' }); o.port.onmessage = (e) => { diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 2cac9fac5..ea075c608 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -238,10 +238,11 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { }; const factory = () => new AudioWorkletNode(ac, 'wavetable-oscillator-processor', { outputChannelCount: [2] }); const source = getNodeFromPool('wavetable', factory); + const now = ac.currentTime; Object.entries(params).forEach(([key, value]) => { - if (value !== undefined) { - source.parameters.get(key).value = value; - } + const param = source.parameters.get(key); + const target = value !== undefined ? value : param.defaultValue; + param.setValueAtTime(target, now); }); source.port.postMessage({ type: 'initialize', payload }); source.port.onmessage = (e) => { From 177c3a4a2ef848e7f532a0fcf374fb63cff9c209 Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Sat, 6 Dec 2025 16:36:25 +0100 Subject: [PATCH 15/79] some items from review --- website/src/pages/learn/faq.mdx | 44 +++++++++++++++++---------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index c22391330..cef6fbf50 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -263,8 +263,6 @@ Try adding `.punchcard()` after the `release(.2)` for a visualization. ## I saw Switch Angel using functions which I cannot find in the reference (e.g. `trancegate`). How do I make it work? -Methods like `trancegate()`, `rlpf()` and `acidenv()` are currently not pattern methods which come natively with strudel. - They are part of a script/prebake for strudel which was written by Switch Angel and published [here](https://github.com/switchangel/strudel-scripts) You can find the instructions how to use that script in the readme.md there. @@ -277,17 +275,20 @@ The method `note` is used to reference a certain note (either as its name, such On the other hand, `n` is a way to reference the nth index of something. This something can be a scale (eg `n("0 2 4").scale("C:major")`) , but it can also be a particular note in a chord (see https://strudel.cc/recipes/recipes/#arpeggios for an example) . -The method `n` can also be used for something completely unrelated to notes like the nth sample from a sample map `s("hh*8").bank("RolandTR909").n("0 1 2 3")`. Note that `pick` does _not_ use `n`. +The method `n` can also be used for something completely unrelated to notes, in particular the nth sample from a sample map `s("hh*8").bank("RolandTR909").n("0 1 2 3")`. ".pickRestart([ - n("0 1 2 0"), - n("2 3 4 ~"), - n("[4 5] [4 3] 2 0"), - n("0 -3 0 ~") - ]).scale("C:major").s("piano")`} -/>{' '} + tune={` + n("<[0 1 2 3@3 -@2] [3 2 1 0@3 -@2] >").scale("A:minor:pentatonic").s("gm_acoustic_guitar_steel").n("<0 1 2 3>/2")`} +/> + + + + + +Note that `n` is not the only way that functions use indices, some take numbered patterns instead. + ## Is there a cheat sheet for all symbols? @@ -297,29 +298,30 @@ Yes! ' marks start and end of strings, is different from " " marks start and end of single line patterns in mini notation, is different from ' ` marks start and end of patterns with line breaks in mini notation, is different from ' -[] used for patterns, each item in it has the same length -<> used for patterns, alternates each item each cycle +[] used for patterns in mini notation, each item in it has the same length +<> used for patterns, alternates between items each cycle {} historically used for polyrhythmic patterns. {a b c}%4 is the same as
*4. -@3 elongates the item by a factor of 3 (other numbers work too) +@3 elongates the item by a factor of 3 (other numbers work too, even non-integer, but for numbers between 0 and 1 you need a leading zero like this: @0.5) @ after an item: elongates the item once (multiple @ work too c @ @ is the same as c@3) -_ after an item: also elongates an item once (multiple _ work too c _ _ is the same as c@3) +_ after an item: also elongates an item once (multiple _ work too c _ _ is the same as c@3), see below for a different usage. . this divides equal parts of a pattern and is called a foot. Can be used instead of [] like this: "1 6 7 8 . 2 . 3 . 4" is the same as "[1 6 7 8] 2 3 4" - silence ~ also silence -x not silence (for the use in struct, same as 1) -s increase a note of a scale by one semitone, i.e. sharp -b decrease a note of a scale by one semitone, i.e. flat -# used in mondo notation -# also used for names of chords, like F# +x not silence (for the use in struct, any non-silence symbol works there) +b decrease by one semitone, i.e. flat, works for steps of scales, note names (but not midi numbers) and chord names +s increase by one semitone, i.e. sharp, works for steps of scales, note names (but not midi numbers) but not chord names +# increase by one semitone, i.e. sharp works for steps of scales, note names (but not midi numbers) and chord names +# also used in mondo notation + *3 play the sample or pattern at thrice the speed, fast(3) !3 play the sample or pattern three times /2 play the sample or pattern at half speed, slow(2) ? play the pattern sometimes | once per cycle, choose randomly a pattern of those separated by i.e. chooseCycles() , play all items separated by it at the same time, i.e. stack() -: is used to separate multiple parameters, such as adsr(".1:.1:.5:.2") +: is used to separate multiple parameters, such as adsr(".1:.1:.5:.2"), this is is an operator which creates a list of these objects. $: at the start of a line, defines a member of the stack. is the only stack name that should occur multiple names -_ before a stack name: mutes the stack, i.e. hush(), for example _$: s("bd") +_ before a stack name: mutes the stack, i.e. hush(), for example _$: s("bd"), see above for a different usage. ``` ## Are there more FAQ items? From bd282f439ab3b30f613e6f60eee33c098d37600e Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Sat, 6 Dec 2025 16:37:39 +0100 Subject: [PATCH 16/79] everyone wants that trancegate --- website/src/pages/learn/faq.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index cef6fbf50..d4c38d414 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -263,6 +263,8 @@ Try adding `.punchcard()` after the `release(.2)` for a visualization. ## I saw Switch Angel using functions which I cannot find in the reference (e.g. `trancegate`). How do I make it work? +Methods like `trancegate()`, `rlpf()` and `acidenv()` are currently not pattern methods which come natively with strudel. + They are part of a script/prebake for strudel which was written by Switch Angel and published [here](https://github.com/switchangel/strudel-scripts) You can find the instructions how to use that script in the readme.md there. From ab03ece2b7ea61e9de4761e73f318e62812168c4 Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Sat, 6 Dec 2025 16:48:40 +0100 Subject: [PATCH 17/79] prettier --- packages/osc/server.js | 0 website/src/pages/learn/faq.mdx | 12 +++--------- 2 files changed, 3 insertions(+), 9 deletions(-) mode change 100755 => 100644 packages/osc/server.js diff --git a/packages/osc/server.js b/packages/osc/server.js old mode 100755 new mode 100644 diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index d4c38d414..36a8bbef1 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -267,7 +267,7 @@ Methods like `trancegate()`, `rlpf()` and `acidenv()` are currently not pattern They are part of a script/prebake for strudel which was written by Switch Angel and published [here](https://github.com/switchangel/strudel-scripts) -You can find the instructions how to use that script in the readme.md there. +You can find the instructions how to use that script in the readme.md there. ## Is there difference between `n` and `note`? @@ -277,21 +277,16 @@ The method `note` is used to reference a certain note (either as its name, such On the other hand, `n` is a way to reference the nth index of something. This something can be a scale (eg `n("0 2 4").scale("C:major")`) , but it can also be a particular note in a chord (see https://strudel.cc/recipes/recipes/#arpeggios for an example) . -The method `n` can also be used for something completely unrelated to notes, in particular the nth sample from a sample map `s("hh*8").bank("RolandTR909").n("0 1 2 3")`. +The method `n` can also be used for something completely unrelated to notes, in particular the nth sample from a sample map `s("hh*8").bank("RolandTR909").n("0 1 2 3")`. ").scale("A:minor:pentatonic").s("gm_acoustic_guitar_steel").n("<0 1 2 3>/2")`} /> - - - - Note that `n` is not the only way that functions use indices, some take numbered patterns instead. - ## Is there a cheat sheet for all symbols? Yes! @@ -314,14 +309,13 @@ b decrease by one semitone, i.e. flat, works for steps of scales, note names ( s increase by one semitone, i.e. sharp, works for steps of scales, note names (but not midi numbers) but not chord names # increase by one semitone, i.e. sharp works for steps of scales, note names (but not midi numbers) and chord names # also used in mondo notation - *3 play the sample or pattern at thrice the speed, fast(3) !3 play the sample or pattern three times /2 play the sample or pattern at half speed, slow(2) ? play the pattern sometimes | once per cycle, choose randomly a pattern of those separated by i.e. chooseCycles() , play all items separated by it at the same time, i.e. stack() -: is used to separate multiple parameters, such as adsr(".1:.1:.5:.2"), this is is an operator which creates a list of these objects. +: is used to separate multiple parameters, such as adsr(".1:.1:.5:.2"), this is is an operator which creates a list of these objects. $: at the start of a line, defines a member of the stack. is the only stack name that should occur multiple names _ before a stack name: mutes the stack, i.e. hush(), for example _$: s("bd"), see above for a different usage. ``` From 6402ad5d37f70583ba967e8364e1610620a95e01 Mon Sep 17 00:00:00 2001 From: scrappy_fiddler Date: Sat, 6 Dec 2025 16:55:57 +0100 Subject: [PATCH 18/79] better linebreak in example --- website/src/pages/learn/faq.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index 36a8bbef1..b91b48cca 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -282,7 +282,9 @@ The method `n` can also be used for something completely unrelated to notes, in ").scale("A:minor:pentatonic").s("gm_acoustic_guitar_steel").n("<0 1 2 3>/2")`} + n("<[0 1 2 3@3 -@2] [3 2 1 0@3 -@2] >") + .scale("A:minor:pentatonic") + .s("gm_acoustic_guitar_steel").n("<0 1 2 3>/2")`} /> Note that `n` is not the only way that functions use indices, some take numbered patterns instead. From 597c94199118adcc597e3e437b0f7174192c8bb5 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 10 Dec 2025 12:01:04 -0600 Subject: [PATCH 19/79] Add keyboard function --- packages/midi/midi.mjs | 72 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index cd38d3587..477da51cd 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -543,3 +543,75 @@ export async function midin(input) { device.addListener('midimessage', listeners[input]); return cc; } + +/** + * MIDI keyboard: Opens a MIDI input port to receive MIDI keyboard messages. + * + * The note length is fixed as Superdough is not currently set up for undetermined + * note durations + * + * @param {string | number} input MIDI device name or index defaulting to 0 + * @returns {function(): Pattern} A function that produces a pattern. + * When queried, the pattern will produces the most recently played midi notes and velocities, + * lasting for the specified duration + * @example + * const cc = await midin('IAC Driver Bus 1') + * note("c a f e").lpf(cc(0).range(0, 1000)).lpq(cc(1).range(0, 10)).sound("sawtooth") + * @example + * const allCC = await midin('IAC Driver Bus 1') + * const cc = (ccNum) => allCC(ccNum, 2) // just channel 2 + * note("c a f e").s("saw") + * .when(cc(0).gt(0), x => x.postgain(0)) + */ +const kHaps = {}; +const kListeners = {}; +export async function keyboard(input, noteLength = 0.5) { + const device = await _initialize(input); + if (!kHaps[input]) { + kHaps[input] = {}; + } + kListeners[input] && device.removeListener('midimessage', kListeners[input]); + kListeners[input] = (e) => { + const { dataBytes, message } = e; + const [cc, v] = dataBytes; + const noteoff = message.command === 8; + const key = `${input}_${cc}`; + const t = getTime() + 0.1; // slight delay so it's not too late for cyclist to catch + const span = new TimeSpan(t, t + noteLength); + let value = { midikey: key }; + if (noteoff) { + /* TODO: It's a big effort, but we could modify superdough to allow for situations where + we don't know the hap duration in advance. This would mean, for example, that if the hap + is flagged as such a special note-on event, we have all effects be persistent & all ADSR + envelopes stop at the S stage [and store references to them by note+pattern] + If this is implemented, then getting full keyboard functionality should be as simple + as sending the corresponding note-off event below and triggering `release` on each of those + referenced effects/envelopes + + value = { ...value, noteoff: true }; + + If this is achieved, we can remove the noteLength parameter + */ + return; + } else { + value = { ...value, note: Math.round(cc), velocity: v / 127 }; + } + kHaps[input][key] = new Hap(span, span, value, {}); + }; + device.addListener('midimessage', kListeners[input]); + const kb = () => { + const query = (state) => { + const haps = []; + for (const [key, hap] of Object.entries(kHaps[input])) { + haps.push(hap); + } + if (state.controls.cyclist) { + // Notes have been sent; clear them + kHaps[input] = {}; + } + return haps; + }; + return new Pattern(query); + }; + return kb; +} From 103b27c21ffa957684bbcd28b72e4ffe080ee6f6 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 10 Dec 2025 13:27:11 -0600 Subject: [PATCH 20/79] Working version of keyboard with variable lengths; tests and cleanup --- packages/midi/midi.mjs | 115 +++++++++++++--------- test/__snapshots__/examples.test.mjs.snap | 4 + test/runtime.mjs | 5 + 3 files changed, 75 insertions(+), 49 deletions(-) diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index 477da51cd..bfc42207a 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as _WebMidi from 'webmidi'; -import { Pattern, isPattern, logger, ref } from '@strudel/core'; +import { Hap, Pattern, TimeSpan, getTime, isPattern, logger, ref, reify } from '@strudel/core'; import { noteToMidi, getControlName } from '@strudel/core'; import { Note } from 'webmidi'; import { scheduleAtTime } from '../superdough/helpers.mjs'; @@ -477,14 +477,41 @@ Pattern.prototype.midi = function (midiport, options = {}) { }); }; -let listeners = {}; -const refs = {}; -const refsByChan = {}; +/** + * Initialize a midi device + */ +async function _initialize(input) { + if (isPattern(input)) { + throw new Error( + `[midi] Midi input cannot be a pattern. Make sure to pass device name with single quotes. Example: midin('${ + WebMidi.outputs?.[0]?.name || 'IAC Driver Bus 1' + }')`, + ); + } + const initial = await enableWebMidi(); // only returns on first init + const device = getDevice(input, WebMidi.inputs); + if (!device) { + throw new Error( + `[midi] Midi device "${input}" not found.. connected devices: ${getMidiDeviceNamesString(WebMidi.inputs)}`, + ); + } + if (initial) { + const otherInputs = WebMidi.inputs.filter((o) => o.name !== device.name); + logger( + `[midi] Midi enabled! Using "${device.name}". ${ + otherInputs?.length ? `Also available: ${getMidiDeviceNamesString(otherInputs)}` : '' + }`, + ); + } + return device; +} /** * MIDI input: Opens a MIDI input port to receive MIDI control change messages. * * The output is a function that accepts a midi cc value to query as well as (optionally) a midi channel + * + * @name midin * @param {string | number} input MIDI device name or index defaulting to 0 * @returns {function(number, number=): Pattern} A function from (cc, channel?) to a pattern. * When queried, the pattern will produces the most recently received midi value (normalized to 0 to 1) @@ -498,29 +525,11 @@ const refsByChan = {}; * note("c a f e").s("saw") * .when(cc(0).gt(0), x => x.postgain(0)) */ +let listeners = {}; +const refs = {}; +const refsByChan = {}; export async function midin(input) { - if (isPattern(input)) { - throw new Error( - `midin: does not accept Pattern as input. Make sure to pass device name with single quotes. Example: midin('${ - WebMidi.outputs?.[0]?.name || 'IAC Driver Bus 1' - }')`, - ); - } - const initial = await enableWebMidi(); // only returns on first init - const device = getDevice(input, WebMidi.inputs); - if (!device) { - throw new Error( - `midiin: device "${input}" not found.. connected devices: ${getMidiDeviceNamesString(WebMidi.inputs)}`, - ); - } - if (initial) { - const otherInputs = WebMidi.inputs.filter((o) => o.name !== device.name); - logger( - `Midi enabled! Using "${device.name}". ${ - otherInputs?.length ? `Also available: ${getMidiDeviceNamesString(otherInputs)}` : '' - }`, - ); - } + const device = await _initialize(input); refs[input] ??= {}; refsByChan[input] ??= {}; const cc = (cc, chan) => { @@ -532,8 +541,7 @@ export async function midin(input) { listeners[input] && device.removeListener('midimessage', listeners[input]); listeners[input] = (e) => { - const ccNum = e.dataBytes[0]; - const v = e.dataBytes[1]; + const [ccNum, v] = e.dataBytes; const chan = e.message.channel; const scaled = v / 127; refsByChan[input][ccNum] ??= {}; @@ -550,40 +558,42 @@ export async function midin(input) { * The note length is fixed as Superdough is not currently set up for undetermined * note durations * + * @name keyboard * @param {string | number} input MIDI device name or index defaulting to 0 - * @returns {function(): Pattern} A function that produces a pattern. + * @returns {function((number | Pattern)=): Pattern} A function that produces a pattern. * When queried, the pattern will produces the most recently played midi notes and velocities, * lasting for the specified duration * @example - * const cc = await midin('IAC Driver Bus 1') - * note("c a f e").lpf(cc(0).range(0, 1000)).lpq(cc(1).range(0, 10)).sound("sawtooth") + * const kb = await keyboard('Arturia KeyStep 32') + * kb().s("tri").lpf(80).lpe(6).lpd(0.1).room(2).delay(0.35) * @example - * const allCC = await midin('IAC Driver Bus 1') - * const cc = (ccNum) => allCC(ccNum, 2) // just channel 2 - * note("c a f e").s("saw") - * .when(cc(0).gt(0), x => x.postgain(0)) + * const kb = await keyboard('Arturia KeyStep 32') + * kb("0.5 1") + * .s("saw") + * .add(note(rand.mul(0.3))) + * .lpf(1000).lpe(2).room(0.5) */ const kHaps = {}; const kListeners = {}; -export async function keyboard(input, noteLength = 0.5) { +export async function keyboard(input) { const device = await _initialize(input); if (!kHaps[input]) { - kHaps[input] = {}; + kHaps[input] = []; } kListeners[input] && device.removeListener('midimessage', kListeners[input]); kListeners[input] = (e) => { const { dataBytes, message } = e; - const [cc, v] = dataBytes; + const [note, velocity] = dataBytes; const noteoff = message.command === 8; - const key = `${input}_${cc}`; + const key = `${input}_${note}`; const t = getTime() + 0.1; // slight delay so it's not too late for cyclist to catch - const span = new TimeSpan(t, t + noteLength); + const span = new TimeSpan(t, t); let value = { midikey: key }; if (noteoff) { /* TODO: It's a big effort, but we could modify superdough to allow for situations where we don't know the hap duration in advance. This would mean, for example, that if the hap is flagged as such a special note-on event, we have all effects be persistent & all ADSR - envelopes stop at the S stage [and store references to them by note+pattern] + envelopes stop at the S stage [and store references to them by `midikey`] If this is implemented, then getting full keyboard functionality should be as simple as sending the corresponding note-off event below and triggering `release` on each of those referenced effects/envelopes @@ -594,20 +604,27 @@ export async function keyboard(input, noteLength = 0.5) { */ return; } else { - value = { ...value, note: Math.round(cc), velocity: v / 127 }; + value = { ...value, note: Math.round(note), velocity: velocity / 127 }; } - kHaps[input][key] = new Hap(span, span, value, {}); + kHaps[input].push(new Hap(span, span, value, {})); }; device.addListener('midimessage', kListeners[input]); - const kb = () => { + const kb = (noteLength = 0.5) => { + const nlPat = reify(noteLength); const query = (state) => { - const haps = []; - for (const [key, hap] of Object.entries(kHaps[input])) { - haps.push(hap); - } + const haps = kHaps[input].flatMap((hap) => { + const lenHaps = nlPat.query(state.setSpan(hap.wholeOrPart())); + return lenHaps.map((lenHap) => { + const nl = lenHap.value ?? 0.5; + const whole = new TimeSpan(hap.whole.begin, hap.whole.begin.add(nl)); + const part = new TimeSpan(hap.part.begin, hap.part.begin.add(nl)); + const context = hap.combineContext(lenHap); + return new Hap(whole, part, hap.value, context); + }); + }); if (state.controls.cyclist) { // Notes have been sent; clear them - kHaps[input] = {}; + kHaps[input] = []; } return haps; }; diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 09d285b5d..62e2de914 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -5943,6 +5943,10 @@ exports[`runs examples > example "juxBy" example index 0 1`] = ` exports[`runs examples > example "keyDown" example index 0 1`] = `[]`; +exports[`runs examples > example "keyboard" example index 0 1`] = `[]`; + +exports[`runs examples > example "keyboard" example index 1 1`] = `[]`; + exports[`runs examples > example "lastOf" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:c3 ]", diff --git a/test/runtime.mjs b/test/runtime.mjs index 2a29de3f5..51a713a60 100644 --- a/test/runtime.mjs +++ b/test/runtime.mjs @@ -131,6 +131,10 @@ const midin = () => { return (ccNum) => strudel.ref(() => 0); // returns ref with default value 0 }; +const keyboard = async () => { + return () => strudel.silence; +}; + const sysex = ([id, data]) => {}; // TODO: refactor to evalScope @@ -150,6 +154,7 @@ evalScope( */ { midin, + keyboard, sysex, // gist, // euclid, From c8b2e1ac9e529333f72cb4ac8e87fe80cdf82a6e Mon Sep 17 00:00:00 2001 From: 1d10t <1d10t@noreply.codeberg.org> Date: Fri, 12 Dec 2025 21:22:21 +0100 Subject: [PATCH 21/79] feat(superdough/audiocontext): make AudioContext injection optional - Modify `setDefaultAudioContext()` to accept an optional `existingAudioCtx` parameter. - If provided, it will use the existing context; otherwise, it creates a new one. - This allows for better integration with external audio systems that manage their own AudioContext. --- packages/superdough/audioContext.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/superdough/audioContext.mjs b/packages/superdough/audioContext.mjs index 71e01d57d..9bae75bd9 100644 --- a/packages/superdough/audioContext.mjs +++ b/packages/superdough/audioContext.mjs @@ -1,7 +1,7 @@ let audioContext; -export const setDefaultAudioContext = () => { - audioContext = new AudioContext(); +export const setDefaultAudioContext = (existingAudioCtx) => { + audioContext = existingAudioCtx ?? new AudioContext(); return audioContext; }; From 4e14718e93b7d9a5ebe7fb1892109745577b8bc7 Mon Sep 17 00:00:00 2001 From: 1d10t <1d10t@noreply.codeberg.org> Date: Fri, 12 Dec 2025 21:56:31 +0100 Subject: [PATCH 22/79] feat(webaudio): enable AudioContext sharing for webaudioRepl - Add support for optional `existingAudioCtx` parameter in `webaudioRepl()` function - When provided, sets it as the default AudioContext via `setDefaultAudioContext()` - Allows integration with external systems that manage their own Web Audio API context - Maintains backward compatibility with existing usage patterns --- packages/webaudio/webaudio.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 383e87f87..8fc9b860f 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as strudel from '@strudel/core'; -import { superdough, getAudioContext, setLogger, doughTrigger, registerWorklet } from 'superdough'; +import { superdough, setDefaultAudioContext, getAudioContext, setLogger, doughTrigger, registerWorklet } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; @@ -27,6 +27,9 @@ export const webaudioOutput = (hap, _deadline, hapDuration, cps, t) => { }; export function webaudioRepl(options = {}) { + if (options.existingAudioCtx) { + setDefaultAudioContext(options.existingAudioCtx); + } options = { getTime: () => getAudioContext().currentTime, defaultOutput: webaudioOutput, From adf9596d070eb33ee8c52726cbd10fef7dea0141 Mon Sep 17 00:00:00 2001 From: Sergey S Yaglov Date: Sat, 13 Dec 2025 00:28:13 +0300 Subject: [PATCH 23/79] codestyle(webaudio) --- packages/webaudio/webaudio.mjs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 8fc9b860f..399e68ab1 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -5,7 +5,14 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as strudel from '@strudel/core'; -import { superdough, setDefaultAudioContext, getAudioContext, setLogger, doughTrigger, registerWorklet } from 'superdough'; +import { + superdough, + setDefaultAudioContext, + getAudioContext, + setLogger, + doughTrigger, + registerWorklet, +} from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; From 181ebee374058b6bf7fcf686f39e7ab3ef23d733 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 19 Dec 2025 01:25:58 +0100 Subject: [PATCH 24/79] fix: repl package init audio properly --- examples/buildless/web-component-no-iframe.html | 3 ++- packages/repl/repl-component.mjs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/buildless/web-component-no-iframe.html b/examples/buildless/web-component-no-iframe.html index 8afa85cb5..ae4fb700d 100644 --- a/examples/buildless/web-component-no-iframe.html +++ b/examples/buildless/web-component-no-iframe.html @@ -1,4 +1,5 @@ - + + - + diff --git a/website/src/components/HeadCommonNext.astro b/website/src/components/HeadCommonNext.astro index 9f323a7a3..1f878bac0 100644 --- a/website/src/components/HeadCommonNext.astro +++ b/website/src/components/HeadCommonNext.astro @@ -24,7 +24,7 @@ const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL - + From 4743334a17388c58993b84fbb6bf57d604d7829e Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 9 Jan 2026 22:50:16 -0600 Subject: [PATCH 37/79] Reduce latency; change name to midikeys; include in i/o learn page --- packages/midi/midi.mjs | 10 +++++----- test/__snapshots__/examples.test.mjs.snap | 8 ++++---- test/runtime.mjs | 4 ++-- website/src/pages/learn/input-output.mdx | 6 +++++- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index bfc42207a..d4f6093a0 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -558,16 +558,16 @@ export async function midin(input) { * The note length is fixed as Superdough is not currently set up for undetermined * note durations * - * @name keyboard + * @name midikeys * @param {string | number} input MIDI device name or index defaulting to 0 * @returns {function((number | Pattern)=): Pattern} A function that produces a pattern. * When queried, the pattern will produces the most recently played midi notes and velocities, * lasting for the specified duration * @example - * const kb = await keyboard('Arturia KeyStep 32') + * const kb = await midikeys('Arturia KeyStep 32') * kb().s("tri").lpf(80).lpe(6).lpd(0.1).room(2).delay(0.35) * @example - * const kb = await keyboard('Arturia KeyStep 32') + * const kb = await midikeys('Arturia KeyStep 32') * kb("0.5 1") * .s("saw") * .add(note(rand.mul(0.3))) @@ -575,7 +575,7 @@ export async function midin(input) { */ const kHaps = {}; const kListeners = {}; -export async function keyboard(input) { +export async function midikeys(input) { const device = await _initialize(input); if (!kHaps[input]) { kHaps[input] = []; @@ -586,7 +586,7 @@ export async function keyboard(input) { const [note, velocity] = dataBytes; const noteoff = message.command === 8; const key = `${input}_${note}`; - const t = getTime() + 0.1; // slight delay so it's not too late for cyclist to catch + const t = getTime() + 0.03; // slight delay so it's not too late for cyclist to catch const span = new TimeSpan(t, t); let value = { midikey: key }; if (noteoff) { diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 62e2de914..2aa20a0eb 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -5943,10 +5943,6 @@ exports[`runs examples > example "juxBy" example index 0 1`] = ` exports[`runs examples > example "keyDown" example index 0 1`] = `[]`; -exports[`runs examples > example "keyboard" example index 0 1`] = `[]`; - -exports[`runs examples > example "keyboard" example index 1 1`] = `[]`; - exports[`runs examples > example "lastOf" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:c3 ]", @@ -7031,6 +7027,10 @@ exports[`runs examples > example "midicmd" example index 0 1`] = ` ] `; +exports[`runs examples > example "midikeys" example index 0 1`] = `[]`; + +exports[`runs examples > example "midikeys" example index 1 1`] = `[]`; + exports[`runs examples > example "midin" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:c cutoff:0 resonance:0 s:sawtooth ]", diff --git a/test/runtime.mjs b/test/runtime.mjs index 51a713a60..5a64913cf 100644 --- a/test/runtime.mjs +++ b/test/runtime.mjs @@ -131,7 +131,7 @@ const midin = () => { return (ccNum) => strudel.ref(() => 0); // returns ref with default value 0 }; -const keyboard = async () => { +const midikeys = async () => { return () => strudel.silence; }; @@ -154,7 +154,7 @@ evalScope( */ { midin, - keyboard, + midikeys, sysex, // gist, // euclid, diff --git a/website/src/pages/learn/input-output.mdx b/website/src/pages/learn/input-output.mdx index 0dd48b7de..1d4bf4c39 100644 --- a/website/src/pages/learn/input-output.mdx +++ b/website/src/pages/learn/input-output.mdx @@ -16,10 +16,14 @@ It is also possible to pattern other things with Strudel, such as software and h Strudel supports MIDI without any additional software (thanks to [webmidi](https://npmjs.com/package/webmidi)), just by adding methods to your pattern: -## midiin(inputName?) +## midin(inputName?) +## midikeys(inputName?) + + + ## midi(outputName?,options?) Either connect a midi device or use the IAC Driver (Mac) or Midi Through Port (Linux) for internal midi messages. From 3b2e9fa0b4bdf1837b7993b59fbb3516d14bb25a Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 10 Jan 2026 01:22:50 -0500 Subject: [PATCH 38/79] wip --- packages/superdough/superdough.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 6ef8435cd..c47939275 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -547,6 +547,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) } else if (getSound(s)) { const { onTrigger } = getSound(s); const onEnded = () => { + chain.releaseNodes(); audioNodes.forEach((n) => (isPoolable(n) ? releaseNodeToPool(n) : n?.disconnect())); activeSoundSources.delete(chainID); }; From e837c516c5eb3815e838df1707ff05a99d740261 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 10 Jan 2026 01:37:14 -0500 Subject: [PATCH 39/79] merge main --- packages/superdough/superdough.mjs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index c47939275..2fe80d441 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -10,17 +10,7 @@ import './vowel.mjs'; import { clamp, nanFallback, _mod, cycleToSeconds, pickAndRename } from './util.mjs'; import workletsUrl from './worklets.mjs?audioworklet'; import { getNodeFromPool, isPoolable, releaseNodeToPool } from './nodePools.mjs'; -import { - createFilter, - effectSend, - gainNode, - getCompressor, - getDistortion, - getLfo, - getWorklet, - releaseAudioNode, - webAudioTimeout, -} from './helpers.mjs'; +import { createFilter, effectSend, gainNode, getCompressor, getDistortion, getLfo, getWorklet } from './helpers.mjs'; import { map } from 'nanostores'; import { logger } from './logger.mjs'; import { connectLFO, connectEnvelope, connectBusModulator } from './modulators.mjs'; @@ -429,7 +419,7 @@ class Chain { return this; } releaseNodes() { - this.audioNodes.forEach((n) => releaseAudioNode(n)); + this.audioNodes.forEach((n) => (isPoolable(n) ? releaseNodeToPool(n) : n?.disconnect())); this.audioNodes = []; this.tails = []; } @@ -548,7 +538,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) const { onTrigger } = getSound(s); const onEnded = () => { chain.releaseNodes(); - audioNodes.forEach((n) => (isPoolable(n) ? releaseNodeToPool(n) : n?.disconnect())); activeSoundSources.delete(chainID); }; // We have to use onEnded because some sources (e.g. `sampler`) have From 0e9c50bf0a55e3225a26404ca593a9e34c484d45 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 10 Jan 2026 01:39:39 -0500 Subject: [PATCH 40/79] fix import --- packages/superdough/wavetable.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index f5da1f3e1..ee044ee49 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -9,6 +9,7 @@ import { getPitchEnvelope, getVibratoOscillator, webAudioTimeout, + releaseAudioNode } from './helpers.mjs'; import { getNodeFromPool, markWorkletAsDead, releaseNodeToPool } from './nodePools.mjs'; import { logger } from './logger.mjs'; From a205f7d87388c8fba8366bee02db55e7a030521e Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 10 Jan 2026 01:42:06 -0500 Subject: [PATCH 41/79] rm dead code --- packages/superdough/superdough.mjs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 2fe80d441..5d562ee2a 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -540,18 +540,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) chain.releaseNodes(); activeSoundSources.delete(chainID); }; - // We have to use onEnded because some sources (e.g. `sampler`) have - // an internal duration which is longer than `value.duration` - // const onEnded = () => - // webAudioTimeout( - // ac, - // () => { - // chain.releaseNodes(); - // activeSoundSources.delete(chainID); - // }, - // 0, - // endWithRelease, - // ); + const soundHandle = await onTrigger(t, value, onEnded, cps); if (soundHandle) { From 7a5020aa71f5692b627ac39e4d3ca7dcc9464896 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 10 Jan 2026 01:42:43 -0500 Subject: [PATCH 42/79] format --- packages/superdough/superdough.mjs | 2 +- packages/superdough/wavetable.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 5d562ee2a..dea314ea2 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -540,7 +540,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) chain.releaseNodes(); activeSoundSources.delete(chainID); }; - + const soundHandle = await onTrigger(t, value, onEnded, cps); if (soundHandle) { diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index ee044ee49..adf8b0c44 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -9,7 +9,7 @@ import { getPitchEnvelope, getVibratoOscillator, webAudioTimeout, - releaseAudioNode + releaseAudioNode, } from './helpers.mjs'; import { getNodeFromPool, markWorkletAsDead, releaseNodeToPool } from './nodePools.mjs'; import { logger } from './logger.mjs'; From b4e00538f86c7d50a276bcfe6698ca4d38ab9fa0 Mon Sep 17 00:00:00 2001 From: floy Date: Sat, 10 Jan 2026 15:30:07 +0100 Subject: [PATCH 43/79] Don't show 'No sounds loaded' text if search is active --- website/src/repl/components/panel/SoundsTab.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index 52fbf928c..0e46b1382 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -210,7 +210,7 @@ export function SoundsTab() { ) : ( '' )} - {!soundEntries.length && soundsFilter !== 'importSounds' ? 'No sounds loaded' : ''} + {!soundEntries.length && soundsFilter !== 'importSounds' && search == '' ? 'No sounds loaded' : ''} ); From fd0209dbc067b4c683f946738dedc9da3f752942 Mon Sep 17 00:00:00 2001 From: floy Date: Sat, 10 Jan 2026 15:39:02 +0100 Subject: [PATCH 44/79] Show explicit help text when search doesn't match --- website/src/repl/components/panel/SoundsTab.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index 0e46b1382..2060c64a9 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -210,7 +210,10 @@ export function SoundsTab() { ) : ( '' )} - {!soundEntries.length && soundsFilter !== 'importSounds' && search == '' ? 'No sounds loaded' : ''} + {!soundEntries.length && soundsFilter !== 'importSounds' ? + search == '' ? 'No sounds loaded' : 'No sounds found' + : '' + } ); From d753eedb901c1ead239f8f288d887af292f3ce66 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 10 Jan 2026 11:20:17 -0600 Subject: [PATCH 45/79] Make latency consistent across all cps --- packages/core/repl.mjs | 3 ++- packages/core/time.mjs | 9 +++++++++ packages/midi/midi.mjs | 6 ++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 4d59f5990..77ceac8c5 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -2,7 +2,7 @@ import { NeoCyclist } from './neocyclist.mjs'; import { Cyclist } from './cyclist.mjs'; import { evaluate as _evaluate } from './evaluate.mjs'; import { errorLogger, logger } from './logger.mjs'; -import { setTime } from './time.mjs'; +import { setCpsFunc, setTime } from './time.mjs'; import { evalScope } from './evaluate.mjs'; import { register, Pattern, isPattern, silence, stack } from './pattern.mjs'; @@ -61,6 +61,7 @@ export function repl({ // NeoCyclist uses a shared worker to communicate between instances, which is not supported on mobile chrome const scheduler = sync && typeof SharedWorker != 'undefined' ? new NeoCyclist(schedulerOptions) : new Cyclist(schedulerOptions); + setCpsFunc(() => scheduler.cps); let pPatterns = {}; let anonymousIndex = 0; let allTransform; diff --git a/packages/core/time.mjs b/packages/core/time.mjs index 80daaf53c..3d94a694c 100644 --- a/packages/core/time.mjs +++ b/packages/core/time.mjs @@ -1,4 +1,5 @@ let time; +let cpsFunc; export function getTime() { if (!time) { throw new Error('no time set! use setTime to define a time source'); @@ -9,3 +10,11 @@ export function getTime() { export function setTime(func) { time = func; } + +export function setCpsFunc(func) { + cpsFunc = func; +} + +export function getCps() { + return cpsFunc?.(); +} diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index d4f6093a0..6233bf60d 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as _WebMidi from 'webmidi'; -import { Hap, Pattern, TimeSpan, getTime, isPattern, logger, ref, reify } from '@strudel/core'; +import { Hap, Pattern, TimeSpan, getCps, getTime, isPattern, logger, ref, reify } from '@strudel/core'; import { noteToMidi, getControlName } from '@strudel/core'; import { Note } from 'webmidi'; import { scheduleAtTime } from '../superdough/helpers.mjs'; @@ -586,7 +586,9 @@ export async function midikeys(input) { const [note, velocity] = dataBytes; const noteoff = message.command === 8; const key = `${input}_${note}`; - const t = getTime() + 0.03; // slight delay so it's not too late for cyclist to catch + const cps = getCps() ?? 0.5; + const latencySeconds = 0.06; // slight delay so it's not too late for cyclist to catch + const t = getTime() + latencySeconds * cps; const span = new TimeSpan(t, t); let value = { midikey: key }; if (noteoff) { From dab16767612e88e2337c46e938d387f361fdceda Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 10 Jan 2026 11:26:30 -0600 Subject: [PATCH 46/79] Add license for time file --- packages/core/time.mjs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/core/time.mjs b/packages/core/time.mjs index 3d94a694c..2d4caecf5 100644 --- a/packages/core/time.mjs +++ b/packages/core/time.mjs @@ -1,3 +1,9 @@ +/* +time.mjs - Core time module. Used to expose parameters from the Scheduler like `time` and `cps` +Copyright (C) 2026 Strudel contributors - see +This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . +*/ + let time; let cpsFunc; export function getTime() { From 0cf11adc2c8416ed1df1563b3f6c16cc7dc637fd Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 10 Jan 2026 13:07:54 -0600 Subject: [PATCH 47/79] Allow naked distortions for the purpose of FX --- packages/core/pattern.mjs | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 02cf91881..58c83a6f8 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -3586,6 +3586,20 @@ export const morph = (frompat, topat, bypat) => { return frompat.innerBind((from) => topat.innerBind((to) => bypat.innerBind((by) => _morph(from, to, by)))); }; +const _distortWithAlg = function (name) { + const func = function (args, pat) { + const argsPat = reify(args).fmap((v) => (Array.isArray(v) ? [...v, name] : [v, 1, name])); + if (!pat) { + return pure({}).distort(argsPat); + } + return pat.distort(argsPat); + }; + Pattern.prototype[name] = function (args) { + return func(args, this); + }; + return func; +}; + /** * Soft-clipping distortion * @@ -3594,6 +3608,8 @@ export const morph = (frompat, topat, bypat) => { * @param {number | Pattern} volume linear postgain of the distortion * */ +export const soft = _distortWithAlg('soft'); + /** * Hard-clipping distortion * @@ -3602,6 +3618,8 @@ export const morph = (frompat, topat, bypat) => { * @param {number | Pattern} volume linear postgain of the distortion * */ +export const hard = _distortWithAlg('hard'); + /** * Cubic polynomial distortion * @@ -3610,6 +3628,8 @@ export const morph = (frompat, topat, bypat) => { * @param {number | Pattern} volume linear postgain of the distortion * */ +export const cubic = _distortWithAlg('cubic'); + /** * Diode-emulating distortion * @@ -3618,6 +3638,8 @@ export const morph = (frompat, topat, bypat) => { * @param {number | Pattern} volume linear postgain of the distortion * */ +export const diode = _distortWithAlg('diode'); + /** * Asymmetrical diode distortion * @@ -3626,6 +3648,8 @@ export const morph = (frompat, topat, bypat) => { * @param {number | Pattern} volume linear postgain of the distortion * */ +export const asym = _distortWithAlg('asym'); + /** * Wavefolding distortion * @@ -3634,6 +3658,8 @@ export const morph = (frompat, topat, bypat) => { * @param {number | Pattern} volume linear postgain of the distortion * */ +export const fold = _distortWithAlg('fold'); + /** * Wavefolding distortion composed with sinusoid * @@ -3642,6 +3668,8 @@ export const morph = (frompat, topat, bypat) => { * @param {number | Pattern} volume linear postgain of the distortion * */ +export const sinefold = _distortWithAlg('sinefold'); + /** * Distortion via Chebyshev polynomials * @@ -3650,14 +3678,7 @@ export const morph = (frompat, topat, bypat) => { * @param {number | Pattern} volume linear postgain of the distortion * */ -const distAlgoNames = ['scurve', 'soft', 'hard', 'cubic', 'diode', 'asym', 'fold', 'sinefold', 'chebyshev']; -for (const name of distAlgoNames) { - // Add aliases for distortion algorithms - Pattern.prototype[name] = function (args) { - const argsPat = reify(args).fmap((v) => (Array.isArray(v) ? [...v, name] : [v, 1, name])); - return this.distort(argsPat); - }; -} +export const chebyshev = _distortWithAlg('chebyshev'); /** * Turns a list of patterns into a single pattern which outputs list-values From 447692106923167d3c0ddc308041bb79d4a944ca Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 10 Jan 2026 16:46:11 -0500 Subject: [PATCH 48/79] use releasenode --- packages/superdough/superdough.mjs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index dea314ea2..41b5ce976 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -419,7 +419,7 @@ class Chain { return this; } releaseNodes() { - this.audioNodes.forEach((n) => (isPoolable(n) ? releaseNodeToPool(n) : n?.disconnect())); + this.audioNodes.forEach((n) => (isPoolable(n) ? releaseNodeToPool(n) : releaseAudioNode(n))); this.audioNodes = []; this.tails = []; } @@ -536,10 +536,17 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) nodes.main['source'] = [sourceNode]; } else if (getSound(s)) { const { onTrigger } = getSound(s); - const onEnded = () => { - chain.releaseNodes(); - activeSoundSources.delete(chainID); - }; + + const onEnded = () => + webAudioTimeout( + ac, + () => { + chain.releaseNodes(); + activeSoundSources.delete(chainID); + }, + 0, + endWithRelease, + ); const soundHandle = await onTrigger(t, value, onEnded, cps); From 741ff3f3f0117298b5c665869979d4144a706984 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 10 Jan 2026 16:55:53 -0500 Subject: [PATCH 49/79] fix import --- packages/superdough/superdough.mjs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 41b5ce976..d2baa9398 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -10,7 +10,17 @@ import './vowel.mjs'; import { clamp, nanFallback, _mod, cycleToSeconds, pickAndRename } from './util.mjs'; import workletsUrl from './worklets.mjs?audioworklet'; import { getNodeFromPool, isPoolable, releaseNodeToPool } from './nodePools.mjs'; -import { createFilter, effectSend, gainNode, getCompressor, getDistortion, getLfo, getWorklet } from './helpers.mjs'; +import { + createFilter, + effectSend, + gainNode, + getCompressor, + getDistortion, + getLfo, + getWorklet, + releaseAudioNode, + webAudioTimeout, +} from './helpers.mjs'; import { map } from 'nanostores'; import { logger } from './logger.mjs'; import { connectLFO, connectEnvelope, connectBusModulator } from './modulators.mjs'; From 0571a8dc7d706f2fbd2647668b8acba18625ece0 Mon Sep 17 00:00:00 2001 From: gueejla Date: Sat, 10 Jan 2026 22:11:13 -0600 Subject: [PATCH 50/79] fixes Serial onTrigger() params #1633 --- packages/serial/serial.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/serial/serial.mjs b/packages/serial/serial.mjs index 692109522..e007b24b9 100644 --- a/packages/serial/serial.mjs +++ b/packages/serial/serial.mjs @@ -68,7 +68,7 @@ Pattern.prototype.serial = function (br = 115200, sendcrc = false, singlecharids if (!(name in writeMessagers)) { getWriter(name, br); } - const onTrigger = (t_deprecate, hap, currentTime, cps, targetTime) => { + const onTrigger = (hap, currentTime, _cps, targetTime) => { var message = ''; var chk = 0; if (typeof hap.value === 'object') { From 604a1b770cab5f55d6cada4915bccff4de460435 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 11 Jan 2026 00:27:07 -0500 Subject: [PATCH 51/79] dialog --- .../panel/ImportPrebakeScriptButton.jsx | 15 +++++++- .../src/repl/components/panel/SettingsTab.jsx | 36 ++++++------------- website/src/repl/util.mjs | 16 +++++++-- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/website/src/repl/components/panel/ImportPrebakeScriptButton.jsx b/website/src/repl/components/panel/ImportPrebakeScriptButton.jsx index c997f6b6e..64ce198be 100644 --- a/website/src/repl/components/panel/ImportPrebakeScriptButton.jsx +++ b/website/src/repl/components/panel/ImportPrebakeScriptButton.jsx @@ -1,6 +1,7 @@ import { errorLogger } from '@strudel/core'; import { useSettings, storePrebakeScript } from '../../../settings.mjs'; import { SpecialActionInput } from '../button/action-button'; +import { confirmDialog, SETTING_CHANGE_RELOAD_MSG } from '@src/repl/util.mjs'; async function importScript(script) { const reader = new FileReader(); @@ -23,7 +24,19 @@ export function ImportPrebakeScriptButton() { type="file" label="import prebake script" accept=".strudel" - onChange={(e) => importScript(e.target.files[0])} + onChange={async (e) => { + const file = e.target.files[0]; + const confirmed = await confirmDialog(SETTING_CHANGE_RELOAD_MSG); + if (!confirmed) { + return; + } + try { + await importScript(file); + window.location.reload(); + } catch (e) { + errorLogger(e); + } + }} /> ); } diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index f46fa661c..7f488c544 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -1,13 +1,13 @@ import { defaultSettings, settingsMap, useSettings } from '../../../settings.mjs'; import { themes } from '@strudel/codemirror'; import { Textbox } from '../textbox/Textbox.jsx'; -import { isUdels } from '../../util.mjs'; +import { confirmAndReloadPage, isUdels } from '../../util.mjs'; import { ButtonGroup } from './Forms.jsx'; import { AudioDeviceSelector } from './AudioDeviceSelector.jsx'; import { AudioEngineTargetSelector } from './AudioEngineTargetSelector.jsx'; import { confirmDialog } from '../../util.mjs'; import { DEFAULT_MAX_POLYPHONY, setMaxPolyphony, setMultiChannelOrbits } from '@strudel/webaudio'; -import { ActionButton, SpecialActionButton } from '../button/action-button.jsx'; +import { SpecialActionButton } from '../button/action-button.jsx'; import { ImportPrebakeScriptButton } from './ImportPrebakeScriptButton.jsx'; function Checkbox({ label, value, onChange, disabled = false }) { @@ -86,8 +86,6 @@ const fontFamilyOptions = { galactico: 'galactico', }; -const RELOAD_MSG = 'Changing this setting requires the window to reload itself. OK?'; - export function SettingsTab({ started }) { const { theme, @@ -127,11 +125,8 @@ export function SettingsTab({ started }) { isDisabled={started} audioDeviceName={audioDeviceName} onChange={(audioDeviceName) => { - confirmDialog(RELOAD_MSG).then((r) => { - if (r == true) { - settingsMap.setKey('audioDeviceName', audioDeviceName); - return window.location.reload(); - } + confirmAndReloadPage(() => { + settingsMap.setKey('audioDeviceName', audioDeviceName); }); }} /> @@ -141,11 +136,8 @@ export function SettingsTab({ started }) { { - confirmDialog(RELOAD_MSG).then((r) => { - if (r == true) { - settingsMap.setKey('audioEngineTarget', target); - return window.location.reload(); - } + confirmAndReloadPage(() => { + settingsMap.setKey('audioEngineTarget', target); }); }} /> @@ -175,12 +167,9 @@ export function SettingsTab({ started }) { label="Multi Channel Orbits" onChange={(cbEvent) => { const val = cbEvent.target.checked; - confirmDialog(RELOAD_MSG).then((r) => { - if (r == true) { - settingsMap.setKey('multiChannelOrbits', val); - setMultiChannelOrbits(val); - return window.location.reload(); - } + confirmAndReloadPage(() => { + settingsMap.setKey('multiChannelOrbits', val); + setMultiChannelOrbits(val); }); }} value={multiChannelOrbits} @@ -297,11 +286,8 @@ export function SettingsTab({ started }) { label="Sync across Browser Tabs / Windows" onChange={(cbEvent) => { const newVal = cbEvent.target.checked; - confirmDialog(RELOAD_MSG).then((r) => { - if (r) { - settingsMap.setKey('isSyncEnabled', newVal); - window.location.reload(); - } + confirmAndReloadPage(() => { + settingsMap.setKey('isSyncEnabled', newVal); }); }} disabled={shouldAlwaysSync} diff --git a/website/src/repl/util.mjs b/website/src/repl/util.mjs index 4a7cb26a8..06dad2467 100644 --- a/website/src/repl/util.mjs +++ b/website/src/repl/util.mjs @@ -1,4 +1,4 @@ -import { code2hash, evalScope, hash2code, logger } from '@strudel/core'; +import { code2hash, errorLogger, evalScope, hash2code, logger } from '@strudel/core'; import { settingPatterns } from '../settings.mjs'; import { setVersionDefaults } from '@strudel/webaudio'; import { getMetadata } from '../metadata_parser'; @@ -107,7 +107,19 @@ export function confirmDialog(msg) { resolve(confirmed); }); } - +export const SETTING_CHANGE_RELOAD_MSG = 'Changing this setting requires the window to reload itself. OK?'; +export function confirmAndReloadPage(onSuccess) { + confirmDialog(SETTING_CHANGE_RELOAD_MSG).then((r) => { + if (r == true) { + try { + onSuccess(); + return window.location.reload(); + } catch (e) { + errorLogger(e); + } + } + }); +} //RIP due to SPAM // let lastShared; // export async function shareCode(codeToShare) { From 0174e086399ae0411e7f6da31cc3fd2bf8df0840 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 11 Jan 2026 10:50:44 +0100 Subject: [PATCH 52/79] fix: add trem to top level --- packages/core/controls.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 8fef91294..f15b3d4cd 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -877,7 +877,7 @@ export const { coarse } = registerControl('coarse'); * note("d d d# d".fast(4)).s("supersaw").tremolo("<3 2 100> ").tremoloskew("<.5>") * */ -export const { tremolo } = registerControl(['tremolo', 'tremolodepth', 'tremoloskew', 'tremolophase'], 'trem'); +export const { tremolo, trem } = registerControl(['tremolo', 'tremolodepth', 'tremoloskew', 'tremolophase'], 'trem'); /** * Modulate the amplitude of a sound with a continuous waveform From c74707e804f926ffc3910a3e80aa8bda8e86d5a4 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 11 Jan 2026 10:58:13 +0100 Subject: [PATCH 53/79] fix: export start cycle min 0 --- website/src/repl/components/panel/ExportTab.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/components/panel/ExportTab.jsx b/website/src/repl/components/panel/ExportTab.jsx index 9671ff1a3..cbb132e44 100644 --- a/website/src/repl/components/panel/ExportTab.jsx +++ b/website/src/repl/components/panel/ExportTab.jsx @@ -66,7 +66,7 @@ export default function ExportTab(Props) {
{ let v = parseInt(e.target.value); From 8f3dc8daea3759330f4a7bd930a42d5653d500a1 Mon Sep 17 00:00:00 2001 From: yaxu Date: Sun, 11 Jan 2026 11:34:55 +0100 Subject: [PATCH 54/79] Update website/src/pages/learn/faq.mdx --- website/src/pages/learn/faq.mdx | 35 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index b91b48cca..7fbc0d572 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -8,27 +8,26 @@ import { JsDoc } from '../../docs/JsDoc'; # Frequently Asked Questions -This page contains frequently asked questions. Usually, the topic is explained in more detail in a section which is linked in the answer. This page's aim is to give an overview over topics which are important to the users of strudel. +This page contains frequently asked questions, with answers. Usually, the topic is explained in more detail in a section which is linked in the answer. ## Is Strudel/Tidal free? -Yes - there is no charge, this is a collective open source project, and the music you make with it is your own. +Yes - there is no charge, this is a collective open source project, and the music you make with it is your own. However if you can, please make a one-off or regular donation to our [opencollective fund](https://opencollective.com/tidalcycles), that supports the software and cultural development of Strudel and other Uzu languages. -However there are some caveats - the source code must stay free, i.e. you cannot distribute strudel or tidal as part of projects with incompatible licenses - see the [license](https://www.gnu.org/licenses/agpl-3.0.en.html) for details. The contributed examples and tracks are also separately licensed, and must not e.g. be used to train AI models without permission. +While there is no charge there are some caveats, e.g.: + +* the source code must stay free, i.e. you cannot distribute strudel or tidal as part of projects with incompatible licenses - see the [license](https://www.gnu.org/licenses/agpl-3.0.en.html) for details. +* the contributed examples and tracks are also separately licensed, and must not e.g. be used to train AI models without permission. ## How to record or export audio? -There are multiple ways to record the audio -- and video -- output of Strudel: +Strudel is not a digital audio workstation and does not operate following the same principles shared by most traditional audio softwares. However, there are multiple ways to record the audio -- and video -- output of Strudel: - - capture the raw stereo signal coming out of your web browser. - - - use the alternative SuperDirt audio engine. Read [this page](/learn/input-output/#oscsuperdirtstrudeldirt) to know more about it. - - - capture the audio/video stream using a capture tool such as [OBS](). - - - don't record anything and code it again in front of your friends. - -You will need an external audio editor/DAW such as Reaper/Audacity/Ardour, etc. Strudel itself does not have functionality for exporting stems / individual tracks to an audio or midi file. Strudel is not a digital audio workstation and does not operate following the same principles shared by most traditional audio softwares. +* Use the 'export' tab to render and download as an audio file. +* capture the raw stereo signal coming out of your web browser. You will need an external audio editor/DAW such as Reaper/Audacity/Ardour, etc. +* use the alternative SuperDirt audio engine. Read [this page](/learn/input-output/#oscsuperdirtstrudeldirt) to know more about it. +* capture the audio/video stream using a capture tool such as [OBS](), which is designed for live streaming, but also works very well for recording. +* don't record anything and code it again in front of your friends. ## Can I use strudel with my IDE? @@ -37,13 +36,13 @@ Yes you can. There are experimental modes, made by community members, for severa - VS Code: [Strudel VS](https://marketplace.visualstudio.com/items?itemName=cmillsdev.strudelvs): an experimental mode for Microsoft VSCode. A revived version of [TidalStrudel](https://marketplace.visualstudio.com/items?itemName=roipoussiere.tidal-strudel), which is defunct. - nvim: [strudel.nvim](https://github.com/gruvw/strudel.nvim) -## How can I record samples? +## How can I use my own samples? -You can use your own samples with Strudel. There are multiple ways to load your sample collection. Some methods are good for quick experimentation, some others are good to share your audio collection with other musicians: +There are multiple ways to load your sample collection. Some methods are good for quick experimentation, some others are good to share your audio collection with other musicians: - - Import folders [from the interface](/learn/samples/#from-disk-via-import-sounds-folder) - - - - Host your sound library e.g. on github and [load them from an URL](/learn/samples/#loading-custom-samples) +- Import folders [from the interface](/learn/samples/#from-disk-via-import-sounds-folder). These are stored locally in your web browser, and not uploaded. +- Serve a folder of samples locally using the [strudel 'sampler' commandline tool](https://strudel.cc/learn/samples/#from-disk-via-strudelsampler). This can be most reliable method, but requires [nodejs](https://nodejs.org) to be installed. +- Host your sound library online on the web and [load them from an URL](/learn/samples/#loading-custom-samples) ## Can I use Strudel with AI/LLM tools? From 25dbfe4c7d38330892a2e8000eb75f8569b7dcfa Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 11 Jan 2026 11:43:04 +0100 Subject: [PATCH 55/79] fix: remove faulty default readme --- website/README.md | 184 +--------------------------------------------- 1 file changed, 1 insertion(+), 183 deletions(-) diff --git a/website/README.md b/website/README.md index 115d6d556..84bf732e1 100644 --- a/website/README.md +++ b/website/README.md @@ -3,186 +3,4 @@ This is the website for Strudel, deployed at [strudel.cc](https://strudel.cc). It includes the REPL live coding editor and the documentation site. -## Run locally - -```bash -# from project root -npm run setup -npm run repl -``` - -## Build - -```bash -cd website -npm run build # <- builds repl + tutorial to ../docs -npm run preview # <- test static build -``` - -## Generate PWA icons - -```sh -cd website/public -npx pwa-asset-generator icon.png icons -``` - -# Standard Readme of Astro Starter Kit: Docs Site - -```bash -npm create astro@latest -- --template docs -``` - -[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/docs) -[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/s/github/withastro/astro/tree/latest/examples/docs) - -![docs](https://user-images.githubusercontent.com/4677417/186189283-0831b9ab-d6b9-485d-8955-3057e532ab31.png) - - -## Features - -- ✅ **Full Markdown support** -- ✅ **Responsive mobile-friendly design** -- ✅ **Sidebar navigation** -- ✅ **Search (powered by Algolia)** -- ✅ **Multi-language i18n** -- ✅ **Automatic table of contents** -- ✅ **Automatic list of contributors** -- ✅ (and, best of all) **dark mode** - -## Commands Cheatsheet - -All commands are run from the root of the project, from a terminal: - -| Command | Action | -| :--------------------- | :----------------------------------------------- | -| `npm install` | Installs dependencies | -| `npm run dev` | Starts local dev server at `localhost:4321` | -| `npm run build` | Build your production site to `./dist/` | -| `npm run preview` | Preview your build locally, before deploying | -| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | -| `npm run astro --help` | Get help using the Astro CLI | - -To deploy your site to production, check out our [Deploy an Astro Website](https://docs.astro.build/guides/deploy) guide. - -## New to Astro? - -Welcome! Check out [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). - -## Customize This Theme - -edit: removed, as css styles have been replaced with tailwind styles - -### Site metadata - -`src/config.ts` contains several data objects that describe metadata about your site like title, description, default language, and Open Graph details. You can customize these to match your project. - -## Page metadata - -Astro uses frontmatter in Markdown pages to choose layouts and pass properties to those layouts. If you are using the default layout, you can customize the page in many different ways to optimize SEO and other things. For example, you can use the `title` and `description` properties to set the document title, meta title, meta description, and Open Graph description. - -```markdown ---- -title: Example title -description: Really cool docs example that uses Astro -layout: ../../layouts/MainLayout.astro ---- - -# Page content... -``` - -For more SEO related properties, look at `src/components/HeadSEO.astro` - -### Sidebar navigation - -The sidebar navigation is controlled by the `SIDEBAR` variable in your `src/config.ts` file. You can customize the sidebar by modifying this object. A default, starter navigation has already been created for you. - -```ts -export const SIDEBAR = { - en: [ - { text: "Section Header", header: true }, - { text: "Introduction", link: "en/introduction" }, - { text: "Page 2", link: "en/page-2" }, - { text: "Page 3", link: "en/page-3" }, - - { text: "Another Section", header: true }, - { text: "Page 4", link: "en/page-4" }, - ], -}; -``` - -Note the top-level `en` key: This is needed for multi-language support. You can change it to whatever language you'd like, or add new languages as you go. More details on this below. - -### Multiple Languages support - -The Astro docs template supports multiple languages out of the box. The default theme only shows `en` documentation, but you can enable multi-language support features by adding a second language to your project. - -To add a new language to your project, you'll want to extend the current `src/pages/[lang]/...` layout: - -```diff - 📂 src/pages - ┣ 📂 en - ┃ ┣ 📜 page-1.md - ┃ ┣ 📜 page-2.md - ┃ ┣ 📜 page-3.astro -+ ┣ 📂 es -+ ┃ ┣ 📜 page-1.md -+ ┃ ┣ 📜 page-2.md -+ ┃ ┣ 📜 page-3.astro -``` - -You'll also need to add the new language name to the `KNOWN_LANGUAGES` map in your `src/config.ts` file. This will enable your new language switcher in the site header. - -```diff -// src/config.ts -export const KNOWN_LANGUAGES = { - English: 'en', -+ Spanish: 'es', -}; -``` - -Last step: you'll need to add a new entry to your sidebar, to create the table of contents for that language. While duplicating every page might not sound ideal to everyone, this extra control allows you to create entirely custom content for every language. - -> Make sure the sidebar `link` value points to the correct language! - -```diff -// src/config.ts -export const SIDEBAR = { - en: [ - { text: 'Section Header', header: true, }, - { text: 'Introduction', link: 'en/introduction' }, - // ... - ], -+ es: [ -+ { text: 'Encabezado de sección', header: true, }, -+ { text: 'Introducción', link: 'es/introduction' }, -+ // ... -+ ], -}; - -// ... -``` - -If you plan to use Spanish as the default language, you just need to modify the redirect path in `src/pages/index.astro`: - -```diff - -``` - -You can also remove the above script and write a landing page in Spanish instead. - -### What if I don't plan to support multiple languages? - -That's totally fine! Not all projects need (or can support) multiple languages. You can continue to use this theme without ever adding a second language. - -If that single language is not English, you can just replace `en` in directory layouts and configurations with the preferred language. - -### Search (Powered by Algolia) - -[Algolia](https://www.algolia.com/) offers a free service to qualified open source projects called [DocSearch](https://docsearch.algolia.com/). If you are accepted to the DocSearch program, provide your API Key & index name in `src/config.ts` and a search box will automatically appear in your site header. - -Note that Aglolia and Astro are not affiliated. We have no say over acceptance to the DocSearch program. - -If you'd prefer to remove Algolia's search and replace it with your own, check out the `src/components/Header.astro` component to see where the component is added. +more setup info, see [project setup](../CONTRIBUTING.md#project-setup) \ No newline at end of file From f3e6f868577a0f3e3ed50c97c9022a5972ac17e3 Mon Sep 17 00:00:00 2001 From: yaxu Date: Sun, 11 Jan 2026 11:55:40 +0100 Subject: [PATCH 56/79] Update website/src/pages/learn/faq.mdx Trimmed all the DAW talk a little! --- website/src/pages/learn/faq.mdx | 61 +++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index 7fbc0d572..f8ebcb0fb 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -46,21 +46,34 @@ There are multiple ways to load your sample collection. Some methods are good fo ## Can I use Strudel with AI/LLM tools? -You are free to do what you like with Strudel, within the terms of the free/open source AGPLv3 license. However as a community we are interested in exploring human creativity. AI is _way_ over-hyped right now, including by people with very shady motives. Many in the community are very wary of people training models on their tunes that they've poured their love into. So please keep discussion and questions around AI and LLMs to channels dedicated to the topic and be fully respectful of other people's work. +You are free to do what you like with Strudel, within the terms of the free/open source AGPLv3 license. +However as a community we are interested in exploring human creativity. AI is _way_ over-hyped right now, +including by people with very shady motives. Many in the community are very wary of people training models +on their tunes that they've poured their love into. So please keep discussion and questions around AI and +LLMs to channels dedicated to the topic and be fully respectful of other people's work. -Furthermore, tools like ChatGPT generally give wrong answers. Please don't ask the community to fix those answers for you, as generally they will be timewasting nonsense. +Furthermore, tools like ChatGPT generally give wrong answers. Please don't ask the community to fix those +answers for you, as generally they will be timewasting nonsense. -Human questions only! +Human questions are always welcome! + +## Where can I download loads of patterns to train my LLM? + +You cannot, as there is no such place. For details regarding our stance towards AI/LLM, see [above](/learn/faq/#can-i-use-strudel-with-aillm-tools) ## How to run offline? -Strudel works offline just fine! There are multiple techniques to run it yourself, see [this explanation](learn/pwa/#using-strudel-offline). +Strudel works offline just fine! There are multiple techniques for this, see [this explanation](learn/pwa/#using-strudel-offline). ## How to change tempo? How do I translate BPM to cpm? -If you have your tempo in beats per minute and use 4 beats per cycle (e.g. if your track is in 4/4ths) then you can do `setcpm(BPM/4)` where BPM is your beats per minute. +Strudel works in cycles, rather than beats, but if you assume a certain number of beats per cycle, you can convert between them. -If you have a different number of beats per bar or are using more or less beats per cycle (e.g. If you want to put only half a bar or two bars into one cycle), adjust accordingly. +For example, if you have your tempo in beats per minute and use 4 beats per cycle (e.g. if your track is in 4/4ths) then you can do `setcpm(BPM/4)` +where BPM is your beats per minute. + +If you have a different number of beats per bar or are using more or less beats per cycle (e.g. If you want to put only half a bar or +two bars into one cycle), adjust accordingly. ## Where can I see all the functions? @@ -72,11 +85,17 @@ If you pop open the sidetab of strudel.cc (small white < on the right hand side) ## How do I use this exactly like a DAW? -Short answer: you don't. +Strudel has different design aims for a DAW, and so treating it like one will likely be frustrating. DAWs are geared towards +sequencing notes over time in predictable ways, whereas Strudel and similar Uzu languages are geared towards combining and +transforming patterns in ways that can be hard to predict. -Long answer: you can use Strudel to work along your creative work in a DAW. There are many ways to do so. +If you want to emulate the functionality of a DAW in Strudel, you'll have to identify the operations +executed by the DAW (sequencing, repeating, applying filters and envelopes) and write code that is equivalent to these +operations. For example in Strudel, the 'arrange' and 'pick' methods are useful for sequencing patterns over time (see question on these later in this document). -If you want to emulate the functionality of a DAW in a live coding language, you'll have to identify the operations executed by the DAW (sequencing, repeating, applying filters and envelopes) and write code that is equivalent to these operations. You might then find that the typical DAW workflow is not really adapted to live coding (because, despite both being ways of making music on the computer, they are two very different tools) and adapt your way of proceeding to the medium of code. This might mean leaving more place to serendipity and writing code that you don't predict the output of. +You might still find that the typical DAW workflow is not really adapted to live coding because, despite +both being ways of making music on the computer, they are two very different tools. You could then adapt your way of proceeding +to the medium of code, which might mean leaving more place to serendipity and writing code that you don't predict the output of. ## Why doesn't everyone just use a DAW? @@ -84,39 +103,29 @@ There is no easy answer to this question. Here are some thoughts: - Live coding tools such as Strudel are excellent for improvising music and visuals using a computer. DAWs are valuable and robust companions for other activities such as producing, mastering and mixing audio, among other usages. Using a tool does not exclude from using any another tool, just build a toolbox. -- Live coding has been practiced for quite some time as a performative activity. Artists like to show their screens while playing in front of an audience. It is an essential part of what they do, of the way they share their activity with everybody. +- Live coding has developed over decades as a distinct creative practice. For example, live coding artists like to show their screens while playing in front of an audience. It is an essential part of what they do, of the way they share their activity with everybody. -- Code is a human language, it is made for other humans to read it. You can read the code and enjoy the music too. It has meaning, value, and there might even be something poetic/important about it! - Strudel is free and open source, you can inspect the code, reshape it, contribute to it if you can/want. It is not opaque and this matters for many people. There is no black box, no obscure abstractions, no business model or hidden features. We need open tools in the arts! - Live coders don't shy away from using DAWs. They use them all of the time, especially when it makes their life easier for... live coding! +- Code is a human language, it is made for other humans to read it. You can read the code and enjoy the music too. It has meaning, value, and there might even be something poetic/important about it! - Strudel is free and open source, you can inspect the code, reshape it, contribute to it if you can/want. It is not opaque and this matters for many people. There is no black box, no obscure abstractions, no business model, no user tracking or hidden features. We need open tools in the arts! - Live coders don't all shy away from using DAWs. Many use them all of the time, especially when it makes their life easier for... live coding! - Code is an artistic material like any other. There is something valuable in the process of making music through code. More generally speaking, it is nice to tackle creative problems through the use of a programming language: creative thinking, building up your own solutions, DIY approach to music-making, unexpected outcome of algorithms, funny human errors, etc. - There are pianos and trumpets in your DAW: why do people continue playing the piano or the trumpet? Think of live coding tools as instruments that you activate through the act of programming. -## Is it more efficient to use Strudel than a DAW? - -Strudel was not build to be a DAW, yet it can still be used to make covers, arrange tracks, or prepare patterns for jamming. When playing concerts or jamming, some livecoders prepare their code, some perform from scratch. - -It might be interesting for you to check out for yourself how strudel can be used to express yourself creatively. Also you are free to combine a language like Strudel with a DAW. - ## How can I interface Strudel with my favorite music software? What can I do with it? Strudel can send [MIDI and OSC](/learn/input-output/), which are protocols for communicating musical information. -Another music software (or hardware!) can then listen to these messages and process them according to its capabilities. +Other music software (or hardware!) can then listen to these messages and process them according to its capabilities. -A simple example would be to send livecoded audio to Ableton on different tracks and then use it to mix them. +A simple example would be to send livecoded audio to a DAW like Ardour on different tracks and then use it to mix them. You could also send the MIDI of a sequenced pattern to Musescore and then have it transcribe your livecoded work as a musical score. -You could also send MIDI to your hardware synths because you think they sound better than the software synths built-in Strudel. +You could also send MIDI to your hardware synths, if you like their sound. -## How do I use this in my closed source webgame? +## How do I use this in my closed source webgame or other software? -You don't. You would need to re-license your game to AGPLv3 to fulfill the license Strudel is distributed under. - -## Where can I download loads of patterns to train my LLM? - -You cannot, as there is no such place. For details regarding our stance towards AI/LLM, see [above](/learn/faq/#can-i-use-strudel-with-aillm-tools) +You don't. You need to license your game to a free/open source license fulfill the [AGPLv3 license](https://codeberg.org/uzu/strudel/src/branch/main/LICENSE) Strudel is distributed under. ## How to play different patterns simultaneously? From 85fd567fb2e2ac40e1aac886af103dc83744201c Mon Sep 17 00:00:00 2001 From: yaxu Date: Sun, 11 Jan 2026 12:21:05 +0100 Subject: [PATCH 57/79] Format and remove link to open document --- website/src/pages/learn/faq.mdx | 46 ++++++++++++++------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index f8ebcb0fb..e43839dc3 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -16,18 +16,18 @@ Yes - there is no charge, this is a collective open source project, and the musi While there is no charge there are some caveats, e.g.: -* the source code must stay free, i.e. you cannot distribute strudel or tidal as part of projects with incompatible licenses - see the [license](https://www.gnu.org/licenses/agpl-3.0.en.html) for details. -* the contributed examples and tracks are also separately licensed, and must not e.g. be used to train AI models without permission. +- the source code must stay free, i.e. you cannot distribute strudel or tidal as part of projects with incompatible licenses - see the [license](https://www.gnu.org/licenses/agpl-3.0.en.html) for details. +- the contributed examples and tracks are also separately licensed, and must not e.g. be used to train AI models without permission. ## How to record or export audio? Strudel is not a digital audio workstation and does not operate following the same principles shared by most traditional audio softwares. However, there are multiple ways to record the audio -- and video -- output of Strudel: -* Use the 'export' tab to render and download as an audio file. -* capture the raw stereo signal coming out of your web browser. You will need an external audio editor/DAW such as Reaper/Audacity/Ardour, etc. -* use the alternative SuperDirt audio engine. Read [this page](/learn/input-output/#oscsuperdirtstrudeldirt) to know more about it. -* capture the audio/video stream using a capture tool such as [OBS](), which is designed for live streaming, but also works very well for recording. -* don't record anything and code it again in front of your friends. +- Use the 'export' tab to render and download as an audio file. +- capture the raw stereo signal coming out of your web browser. You will need an external audio editor/DAW such as Reaper/Audacity/Ardour, etc. +- use the alternative SuperDirt audio engine. Read [this page](/learn/input-output/#oscsuperdirtstrudeldirt) to know more about it. +- capture the audio/video stream using a capture tool such as [OBS](https://obsproject.com/fr), which is designed for live streaming, but also works very well for recording. +- don't record anything and code it again in front of your friends. ## Can I use strudel with my IDE? @@ -40,19 +40,19 @@ Yes you can. There are experimental modes, made by community members, for severa There are multiple ways to load your sample collection. Some methods are good for quick experimentation, some others are good to share your audio collection with other musicians: -- Import folders [from the interface](/learn/samples/#from-disk-via-import-sounds-folder). These are stored locally in your web browser, and not uploaded. +- Import folders [from the interface](/learn/samples/#from-disk-via-import-sounds-folder). These are stored locally in your web browser, and not uploaded. - Serve a folder of samples locally using the [strudel 'sampler' commandline tool](https://strudel.cc/learn/samples/#from-disk-via-strudelsampler). This can be most reliable method, but requires [nodejs](https://nodejs.org) to be installed. - Host your sound library online on the web and [load them from an URL](/learn/samples/#loading-custom-samples) ## Can I use Strudel with AI/LLM tools? -You are free to do what you like with Strudel, within the terms of the free/open source AGPLv3 license. -However as a community we are interested in exploring human creativity. AI is _way_ over-hyped right now, -including by people with very shady motives. Many in the community are very wary of people training models -on their tunes that they've poured their love into. So please keep discussion and questions around AI and +You are free to do what you like with Strudel, within the terms of the free/open source AGPLv3 license. +However as a community we are interested in exploring human creativity. AI is _way_ over-hyped right now, +including by people with very shady motives. Many in the community are very wary of people training models +on their tunes that they've poured their love into. So please keep discussion and questions around AI and LLMs to channels dedicated to the topic and be fully respectful of other people's work. -Furthermore, tools like ChatGPT generally give wrong answers. Please don't ask the community to fix those +Furthermore, tools like ChatGPT generally give wrong answers. Please don't ask the community to fix those answers for you, as generally they will be timewasting nonsense. Human questions are always welcome! @@ -69,7 +69,7 @@ Strudel works offline just fine! There are multiple techniques for this, see [th Strudel works in cycles, rather than beats, but if you assume a certain number of beats per cycle, you can convert between them. -For example, if you have your tempo in beats per minute and use 4 beats per cycle (e.g. if your track is in 4/4ths) then you can do `setcpm(BPM/4)` +For example, if you have your tempo in beats per minute and use 4 beats per cycle (e.g. if your track is in 4/4ths) then you can do `setcpm(BPM/4)` where BPM is your beats per minute. If you have a different number of beats per bar or are using more or less beats per cycle (e.g. If you want to put only half a bar or @@ -85,16 +85,16 @@ If you pop open the sidetab of strudel.cc (small white < on the right hand side) ## How do I use this exactly like a DAW? -Strudel has different design aims for a DAW, and so treating it like one will likely be frustrating. DAWs are geared towards -sequencing notes over time in predictable ways, whereas Strudel and similar Uzu languages are geared towards combining and +Strudel has different design aims for a DAW, and so treating it like one will likely be frustrating. DAWs are geared towards +sequencing notes over time in predictable ways, whereas Strudel and similar Uzu languages are geared towards combining and transforming patterns in ways that can be hard to predict. -If you want to emulate the functionality of a DAW in Strudel, you'll have to identify the operations -executed by the DAW (sequencing, repeating, applying filters and envelopes) and write code that is equivalent to these +If you want to emulate the functionality of a DAW in Strudel, you'll have to identify the operations +executed by the DAW (sequencing, repeating, applying filters and envelopes) and write code that is equivalent to these operations. For example in Strudel, the 'arrange' and 'pick' methods are useful for sequencing patterns over time (see question on these later in this document). -You might still find that the typical DAW workflow is not really adapted to live coding because, despite -both being ways of making music on the computer, they are two very different tools. You could then adapt your way of proceeding +You might still find that the typical DAW workflow is not really adapted to live coding because, despite +both being ways of making music on the computer, they are two very different tools. You could then adapt your way of proceeding to the medium of code, which might mean leaving more place to serendipity and writing code that you don't predict the output of. ## Why doesn't everyone just use a DAW? @@ -329,9 +329,3 @@ s increase by one semitone, i.e. sharp, works for steps of scales, note names $: at the start of a line, defines a member of the stack. is the only stack name that should occur multiple names _ before a stack name: mutes the stack, i.e. hush(), for example _$: s("bd"), see above for a different usage. ``` - -## Are there more FAQ items? - -These pages have been taken from [this pad](https://doc.patternclub.org/_CgofWouTciXXHexUP9AVg?both). Some of the items there have not been brushed up and brought here. - -These include the following items: 9, 11, 12 and 19 From a659c89385b84e08c001c47669fb98253ffb55f9 Mon Sep 17 00:00:00 2001 From: floy Date: Sun, 11 Jan 2026 13:25:44 +0100 Subject: [PATCH 58/79] fix code formatting --- website/src/repl/components/panel/SoundsTab.jsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index 2060c64a9..5a7df5ba9 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -210,10 +210,11 @@ export function SoundsTab() { ) : ( '' )} - {!soundEntries.length && soundsFilter !== 'importSounds' ? - search == '' ? 'No sounds loaded' : 'No sounds found' - : '' - } + {!soundEntries.length && soundsFilter !== 'importSounds' + ? search == '' + ? 'No sounds loaded' + : 'No sounds found' + : ''}
); From 8d2bca59c4373a74d6f05ecb9432b5384135109c Mon Sep 17 00:00:00 2001 From: JesCoding Date: Wed, 24 Dec 2025 11:39:28 +0100 Subject: [PATCH 59/79] Fix sounds example to work in the REPL `freq` only takes one argument, so switch this to mini-notation so this can be used in the REPL as indicated in the paragraph below. Make it so this can be played by the user. Fix syntax-type typo. --- website/src/pages/technical-manual/sounds.mdx | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/website/src/pages/technical-manual/sounds.mdx b/website/src/pages/technical-manual/sounds.mdx index 11078713f..73ae05796 100644 --- a/website/src/pages/technical-manual/sounds.mdx +++ b/website/src/pages/technical-manual/sounds.mdx @@ -13,7 +13,7 @@ Let's take a closer look about how sounds are implemented in the webaudio output All sounds are registered in the sound map, using the the `registerSound` function: -```ts +```js function registerSound( name: string, // The name of the sound that should be given to `s`, e.g. `mysaw` // The function called by the scheduler to trigger the sound: @@ -35,34 +35,36 @@ When `registerSound` is called, it registers `{ onTrigger, data }` under the giv This might be a bit abstract, so here is a minimal example: -```js -registerSound( - 'mysaw', - (time, value, onended) => { - let { freq } = value; // destructure control params - const ctx = getAudioContext(); - // create oscillator - const o = new OscillatorNode(ctx, { type: 'sawtooth', frequency: Number(freq) }); - o.start(time); - // add gain node to level down osc - const g = new GainNode(ctx, { gain: 0.3 }); - // connect osc to gain - const node = o.connect(g); - // this function can be called from outside to stop the sound - const stop = (time) => o.stop(time); - // ended will be fired when stop has been fired - o.addEventListener('ended', () => { - o.disconnect(); - g.disconnect(); - onended(); - }); - return { node, stop }; - }, - { type: 'synth' }, -); -// use the sound -freq(220, 440, 330).s('mysaw'); -``` + { + let { freq } = value; // destructure control params + const ctx = getAudioContext(); + // create oscillator + const o = new OscillatorNode(ctx, { type: 'sawtooth', frequency: Number(freq) }); + o.start(time); + // add gain node to level down osc + const g = new GainNode(ctx, { gain: 0.3 }); + // connect osc to gain + const node = o.connect(g); + // this function can be called from outside to stop the sound + const stop = (time) => o.stop(time); + // ended will be fired when stop has been fired + o.addEventListener('ended', () => { + o.disconnect(); + g.disconnect(); + onended(); + }); + return { node, stop }; + }, + { type: 'synth' }, + ); + // use the sound + freq("220 440 330").s('mysaw');`} +/> You can actually use this code in the [REPL](https://strudel.cc/) and it'll work. After evaluating the code, you should see `mysaw` in listed in the sounds tab. From 31cacc3c29a18e59761cda66e912c8ee8e00d8a3 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 11 Jan 2026 16:23:17 +0000 Subject: [PATCH 60/79] add warm to faq --- website/src/pages/learn/faq.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/website/src/pages/learn/faq.mdx b/website/src/pages/learn/faq.mdx index e43839dc3..fc3bcdb2d 100644 --- a/website/src/pages/learn/faq.mdx +++ b/website/src/pages/learn/faq.mdx @@ -19,6 +19,14 @@ While there is no charge there are some caveats, e.g.: - the source code must stay free, i.e. you cannot distribute strudel or tidal as part of projects with incompatible licenses - see the [license](https://www.gnu.org/licenses/agpl-3.0.en.html) for details. - the contributed examples and tracks are also separately licensed, and must not e.g. be used to train AI models without permission. +## How do I try out the latest features? + +The main, stable strudel website is [strudel.cc](https://strudel.cc/). There is also [warm.strudel.cc](https://warm.strudel.cc), known as "warm strudel", which has the latest development features. You might find warm strudel has bug fixes and features that the main website doesn't, but it will often be less stable and probably not suitable for important performances. + +Alternatively, you can run strudel locally to try out the latest features. You can find development-oriented [instructions for that here](https://codeberg.org/uzu/strudel/src/branch/main/CONTRIBUTING.md#project-setup). + +You can see the [latest changes here](https://codeberg.org/uzu/strudel/pulls?q=&type=all&sort=recentupdate&state=closed&labels=&milestone=0&project=0&assignee=0&poster=0), as 'pull requests'. + ## How to record or export audio? Strudel is not a digital audio workstation and does not operate following the same principles shared by most traditional audio softwares. However, there are multiple ways to record the audio -- and video -- output of Strudel: From 753dc48b69ef800d21efe4541a6126b30e9f292e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 11 Jan 2026 19:12:45 +0100 Subject: [PATCH 61/79] update changelog --- CHANGELOG.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a13e379d9..19a502f33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,62 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly sorted... +## january 2026 + +- 2026-01-11T19:00:25+01:00 Fix sounds example to work in the REPL by JesCoding in: [#1851](https://codeberg.org/uzu/strudel/pulls/1851) +- 2026-01-11T13:52:02+01:00 Improve hint text when sound search has no results by floy in: [#1883](https://codeberg.org/uzu/strudel/pulls/1883) +- 2026-01-11T12:45:07+01:00 fix: remove faulty default readme by froos in: [#1889](https://codeberg.org/uzu/strudel/pulls/1889) +- 2026-01-11T12:15:34+01:00 fix/self-hosted-config by alienmind in: [#1880](https://codeberg.org/uzu/strudel/pulls/1880) +- 2026-01-11T12:07:48+01:00 Feat: Support External AudioContext Injection by 1d10t in: [#1833](https://codeberg.org/uzu/strudel/pulls/1833) +- 2026-01-11T11:37:37+01:00 fix: add trem to top level by froos in: [#1887](https://codeberg.org/uzu/strudel/pulls/1887) +- 2026-01-11T11:37:18+01:00 fix: export start cycle min 0 by froos in: [#1888](https://codeberg.org/uzu/strudel/pulls/1888) +- 2026-01-11T11:05:44+01:00 fix: repl package init audio properly by froos in: [#1836](https://codeberg.org/uzu/strudel/pulls/1836) +- 2026-01-11T06:51:24+01:00 Fix: show reload dialog when uploading prebake script by daslyfe in: [#1886](https://codeberg.org/uzu/strudel/pulls/1886) +- 2026-01-11T06:01:42+01:00 fixes Serial onTrigger() params #1633 by gueejla in: [#1885](https://codeberg.org/uzu/strudel/pulls/1885) +- 2026-01-10T20:52:40+01:00 Allow top level distortions for the purpose of FX by glossing in: [#1884](https://codeberg.org/uzu/strudel/pulls/1884) +- 2026-01-10T23:12:48+01:00 Perf: Targeted node pools by glossing in: [#1810](https://codeberg.org/uzu/strudel/pulls/1810) +- 2026-01-09T03:43:37+01:00 Bake in scaling by `freq` for FM with a gain node by glossing in: [#1878](https://codeberg.org/uzu/strudel/pulls/1878) +- 2026-01-09T02:53:38+01:00 Bug fix: Properly handle subcontrols by glossing in: [#1877](https://codeberg.org/uzu/strudel/pulls/1877) +- 2026-01-07T20:06:18+01:00 Feat: Add ability to turn mini parsing off with mini-off decorator by glossing in: [#1786](https://codeberg.org/uzu/strudel/pulls/1786) +- 2026-01-07T19:22:24+01:00 Bug Fix: Update loopStart/End to not be offset by glossing in: [#1826](https://codeberg.org/uzu/strudel/pulls/1826) +- 2026-01-06T06:35:49+01:00 Update modulator docstrings and allow ids to be patterns by glossing in: [#1874](https://codeberg.org/uzu/strudel/pulls/1874) +- 2026-01-04T17:14:11+01:00 Fix doc link in @strudel/osc README.md by forrcaho in: [#1872](https://codeberg.org/uzu/strudel/pulls/1872) +- 2026-01-04T02:01:07+01:00 Make stretch modulatable by glossing in: [#1870](https://codeberg.org/uzu/strudel/pulls/1870) +- 2026-01-02T18:44:53+01:00 Make pan modulatable by glossing in: [#1865](https://codeberg.org/uzu/strudel/pulls/1865) +- 2026-01-01T21:42:23+01:00 Fix transpilation example to have same mini-notation by JesCoding in: [#1850](https://codeberg.org/uzu/strudel/pulls/1850) +- 2026-01-01T21:39:05+01:00 fix: missing punctuation by eddyflux in: [#1860](https://codeberg.org/uzu/strudel/pulls/1860) +- 2026-01-01T20:20:34+01:00 Fix formatting of docstring by glossing in: [#1864](https://codeberg.org/uzu/strudel/pulls/1864) +- 2026-01-01T19:52:15+01:00 Feat: FX Chains by glossing in: [#1861](https://codeberg.org/uzu/strudel/pulls/1861) + +## december 2025 + +- 2025-12-29T21:59:11+01:00 Bugfix: Fix modulator clamping when min/max not specified by glossing in: [#1859](https://codeberg.org/uzu/strudel/pulls/1859) +- 2025-12-29T16:07:18+01:00 Fix AudioContext change detection. Use AudioNode.context by jeromew in: [#1858](https://codeberg.org/uzu/strudel/pulls/1858) +- 2025-12-28T14:20:03+01:00 dough repl fixes by froos in: [#1855](https://codeberg.org/uzu/strudel/pulls/1855) +- 2025-12-19T08:11:50+01:00 fix: visual block selection mode for vim bindings by Dsm0 in: [#1839](https://codeberg.org/uzu/strudel/pulls/1839) +- 2025-12-28T22:58:38+01:00 Say that @license should use SPDX identifier by Wuzzy in: [#1817](https://codeberg.org/uzu/strudel/pulls/1817) +- 2025-12-28T22:56:07+01:00 Expose Vim object in order to create custom keybindings by JohnBjrk in: [#1816](https://codeberg.org/uzu/strudel/pulls/1816) +- 2025-12-20T22:27:52+01:00 Document "-" in mini-notation by Wuzzy in: [#1818](https://codeberg.org/uzu/strudel/pulls/1818) +- 2025-12-20T22:20:27+01:00 simplify envValAtTime and remove asymmetric behavior (fix #1653) by pulu in: [#1815](https://codeberg.org/uzu/strudel/pulls/1815) +- 2025-12-14T15:09:12+01:00 delta -> per / perx / cyclesPer refinements by yaxu in: [#1832](https://codeberg.org/uzu/strudel/pulls/1832) +- 2025-12-14T19:33:37+01:00 Fix: wrong warning in build environments by jeromew in: [#1835](https://codeberg.org/uzu/strudel/pulls/1835) +- 2025-12-12T10:28:27+01:00 Add delta signal for representing the duration of events in patterns that are combined with it by yaxu in: [#1831](https://codeberg.org/uzu/strudel/pulls/1831) +- 2025-12-11T16:37:58+01:00 Updates relating to LLM, github, etc by yaxu in: [#1830](https://codeberg.org/uzu/strudel/pulls/1830) +- 2025-12-10T15:32:44+01:00 fix .as so it doesn't set undefined values by yaxu in: [#1827](https://codeberg.org/uzu/strudel/pulls/1827) +- 2025-12-08T19:27:31+01:00 [perf] propagate `onceEnded` and `releaseAudioNode` by jeromew in: [#1809](https://codeberg.org/uzu/strudel/pulls/1809) +- 2025-12-07T19:15:43+01:00 Add vel as a synonym for velocity & update a few docstrings by glossing in: [#1781](https://codeberg.org/uzu/strudel/pulls/1781) +- 2025-12-07T18:53:04+01:00 [perf] fix phaser leak of unused biquads by jeromew in: [#1800](https://codeberg.org/uzu/strudel/pulls/1800) +- 2025-12-07T18:42:50+01:00 Bug fix: Remove failing tests due to shabda removal by glossing in: [#1820](https://codeberg.org/uzu/strudel/pulls/1820) +- 2025-12-03T17:35:05+01:00 [perf] release unused AudioBufferSourceNode + releaseAudioNode by jeromew in: [#1805](https://codeberg.org/uzu/strudel/pulls/1805) +- **2025-12-01 strudel.cc deployed** + ## november 2025 +- 2025-11-29T01:00:42+01:00 added export to getSuperdoughAudioController() so that its possible to route superdough audio through other webaudio applications. by ndr0n in: [#1796](https://codeberg.org/uzu/strudel/pulls/1796) +- 2025-11-28T23:26:20+01:00 add revv() for reversing whole patterns by yaxu in: [#1791](https://codeberg.org/uzu/strudel/pulls/1791) +- 2025-11-28T20:19:16+01:00 [perf] Disconnect lfos for phaser and filters by glossing in: [#1787](https://codeberg.org/uzu/strudel/pulls/1787) +- 2025-11-27T23:08:52+01:00 fix: return silence when no pattern is returned by froos in: [#1795](https://codeberg.org/uzu/strudel/pulls/1795) +- 2025-11-27T22:38:05+01:00 add CHANGELOG.md + basic script to generate by froos in: [#1794](https://codeberg.org/uzu/strudel/pulls/1794) - 2025-11-27T22:03:53+01:00 [perf] in `noise`, let noiseMix do the disconnect when it exists by jeromew in: [#1783](https://codeberg.org/uzu/strudel/pulls/1783) - 2025-11-27T22:01:01+01:00 Bug Fix: Retries for sounds tab by glossing in: [#1754](https://codeberg.org/uzu/strudel/pulls/1754) - 2025-11-27T20:36:46+01:00 [hydra] return the hydra object when await initHydra(..) is called by jeromew in: [#1784](https://codeberg.org/uzu/strudel/pulls/1784) @@ -52,6 +106,7 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly - 2025-10-28T22:51:16+01:00 Repurpose vim shortcuts for usability by dtricks in: [#1624](https://codeberg.org/uzu/strudel/pulls/1624) - 2025-10-28T22:35:21+01:00 Add support for euclidian in mondo with `bd&3:8` by TristanCacqueray in: [#1630](https://codeberg.org/uzu/strudel/pulls/1630) - 2025-10-27T10:42:07+01:00 Use bunny cdn for all samples and json files by yaxu in: [#1701](https://codeberg.org/uzu/strudel/pulls/1701) +- **2025-10-27 @strudel/core@1.2.5** - 2025-10-26T22:52:54+01:00 degithub - switch some samples to bunnycdn by yaxu in: [#1697](https://codeberg.org/uzu/strudel/pulls/1697) - 2025-10-26T17:09:22+01:00 Fix ZZFX example by moumar in: [#1685](https://codeberg.org/uzu/strudel/pulls/1685) - 2025-10-23T15:56:04+02:00 Make osc port and host configurable. Changes dependencies. by yaxu in: [#1682](https://codeberg.org/uzu/strudel/pulls/1682) From 12cc1e9b5ea22017bacfce974e2c5aad0ca7eaa6 Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 11 Jan 2026 14:51:47 -0600 Subject: [PATCH 62/79] Add immediate triggering; move time to schedulerState --- packages/core/index.mjs | 2 +- packages/core/repl.mjs | 4 +- .../core/{time.mjs => schedulerState.mjs} | 22 ++++++- packages/midi/midi.mjs | 59 +++++++++++++++++-- 4 files changed, 79 insertions(+), 8 deletions(-) rename packages/core/{time.mjs => schedulerState.mjs} (70%) diff --git a/packages/core/index.mjs b/packages/core/index.mjs index 9260e3671..542a54243 100644 --- a/packages/core/index.mjs +++ b/packages/core/index.mjs @@ -22,7 +22,7 @@ export * from './repl.mjs'; export * from './signal.mjs'; export * from './speak.mjs'; export * from './state.mjs'; -export * from './time.mjs'; +export * from './schedulerState.mjs'; export * from './timespan.mjs'; export * from './ui.mjs'; export * from './util.mjs'; diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 71f68b809..e39b57de3 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -2,7 +2,7 @@ import { NeoCyclist } from './neocyclist.mjs'; import { Cyclist } from './cyclist.mjs'; import { evaluate as _evaluate } from './evaluate.mjs'; import { errorLogger, logger } from './logger.mjs'; -import { setCpsFunc, setTime } from './time.mjs'; +import { setCpsFunc, setPattern as exposeSchedulerPattern, setTime, setTriggerFunc } from './schedulerState.mjs'; import { evalScope } from './evaluate.mjs'; import { register, Pattern, isPattern, silence, stack } from './pattern.mjs'; import { reset_state } from './impure.mjs'; @@ -65,6 +65,7 @@ export function repl({ // NeoCyclist uses a shared worker to communicate between instances, which is not supported on mobile chrome const scheduler = sync && typeof SharedWorker != 'undefined' ? new NeoCyclist(schedulerOptions) : new Cyclist(schedulerOptions); + setTriggerFunc(schedulerOptions.onTrigger); setCpsFunc(() => scheduler.cps); let pPatterns = {}; let anonymousIndex = 0; @@ -90,6 +91,7 @@ export function repl({ const setPattern = async (pattern, autostart = true) => { pattern = editPattern?.(pattern) || pattern; await scheduler.setPattern(pattern, autostart); + exposeSchedulerPattern(pattern); return pattern; }; setTime(() => scheduler.now()); // TODO: refactor? diff --git a/packages/core/time.mjs b/packages/core/schedulerState.mjs similarity index 70% rename from packages/core/time.mjs rename to packages/core/schedulerState.mjs index 2d4caecf5..97a4f56dc 100644 --- a/packages/core/time.mjs +++ b/packages/core/schedulerState.mjs @@ -1,11 +1,13 @@ /* -time.mjs - Core time module. Used to expose parameters from the Scheduler like `time` and `cps` -Copyright (C) 2026 Strudel contributors - see +schedulerState.mjs - Module to pipe out various parameters from the scheduler for global consumption +Copyright (C) 2026 Strudel contributors - see This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ let time; let cpsFunc; +let pattern; +let triggerFunc; export function getTime() { if (!time) { throw new Error('no time set! use setTime to define a time source'); @@ -24,3 +26,19 @@ export function setCpsFunc(func) { export function getCps() { return cpsFunc?.(); } + +export function setPattern(pat) { + pattern = pat; +} + +export function getPattern() { + return pattern; +} + +export function setTriggerFunc(func) { + triggerFunc = func; +} + +export function getTriggerFunc() { + return triggerFunc; +} diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index 6233bf60d..ad6b799dc 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -5,9 +5,22 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as _WebMidi from 'webmidi'; -import { Hap, Pattern, TimeSpan, getCps, getTime, isPattern, logger, ref, reify } from '@strudel/core'; +import { + Hap, + Pattern, + TimeSpan, + getCps, + getPattern, + getTime, + getTriggerFunc, + isPattern, + logger, + ref, + reify, +} from '@strudel/core'; import { noteToMidi, getControlName } from '@strudel/core'; import { Note } from 'webmidi'; +import { getAudioContext } from '@strudel/webaudio'; import { scheduleAtTime } from '../superdough/helpers.mjs'; // if you use WebMidi from outside of this package, make sure to import that instance: @@ -575,6 +588,33 @@ export async function midin(input) { */ const kHaps = {}; const kListeners = {}; + +function triggerKbNow(input, cps, now, latencyCycles) { + const pattern = getPattern(); + const trigger = getTriggerFunc(); + if (!pattern || !trigger) { + return false; + } + const t = now + latencyCycles; + const eps = 1e-6; + const haps = pattern.queryArc(t - eps, t + eps, { _cps: cps }); + // Only keep haps coming from `midikeys` + const kbHaps = haps.filter((hap) => hap.value?.midikey?.startsWith(`${input}_`)); + const ctxNow = getAudioContext().currentTime; + if (!kbHaps.length) { + return false; + } + kbHaps.forEach((hap) => { + if (!hap.hasOnset()) { + return; + } + const t = ctxNow + (hap.whole.begin - now) / cps; + const duration = hap.duration / cps; + trigger(hap, t - ctxNow, duration, cps, t); + }); + + return true; +} export async function midikeys(input) { const device = await _initialize(input); if (!kHaps[input]) { @@ -584,11 +624,14 @@ export async function midikeys(input) { kListeners[input] = (e) => { const { dataBytes, message } = e; const [note, velocity] = dataBytes; - const noteoff = message.command === 8; + const noteon = message.command === 9; + const noteoff = message.command === 8 || (noteon && velocity === 0); const key = `${input}_${note}`; const cps = getCps() ?? 0.5; - const latencySeconds = 0.06; // slight delay so it's not too late for cyclist to catch - const t = getTime() + latencySeconds * cps; + const triggerAvailable = !!(getPattern() && getTriggerFunc()); + const latencySeconds = triggerAvailable ? 0.01 : 0.06; // avoid missing notes due to cyclist / trigger latency + const now = getTime(); + const t = now + latencySeconds * cps; const span = new TimeSpan(t, t); let value = { midikey: key }; if (noteoff) { @@ -609,6 +652,14 @@ export async function midikeys(input) { value = { ...value, note: Math.round(note), velocity: velocity / 127 }; } kHaps[input].push(new Hap(span, span, value, {})); + if (!noteoff && triggerAvailable) { + // If we have access to a trigger function, we call it to immediately + // dispatch to the audio engine, rather than waiting for cyclist to catch these haps + const triggered = triggerKbNow(input, cps, now, latencySeconds * cps); + if (triggered) { + kHaps[input] = []; + } + } }; device.addListener('midimessage', kListeners[input]); const kb = (noteLength = 0.5) => { From 5355a0c563bea7b0e98dbfbfbff65c7a60f00b01 Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 11 Jan 2026 23:34:52 -0600 Subject: [PATCH 63/79] Ignore non-note messages --- packages/midi/midi.mjs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index ad6b799dc..50a58b059 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -589,7 +589,7 @@ export async function midin(input) { const kHaps = {}; const kListeners = {}; -function triggerKbNow(input, cps, now, latencyCycles) { +function _triggerKeyboard(input, cps, now, latencyCycles) { const pattern = getPattern(); const trigger = getTriggerFunc(); if (!pattern || !trigger) { @@ -623,9 +623,14 @@ export async function midikeys(input) { kListeners[input] && device.removeListener('midimessage', kListeners[input]); kListeners[input] = (e) => { const { dataBytes, message } = e; - const [note, velocity] = dataBytes; const noteon = message.command === 9; - const noteoff = message.command === 8 || (noteon && velocity === 0); + let noteoff = message.command === 8; + if (!noteon && !noteoff) { + // Ignore non-note messages (e.g. CC, pitchbend, modwheel, etc.) + return; + } + const [note, velocity] = dataBytes; + noteoff ||= noteon && velocity === 0; // handle devices which may use velocity = 0 to signal noteoff const key = `${input}_${note}`; const cps = getCps() ?? 0.5; const triggerAvailable = !!(getPattern() && getTriggerFunc()); @@ -655,7 +660,7 @@ export async function midikeys(input) { if (!noteoff && triggerAvailable) { // If we have access to a trigger function, we call it to immediately // dispatch to the audio engine, rather than waiting for cyclist to catch these haps - const triggered = triggerKbNow(input, cps, now, latencySeconds * cps); + const triggered = _triggerKeyboard(input, cps, now, latencySeconds * cps); if (triggered) { kHaps[input] = []; } From c2720a573821562b816a11d75311613cf57541f9 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 12 Jan 2026 11:26:18 -0800 Subject: [PATCH 64/79] working --- packages/core/pattern.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 58c83a6f8..4cf30c787 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -26,6 +26,7 @@ import { } from './util.mjs'; import drawLine from './drawLine.mjs'; import { errorLogger, logger } from './logger.mjs'; +import { strudelScope } from './evaluate.mjs'; let stringParser; @@ -1683,7 +1684,9 @@ export function register(name, func, patternify = true, preserveSteps = false, j // toplevel functions get curried as well as patternified // because pfunc uses spread args, we need to state the arity explicitly! - return curry(pfunc, null, arity); + const curried = curry(pfunc, null, arity); + strudelScope[name] = pfunc; + return curried; } // Like register, but defaults to stepJoin From 35bfd8b3ff53111425fd35eb0486979ba5265a3b Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 12 Jan 2026 11:28:54 -0800 Subject: [PATCH 65/79] curried --- packages/core/pattern.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 4cf30c787..25a2bb0b9 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -1685,7 +1685,7 @@ export function register(name, func, patternify = true, preserveSteps = false, j // toplevel functions get curried as well as patternified // because pfunc uses spread args, we need to state the arity explicitly! const curried = curry(pfunc, null, arity); - strudelScope[name] = pfunc; + strudelScope[name] = curried; return curried; } From 7c5f53f9ae8b85507300164be00852eccf6d0bf6 Mon Sep 17 00:00:00 2001 From: Aria Date: Mon, 12 Jan 2026 13:51:21 -0600 Subject: [PATCH 66/79] Add ack message for worklet death; remove max pool size --- packages/superdough/nodePools.mjs | 7 ++----- packages/superdough/synth.mjs | 5 ++++- packages/superdough/wavetable.mjs | 5 ++++- packages/superdough/worklets.mjs | 26 ++++++++++++++++++++++++-- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/packages/superdough/nodePools.mjs b/packages/superdough/nodePools.mjs index 205352247..000099dc6 100644 --- a/packages/superdough/nodePools.mjs +++ b/packages/superdough/nodePools.mjs @@ -8,7 +8,6 @@ This program is free software: you can redistribute it and/or modify it under th const nodePools = new Map(); const POOL_KEY = Symbol('nodePoolKey'); const IS_WORKLET_DEAD = Symbol('nodePoolIsWorkletDead'); -const MAX_POOL_SIZE = 64; export const isPoolable = (node) => !!node[POOL_KEY]; @@ -47,10 +46,8 @@ export const releaseNodeToPool = (node) => { const now = node.context?.currentTime ?? 0; getParams(node).forEach((param) => param.cancelScheduledValues(now)); const pool = nodePools.get(key) ?? []; - if (pool.length < MAX_POOL_SIZE) { - pool.push(new WeakRef(node)); - nodePools.set(key, pool); - } + pool.push(new WeakRef(node)); + nodePools.set(key, pool); }; export const markWorkletAsDead = (worklet) => (worklet[IS_WORKLET_DEAD] = true); diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index f4bdd749f..ec1724da0 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -186,7 +186,10 @@ export function registerSynthSounds() { }); o.port.postMessage({ type: 'initialize' }); o.port.onmessage = (e) => { - if (e.data.type === 'died') markWorkletAsDead(o); + if (e.data.type === 'died') { + markWorkletAsDead(o); + o.port.postMessage({ type: 'diedACK' }); + } o.port.onmessage = null; }; const gainAdjustment = 1 / Math.sqrt(voices); diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index adf8b0c44..a228bc1d7 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -252,7 +252,10 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { }); source.port.postMessage({ type: 'initialize', payload }); source.port.onmessage = (e) => { - if (e.data.type === 'died') markWorkletAsDead(source); + if (e.data.type === 'died') { + markWorkletAsDead(source); + source.port.postMessage({ type: 'diedACK' }); + } source.port.onmessage = null; }; if (ac.currentTime > t) { diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 52c13e836..61c620878 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -464,11 +464,19 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { constructor() { super(); this.isAlive = true; // used internally to prevent multiple death messages + // diedACK is used for the main thread to acknowledge that the worklet has died + // This is so that we don't risk simultaneously killing the worklet (`return false`) + // and pooling the worklet (main thread) before the async `died` message hits + // the main thread + this.diedACK = false; this.port.onmessage = (e) => { const { type, payload } = e.data || {}; if (type === 'initialize') { this.initialize(payload); } + if (type === 'diedACK') { + this.diedACK = true; + } }; this.initialize(); } @@ -529,7 +537,10 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { this.port.postMessage({ type: 'died' }); this.isAlive = false; } - return false; + if (this.diedACK || currentTime >= params.end[1] + 1) { + return false; + } + return true; } if (currentTime >= params.end[0] || currentTime <= params.begin[0]) { // Inside of grace period or not yet started @@ -1165,11 +1176,19 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { constructor(options) { super(options); this.isAlive = true; // used internally to prevent multiple death messages + // diedACK is used for the main thread to acknowledge that the worklet has died + // This is so that we don't risk simultaneously killing the worklet (`return false`) + // and pooling the worklet (main thread) before the async `died` message hits + // the main thread + this.diedACK = false; this.port.onmessage = (e) => { const { type, payload } = e.data || {}; if (type === 'initialize') { this.initialize(payload); } + if (type === 'diedACK') { + this.diedACK = true; + } }; this.initialize(); } @@ -1338,7 +1357,10 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { this.port.postMessage({ type: 'died' }); this.isAlive = false; } - return false; + if (this.diedACK || currentTime >= parameters.end[1] + 1) { + return false; + } + return true; } if (currentTime >= parameters.end[0] || currentTime <= parameters.begin[0]) { // Inside of grace period or not yet started From 1f1f3288a6fe0d9f1803f1ceb00cd12bb746ba05 Mon Sep 17 00:00:00 2001 From: Aria Date: Mon, 12 Jan 2026 17:58:20 -0600 Subject: [PATCH 67/79] Switch to tracking grace period in node pool; add negative begin and ends --- packages/superdough/nodePools.mjs | 32 +++++++++---- packages/superdough/synth.mjs | 9 +--- packages/superdough/wavetable.mjs | 9 +--- packages/superdough/worklets.mjs | 78 +++++++++++-------------------- 4 files changed, 53 insertions(+), 75 deletions(-) diff --git a/packages/superdough/nodePools.mjs b/packages/superdough/nodePools.mjs index 000099dc6..90b4c0ae7 100644 --- a/packages/superdough/nodePools.mjs +++ b/packages/superdough/nodePools.mjs @@ -7,10 +7,13 @@ This program is free software: you can redistribute it and/or modify it under th const nodePools = new Map(); const POOL_KEY = Symbol('nodePoolKey'); -const IS_WORKLET_DEAD = Symbol('nodePoolIsWorkletDead'); export const isPoolable = (node) => !!node[POOL_KEY]; +const getNodeTime = (node) => { + return node.context?.currentTime ?? 0; +}; + const getParams = (node) => { const params = new Set(); node.parameters?.forEach((param) => params.add(param)); @@ -37,32 +40,43 @@ export const releaseNodeToPool = (node) => { // not reusable return; } - if (node[IS_WORKLET_DEAD]) { - // Worklet already terminated, don't pool it - return; - } const key = node[POOL_KEY]; if (key == null) return; - const now = node.context?.currentTime ?? 0; + const now = getNodeTime(node); getParams(node).forEach((param) => param.cancelScheduledValues(now)); const pool = nodePools.get(key) ?? []; pool.push(new WeakRef(node)); nodePools.set(key, pool); }; -export const markWorkletAsDead = (worklet) => (worklet[IS_WORKLET_DEAD] = true); +// Audio worklets are given a grace period to survive (`return true`) after +// being released. This concludes at time `end + 0.5`. We test here whether we are +// within some safe distance of that (`end + 0.45`) and if so, permit the node to be +// released. This helps to prevent race conditions between node termination and node +// re-use +const isNodeAlive = (node) => { + // Skip check if node is not a worklet + if (!(node instanceof AudioWorkletNode)) return true; + const now = getNodeTime(node); + const end = node?.parameters?.get('end').value ?? 0; + return now < end + 0.45; +}; // Attempt to get node from the pool. If this fails, fall back // to building it with the factory export const getNodeFromPool = (key, factory) => { const pool = nodePools.get(key) ?? []; let node; + let found = false; while (pool.length) { const ref = pool.pop(); node = ref?.deref(); - if (node != null && !node[IS_WORKLET_DEAD]) break; + if (node != null && isNodeAlive(node)) { + found = true; + break; + } } - if (node == null || node[IS_WORKLET_DEAD]) { + if (!found) { node = factory(); } node[POOL_KEY] = key; diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index ec1724da0..9561ab363 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -18,7 +18,7 @@ import { } from './helpers.mjs'; import { logger } from './logger.mjs'; import { getNoiseMix, getNoiseOscillator } from './noise.mjs'; -import { getNodeFromPool, markWorkletAsDead, releaseNodeToPool } from './nodePools.mjs'; +import { getNodeFromPool, releaseNodeToPool } from './nodePools.mjs'; const waveforms = ['triangle', 'square', 'sawtooth', 'sine', 'user', 'one']; const waveformAliases = [ @@ -185,13 +185,6 @@ export function registerSynthSounds() { param.setValueAtTime(target, now); }); o.port.postMessage({ type: 'initialize' }); - o.port.onmessage = (e) => { - if (e.data.type === 'died') { - markWorkletAsDead(o); - o.port.postMessage({ type: 'diedACK' }); - } - o.port.onmessage = null; - }; const gainAdjustment = 1 / Math.sqrt(voices); getPitchEnvelope(o.parameters.get('detune'), value, begin, holdend); const vibratoHandle = getVibratoOscillator(o.parameters.get('detune'), value, begin); diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index a228bc1d7..1de42f643 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -11,7 +11,7 @@ import { webAudioTimeout, releaseAudioNode, } from './helpers.mjs'; -import { getNodeFromPool, markWorkletAsDead, releaseNodeToPool } from './nodePools.mjs'; +import { getNodeFromPool, releaseNodeToPool } from './nodePools.mjs'; import { logger } from './logger.mjs'; export const Warpmode = Object.freeze({ @@ -251,13 +251,6 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { param.setValueAtTime(target, now); }); source.port.postMessage({ type: 'initialize', payload }); - source.port.onmessage = (e) => { - if (e.data.type === 'died') { - markWorkletAsDead(source); - source.port.postMessage({ type: 'diedACK' }); - } - source.port.onmessage = null; - }; if (ac.currentTime > t) { logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight'); return; diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 61c620878..6689278e3 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -463,20 +463,11 @@ registerProcessor('distort-processor', DistortProcessor); class SuperSawOscillatorProcessor extends AudioWorkletProcessor { constructor() { super(); - this.isAlive = true; // used internally to prevent multiple death messages - // diedACK is used for the main thread to acknowledge that the worklet has died - // This is so that we don't risk simultaneously killing the worklet (`return false`) - // and pooling the worklet (main thread) before the async `died` message hits - // the main thread - this.diedACK = false; this.port.onmessage = (e) => { const { type, payload } = e.data || {}; if (type === 'initialize') { this.initialize(payload); } - if (type === 'diedACK') { - this.diedACK = true; - } }; this.initialize(); } @@ -487,16 +478,16 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { return [ { name: 'begin', - defaultValue: 0, + defaultValue: -1, max: Number.POSITIVE_INFINITY, - min: 0, + min: -1, }, { name: 'end', - defaultValue: 0, + defaultValue: -1, max: Number.POSITIVE_INFINITY, - min: 0, + min: -1, }, { @@ -531,19 +522,17 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { ]; } process(_input, outputs, params) { - if (currentTime >= params.end[0] + 0.5) { - // Outside of grace period - should terminate - if (this.isAlive) { - this.port.postMessage({ type: 'died' }); - this.isAlive = false; - } - if (this.diedACK || currentTime >= params.end[1] + 1) { - return false; - } - return true; - } - if (currentTime >= params.end[0] || currentTime <= params.begin[0]) { - // Inside of grace period or not yet started + const begin = params.begin[0]; + const end = params.end[0]; + const beginDefined = begin >= 0; + const endDefined = end >= 0; + // We give a 0.5s grace period (for node pooling) before termination + const shouldTerminate = endDefined && currentTime >= end + 0.5; + const ended = endDefined && currentTime >= end; + const notStarted = currentTime <= begin; + if (shouldTerminate) { + return false; + } else if (ended || notStarted || !beginDefined) { return true; } const output = outputs[0]; @@ -1159,8 +1148,8 @@ const tablesCache = {}; class WavetableOscillatorProcessor extends AudioWorkletProcessor { static get parameterDescriptors() { return [ - { name: 'begin', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, - { name: 'end', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, + { name: 'begin', defaultValue: -1, min: -1, max: Number.POSITIVE_INFINITY }, + { name: 'end', defaultValue: -1, min: -1, max: Number.POSITIVE_INFINITY }, { name: 'frequency', defaultValue: 440, min: Number.EPSILON }, { name: 'detune', defaultValue: 0 }, { name: 'freqspread', defaultValue: 0.18, min: 0 }, @@ -1175,20 +1164,11 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { constructor(options) { super(options); - this.isAlive = true; // used internally to prevent multiple death messages - // diedACK is used for the main thread to acknowledge that the worklet has died - // This is so that we don't risk simultaneously killing the worklet (`return false`) - // and pooling the worklet (main thread) before the async `died` message hits - // the main thread - this.diedACK = false; this.port.onmessage = (e) => { const { type, payload } = e.data || {}; if (type === 'initialize') { this.initialize(payload); } - if (type === 'diedACK') { - this.diedACK = true; - } }; this.initialize(); } @@ -1351,19 +1331,17 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } process(_inputs, outputs, parameters) { - if (currentTime >= parameters.end[0] + 0.5) { - // Outside of grace period - should terminate - if (this.isAlive) { - this.port.postMessage({ type: 'died' }); - this.isAlive = false; - } - if (this.diedACK || currentTime >= parameters.end[1] + 1) { - return false; - } - return true; - } - if (currentTime >= parameters.end[0] || currentTime <= parameters.begin[0]) { - // Inside of grace period or not yet started + const begin = parameters.begin[0]; + const end = parameters.end[0]; + const beginDefined = begin >= 0; + const endDefined = end >= 0; + // We give a 0.5s grace period (for node pooling) before termination + const shouldTerminate = endDefined && currentTime >= end + 0.5; + const ended = endDefined && currentTime >= end; + const notStarted = currentTime <= begin; + if (shouldTerminate) { + return false; + } else if (ended || notStarted || !beginDefined) { return true; } const outL = outputs[0][0]; From 8b1fb12388aa523224f8e7a93e5bca0e3368fbd0 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 13 Jan 2026 03:32:19 +0100 Subject: [PATCH 68/79] fix: class -> className --- website/src/repl/components/panel/PatternsTab.jsx | 2 +- website/src/repl/components/panel/Reference.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 56f0b4cb8..04f6452e5 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -126,7 +126,7 @@ export function PatternsTab({ context }) { return (
-
+
diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 505cf50d2..c03ac0cf9 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -55,7 +55,7 @@ export function Reference() { return (
-
+
From e82bb6c4100e58b4a9f99e617745a74d1fb74b1c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 13 Jan 2026 03:38:09 +0100 Subject: [PATCH 69/79] fix: use pattern.id as title fallback --- website/src/repl/components/panel/PatternsTab.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 04f6452e5..75c019438 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -29,7 +29,7 @@ export function PatternLabel({ pattern } /* : { pattern: Tables<'code'> } */) { if (!isNaN(date)) { title = date.toLocaleDateString(); } else { - title = 'unnamed'; + title = pattern.id || 'unnamed'; } } From e5ab6b3c93b35973e46607c45bb071b323177bbf Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 13 Jan 2026 03:47:33 +0100 Subject: [PATCH 70/79] fix: short circuit --- website/src/repl/components/panel/PatternsTab.jsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 75c019438..c72ebaa30 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -89,12 +89,11 @@ export function PatternsTab({ context }) { const viewingPatternID = viewingPatternData?.id; const visiblePatterns = useMemo(() => { + if (!search) { + return userPatterns; + } return Object.fromEntries( Object.entries(userPatterns).filter(([_key, pattern]) => { - if (!search) { - return true; - } - const meta = getMetadata(pattern.code); // Search for specific meta keys From 80875cca956024e017281108fcd2fee673e6f1f3 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 14 Jan 2026 11:44:48 -0600 Subject: [PATCH 71/79] Expose scheduler state and don't enqueue/trigger midi keys when repl stopped --- packages/core/repl.mjs | 9 ++++++++- packages/core/schedulerState.mjs | 9 +++++++++ packages/midi/midi.mjs | 8 ++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index e39b57de3..a056cac53 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -2,7 +2,13 @@ import { NeoCyclist } from './neocyclist.mjs'; import { Cyclist } from './cyclist.mjs'; import { evaluate as _evaluate } from './evaluate.mjs'; import { errorLogger, logger } from './logger.mjs'; -import { setCpsFunc, setPattern as exposeSchedulerPattern, setTime, setTriggerFunc } from './schedulerState.mjs'; +import { + setCpsFunc, + setIsStarted, + setPattern as exposeSchedulerPattern, + setTime, + setTriggerFunc, +} from './schedulerState.mjs'; import { evalScope } from './evaluate.mjs'; import { register, Pattern, isPattern, silence, stack } from './pattern.mjs'; import { reset_state } from './impure.mjs'; @@ -52,6 +58,7 @@ export function repl({ getTime, onToggle: (started) => { updateState({ started }); + setIsStarted(started); onToggle?.(started); if (!started) { reset_state(); diff --git a/packages/core/schedulerState.mjs b/packages/core/schedulerState.mjs index 97a4f56dc..14b4c9054 100644 --- a/packages/core/schedulerState.mjs +++ b/packages/core/schedulerState.mjs @@ -8,6 +8,7 @@ let time; let cpsFunc; let pattern; let triggerFunc; +let isStarted; export function getTime() { if (!time) { throw new Error('no time set! use setTime to define a time source'); @@ -42,3 +43,11 @@ export function setTriggerFunc(func) { export function getTriggerFunc() { return triggerFunc; } + +export function setIsStarted(val) { + isStarted = !!val; +} + +export function getIsStarted() { + return isStarted; +} diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index 50a58b059..d0a1ce18d 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -10,6 +10,7 @@ import { Pattern, TimeSpan, getCps, + getIsStarted, getPattern, getTime, getTriggerFunc, @@ -625,8 +626,11 @@ export async function midikeys(input) { const { dataBytes, message } = e; const noteon = message.command === 9; let noteoff = message.command === 8; - if (!noteon && !noteoff) { - // Ignore non-note messages (e.g. CC, pitchbend, modwheel, etc.) + // Don't enqueue or trigger midi notes if scheduler is not started + const notStarted = !getIsStarted(); + // Ignore non-note messages (e.g. CC, pitchbend, modwheel, etc.) + const notANote = !noteon && !noteoff; + if (notStarted || notANote) { return; } const [note, velocity] = dataBytes; From ffcab7bf6c774b452b99709f035f9f2b7116599c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Bj=C3=B6rk?= Date: Wed, 14 Jan 2026 22:25:27 +0100 Subject: [PATCH 72/79] Added docs for pattern search --- website/src/pages/learn/metadata.mdx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/website/src/pages/learn/metadata.mdx b/website/src/pages/learn/metadata.mdx index c94257925..35a1ad05c 100644 --- a/website/src/pages/learn/metadata.mdx +++ b/website/src/pages/learn/metadata.mdx @@ -53,6 +53,7 @@ Available tags are: - `@url`: web page(s) related to the music (git repository, Soundcloud link, etc.) - `@genre`: music genre(s) (pop, jazz, etc.) - `@album`: music album name +- `@tag`: custom tag Note to tool authors: _Never_ trust that a song has filled those fields with syntactically correct values; make sure your software is robust enough it doesn't break if it encounters bad values @@ -92,3 +93,18 @@ If a tag doesn't accept a list, it can take multi-line values: the sofa in the living room. */ ``` + +# Searching meta-data in the online repl + +Meta-data can be used in the search field of the patterns tab in the online repl. + +For example to search for all patterns by a specific author use the search term +``` +by: Ada L +``` +or search for patterns with a specific genre like +``` +genre: unicorns +``` + +Hint: If no meta-data property is provided in the search all patterns with a `@title`, `@by` or `@tag` matching the search term will be shown. From 71dfbeea8828590a7cf061f5d9aa8648c35b96c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Bj=C3=B6rk?= Date: Wed, 14 Jan 2026 22:35:10 +0100 Subject: [PATCH 73/79] Fix markdown format --- website/src/pages/learn/metadata.mdx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/src/pages/learn/metadata.mdx b/website/src/pages/learn/metadata.mdx index 35a1ad05c..07a1357c1 100644 --- a/website/src/pages/learn/metadata.mdx +++ b/website/src/pages/learn/metadata.mdx @@ -99,10 +99,13 @@ If a tag doesn't accept a list, it can take multi-line values: Meta-data can be used in the search field of the patterns tab in the online repl. For example to search for all patterns by a specific author use the search term + ``` by: Ada L -``` +``` + or search for patterns with a specific genre like + ``` genre: unicorns ``` From 85e79d993263f84b1aa63f4efa9eb71b9cb93d42 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 14 Jan 2026 16:53:11 -0600 Subject: [PATCH 74/79] Set pooled values immediately instead of scheduling --- packages/superdough/helpers.mjs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 0ca085e3e..bb402ea78 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -154,9 +154,8 @@ export function getCompressor(ac, threshold, ratio, knee, attack, release) { attack: attack ?? 0.005, release: release ?? 0.05, }; - const now = ac.currentTime; Object.entries(options).forEach(([key, value]) => { - node[key].setValueAtTime(value, now); + node[key].value = value;; }); return node; } @@ -242,9 +241,8 @@ export function createFilter(context, start, end, params, cps, cycle) { const factory = () => context.createBiquadFilter(); filter = getNodeFromPool('filter', factory); filter.type = type; - const now = context.currentTime; Object.entries({ Q: q, frequency }).forEach(([key, value]) => { - filter[key].setValueAtTime(value, now); + filter[key].value = value; }); frequencyParam = filter.frequency; } From 21e6d81d349f475527d26509749385d70c5d0374 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 14 Jan 2026 16:58:45 -0600 Subject: [PATCH 75/79] Also set values immediately for supersaw and wavetable --- packages/superdough/helpers.mjs | 2 +- packages/superdough/synth.mjs | 3 +-- packages/superdough/wavetable.mjs | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index bb402ea78..584b19673 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -155,7 +155,7 @@ export function getCompressor(ac, threshold, ratio, knee, attack, release) { release: release ?? 0.05, }; Object.entries(options).forEach(([key, value]) => { - node[key].value = value;; + node[key].value = value; }); return node; } diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 9561ab363..38ad643de 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -178,11 +178,10 @@ export function registerSynthSounds() { }; const factory = () => new AudioWorkletNode(ac, 'supersaw-oscillator', { outputChannelCount: [2] }); const o = getNodeFromPool('supersaw', factory); - const now = ac.currentTime; Object.entries(params).forEach(([key, value]) => { const param = o.parameters.get(key); const target = value !== undefined ? value : param.defaultValue; - param.setValueAtTime(target, now); + param.value = target; }); o.port.postMessage({ type: 'initialize' }); const gainAdjustment = 1 / Math.sqrt(voices); diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 1de42f643..6ef1f0ebb 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -244,11 +244,10 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { }; const factory = () => new AudioWorkletNode(ac, 'wavetable-oscillator-processor', { outputChannelCount: [2] }); const source = getNodeFromPool('wavetable', factory); - const now = ac.currentTime; Object.entries(params).forEach(([key, value]) => { const param = source.parameters.get(key); const target = value !== undefined ? value : param.defaultValue; - param.setValueAtTime(target, now); + param.value = target; }); source.port.postMessage({ type: 'initialize', payload }); if (ac.currentTime > t) { From 60e5682829848dcc65a3073c9e0fb0eb46a08183 Mon Sep 17 00:00:00 2001 From: jeromew Date: Thu, 15 Jan 2026 15:42:34 +0000 Subject: [PATCH 76/79] Update kabelsalat dependency --- packages/core/package.json | 2 +- packages/superdough/package.json | 2 +- pnpm-lock.yaml | 36 ++++++++++++++++---------------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 64253b081..abb54e9ce 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,7 @@ }, "homepage": "https://strudel.cc", "dependencies": { - "@kabelsalat/web": "^0.4.0", + "@kabelsalat/web": "^0.4.1", "fraction.js": "^5.2.1" }, "gitHead": "0e26d4e741500f5bae35b023608f062a794905c2", diff --git a/packages/superdough/package.json b/packages/superdough/package.json index 2125b8d98..78db8338e 100644 --- a/packages/superdough/package.json +++ b/packages/superdough/package.json @@ -36,7 +36,7 @@ "vite-plugin-bundle-audioworklet": "workspace:*" }, "dependencies": { - "@kabelsalat/lib": "^0.4.0", + "@kabelsalat/lib": "^0.4.1", "nanostores": "^0.11.3" }, "engines": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2684ce3bb..53437f8f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,7 +41,7 @@ importers: version: 2.2.7 '@vitest/coverage-v8': specifier: 3.0.4 - version: 3.0.4(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0)) + version: 3.0.4(vitest@3.0.4) '@vitest/ui': specifier: ^3.0.4 version: 3.0.4(vitest@3.0.4) @@ -235,8 +235,8 @@ importers: packages/core: dependencies: '@kabelsalat/web': - specifier: ^0.4.0 - version: 0.4.0 + specifier: ^0.4.1 + version: 0.4.1 fraction.js: specifier: ^5.2.1 version: 5.2.1 @@ -522,8 +522,8 @@ importers: packages/superdough: dependencies: '@kabelsalat/lib': - specifier: ^0.4.0 - version: 0.4.0 + specifier: ^0.4.1 + version: 0.4.1 nanostores: specifier: ^0.11.3 version: 0.11.3 @@ -1975,14 +1975,14 @@ packages: resolution: {integrity: sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==} engines: {node: '>=v12.0.0'} - '@kabelsalat/core@0.3.1': - resolution: {integrity: sha512-y2wHZyKnwbhJdGuwXvkaIb5vqbNTW6rMDnBslHGxQHTFX5xYyxJLOcuF2/EOB698t09kOVhmmpLXKbyokf3pOA==} + '@kabelsalat/core@0.4.0': + resolution: {integrity: sha512-5zV8nh8HffW8aexObXs5pE0xgL0jb1cHc3o8UN6AvK0mBt87fjZvW65E4rMslHyq+OuCscoBJW7B3MbYfWrwMQ==} - '@kabelsalat/lib@0.4.0': - resolution: {integrity: sha512-UoOUhYOFShDjYCTne1edevCHHxSC07FsxG9tQ5GGOOzNoKMUpGVY8Ecq9X1GVyseQFvQBgz3aqAC6K8FPZp4ZQ==} + '@kabelsalat/lib@0.4.1': + resolution: {integrity: sha512-gBCjrZKD9huTKNJuBC6BXM4PMQSg8otL8A/vp8j98P9v6yWTX1TuyaqdLg/1PrIAMV4hlWoav9ZD3YMFlrvouw==} - '@kabelsalat/web@0.4.0': - resolution: {integrity: sha512-uvcOJjpKf8PG6KrgY0QEpoV4IAbIPDXh73bPtFSdDcXApbkSyEEyeNE8IoqIlqfcjIX926IOCAx9nM6FsFp6DA==} + '@kabelsalat/web@0.4.1': + resolution: {integrity: sha512-ASkFhePJLx3GjadYOueI7sHKXBbRPk/a1pfslFeQNI9gU7yZq/KrnkmOmLrgrtixAsy7gyi1vWqkmRRvH3Ki6w==} '@lerna/create@8.1.9': resolution: {integrity: sha512-DPnl5lPX4v49eVxEbJnAizrpMdMTBz1qykZrAbBul9rfgk531v8oAt+Pm6O/rpAleRombNM7FJb5rYGzBJatOQ==} @@ -9276,16 +9276,16 @@ snapshots: dependencies: lodash: 4.17.21 - '@kabelsalat/core@0.3.1': {} + '@kabelsalat/core@0.4.0': {} - '@kabelsalat/lib@0.4.0': + '@kabelsalat/lib@0.4.1': dependencies: - '@kabelsalat/core': 0.3.1 + '@kabelsalat/core': 0.4.0 - '@kabelsalat/web@0.4.0': + '@kabelsalat/web@0.4.1': dependencies: - '@kabelsalat/core': 0.3.1 - '@kabelsalat/lib': 0.4.0 + '@kabelsalat/core': 0.4.0 + '@kabelsalat/lib': 0.4.1 '@lerna/create@8.1.9(encoding@0.1.13)(typescript@5.7.3)': dependencies: @@ -10580,7 +10580,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@3.0.4(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0))': + '@vitest/coverage-v8@3.0.4(vitest@3.0.4)': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 From ae9638c3534635e48d9671ef018a297f8ffcd11c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 16 Jan 2026 09:58:14 +0100 Subject: [PATCH 77/79] update changelog + fix script to not miss entries --- CHANGELOG.md | 961 ++++++++++++++++++++++++++++++++++++++++++++++++++- warm.js | 40 ++- 2 files changed, 977 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19a502f33..3daf4e6cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,20 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly ## january 2026 + +- 2026-01-15T16:59:14+01:00 mondo fix: add registered functions to scope automatically by daslyfe in: [#1896](https://codeberg.org/uzu/strudel/pulls/1896) +- 2026-01-15T16:58:14+01:00 Added docs for pattern search by JohnBjrk in: [#1905](https://codeberg.org/uzu/strudel/pulls/1905) +- 2026-01-15T16:57:19+01:00 Update kabelsalat dependency by jeromew in: [#1911](https://codeberg.org/uzu/strudel/pulls/1911) +- 2026-01-15T00:24:39+01:00 Bug Fix: Set pooled values immediately instead of scheduling by glossing in: [#1907](https://codeberg.org/uzu/strudel/pulls/1907) +- 2026-01-14T20:29:16+01:00 Feat: Kabelsalat integration by glossing in: [#1876](https://codeberg.org/uzu/strudel/pulls/1876) +- 2026-01-14T19:07:49+01:00 Feat: MIDI Keyboard 🎹🐈 by glossing in: [#1828](https://codeberg.org/uzu/strudel/pulls/1828) +- 2026-01-14T18:14:52+01:00 Bug Fix: Fix race condition between worklet termination and port messages by glossing in: [#1897](https://codeberg.org/uzu/strudel/pulls/1897) +- 2026-01-13T04:06:52+01:00 Add search/filter in patterns tab by JohnBjrk in: [#1842](https://codeberg.org/uzu/strudel/pulls/1842) +- 2026-01-13T00:18:10+01:00 Add shortcut for navigating through labels! by daslyfe in: [#1807](https://codeberg.org/uzu/strudel/pulls/1807) +- 2026-01-12T00:17:37+01:00 add warm.strudel.cc to faq by yaxu in: [#1891](https://codeberg.org/uzu/strudel/pulls/1891) - 2026-01-11T19:00:25+01:00 Fix sounds example to work in the REPL by JesCoding in: [#1851](https://codeberg.org/uzu/strudel/pulls/1851) - 2026-01-11T13:52:02+01:00 Improve hint text when sound search has no results by floy in: [#1883](https://codeberg.org/uzu/strudel/pulls/1883) +- 2026-01-11T13:19:46+01:00 New page FAQ in "More" by scrappy_fiddler in: [#1753](https://codeberg.org/uzu/strudel/pulls/1753) - 2026-01-11T12:45:07+01:00 fix: remove faulty default readme by froos in: [#1889](https://codeberg.org/uzu/strudel/pulls/1889) - 2026-01-11T12:15:34+01:00 fix/self-hosted-config by alienmind in: [#1880](https://codeberg.org/uzu/strudel/pulls/1880) - 2026-01-11T12:07:48+01:00 Feat: Support External AudioContext Injection by 1d10t in: [#1833](https://codeberg.org/uzu/strudel/pulls/1833) @@ -14,8 +26,8 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly - 2026-01-11T11:05:44+01:00 fix: repl package init audio properly by froos in: [#1836](https://codeberg.org/uzu/strudel/pulls/1836) - 2026-01-11T06:51:24+01:00 Fix: show reload dialog when uploading prebake script by daslyfe in: [#1886](https://codeberg.org/uzu/strudel/pulls/1886) - 2026-01-11T06:01:42+01:00 fixes Serial onTrigger() params #1633 by gueejla in: [#1885](https://codeberg.org/uzu/strudel/pulls/1885) -- 2026-01-10T20:52:40+01:00 Allow top level distortions for the purpose of FX by glossing in: [#1884](https://codeberg.org/uzu/strudel/pulls/1884) - 2026-01-10T23:12:48+01:00 Perf: Targeted node pools by glossing in: [#1810](https://codeberg.org/uzu/strudel/pulls/1810) +- 2026-01-10T20:52:40+01:00 Allow top level distortions for the purpose of FX by glossing in: [#1884](https://codeberg.org/uzu/strudel/pulls/1884) - 2026-01-09T03:43:37+01:00 Bake in scaling by `freq` for FM with a gain node by glossing in: [#1878](https://codeberg.org/uzu/strudel/pulls/1878) - 2026-01-09T02:53:38+01:00 Bug fix: Properly handle subcontrols by glossing in: [#1877](https://codeberg.org/uzu/strudel/pulls/1877) - 2026-01-07T20:06:18+01:00 Feat: Add ability to turn mini parsing off with mini-off decorator by glossing in: [#1786](https://codeberg.org/uzu/strudel/pulls/1786) @@ -32,23 +44,32 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly ## december 2025 - 2025-12-29T21:59:11+01:00 Bugfix: Fix modulator clamping when min/max not specified by glossing in: [#1859](https://codeberg.org/uzu/strudel/pulls/1859) +- 2025-12-29T20:54:11+01:00 Feature: LFOs and Envelopes by glossing in: [#1507](https://codeberg.org/uzu/strudel/pulls/1507) - 2025-12-29T16:07:18+01:00 Fix AudioContext change detection. Use AudioNode.context by jeromew in: [#1858](https://codeberg.org/uzu/strudel/pulls/1858) -- 2025-12-28T14:20:03+01:00 dough repl fixes by froos in: [#1855](https://codeberg.org/uzu/strudel/pulls/1855) -- 2025-12-19T08:11:50+01:00 fix: visual block selection mode for vim bindings by Dsm0 in: [#1839](https://codeberg.org/uzu/strudel/pulls/1839) - 2025-12-28T22:58:38+01:00 Say that @license should use SPDX identifier by Wuzzy in: [#1817](https://codeberg.org/uzu/strudel/pulls/1817) - 2025-12-28T22:56:07+01:00 Expose Vim object in order to create custom keybindings by JohnBjrk in: [#1816](https://codeberg.org/uzu/strudel/pulls/1816) +- 2025-12-28T14:20:03+01:00 dough repl fixes by froos in: [#1855](https://codeberg.org/uzu/strudel/pulls/1855) +- 2025-12-28T13:40:29+01:00 add basic dough repl by froos in: [#1749](https://codeberg.org/uzu/strudel/pulls/1749) - 2025-12-20T22:27:52+01:00 Document "-" in mini-notation by Wuzzy in: [#1818](https://codeberg.org/uzu/strudel/pulls/1818) - 2025-12-20T22:20:27+01:00 simplify envValAtTime and remove asymmetric behavior (fix #1653) by pulu in: [#1815](https://codeberg.org/uzu/strudel/pulls/1815) +- 2025-12-19T08:11:50+01:00 fix: visual block selection mode for vim bindings by Dsm0 in: [#1839](https://codeberg.org/uzu/strudel/pulls/1839) +- 2025-12-19T01:03:53+01:00 [perf] Add audiograph `await debugAudiograph()` feature by jeromew in: [#1763](https://codeberg.org/uzu/strudel/pulls/1763) +- 2025-12-19T00:45:41+01:00 Feature: non-realtime exporting by Ghost in: [#1674](https://codeberg.org/uzu/strudel/pulls/1674) +- 2025-12-14T19:33:37+01:00 Fix: wrong warning in build environments by jeromew in: [#1835](https://codeberg.org/uzu/strudel/pulls/1835) - 2025-12-14T15:09:12+01:00 delta -> per / perx / cyclesPer refinements by yaxu in: [#1832](https://codeberg.org/uzu/strudel/pulls/1832) -- 2025-12-14T19:33:37+01:00 Fix: wrong warning in build environments by jeromew in: [#1835](https://codeberg.org/uzu/strudel/pulls/1835) +- 2025-12-14T01:07:36+01:00 Improved randomness by glossing in: [#1505](https://codeberg.org/uzu/strudel/pulls/1505) - 2025-12-12T10:28:27+01:00 Add delta signal for representing the duration of events in patterns that are combined with it by yaxu in: [#1831](https://codeberg.org/uzu/strudel/pulls/1831) +- 2025-12-11T18:00:49+01:00 Feature: stateful timeline function for jumping between timelines by yaxu in: [#1669](https://codeberg.org/uzu/strudel/pulls/1669) - 2025-12-11T16:37:58+01:00 Updates relating to LLM, github, etc by yaxu in: [#1830](https://codeberg.org/uzu/strudel/pulls/1830) - 2025-12-10T15:32:44+01:00 fix .as so it doesn't set undefined values by yaxu in: [#1827](https://codeberg.org/uzu/strudel/pulls/1827) - 2025-12-08T19:27:31+01:00 [perf] propagate `onceEnded` and `releaseAudioNode` by jeromew in: [#1809](https://codeberg.org/uzu/strudel/pulls/1809) +- 2025-12-07T21:51:40+01:00 Feat: Add channel support to midi in by glossing in: [#1775](https://codeberg.org/uzu/strudel/pulls/1775) +- 2025-12-07T21:23:43+01:00 Feat: Transient shaper by glossing in: [#1777](https://codeberg.org/uzu/strudel/pulls/1777) - 2025-12-07T19:15:43+01:00 Add vel as a synonym for velocity & update a few docstrings by glossing in: [#1781](https://codeberg.org/uzu/strudel/pulls/1781) - 2025-12-07T18:53:04+01:00 [perf] fix phaser leak of unused biquads by jeromew in: [#1800](https://codeberg.org/uzu/strudel/pulls/1800) - 2025-12-07T18:42:50+01:00 Bug fix: Remove failing tests due to shabda removal by glossing in: [#1820](https://codeberg.org/uzu/strudel/pulls/1820) -- 2025-12-03T17:35:05+01:00 [perf] release unused AudioBufferSourceNode + releaseAudioNode by jeromew in: [#1805](https://codeberg.org/uzu/strudel/pulls/1805) +- 2025-12-03T18:27:28+01:00 Feature: Eight FMs by glossing in: [#1628](https://codeberg.org/uzu/strudel/pulls/1628) +- 2025-12-03T17:35:05+01:00 [perf] release unused AudioBufferSourceNode + releaseAudioNode by jeromew in: [#1805](https://codeberg.org/uzu/strudel/pulls/1805) - **2025-12-01 strudel.cc deployed** ## november 2025 @@ -57,6 +78,7 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly - 2025-11-28T23:26:20+01:00 add revv() for reversing whole patterns by yaxu in: [#1791](https://codeberg.org/uzu/strudel/pulls/1791) - 2025-11-28T20:19:16+01:00 [perf] Disconnect lfos for phaser and filters by glossing in: [#1787](https://codeberg.org/uzu/strudel/pulls/1787) - 2025-11-27T23:08:52+01:00 fix: return silence when no pattern is returned by froos in: [#1795](https://codeberg.org/uzu/strudel/pulls/1795) +- 2025-11-27T22:47:03+01:00 fix(tool/dbpatch): add missing package name by peterpf in: [#1765](https://codeberg.org/uzu/strudel/pulls/1765) - 2025-11-27T22:38:05+01:00 add CHANGELOG.md + basic script to generate by froos in: [#1794](https://codeberg.org/uzu/strudel/pulls/1794) - 2025-11-27T22:03:53+01:00 [perf] in `noise`, let noiseMix do the disconnect when it exists by jeromew in: [#1783](https://codeberg.org/uzu/strudel/pulls/1783) - 2025-11-27T22:01:01+01:00 Bug Fix: Retries for sounds tab by glossing in: [#1754](https://codeberg.org/uzu/strudel/pulls/1754) @@ -73,6 +95,7 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly - 2025-11-23T09:47:24+01:00 Fix interoperability issue between `all` and `await initHydra()` by jeromew in: [#1663](https://codeberg.org/uzu/strudel/pulls/1663) - 2025-11-23T04:23:06+01:00 Bug fix: Swap l/r gains with temp variable by glossing in: [#1768](https://codeberg.org/uzu/strudel/pulls/1768) - 2025-11-23T00:52:28+01:00 FIX: prevent LFO filter modulation from popping from negative values by daslyfe in: [#1767](https://codeberg.org/uzu/strudel/pulls/1767) +- 2025-11-23T00:03:32+01:00 prefix "S" for solo by froos in: [#1481](https://codeberg.org/uzu/strudel/pulls/1481) - 2025-11-21T01:56:11+01:00 Bug Fix: Use frac due to negative frequencies from FM by glossing in: [#1759](https://codeberg.org/uzu/strudel/pulls/1759) - 2025-11-20T19:48:16+01:00 [perf] fix `connect-leak` added by #1742 when noise() is not used by jeromew in: [#1757](https://codeberg.org/uzu/strudel/pulls/1757) - 2025-11-20T14:51:00+01:00 [perf] fix `connect-leak` in `delay` effect by jeromew in: [#1755](https://codeberg.org/uzu/strudel/pulls/1755) @@ -80,6 +103,7 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly - 2025-11-18T23:52:45+01:00 wchooseCycles has now notes in an example by scrappy_fiddler in: [#1748](https://codeberg.org/uzu/strudel/pulls/1748) - 2025-11-17T05:31:54+01:00 Feature: Partials by glossing in: [#1659](https://codeberg.org/uzu/strudel/pulls/1659) - 2025-11-16T22:06:14+01:00 README: update superdough documentation by TristanMlct in: [#1741](https://codeberg.org/uzu/strudel/pulls/1741) +- 2025-11-16T22:00:43+01:00 Feature: Envelope worklet by glossing in: [#1524](https://codeberg.org/uzu/strudel/pulls/1524) - 2025-11-16T21:08:54+01:00 Worklet optimizations by glossing in: [#1730](https://codeberg.org/uzu/strudel/pulls/1730) - 2025-11-15T14:59:30+01:00 [perf] disconnect Offline AudioNode connections in generateReverb by jeromew in: [#1740](https://codeberg.org/uzu/strudel/pulls/1740) - 2025-11-15T14:57:47+01:00 [perf] disconnect `send` effect AudioNode when `room` is used by jeromew in: [#1736](https://codeberg.org/uzu/strudel/pulls/1736) @@ -88,15 +112,15 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly - 2025-11-12T21:06:13+01:00 Fix web README sample code by Kissaki in: [#1725](https://codeberg.org/uzu/strudel/pulls/1725) - 2025-11-12T20:59:39+01:00 Fix typo: 'studel' -> 'strudel' by drhayes in: [#1726](https://codeberg.org/uzu/strudel/pulls/1726) - 2025-11-12T15:23:41+01:00 fix for node 24 support in tests - #1718 by ausav in: [#1719](https://codeberg.org/uzu/strudel/pulls/1719) -- 2025-11-11T09:00:49+01:00 soundAlias example fix by PepsiiMan in: [#1720](https://codeberg.org/uzu/strudel/pulls/1720) +- 2025-11-11T09:00:49+01:00 soundAlias example fix by PepsiiMan in: [#1720](https://codeberg.org/uzu/strudel/pulls/1720) - 2025-11-10T08:18:36+01:00 fix: Make Supradough package build by munshkr in: [#1711](https://codeberg.org/uzu/strudel/pulls/1711) - 2025-11-10T08:18:00+01:00 added docs for spaces in scale names by ondras in: [#1715](https://codeberg.org/uzu/strudel/pulls/1715) -- 2025-11-10T02:44:01+01:00 Feature: LFOs for Filters by glossing in: [#1636](https://codeberg.org/uzu/strudel/pulls/1636) +- 2025-11-10T02:44:01+01:00 Feature: LFOs for Filters by glossing in: [#1636](https://codeberg.org/uzu/strudel/pulls/1636) - 2025-11-05T17:07:00+01:00 improvement: sync midi messages to audio context clock by daslyfe in: [#1708](https://codeberg.org/uzu/strudel/pulls/1708) - 2025-11-04T19:36:14+01:00 Add stick button mappings to gamepad implementation and improve docs by kaosuryoko in: [#1696](https://codeberg.org/uzu/strudel/pulls/1696) - 2025-11-04T19:29:35+01:00 Refactor sound stopping and triggering logic in SoundsTab component by IJOL in: [#1688](https://codeberg.org/uzu/strudel/pulls/1688) - 2025-11-04T19:13:21+01:00 Add setting to toggle pattern auto-start on pattern change by moumar in: [#1690](https://codeberg.org/uzu/strudel/pulls/1690) -- 2025-11-04T18:58:50+01:00 Voicings JSDoc by sharkeys_lunchbox in: [#1686](https://codeberg.org/uzu/strudel/pulls/1686) +- 2025-11-04T18:58:50+01:00 Voicings JSDoc by sharkeys_lunchbox in: [#1686](https://codeberg.org/uzu/strudel/pulls/1686) - 2025-11-01T07:50:40+01:00 FIX: Loading local samples uses too much memory by daslyfe in: [#1706](https://codeberg.org/uzu/strudel/pulls/1706) @@ -104,7 +128,7 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly - 2025-10-28T22:58:24+01:00 Bug Fix: Handle scale-for-notes when n also supplied by glossing in: [#1625](https://codeberg.org/uzu/strudel/pulls/1625) - 2025-10-28T22:51:16+01:00 Repurpose vim shortcuts for usability by dtricks in: [#1624](https://codeberg.org/uzu/strudel/pulls/1624) -- 2025-10-28T22:35:21+01:00 Add support for euclidian in mondo with `bd&3:8` by TristanCacqueray in: [#1630](https://codeberg.org/uzu/strudel/pulls/1630) +- 2025-10-28T22:35:21+01:00 Add support for euclidian in mondo with `bd&3:8` by TristanCacqueray in: [#1630](https://codeberg.org/uzu/strudel/pulls/1630) - 2025-10-27T10:42:07+01:00 Use bunny cdn for all samples and json files by yaxu in: [#1701](https://codeberg.org/uzu/strudel/pulls/1701) - **2025-10-27 @strudel/core@1.2.5** - 2025-10-26T22:52:54+01:00 degithub - switch some samples to bunnycdn by yaxu in: [#1697](https://codeberg.org/uzu/strudel/pulls/1697) @@ -114,30 +138,943 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly - 2025-10-22T22:15:19+02:00 Fix sampler.mjs githubPath by jeromew in: [#1684](https://codeberg.org/uzu/strudel/pulls/1684) - 2025-10-22T16:20:50+02:00 Fix onPaint for widgets by yaxu in: [#1658](https://codeberg.org/uzu/strudel/pulls/1658) - 2025-10-22T15:19:12+02:00 Fix a bug introduced by #4e17cfbdd6 by milliganf in: [#1679](https://codeberg.org/uzu/strudel/pulls/1679) +- 2025-10-20T22:37:15+02:00 feature/autocomplete-sound-names by drdozer in: [#1564](https://codeberg.org/uzu/strudel/pulls/1564) +- 2025-10-20T21:58:12+02:00 add replicate + use it for ! in mondo by JoStro in: [#1436](https://codeberg.org/uzu/strudel/pulls/1436) - 2025-10-18T04:29:20+02:00 Bug Fix: Wavetable: phase wrapping at 1 and detune by glossing in: [#1620](https://codeberg.org/uzu/strudel/pulls/1620) - 2025-10-16T20:26:28+02:00 github samples: default to "samples" if repository is not specified by prezmop in: [#1644](https://codeberg.org/uzu/strudel/pulls/1644) - 2025-10-16T17:33:39+02:00 Docs: add example of custom chained function by dariusk in: [#1642](https://codeberg.org/uzu/strudel/pulls/1642) - 2025-10-14T12:39:48+02:00 textbox by yaxu in: [#1650](https://codeberg.org/uzu/strudel/pulls/1650) +- 2025-10-13T07:26:51+02:00 Feature: Distortion Modes by glossing in: [#1561](https://codeberg.org/uzu/strudel/pulls/1561) - 2025-10-13T07:05:57+02:00 Feature: Wavetable FM by glossing in: [#1623](https://codeberg.org/uzu/strudel/pulls/1623) -- 2025-10-12T20:43:42+02:00 fix: repair REPL sample sources and URL concat (#1640) by erikfox in: [#1646](https://codeberg.org/uzu/strudel/pulls/1646) +- 2025-10-12T20:43:42+02:00 fix: repair REPL sample sources and URL concat (#1640) by erikfox in: [#1646](https://codeberg.org/uzu/strudel/pulls/1646) - 2025-10-10T11:25:02+02:00 Add control-metadata by yaxu in: [#1634](https://codeberg.org/uzu/strudel/pulls/1634) - 2025-10-07T22:59:39+02:00 Fix MQTT: change the trigger handler to match new hap by jurrchen in: [#1629](https://codeberg.org/uzu/strudel/pulls/1629) - 2025-10-05T21:42:19+02:00 Fix case sensitivity for synonym search by vvolhejn in: [#1618](https://codeberg.org/uzu/strudel/pulls/1618) - 2025-10-01T08:56:35+02:00 Optimize wavetable synth by glossing in: [#1613](https://codeberg.org/uzu/strudel/pulls/1613) - 2025-10-01T02:02:33+02:00 fix: pattern switching by daslyfe in: [#1616](https://codeberg.org/uzu/strudel/pulls/1616) -## September 2025 +## september 2025 - 2025-09-29T02:10:54+02:00 fix wavetable JSON by daslyfe in: [#1611](https://codeberg.org/uzu/strudel/pulls/1611) - 2025-09-28T21:28:16+02:00 rename wavetable controls to match existing naming conventions by daslyfe in: [#1610](https://codeberg.org/uzu/strudel/pulls/1610) - 2025-09-27T23:28:13+02:00 Feature: Wavetable synth improvements by glossing in: [#1607](https://codeberg.org/uzu/strudel/pulls/1607) - 2025-09-27T21:43:10+02:00 wavetable improvements by daslyfe in: [#1608](https://codeberg.org/uzu/strudel/pulls/1608) - 2025-09-26T08:48:46+02:00 create orbit based DJ filter by daslyfe in: [#1603](https://codeberg.org/uzu/strudel/pulls/1603) +- 2025-09-26T08:15:49+02:00 Feature: Wavetable synth by glossing in: [#1525](https://codeberg.org/uzu/strudel/pulls/1525) - 2025-09-23T13:28:20+02:00 fix: time signal by daslyfe in: [#1583](https://codeberg.org/uzu/strudel/pulls/1583) - 2025-09-21T16:16:06+02:00 mondo: fix all + setcpm + setcps by froos in: [#1600](https://codeberg.org/uzu/strudel/pulls/1600) - 2025-09-19T21:59:43+02:00 fix: osc error message by froos in: [#1597](https://codeberg.org/uzu/strudel/pulls/1597) - 2025-09-18T21:09:56+02:00 osc: --debug flag to see incoming messages by froos in: [#1595](https://codeberg.org/uzu/strudel/pulls/1595) - 2025-09-17T14:12:10+02:00 simplify osc usage by froos in: [#1588](https://codeberg.org/uzu/strudel/pulls/1588) - 2025-09-16T16:59:58+02:00 dev: logger errors to console in dev mode by daslyfe in: [#1585](https://codeberg.org/uzu/strudel/pulls/1585) +- 2025-09-16T03:19:37+02:00 Bug Fix / Feature: Updates to `duck` to avoid clicks and allow configuration over release/attack by glossing in: [#1514](https://codeberg.org/uzu/strudel/pulls/1514) +- 2025-09-15T23:36:31+02:00 Feat: Enhance `scale` function to quantize notes to a named scale by glossing in: [#1492](https://codeberg.org/uzu/strudel/pulls/1492) - 2025-09-15T22:52:14+02:00 add tic80 font by froos in: [#1579](https://codeberg.org/uzu/strudel/pulls/1579) -- 2025-09-15T00:00:19+02:00 supradough: fix delay + add some jsdoc types by froos in: [#1578](https://codeberg.org/uzu/strudel/pulls/1578) \ No newline at end of file +- 2025-09-15T00:00:19+02:00 supradough: fix delay + add some jsdoc types by froos in: [#1578](https://codeberg.org/uzu/strudel/pulls/1578) +- 2025-09-14T12:42:58+02:00 added plyWith/plyWithClassic functions by Dsm0 in: [#1571](https://codeberg.org/uzu/strudel/pulls/1571) +- 2025-09-14T10:39:12+02:00 feat: sound alias by Options in: [#1494](https://codeberg.org/uzu/strudel/pulls/1494) +- 2025-09-14T01:20:15+02:00 Bug Fix: Allow penv values to be falsy by glossing in: [#1559](https://codeberg.org/uzu/strudel/pulls/1559) +- 2025-09-14T01:10:48+02:00 Update website/src/pages/workshop/first-sounds.mdx by fesmith in: [#1566](https://codeberg.org/uzu/strudel/pulls/1566) +- 2025-09-14T01:07:47+02:00 fix: autocomplete-styles + html rendering by froos in: [#1570](https://codeberg.org/uzu/strudel/pulls/1570) +- 2025-09-14T00:49:17+02:00 Feature: Synonyms in autocomplete and reference by glossing in: [#1535](https://codeberg.org/uzu/strudel/pulls/1535) +- 2025-09-13T20:01:48+02:00 Docs: add xen package examples by dudymas in: [#1446](https://codeberg.org/uzu/strudel/pulls/1446) +- 2025-09-13T19:51:10+02:00 Update website/src/pages/learn/code.mdx by anecondev in: [#1391](https://codeberg.org/uzu/strudel/pulls/1391) +- 2025-09-11T22:52:30+02:00 supradough poc by froos in: [#1362](https://codeberg.org/uzu/strudel/pulls/1362) +- 2025-09-11T17:29:35+02:00 fix: exclude mondough dependencies by froos in: [#1563](https://codeberg.org/uzu/strudel/pulls/1563) +- 2025-09-11T00:27:21+02:00 add basicSetup for keybindings by Dsm0 in: [#1462](https://codeberg.org/uzu/strudel/pulls/1462) +- 2025-09-10T17:25:26+02:00 feat: add delete user samples button for convenience by daslyfe in: [#1556](https://codeberg.org/uzu/strudel/pulls/1556) +- 2025-09-08T08:54:01+02:00 Fix formatting of REPL footnote by ddbeck in: [#1547](https://codeberg.org/uzu/strudel/pulls/1547) +- 2025-09-08T05:38:08+02:00 fix: OSC by daslyfe in: [#1557](https://codeberg.org/uzu/strudel/pulls/1557) +- 2025-09-07T22:47:13+02:00 Add examples for ? and | operators to documentation by james-collapse in: [#1532](https://codeberg.org/uzu/strudel/pulls/1532) +- 2025-09-07T21:48:19+02:00 Signal flow documentation by glossing in: [#1504](https://codeberg.org/uzu/strudel/pulls/1504) +- 2025-09-07T21:27:29+02:00 Allow flattening of dirs with sample server by glossing in: [#1529](https://codeberg.org/uzu/strudel/pulls/1529) +- 2025-09-07T21:05:24+02:00 fix: prevent orbit clicking by defining max number of channels in an orbit by daslyfe in: [#1552](https://codeberg.org/uzu/strudel/pulls/1552) +- 2025-09-02T08:42:42+02:00 Padding for tooltips, preserving linebreaks in descriptions, not closing autocompletes on click by glossing in: [#1521](https://codeberg.org/uzu/strudel/pulls/1521) +- 2025-09-01T17:50:11+02:00 Update "restore defaults" to not delete patterns by glossing in: [#1519](https://codeberg.org/uzu/strudel/pulls/1519) + +## august 2025 + +- 2025-08-31T19:10:04+02:00 feat: add the ability to control the speed and start time of the reverb IR by daslyfe in: [#1501](https://codeberg.org/uzu/strudel/pulls/1501) +- 2025-08-25T02:31:22+02:00 Bug Fix: Duck on Mobile / Safari by glossing in: [#1503](https://codeberg.org/uzu/strudel/pulls/1503) +- 2025-08-23T18:39:53+02:00 fix benchmarks by yaxu in: [#1517](https://codeberg.org/uzu/strudel/pulls/1517) +- 2025-08-21T20:57:31+02:00 add --json flag to @strudel/sampler to generate a strudel.json by froos in: [#1513](https://codeberg.org/uzu/strudel/pulls/1513) +- 2025-08-21T10:04:28+02:00 remove hs2js postinstall by froos in: [#1510](https://codeberg.org/uzu/strudel/pulls/1510) +- 2025-08-20T15:15:34+02:00 doc: scrub, duckorbit, duckattack, duckdepth + fix: arp, arpWidth, hush by fyynn in: [#1502](https://codeberg.org/uzu/strudel/pulls/1502) +- 2025-08-20T12:31:37+02:00 fix: repl autocomplete not rendering correctly by robase in: [#1480](https://codeberg.org/uzu/strudel/pulls/1480) +- 2025-08-20T12:10:02+02:00 BUG FIX: make 'midin' initialization work with multiple controllers by cbabraham in: [#1469](https://codeberg.org/uzu/strudel/pulls/1469) +- 2025-08-17T23:18:46+02:00 euclidish by yaxu in: [#1482](https://codeberg.org/uzu/strudel/pulls/1482) +- 2025-08-17T06:37:23+02:00 feat: Create a duck (sidechain) orbit effect by daslyfe in: [#1470](https://codeberg.org/uzu/strudel/pulls/1470) +- 2025-08-17T04:40:15+02:00 Bug Fix: Restore `log` functionality after onTrigger arg removal by glossing in: [#1491](https://codeberg.org/uzu/strudel/pulls/1491) +- 2025-08-17T04:33:39+02:00 Bug Fix: Handle zero appearing first in FM's ADSR by glossing in: [#1496](https://codeberg.org/uzu/strudel/pulls/1496) +- 2025-08-17T04:27:19+02:00 Bug Fix: FM (and vibrato) for Supersaws by glossing in: [#1495](https://codeberg.org/uzu/strudel/pulls/1495) +- 2025-08-04T07:51:31+02:00 Fix incorrect stack Mini Notation by samyk in: [#1484](https://codeberg.org/uzu/strudel/pulls/1484) +- 2025-08-03T18:57:45+02:00 fix: regression caused by incorrectly exported alias for transpose and scaleTranspose by daslyfe in: [#1489](https://codeberg.org/uzu/strudel/pulls/1489) +- 2025-08-03T18:34:13+02:00 Add `strans` and `scaleTrans` as synonyms of `scaleTranspose` by TodePond in: [#1488](https://codeberg.org/uzu/strudel/pulls/1488) +- 2025-08-02T18:18:28+02:00 Add `trans` alias for `transpose` by TodePond in: [#1487](https://codeberg.org/uzu/strudel/pulls/1487) +- 2025-08-02T03:27:26+02:00 feat: Create Accurate 909 bass drum synthesizer by daslyfe in: [#1478](https://codeberg.org/uzu/strudel/pulls/1478) +- 2025-08-02T03:23:49+02:00 feat: Add fmwave control and ability to fm with noise by daslyfe in: [#1472](https://codeberg.org/uzu/strudel/pulls/1472) + +## july 2025 + +- 2025-07-30T00:22:41+02:00 hotfix: uzu kit JSON should be in the repo to avoid offline loading errors by daslyfe in: [#1485](https://codeberg.org/uzu/strudel/pulls/1485) +- 2025-07-24T05:28:23+02:00 feat: make uzu-drumkit the default drumkit by daslyfe in: [#1422](https://codeberg.org/uzu/strudel/pulls/1422) +- 2025-07-21T07:16:19+02:00 FIX: PWM modulation by daslyfe in: [#1467](https://codeberg.org/uzu/strudel/pulls/1467) +- 2025-07-19T17:16:22+02:00 Tremolo modulation by Ghost in: [#1095](https://codeberg.org/uzu/strudel/pulls/1095) +- 2025-07-15T09:39:33+02:00 fix: can now use def in mondough by froos in: [#1461](https://codeberg.org/uzu/strudel/pulls/1461) +- 2025-07-11T11:10:24+02:00 fixed keybinding presedence issue by Dsm0 in: [#1456](https://codeberg.org/uzu/strudel/pulls/1456) +- 2025-07-11T11:09:05+02:00 added multicursor support on ctrl/cmd + click by Dsm0 in: [#1457](https://codeberg.org/uzu/strudel/pulls/1457) +- 2025-07-09T09:39:46+02:00 added tab-indent setting by Dsm0 in: [#1454](https://codeberg.org/uzu/strudel/pulls/1454) +- 2025-07-08T15:48:41+02:00 ontrigger-refactoring by froos in: [#1442](https://codeberg.org/uzu/strudel/pulls/1442) +- 2025-07-07T23:14:24+02:00 fix: remove first gm_synth_bass_1, as it doesn't work in safari by froos in: [#1452](https://codeberg.org/uzu/strudel/pulls/1452) +- 2025-07-07T00:06:16+02:00 fix: minor doc changes by Aurel300 in: [#1435](https://codeberg.org/uzu/strudel/pulls/1435) +- 2025-07-05T12:53:45+02:00 Fix randrun and deps including shuffle. Fixes #1441 by yaxu in: [#1447](https://codeberg.org/uzu/strudel/pulls/1447) +- 2025-07-05T12:15:52+02:00 add setDefault + resetDefaults to superdough by froos in: [#1433](https://codeberg.org/uzu/strudel/pulls/1433) +- 2025-07-04T22:36:19+02:00 disable fm for supersaw by froos in: [#1443](https://codeberg.org/uzu/strudel/pulls/1443) + +## june 2025 + +- 2025-06-30T13:28:10+02:00 corrected minor spelling mistake (#1425) by tj-mueller in: [#1434](https://codeberg.org/uzu/strudel/pulls/1434) +- 2025-06-30T05:26:11+02:00 Add browser cache explanation in samples.mdx by Ghost in: [#1369](https://codeberg.org/uzu/strudel/pulls/1369) +- 2025-06-30T05:18:42+02:00 add-release-notes by froos in: [#1432](https://codeberg.org/uzu/strudel/pulls/1432) +- 2025-06-28T20:30:49+02:00 feat: delaytime in cycles by Ghost in: [#1341](https://codeberg.org/uzu/strudel/pulls/1341) +- 2025-06-28T13:44:49+02:00 Case insensitive search in the reference tab by kdiab in: [#1420](https://codeberg.org/uzu/strudel/pulls/1420) +- 2025-06-28T00:04:13+02:00 add unjoin, into and chunkinto by yaxu in: [#1418](https://codeberg.org/uzu/strudel/pulls/1418) +- 2025-06-26T15:29:46+02:00 mondo notation by froos in: [#1311](https://codeberg.org/uzu/strudel/pulls/1311) +- 2025-06-24T06:14:15+02:00 allow calling `all` multiple times by froos in: [#1417](https://codeberg.org/uzu/strudel/pulls/1417) +- 2025-06-24T05:53:22+02:00 tonal: allow scales without tonic (default to C) by Ghost in: [#1092](https://codeberg.org/uzu/strudel/pulls/1092) +- 2025-06-20T20:00:12+02:00 website intro: fix whitespace and code hosting name by trofi in: [#1400](https://codeberg.org/uzu/strudel/pulls/1400) +- 2025-06-19T10:15:07+02:00 fix stepcat #1396 by yaxu in: [#1398](https://codeberg.org/uzu/strudel/pulls/1398) +- 2025-06-19T09:52:38+02:00 deprecate cpm + refactor docs to use setcpm by froos in: [#1397](https://codeberg.org/uzu/strudel/pulls/1397) +- 2025-06-19T02:49:09+02:00 feat: 3 new codemirror themes by daslyfe in: [#1394](https://codeberg.org/uzu/strudel/pulls/1394) +- 2025-06-14T16:23:00+02:00 link back to tech manual in wiki by yaxu in: [#1382](https://codeberg.org/uzu/strudel/pulls/1382) +- 2025-06-14T14:55:37+02:00 degithub-links by froos in: [#1380](https://codeberg.org/uzu/strudel/pulls/1380) +- 2025-06-13T15:24:42+02:00 fix euclidLegatoRot by bwagner in: [#1378](https://codeberg.org/uzu/strudel/pulls/1378) +- 2025-06-13T10:07:51+02:00 remove-ms by yaxu in: [#1377](https://codeberg.org/uzu/strudel/pulls/1377) +- 2025-06-12T10:25:48+02:00 Share fat URL by Ghost in: [#1375](https://codeberg.org/uzu/strudel/pulls/1375) +- 2025-06-05T20:39:16+02:00 feat: onTriggerTime for interfacing with random APIs and doing illegal things on event time by Ghost in: [#1364](https://codeberg.org/uzu/strudel/pulls/1364) +- 2025-06-05T01:08:18+02:00 feat: berlin noise by Ghost in: [#1363](https://codeberg.org/uzu/strudel/pulls/1363) + +## may 2025 + +- 2025-05-29T14:36:43+02:00 Fix bytebeat sample offset by Ghost in: [#1359](https://codeberg.org/uzu/strudel/pulls/1359) +- 2025-05-29T12:14:18+02:00 preserve stepcount in chunks by yaxu in: [#1358](https://codeberg.org/uzu/strudel/pulls/1358) +- 2025-05-29T02:34:30+02:00 Byte Beat improvements -> 2 by Ghost in: [#1357](https://codeberg.org/uzu/strudel/pulls/1357) +- 2025-05-28T16:40:32+02:00 Bytebeat improvements by Ghost in: [#1356](https://codeberg.org/uzu/strudel/pulls/1356) +- 2025-05-27T17:42:39+02:00 feat: Byte Beats! by Ghost in: [#1354](https://codeberg.org/uzu/strudel/pulls/1354) +- 2025-05-18T21:43:05+02:00 fix: typo on docs causing problems with autocompletion. by Ghost in: [#1350](https://codeberg.org/uzu/strudel/pulls/1350) +- 2025-05-15T01:12:07+02:00 feat: Create pulsewidth (pw) and pulsewidth lfo parameters by Ghost in: [#1343](https://codeberg.org/uzu/strudel/pulls/1343) +- 2025-05-14T18:25:17+02:00 feat: Multi Channel Orbits by Ghost in: [#1344](https://codeberg.org/uzu/strudel/pulls/1344) +- 2025-05-13T17:45:29+02:00 Fix typo by Ghost in: [#1346](https://codeberg.org/uzu/strudel/pulls/1346) +- 2025-05-02T00:01:27+02:00 Fix web + repl package builds by froos in: [#1339](https://codeberg.org/uzu/strudel/pulls/1339) +- 2025-05-01T23:50:57+02:00 fix: superdough worklets bundling by froos in: [#1338](https://codeberg.org/uzu/strudel/pulls/1338) + +## april 2025 + +- 2025-04-27T22:25:54+02:00 FIX: sound import order by Ghost in: [#1333](https://codeberg.org/uzu/strudel/pulls/1333) +- 2025-04-27T18:39:49+02:00 update docs to reflect import sounds tab change by hpunq in: [#1332](https://codeberg.org/uzu/strudel/pulls/1332) +- 2025-04-27T18:38:26+02:00 feat: Improve gain curve by Ghost in: [#1318](https://codeberg.org/uzu/strudel/pulls/1318) +- 2025-04-27T07:54:49+02:00 Add Icon to import sample button by Ghost in: [#1331](https://codeberg.org/uzu/strudel/pulls/1331) +- 2025-04-27T07:53:41+02:00 Add new "import-sounds" tab with explanation on folder import by hpunq in: [#1329](https://codeberg.org/uzu/strudel/pulls/1329) +- 2025-04-22T00:04:38+02:00 feat: new themes + theme improvements by Ghost in: [#1326](https://codeberg.org/uzu/strudel/pulls/1326) +- 2025-04-20T18:24:15+02:00 feat: Create scrub function for scrubbing an audio file by Ghost in: [#1321](https://codeberg.org/uzu/strudel/pulls/1321) +- 2025-04-18T07:17:39+02:00 fix: disable astro toolbar by default by Ghost in: [#1324](https://codeberg.org/uzu/strudel/pulls/1324) +- 2025-04-18T07:17:38+02:00 fix: udels header by Ghost in: [#1325](https://codeberg.org/uzu/strudel/pulls/1325) +- 2025-04-11T09:18:58+02:00 Send delta in OSC message in seconds, to match tidal/superdirt by yaxu in: [#1323](https://codeberg.org/uzu/strudel/pulls/1323) +- 2025-04-08T06:08:57+02:00 FIX: Multichannel Audio by Ghost in: [#1322](https://codeberg.org/uzu/strudel/pulls/1322) +- 2025-04-08T04:18:03+02:00 feat: add max polyphony feature for superdough by Ghost in: [#1317](https://codeberg.org/uzu/strudel/pulls/1317) +- 2025-04-05T21:12:05+02:00 enhancement: make error messages easier to read by Ghost in: [#1315](https://codeberg.org/uzu/strudel/pulls/1315) +- 2025-04-04T06:26:57+02:00 fix: replace empty spaces in registered sound keys by Ghost in: [#1319](https://codeberg.org/uzu/strudel/pulls/1319) + +## march 2025 + +- 2025-03-26T17:01:05+01:00 small feat: Add alias for segment and ribbon by Ghost in: [#1314](https://codeberg.org/uzu/strudel/pulls/1314) +- 2025-03-26T14:54:18+01:00 Fix typo pattnr by Ghost in: [#1316](https://codeberg.org/uzu/strudel/pulls/1316) +- 2025-03-23T20:05:31+01:00 bugfix: Allow single param to be used in the as function by Ghost in: [#1312](https://codeberg.org/uzu/strudel/pulls/1312) +- 2025-03-20T23:35:18+01:00 Add MIDI Program Change, SysEx, NRPN, PitchBend and AfterTouch Output by nkymut in: [#1244](https://codeberg.org/uzu/strudel/pulls/1244) +- 2025-03-19T17:32:30+01:00 make soundfont base url configurable by Ghost in: [#1040](https://codeberg.org/uzu/strudel/pulls/1040) +- 2025-03-18T20:07:08+01:00 Add num samples from 0 up to 20 by yaxu in: [#1310](https://codeberg.org/uzu/strudel/pulls/1310) +- 2025-03-17T10:38:54+01:00 add num samples (edited numbers) by yaxu in: [#1309](https://codeberg.org/uzu/strudel/pulls/1309) +- 2025-03-08T22:17:47+01:00 @strudel/sampler improvements by froos in: [#1288](https://codeberg.org/uzu/strudel/pulls/1288) +- 2025-03-08T21:56:50+01:00 Add Gamepad module by nkymut in: [#1223](https://codeberg.org/uzu/strudel/pulls/1223) +- 2025-03-04T19:17:37+01:00 change behaviour of polymeter, and remove polymeterSteps by yaxu in: [#1302](https://codeberg.org/uzu/strudel/pulls/1302) +- 2025-03-04T03:36:57+01:00 feat: Create Pulse Oscillator with variable PWM by Ghost in: [#1304](https://codeberg.org/uzu/strudel/pulls/1304) +- 2025-03-02T17:08:31+01:00 feat: Theme improvements by Ghost in: [#1295](https://codeberg.org/uzu/strudel/pulls/1295) +- 2025-03-02T11:58:46+01:00 bugfix zoom stepcount by yaxu in: [#1301](https://codeberg.org/uzu/strudel/pulls/1301) + +## february 2025 + +- 2025-02-28T16:01:20+01:00 Fix test error #1297 by nkymut in: [#1298](https://codeberg.org/uzu/strudel/pulls/1298) +- 2025-02-28T02:53:42+01:00 Hotfix: prevent undefined pattern code from crashing strudel on load by Ghost in: [#1297](https://codeberg.org/uzu/strudel/pulls/1297) +- 2025-02-27T08:24:58+01:00 Fix misplaced ending sentence by Ghost in: [#1296](https://codeberg.org/uzu/strudel/pulls/1296) +- 2025-02-23T10:54:13+01:00 Signpost licenses for source code and samples a bit more, ref #1277 by yaxu in: [#1289](https://codeberg.org/uzu/strudel/pulls/1289) +- 2025-02-23T10:52:27+01:00 Allow wchooseCycles probabilities to be patterned by yaxu in: [#1292](https://codeberg.org/uzu/strudel/pulls/1292) +- 2025-02-22T02:18:59+01:00 Create Pattern Page Pagination by Ghost in: [#1287](https://codeberg.org/uzu/strudel/pulls/1287) +- 2025-02-21T22:38:10+01:00 showcase tweaks by yaxu in: [#1291](https://codeberg.org/uzu/strudel/pulls/1291) +- 2025-02-11T16:34:24+01:00 Fixes inverted triangle wave by renaming it to `itri`, making non-inverted `tri` by yaxu in: [#1283](https://codeberg.org/uzu/strudel/pulls/1283) +- 2025-02-11T10:02:34+01:00 Fix `squeezejoin` and functions using it, including `bite` by yaxu in: [#1286](https://codeberg.org/uzu/strudel/pulls/1286) +- 2025-02-09T16:18:28+01:00 Rename repeat back to extend by yaxu in: [#1285](https://codeberg.org/uzu/strudel/pulls/1285) +- 2025-02-07T18:11:52+01:00 mqtt bugfix - connection check by yaxu in: [#1282](https://codeberg.org/uzu/strudel/pulls/1282) +- 2025-02-07T17:38:29+01:00 Bugfix: update mqtt connections dictionary by yaxu in: [#1281](https://codeberg.org/uzu/strudel/pulls/1281) +- 2025-02-07T11:39:54+01:00 make mqtt topic patternable by yaxu in: [#1280](https://codeberg.org/uzu/strudel/pulls/1280) +- 2025-02-07T11:07:32+01:00 midimaps by froos in: [#1274](https://codeberg.org/uzu/strudel/pulls/1274) +- 2025-02-06T15:59:03+01:00 MQTT - support adding hap duration and cps metadata to JSON messages by yaxu in: [#1279](https://codeberg.org/uzu/strudel/pulls/1279) +- 2025-02-05T16:10:54+01:00 [breaking change] Sample signals from query onset, rather than midpoint by yaxu in: [#1278](https://codeberg.org/uzu/strudel/pulls/1278) +- 2025-02-03T00:55:36+01:00 Stepwise documentation tweaks, with mridangam samples by yaxu in: [#1275](https://codeberg.org/uzu/strudel/pulls/1275) +- 2025-02-02T21:26:44+01:00 Polish, rename, and document stepwise functions by yaxu in: [#1262](https://codeberg.org/uzu/strudel/pulls/1262) +- 2025-02-01T22:57:00+01:00 Fix sf2 timing by froos in: [#1272](https://codeberg.org/uzu/strudel/pulls/1272) +- 2025-02-01T22:32:59+01:00 Add bank aliasing and case insensitivity by TodePond in: [#1245](https://codeberg.org/uzu/strudel/pulls/1245) + +## january 2025 + +- 2025-01-31T09:39:54+01:00 Add Device Motion module by nkymut in: [#1217](https://codeberg.org/uzu/strudel/pulls/1217) +- 2025-01-29T15:40:01+01:00 add "as" function + getControlName by froos in: [#1247](https://codeberg.org/uzu/strudel/pulls/1247) +- 2025-01-29T15:30:04+01:00 Theme glowup by froos in: [#1268](https://codeberg.org/uzu/strudel/pulls/1268) +- 2025-01-29T15:22:18+01:00 patchday by froos in: [#1264](https://codeberg.org/uzu/strudel/pulls/1264) +- 2025-01-28T00:00:03+01:00 Revert "Fix sometimes" by yaxu in: [#1267](https://codeberg.org/uzu/strudel/pulls/1267) +- 2025-01-24T15:32:48+01:00 add reference package by froos in: [#1252](https://codeberg.org/uzu/strudel/pulls/1252) +- 2025-01-24T15:16:55+01:00 support `all(pianoroll)` and `all(pianoroll({labels: true}))` by yaxu in: [#1234](https://codeberg.org/uzu/strudel/pulls/1234) +- 2025-01-24T12:13:49+01:00 MQTT - if password isn't provided, prompt for one by yaxu in: [#1249](https://codeberg.org/uzu/strudel/pulls/1249) +- 2025-01-21T06:24:03+01:00 fix docs for beat function by Ghost in: [#1248](https://codeberg.org/uzu/strudel/pulls/1248) +- 2025-01-18T23:27:51+01:00 understand voicings page by froos in: [#1230](https://codeberg.org/uzu/strudel/pulls/1230) +- 2025-01-17T19:27:00+01:00 Add binary and binaryN by Ghost in: [#1226](https://codeberg.org/uzu/strudel/pulls/1226) +- 2025-01-16T12:18:33+01:00 Fix sometimes by yaxu in: [#1243](https://codeberg.org/uzu/strudel/pulls/1243) +- 2025-01-16T05:55:46+01:00 "beat" function for "step sequencer" style rhythm notation by Ghost in: [#1237](https://codeberg.org/uzu/strudel/pulls/1237) +- 2025-01-14T14:39:15+01:00 Add stepBind, and some toplevel aliases for binds and withValue by yaxu in: [#1241](https://codeberg.org/uzu/strudel/pulls/1241) +- 2025-01-14T06:11:10+01:00 Add onKey function for custom key commands for patterns by Ghost in: [#1235](https://codeberg.org/uzu/strudel/pulls/1235) +- 2025-01-12T11:32:24+01:00 Update documentation for param value modification by Ghost in: [#1238](https://codeberg.org/uzu/strudel/pulls/1238) + +## december 2024 + +- 2024-12-29T13:16:08+01:00 Documentation for all/each, and bugfix for each by yaxu in: [#1233](https://codeberg.org/uzu/strudel/pulls/1233) +- 2024-12-29T11:29:52+01:00 Make `all()` post-stack again, and add `each()` for pre-stack by yaxu in: [#1229](https://codeberg.org/uzu/strudel/pulls/1229) +- 2024-12-27T22:16:54+01:00 suggested changes to voicings.mdx by Ghost in: [#1231](https://codeberg.org/uzu/strudel/pulls/1231) +- 2024-12-23T11:53:11+01:00 add basic spectrum function by froos in: [#1213](https://codeberg.org/uzu/strudel/pulls/1213) +- 2024-12-22T21:04:45+01:00 Fix regression for d1, p1, p(n) by yaxu in: [#1227](https://codeberg.org/uzu/strudel/pulls/1227) + +## november 2024 + +- 2024-11-30T10:09:36+01:00 Make cps patternable by eefano in: [#1001](https://codeberg.org/uzu/strudel/pulls/1001) +- 2024-11-30T10:07:56+01:00 MQTT support by yaxu in: [#1224](https://codeberg.org/uzu/strudel/pulls/1224) +- 2024-11-30T09:46:14+01:00 Apply `all` function to individual patterns rather than final stack by yaxu in: [#1209](https://codeberg.org/uzu/strudel/pulls/1209) +- 2024-11-20T16:32:51+01:00 REPL: solo and sync configuration by Ghost in: [#1214](https://codeberg.org/uzu/strudel/pulls/1214) + +## october 2024 + +- 2024-10-30T21:29:43+01:00 Add s_zip for 'cat'-ing patterns together step-by-step, bugfix `steps` by yaxu in: [#1208](https://codeberg.org/uzu/strudel/pulls/1208) +- 2024-10-30T21:28:32+01:00 Preserve tactus for 'degrade' and friends, and tidy up 'pick' and friends by yaxu in: [#1205](https://codeberg.org/uzu/strudel/pulls/1205) +- 2024-10-30T17:11:53+01:00 chore: Edit run locally instructions in README.md by Ghost in: [#1206](https://codeberg.org/uzu/strudel/pulls/1206) +- 2024-10-23T23:08:14+02:00 colorize console + tweak header by froos in: [#1203](https://codeberg.org/uzu/strudel/pulls/1203) +- 2024-10-22T22:55:00+02:00 markcss by froos in: [#1202](https://codeberg.org/uzu/strudel/pulls/1202) +- 2024-10-21T22:56:37+02:00 add 2 new ui settings by froos in: [#1200](https://codeberg.org/uzu/strudel/pulls/1200) +- 2024-10-21T20:22:52+02:00 Make panel hover behavior optional by Ghost in: [#1199](https://codeberg.org/uzu/strudel/pulls/1199) +- 2024-10-19T04:28:36+02:00 Menu Panel Improvements! by Ghost in: [#1193](https://codeberg.org/uzu/strudel/pulls/1193) +- 2024-10-19T01:10:06+02:00 update lockfile + minor versions by froos in: [#1198](https://codeberg.org/uzu/strudel/pulls/1198) + +## september 2024 + +- 2024-09-27T00:17:00+02:00 remove redundant example for cat, update snapshot by Ghost in: [#1189](https://codeberg.org/uzu/strudel/pulls/1189) +- 2024-09-25T13:18:19+02:00 Adding search bar (soundtab.jsx) by Ghost in: [#1185](https://codeberg.org/uzu/strudel/pulls/1185) +- 2024-09-23T17:18:34+02:00 Screenreader improvements by yaxu in: [#1158](https://codeberg.org/uzu/strudel/pulls/1158) +- 2024-09-20T22:26:41+02:00 Fix serial timing by yaxu in: [#1188](https://codeberg.org/uzu/strudel/pulls/1188) +- 2024-09-20T00:26:30+02:00 Add bite function by yaxu in: [#1187](https://codeberg.org/uzu/strudel/pulls/1187) +- 2024-09-14T13:30:53+02:00 better spacing in zen mode by froos in: [#1147](https://codeberg.org/uzu/strudel/pulls/1147) +- 2024-09-14T10:50:24+02:00 add filter + filterWhen + within by froos in: [#1039](https://codeberg.org/uzu/strudel/pulls/1039) +- 2024-09-14T10:49:21+02:00 refactor sampler by froos in: [#1101](https://codeberg.org/uzu/strudel/pulls/1101) +- 2024-09-14T10:43:17+02:00 handle midin device not found error by froos in: [#1146](https://codeberg.org/uzu/strudel/pulls/1146) +- 2024-09-13T21:59:23+02:00 Add a search bar to the REPL Reference tab by Ghost in: [#1165](https://codeberg.org/uzu/strudel/pulls/1165) +- 2024-09-13T21:58:47+02:00 Correct spelling mistakes by Ghost in: [#1183](https://codeberg.org/uzu/strudel/pulls/1183) +- 2024-09-07T23:41:29+02:00 Add seqPLoop from Tidal by yaxu in: [#1182](https://codeberg.org/uzu/strudel/pulls/1182) +- 2024-09-05T05:52:50+02:00 make phaser control match superdirt by Ghost in: [#1180](https://codeberg.org/uzu/strudel/pulls/1180) +- 2024-09-05T05:33:41+02:00 Revert "Make phaser control consistent with superdirt" by Ghost in: [#1179](https://codeberg.org/uzu/strudel/pulls/1179) +- 2024-09-05T05:29:12+02:00 Make phaser control consistent with superdirt by Ghost in: [#1178](https://codeberg.org/uzu/strudel/pulls/1178) +- 2024-09-03T04:37:15+02:00 fix sample speed when using splice and fit with superdirt by Ghost in: [#1172](https://codeberg.org/uzu/strudel/pulls/1172) +- 2024-09-01T16:02:24+02:00 Create audio target selector for OSC/Superdirt by Ghost in: [#1160](https://codeberg.org/uzu/strudel/pulls/1160) +- 2024-09-01T15:03:47+02:00 Fixes fit so it works after a chop or slice by yaxu in: [#1171](https://codeberg.org/uzu/strudel/pulls/1171) + +## august 2024 + +- 2024-08-30T14:24:08+02:00 polyJoin by yaxu in: [#1168](https://codeberg.org/uzu/strudel/pulls/1168) +- 2024-08-23T17:05:10+02:00 Add scramble and shuffle by yaxu in: [#1167](https://codeberg.org/uzu/strudel/pulls/1167) +- 2024-08-18T18:22:20+02:00 Improve + simplify neocyclist timing by Ghost in: [#1164](https://codeberg.org/uzu/strudel/pulls/1164) +- 2024-08-15T05:18:33+02:00 containerize/seperate out boolean checks for repl types/Repl logic into bespoke components. by Ghost in: [#1163](https://codeberg.org/uzu/strudel/pulls/1163) +- 2024-08-12T18:57:21+02:00 [CORS HOTFIX] by Ghost in: [#1162](https://codeberg.org/uzu/strudel/pulls/1162) +- 2024-08-09T05:11:28+02:00 Fix OSC clock jitter by Ghost in: [#1157](https://codeberg.org/uzu/strudel/pulls/1157) + +## july 2024 + +- 2024-07-27T11:02:38+02:00 Fix loopAt tactus by yaxu in: [#1145](https://codeberg.org/uzu/strudel/pulls/1145) +- 2024-07-26T04:37:34+02:00 "stretch" function (phase vocoder) by Ghost in: [#1130](https://codeberg.org/uzu/strudel/pulls/1130) +- 2024-07-26T04:37:17+02:00 Udels (MultiFrame Strudel) Revisited by Ghost in: [#1132](https://codeberg.org/uzu/strudel/pulls/1132) +- 2024-07-24T11:40:28+02:00 Fix tactus marking in mininotation by yaxu in: [#1144](https://codeberg.org/uzu/strudel/pulls/1144) + +## june 2024 + +- 2024-06-25T18:13:28+02:00 export comment commands by froos in: [#1136](https://codeberg.org/uzu/strudel/pulls/1136) +- 2024-06-24T18:19:22+02:00 Chop chop by yaxu in: [#1078](https://codeberg.org/uzu/strudel/pulls/1078) +- 2024-06-18T23:58:08+02:00 Fix bug in Fraction.lcm by yaxu in: [#1133](https://codeberg.org/uzu/strudel/pulls/1133) +- 2024-06-18T05:32:12+02:00 Fix clock worker dependency path in module builds by Ghost in: [#1129](https://codeberg.org/uzu/strudel/pulls/1129) +- 2024-06-04T00:26:48+02:00 Labeled statements doc by froos in: [#1126](https://codeberg.org/uzu/strudel/pulls/1126) +- 2024-06-03T22:40:21+02:00 doc: visual functions + refactor onPaint by froos in: [#1125](https://codeberg.org/uzu/strudel/pulls/1125) +- 2024-06-02T18:36:29+02:00 Fix indexDB failing with large amount of files by Ghost in: [#1124](https://codeberg.org/uzu/strudel/pulls/1124) + +## may 2024 + +- 2024-05-31T12:17:34+02:00 Migrate tutorial fanchor by froos in: [#1122](https://codeberg.org/uzu/strudel/pulls/1122) +- 2024-05-31T10:46:47+02:00 [BUG FIX] Audio worklets sometimes dont load by Ghost in: [#1121](https://codeberg.org/uzu/strudel/pulls/1121) +- 2024-05-31T10:25:24+02:00 change fanchor to 0 by Ghost in: [#1107](https://codeberg.org/uzu/strudel/pulls/1107) +- 2024-05-30T14:39:30+02:00 fix: use full repl in web package by froos in: [#1119](https://codeberg.org/uzu/strudel/pulls/1119) +- 2024-05-30T09:36:32+02:00 can now access strudelMirror from repl by froos in: [#1117](https://codeberg.org/uzu/strudel/pulls/1117) +- 2024-05-29T13:06:34+02:00 Add the mousex and mousey signal by Ghost in: [#1112](https://codeberg.org/uzu/strudel/pulls/1112) +- 2024-05-29T13:02:00+02:00 Fixes drawPianoroll import in codemirror example by Ghost in: [#1116](https://codeberg.org/uzu/strudel/pulls/1116) +- 2024-05-28T22:43:46+02:00 clarify `off` in pattern-effects.mdx by Ghost in: [#1074](https://codeberg.org/uzu/strudel/pulls/1074) +- 2024-05-26T17:33:07+02:00 rollback phaser by Ghost in: [#1113](https://codeberg.org/uzu/strudel/pulls/1113) +- 2024-05-26T17:33:06+02:00 Fix audio worklets by Ghost in: [#1114](https://codeberg.org/uzu/strudel/pulls/1114) +- 2024-05-26T16:53:56+02:00 Calculate phaser modulation phase based on time by Ghost in: [#1110](https://codeberg.org/uzu/strudel/pulls/1110) +- 2024-05-23T15:06:01+02:00 Add analog-style ladder filter by Ghost in: [#1103](https://codeberg.org/uzu/strudel/pulls/1103) +- 2024-05-22T12:53:20+02:00 fix sampler on windows by Ghost in: [#1109](https://codeberg.org/uzu/strudel/pulls/1109) +- 2024-05-20T23:26:20+02:00 web package fixes by froos in: [#1044](https://codeberg.org/uzu/strudel/pulls/1044) +- 2024-05-20T22:41:28+02:00 Fix sampler windows by froos in: [#1108](https://codeberg.org/uzu/strudel/pulls/1108) +- 2024-05-19T12:07:26+02:00 hs2js package / tidal parser by froos in: [#870](https://codeberg.org/uzu/strudel/pulls/870) +- 2024-05-18T10:49:08+02:00 fix little dub tune example by Ghost in: [#1104](https://codeberg.org/uzu/strudel/pulls/1104) +- 2024-05-17T14:43:58+02:00 Samples tab improvements by Ghost in: [#1102](https://codeberg.org/uzu/strudel/pulls/1102) +- 2024-05-13T10:10:34+02:00 osc: couple of fixes by Ghost in: [#1093](https://codeberg.org/uzu/strudel/pulls/1093) +- 2024-05-13T06:31:20+02:00 Use sessionStorage for viewingPatternData and activePattern by Ghost in: [#1091](https://codeberg.org/uzu/strudel/pulls/1091) +- 2024-05-12T18:23:09+02:00 repl: set document.title from @title by Ghost in: [#1090](https://codeberg.org/uzu/strudel/pulls/1090) +- 2024-05-07T14:29:22+02:00 fix: missing events due to premature worklet cleanup by froos in: [#1089](https://codeberg.org/uzu/strudel/pulls/1089) +- 2024-05-03T11:52:57+02:00 Benchmarks by yaxu in: [#1079](https://codeberg.org/uzu/strudel/pulls/1079) +- 2024-05-03T08:46:52+02:00 fix: csound + dough timing by froos in: [#1086](https://codeberg.org/uzu/strudel/pulls/1086) +- 2024-05-03T00:37:32+02:00 Improve performance of ! (replicate) by yaxu in: [#1084](https://codeberg.org/uzu/strudel/pulls/1084) +- 2024-05-02T23:40:22+02:00 fix: url parsing with extra params by froos in: [#1083](https://codeberg.org/uzu/strudel/pulls/1083) + +## april 2024 + +- 2024-04-29T12:36:11+02:00 Tactus calculation toggle and breaking change to tactus calculation in fast/slow/hurry by yaxu in: [#1081](https://codeberg.org/uzu/strudel/pulls/1081) +- 2024-04-28T20:56:21+02:00 fix docs on alignment.mdx by Ghost in: [#1076](https://codeberg.org/uzu/strudel/pulls/1076) +- 2024-04-28T20:49:18+02:00 add signals to recap in first-effects.mdx by Ghost in: [#1073](https://codeberg.org/uzu/strudel/pulls/1073) +- 2024-04-28T20:44:57+02:00 fix translation issue in first-effects.mdx by Ghost in: [#1072](https://codeberg.org/uzu/strudel/pulls/1072) +- 2024-04-28T20:44:29+02:00 fix failing format test by Ghost in: [#1077](https://codeberg.org/uzu/strudel/pulls/1077) +- 2024-04-27T22:50:17+02:00 add nesting to `off` example variation in pattern-effects.mdx by Ghost in: [#1075](https://codeberg.org/uzu/strudel/pulls/1075) +- 2024-04-27T22:48:58+02:00 add `<...>` to first-sounds.mdx recap by Ghost in: [#1070](https://codeberg.org/uzu/strudel/pulls/1070) +- 2024-04-27T22:48:07+02:00 fix first sounds typo by Ghost in: [#1069](https://codeberg.org/uzu/strudel/pulls/1069) +- 2024-04-27T22:47:44+02:00 fix cr typo on first-sounds.mdx by Ghost in: [#1068](https://codeberg.org/uzu/strudel/pulls/1068) +- 2024-04-26T15:12:30+02:00 More tactus tidying by yaxu in: [#1071](https://codeberg.org/uzu/strudel/pulls/1071) +- 2024-04-23T23:37:21+02:00 Fix stepjoin by yaxu in: [#1067](https://codeberg.org/uzu/strudel/pulls/1067) +- 2024-04-23T23:32:00+02:00 clarify license by yaxu in: [#1064](https://codeberg.org/uzu/strudel/pulls/1064) +- 2024-04-23T15:14:30+02:00 Tactus tweaks - fixes for maintaining tactus and highlight locations by yaxu in: [#1065](https://codeberg.org/uzu/strudel/pulls/1065) +- 2024-04-21T23:57:57+02:00 fix OSC timing for recent scheduler updates by Ghost in: [#1062](https://codeberg.org/uzu/strudel/pulls/1062) +- 2024-04-21T22:17:07+02:00 Stepwise functions from Tidal by yaxu in: [#1060](https://codeberg.org/uzu/strudel/pulls/1060) +- 2024-04-21T11:03:55+02:00 Fix wchooseCycles not picking the whole pattern by Ghost in: [#1061](https://codeberg.org/uzu/strudel/pulls/1061) +- 2024-04-19T00:05:52+02:00 add swing + swingBy by froos in: [#1038](https://codeberg.org/uzu/strudel/pulls/1038) +- 2024-04-19T00:05:08+02:00 anonymous patterns + muting by froos in: [#1059](https://codeberg.org/uzu/strudel/pulls/1059) +- 2024-04-12T12:34:27+02:00 improve tutorial + custom samples doc by froos in: [#1053](https://codeberg.org/uzu/strudel/pulls/1053) +- 2024-04-12T12:31:49+02:00 fix: do not reset cc input values on each eval by froos in: [#1054](https://codeberg.org/uzu/strudel/pulls/1054) +- 2024-04-08T17:25:27+02:00 transpose: support all combinations of numbers and strings for notes and intervals by froos in: [#1048](https://codeberg.org/uzu/strudel/pulls/1048) +- 2024-04-08T10:46:18+02:00 Wax, wane, taper and taperlist by yaxu in: [#1042](https://codeberg.org/uzu/strudel/pulls/1042) +- 2024-04-06T23:44:57+02:00 Midi Time hotfix for scheduler updates by Ghost in: [#1047](https://codeberg.org/uzu/strudel/pulls/1047) +- 2024-04-05T12:48:03+02:00 pitchwheel visual by froos in: [#1041](https://codeberg.org/uzu/strudel/pulls/1041) +- 2024-04-05T12:47:19+02:00 fix cyclist fizzling out by froos in: [#1046](https://codeberg.org/uzu/strudel/pulls/1046) + +## march 2024 + +- 2024-03-30T16:05:59+01:00 remove dangerous arithmetic feature by froos in: [#1030](https://codeberg.org/uzu/strudel/pulls/1030) +- 2024-03-30T16:05:27+01:00 Fix sampler paths by froos in: [#1034](https://codeberg.org/uzu/strudel/pulls/1034) +- 2024-03-30T14:43:08+01:00 local sample server cli by froos in: [#1033](https://codeberg.org/uzu/strudel/pulls/1033) +- 2024-03-29T17:14:28+01:00 add font file types to offline cache by froos in: [#1032](https://codeberg.org/uzu/strudel/pulls/1032) +- 2024-03-29T17:10:16+01:00 add closeBrackets setting by froos in: [#1031](https://codeberg.org/uzu/strudel/pulls/1031) +- 2024-03-29T14:55:06+01:00 Tactus tidy by yaxu in: [#1027](https://codeberg.org/uzu/strudel/pulls/1027) +- 2024-03-28T17:06:44+01:00 add setting for sync flag by froos in: [#1025](https://codeberg.org/uzu/strudel/pulls/1025) +- 2024-03-28T11:37:57+01:00 better theme integration for visuals + various fixes by froos in: [#1024](https://codeberg.org/uzu/strudel/pulls/1024) +- 2024-03-28T11:33:25+01:00 More fonts by froos in: [#1023](https://codeberg.org/uzu/strudel/pulls/1023) +- 2024-03-27T13:06:05+01:00 Feature: tactus marking by yaxu in: [#1021](https://codeberg.org/uzu/strudel/pulls/1021) +- 2024-03-25T06:02:02+01:00 hotfix for 1017 by Ghost in: [#1020](https://codeberg.org/uzu/strudel/pulls/1020) +- 2024-03-24T15:06:33+01:00 Document signals by Ghost in: [#1015](https://codeberg.org/uzu/strudel/pulls/1015) +- 2024-03-24T10:16:11+01:00 Repl sync fixes by Ghost in: [#1014](https://codeberg.org/uzu/strudel/pulls/1014) +- 2024-03-23T20:21:51+01:00 eliminate chromium clock jitter by froos in: [#1004](https://codeberg.org/uzu/strudel/pulls/1004) +- 2024-03-23T15:51:07+01:00 update undocumented script by froos in: [#1013](https://codeberg.org/uzu/strudel/pulls/1013) +- 2024-03-23T15:26:52+01:00 fix: await injectPatternMethods by froos in: [#1012](https://codeberg.org/uzu/strudel/pulls/1012) +- 2024-03-23T15:18:12+01:00 rename trig -> reset, trigzero -> restart by froos in: [#1010](https://codeberg.org/uzu/strudel/pulls/1010) +- 2024-03-23T12:30:03+01:00 Inline punchcard + spiral by froos in: [#1008](https://codeberg.org/uzu/strudel/pulls/1008) +- 2024-03-23T12:27:22+01:00 Color in hap value by froos in: [#1007](https://codeberg.org/uzu/strudel/pulls/1007) +- 2024-03-22T23:53:51+01:00 using strudel in your project guide + cleanup examples by froos in: [#1006](https://codeberg.org/uzu/strudel/pulls/1006) +- 2024-03-22T23:41:50+01:00 accidentals in scale degrees by eefano in: [#1000](https://codeberg.org/uzu/strudel/pulls/1000) +- 2024-03-21T22:53:55+01:00 supersaw oscillator by Ghost in: [#978](https://codeberg.org/uzu/strudel/pulls/978) +- 2024-03-21T13:00:04+01:00 remove canvas, externalize samples, delete junk by froos in: [#1003](https://codeberg.org/uzu/strudel/pulls/1003) +- 2024-03-18T11:37:55+01:00 Fix pure mini highlight by yaxu in: [#994](https://codeberg.org/uzu/strudel/pulls/994) +- 2024-03-18T07:12:14+01:00 inline viz / widgets package by froos in: [#989](https://codeberg.org/uzu/strudel/pulls/989) +- 2024-03-17T04:07:00+01:00 Labeled statements by froos in: [#991](https://codeberg.org/uzu/strudel/pulls/991) +- 2024-03-16T18:24:38+01:00 Beat-oriented functionality by yaxu in: [#976](https://codeberg.org/uzu/strudel/pulls/976) +- 2024-03-15T01:47:35+01:00 REPL sync between windows by Ghost in: [#900](https://codeberg.org/uzu/strudel/pulls/900) +- 2024-03-14T00:20:07+01:00 Update synths.mdx by Ghost in: [#984](https://codeberg.org/uzu/strudel/pulls/984) +- 2024-03-13T00:36:22+01:00 fix: share now shares what's visible instead of active by froos in: [#985](https://codeberg.org/uzu/strudel/pulls/985) +- 2024-03-10T01:18:57+01:00 use ireal as default voicing dict by froos in: [#967](https://codeberg.org/uzu/strudel/pulls/967) +- 2024-03-10T00:50:23+01:00 little fix for withVal by eefano in: [#980](https://codeberg.org/uzu/strudel/pulls/980) +- 2024-03-10T00:46:51+01:00 Velocity in value by froos in: [#974](https://codeberg.org/uzu/strudel/pulls/974) +- 2024-03-10T00:42:50+01:00 fix: clear hydra on reset by froos in: [#983](https://codeberg.org/uzu/strudel/pulls/983) +- 2024-03-10T00:38:43+01:00 move canvas related helpers from core to new draw package by froos in: [#971](https://codeberg.org/uzu/strudel/pulls/971) +- 2024-03-08T05:38:07+01:00 replace shape with distort in learn doc by Ghost in: [#982](https://codeberg.org/uzu/strudel/pulls/982) +- 2024-03-06T12:14:49+01:00 alias - for ~ by yaxu in: [#981](https://codeberg.org/uzu/strudel/pulls/981) +- 2024-03-04T16:04:23+01:00 Worklet Improvents / fixes by Ghost in: [#963](https://codeberg.org/uzu/strudel/pulls/963) +- 2024-03-01T17:30:19+01:00 Nested controls by froos in: [#973](https://codeberg.org/uzu/strudel/pulls/973) + +## february 2024 + +- 2024-02-29T15:33:12+01:00 feat: can now invert euclid pulses with negative numbers by froos in: [#959](https://codeberg.org/uzu/strudel/pulls/959) +- 2024-02-29T15:31:23+01:00 pickOut(), pickRestart(), pickReset() by eefano in: [#950](https://codeberg.org/uzu/strudel/pulls/950) +- 2024-02-29T15:12:45+01:00 remove legacy legato + duration implementations by froos in: [#965](https://codeberg.org/uzu/strudel/pulls/965) +- 2024-02-29T08:47:53+01:00 fix for transpose(): preserve hap value object structure by eefano in: [#966](https://codeberg.org/uzu/strudel/pulls/966) +- 2024-02-29T08:32:00+01:00 add debounce to logger by froos in: [#968](https://codeberg.org/uzu/strudel/pulls/968) +- 2024-02-28T18:43:52+01:00 controls refactoring: simplify exports by froos in: [#962](https://codeberg.org/uzu/strudel/pulls/962) +- 2024-02-25T19:17:00+01:00 fix: reset global fx on pattern change by froos in: [#960](https://codeberg.org/uzu/strudel/pulls/960) +- 2024-02-25T14:15:30+01:00 fix midi issue on firefox and added quote error by Ghost in: [#936](https://codeberg.org/uzu/strudel/pulls/936) +- 2024-02-25T13:19:47+01:00 'Enable Bracket Matching' option in Codemirror by eefano in: [#956](https://codeberg.org/uzu/strudel/pulls/956) +- 2024-02-23T14:37:46+01:00 fix script importable packages (web + repl) by froos in: [#957](https://codeberg.org/uzu/strudel/pulls/957) +- 2024-02-21T16:17:37+01:00 account for cps in midi time duration by Ghost in: [#954](https://codeberg.org/uzu/strudel/pulls/954) +- 2024-02-21T10:27:12+01:00 Auto await samples by froos in: [#955](https://codeberg.org/uzu/strudel/pulls/955) +- 2024-02-08T13:16:15+01:00 remove cjs builds by froos in: [#945](https://codeberg.org/uzu/strudel/pulls/945) +- 2024-02-04T23:15:37+01:00 Minor documentation error: Update first-sounds.mdx by Ghost in: [#941](https://codeberg.org/uzu/strudel/pulls/941) + + +## january 2024 + +- 2024-01-24T16:48:57+01:00 fix: pianoroll sorting by froos in: [#938](https://codeberg.org/uzu/strudel/pulls/938) +- 2024-01-23T00:04:03+01:00 V1 release notes by froos in: [#935](https://codeberg.org/uzu/strudel/pulls/935) +- 2024-01-22T20:20:53+01:00 2 years blog post by froos in: [#929](https://codeberg.org/uzu/strudel/pulls/929) +- 2024-01-22T20:02:34+01:00 make 0.5hz cps the default by yaxu in: [#931](https://codeberg.org/uzu/strudel/pulls/931) +- 2024-01-22T00:52:01+01:00 Fix pattern tab not showing patterns without created date by Ghost in: [#934](https://codeberg.org/uzu/strudel/pulls/934) +- 2024-01-21T20:46:28+01:00 Add useful pattern selection behavior for performing. by Ghost in: [#897](https://codeberg.org/uzu/strudel/pulls/897) +- 2024-01-21T01:30:28+01:00 Refactor cps functions by froos in: [#933](https://codeberg.org/uzu/strudel/pulls/933) +- 2024-01-20T23:47:31+01:00 Make splice cps-aware by yaxu in: [#932](https://codeberg.org/uzu/strudel/pulls/932) +- 2024-01-19T18:50:57+01:00 community bakery by froos in: [#923](https://codeberg.org/uzu/strudel/pulls/923) +- 2024-01-19T18:49:54+01:00 add pickF and pickmodF by Ghost in: [#924](https://codeberg.org/uzu/strudel/pulls/924) +- 2024-01-19T15:10:48+01:00 Mini-notation additions towards tidal compatibility by yaxu in: [#926](https://codeberg.org/uzu/strudel/pulls/926) +- 2024-01-18T23:34:11+01:00 Blog improvements by froos in: [#919](https://codeberg.org/uzu/strudel/pulls/919) +- 2024-01-18T18:08:29+01:00 pick, pickmod, inhabit, inhabitmod by yaxu in: [#921](https://codeberg.org/uzu/strudel/pulls/921) +- 2024-01-18T18:04:27+01:00 Revert "`pick` now accepts lookup tables, with alternate cycle squeezing behaviour as new `inhabit` function" by yaxu in: [#920](https://codeberg.org/uzu/strudel/pulls/920) +- 2024-01-18T17:45:39+01:00 `pick` now accepts lookup tables, with alternate cycle squeezing behaviour as new `inhabit` function by yaxu in: [#918](https://codeberg.org/uzu/strudel/pulls/918) +- 2024-01-18T10:30:08+01:00 rename @strudel.cycles/* packages to @strudel/* by froos in: [#917](https://codeberg.org/uzu/strudel/pulls/917) +- 2024-01-18T06:54:33+01:00 pitch envelopes by froos in: [#913](https://codeberg.org/uzu/strudel/pulls/913) +- 2024-01-18T05:09:38+01:00 Fix: swatch/[name].png.js static path by Ghost in: [#916](https://codeberg.org/uzu/strudel/pulls/916) +- 2024-01-16T08:22:28+01:00 Add more vowel qualities for the vowels function by Ghost in: [#907](https://codeberg.org/uzu/strudel/pulls/907) +- 2024-01-14T23:56:36+01:00 adds a blog by froos in: [#911](https://codeberg.org/uzu/strudel/pulls/911) +- 2024-01-14T23:52:41+01:00 Remove hideHeader for better mobile UI and consistency by Ghost in: [#894](https://codeberg.org/uzu/strudel/pulls/894) +- 2024-01-14T22:43:06+01:00 Further Envelope improvements by Ghost in: [#868](https://codeberg.org/uzu/strudel/pulls/868) +- 2024-01-14T00:48:04+01:00 public sharing by froos in: [#910](https://codeberg.org/uzu/strudel/pulls/910) +- 2024-01-12T18:31:41+01:00 fix some build warnings by froos in: [#902](https://codeberg.org/uzu/strudel/pulls/902) +- 2024-01-12T18:01:55+01:00 prevent vite from complaining about additional exports in jsx files by Ghost in: [#891](https://codeberg.org/uzu/strudel/pulls/891) +- 2024-01-12T17:05:47+01:00 Update Vite version so hot reload works properly with newest pnpm version by Ghost in: [#892](https://codeberg.org/uzu/strudel/pulls/892) +- 2024-01-12T15:09:41+01:00 support , in < > by froos in: [#886](https://codeberg.org/uzu/strudel/pulls/886) +- 2024-01-10T13:55:39+01:00 fix: autocomplete / tooltip code example bug by froos in: [#898](https://codeberg.org/uzu/strudel/pulls/898) +- 2024-01-06T15:23:55+01:00 fix: invisible selection on vim + emacs mode by froos in: [#889](https://codeberg.org/uzu/strudel/pulls/889) +- 2024-01-05T22:29:20+01:00 scales can now be anchored by froos in: [#888](https://codeberg.org/uzu/strudel/pulls/888) +- 2024-01-04T11:21:42+01:00 add root mode for voicings by froos in: [#887](https://codeberg.org/uzu/strudel/pulls/887) +- 2024-01-01T18:32:17+01:00 Showcase by froos in: [#885](https://codeberg.org/uzu/strudel/pulls/885) +- 2024-01-01T14:22:11+01:00 bugfix: suspend and close exisiting audio context when changing interface by Ghost in: [#882](https://codeberg.org/uzu/strudel/pulls/882) +- 2024-01-01T14:21:52+01:00 add mastodon link by froos in: [#884](https://codeberg.org/uzu/strudel/pulls/884) + +## december 2023 + +- 2023-12-31T17:02:57+01:00 fix: make sure n is never undefined before nanFallback by froos in: [#881](https://codeberg.org/uzu/strudel/pulls/881) +- 2023-12-31T16:47:22+01:00 Error tolerance by froos in: [#880](https://codeberg.org/uzu/strudel/pulls/880) +- 2023-12-31T10:06:24+01:00 bugfix: sound select indexes out of bounds by Ghost in: [#871](https://codeberg.org/uzu/strudel/pulls/871) +- 2023-12-31T10:03:01+01:00 Audio device selection by Ghost in: [#854](https://codeberg.org/uzu/strudel/pulls/854) +- 2023-12-31T00:59:49+01:00 Dependency update by froos in: [#879](https://codeberg.org/uzu/strudel/pulls/879) +- 2023-12-29T16:53:41+01:00 move all examples to separate examples folder by froos in: [#878](https://codeberg.org/uzu/strudel/pulls/878) +- 2023-12-29T15:29:17+01:00 final vanillification by froos in: [#876](https://codeberg.org/uzu/strudel/pulls/876) +- 2023-12-27T18:38:09+01:00 Bug Fix #119: Clock drift by Ghost in: [#874](https://codeberg.org/uzu/strudel/pulls/874) +- 2023-12-27T13:17:03+01:00 main repl vanillification by froos in: [#873](https://codeberg.org/uzu/strudel/pulls/873) +- 2023-12-25T17:47:25+01:00 more work on vanilla repl: repl web component + package + MicroRepl by froos in: [#866](https://codeberg.org/uzu/strudel/pulls/866) +- 2023-12-15T00:11:35+01:00 Vanilla repl 3 by froos in: [#865](https://codeberg.org/uzu/strudel/pulls/865) +- 2023-12-14T21:28:49+01:00 Vanilla repl 2 by froos in: [#863](https://codeberg.org/uzu/strudel/pulls/863) +- 2023-12-12T21:49:23+01:00 fix: finally repair envelopes by froos in: [#861](https://codeberg.org/uzu/strudel/pulls/861) +- 2023-12-12T21:20:00+01:00 add missing trailing slashes by froos in: [#860](https://codeberg.org/uzu/strudel/pulls/860) +- 2023-12-12T19:08:31+01:00 Sound Import from local file system by Ghost in: [#839](https://codeberg.org/uzu/strudel/pulls/839) +- 2023-12-11T22:48:35+01:00 Pattern organization by froos in: [#858](https://codeberg.org/uzu/strudel/pulls/858) +- 2023-12-09T17:25:11+01:00 Export patterns + ui tweaks by froos in: [#855](https://codeberg.org/uzu/strudel/pulls/855) +- 2023-12-08T09:41:10+01:00 patterns tab: import patterns + style by froos in: [#852](https://codeberg.org/uzu/strudel/pulls/852) +- 2023-12-07T20:42:00+01:00 Patterns tab + Refactor Panel by froos in: [#769](https://codeberg.org/uzu/strudel/pulls/769) +- 2023-12-07T10:25:16+01:00 CHANGES: pnpm 8.1.3 to 8.11.0 by Ghost in: [#850](https://codeberg.org/uzu/strudel/pulls/850) +- 2023-12-07T09:35:14+01:00 Fix edge case with rehype-urls and trailing slashes in image file paths by Ghost in: [#849](https://codeberg.org/uzu/strudel/pulls/849) +- 2023-12-06T23:02:31+01:00 Fix examples page, piano() and a few workshop imgs by Ghost in: [#848](https://codeberg.org/uzu/strudel/pulls/848) +- 2023-12-06T22:30:59+01:00 fix: swatch png src by froos in: [#846](https://codeberg.org/uzu/strudel/pulls/846) +- 2023-12-06T22:19:30+01:00 fix: missing hash for links starting with / by froos in: [#845](https://codeberg.org/uzu/strudel/pulls/845) +- 2023-12-06T22:05:05+01:00 improve slashing + base href behavior by froos in: [#842](https://codeberg.org/uzu/strudel/pulls/842) +- 2023-12-06T21:26:49+01:00 Add in fixes from my fork to slashocalypse branch by Ghost in: [#843](https://codeberg.org/uzu/strudel/pulls/843) +- 2023-12-05T18:43:58+01:00 Prevent 404 on Algolia crawls by Ghost in: [#838](https://codeberg.org/uzu/strudel/pulls/838) +- 2023-12-05T18:26:47+01:00 Multichannel audio by Ghost in: [#820](https://codeberg.org/uzu/strudel/pulls/820) +- 2023-12-05T12:19:58+01:00 ADDS: JetBrains IDE files and directories to .gitignore by Ghost in: [#840](https://codeberg.org/uzu/strudel/pulls/840) +- 2023-12-05T12:19:27+01:00 CHANGES: github action pnpm version from 7 to 8.3.1 by Ghost in: [#835](https://codeberg.org/uzu/strudel/pulls/835) +- 2023-12-05T12:19:17+01:00 CHANGES: pin pnpm to version 8.3.1 by Ghost in: [#834](https://codeberg.org/uzu/strudel/pulls/834) +- 2023-12-05T12:19:06+01:00 CHANGES: github action checkout v2 -> v4 by Ghost in: [#837](https://codeberg.org/uzu/strudel/pulls/837) +- 2023-12-05T11:15:14+01:00 FIXES: palindrome abc -> abccba by Ghost in: [#831](https://codeberg.org/uzu/strudel/pulls/831) +- 2023-12-02T09:43:50+01:00 Fix a typo by Ghost in: [#830](https://codeberg.org/uzu/strudel/pulls/830) + +## november 2023 + +- 2023-11-30T10:42:41+01:00 Add and style algolia search by Ghost in: [#827](https://codeberg.org/uzu/strudel/pulls/827) +- 2023-11-25T15:50:44+01:00 Hydra fixes and improvements by Ghost in: [#818](https://codeberg.org/uzu/strudel/pulls/818) +- 2023-11-24T10:07:17+01:00 add options param to initHydra by Ghost in: [#808](https://codeberg.org/uzu/strudel/pulls/808) +- 2023-11-24T09:57:02+01:00 Improve documentation for synonym functions by Ghost in: [#800](https://codeberg.org/uzu/strudel/pulls/800) +- 2023-11-24T09:00:54+01:00 New noise type: "crackle" by Ghost in: [#806](https://codeberg.org/uzu/strudel/pulls/806) +- 2023-11-18T21:18:16+01:00 Color hsl by froos in: [#815](https://codeberg.org/uzu/strudel/pulls/815) +- 2023-11-17T23:18:23+01:00 fix: multiple repls by froos in: [#813](https://codeberg.org/uzu/strudel/pulls/813) +- 2023-11-17T20:52:25+01:00 upstream changes by yaxu in: [#809](https://codeberg.org/uzu/strudel/pulls/809) +- 2023-11-17T16:04:10+01:00 Add doc for euclidLegatoRot, wordfall and slider by Ghost in: [#801](https://codeberg.org/uzu/strudel/pulls/801) +- 2023-11-17T14:42:58+01:00 add option to disable active line highlighting in Code Settings by Ghost in: [#804](https://codeberg.org/uzu/strudel/pulls/804) +- 2023-11-17T14:37:52+01:00 tidal style d1 ... d9 functions + more by froos in: [#805](https://codeberg.org/uzu/strudel/pulls/805) +- 2023-11-15T20:12:23+01:00 remove unwanted cm6 outline for strudelTheme by Ghost in: [#802](https://codeberg.org/uzu/strudel/pulls/802) +- 2023-11-13T23:30:15+01:00 Create phaser effect by Ghost in: [#798](https://codeberg.org/uzu/strudel/pulls/798) +- 2023-11-10T12:17:35+01:00 support multiple named serial connections, change default baudrate by yaxu in: [#551](https://codeberg.org/uzu/strudel/pulls/551) +- 2023-11-09T09:27:57+01:00 Fix for #1. Enables named instruments for csoundm. by gogins in: [#662](https://codeberg.org/uzu/strudel/pulls/662) +- 2023-11-09T09:26:45+01:00 Adding vibrato to Superdough sampler by Ghost in: [#706](https://codeberg.org/uzu/strudel/pulls/706) +- 2023-11-09T08:46:03+01:00 Document pianoroll by Ghost in: [#784](https://codeberg.org/uzu/strudel/pulls/784) +- 2023-11-09T08:45:29+01:00 Update first-effects.mdx by Ghost in: [#795](https://codeberg.org/uzu/strudel/pulls/795) +- 2023-11-09T08:44:43+01:00 Update pattern-effects.mdx by Ghost in: [#796](https://codeberg.org/uzu/strudel/pulls/796) +- 2023-11-09T08:43:50+01:00 Update recap.mdx by Ghost in: [#797](https://codeberg.org/uzu/strudel/pulls/797) +- 2023-11-07T11:53:49+01:00 Update first-sounds.mdx by Ghost in: [#794](https://codeberg.org/uzu/strudel/pulls/794) +- 2023-11-06T23:17:32+01:00 don't use anchor links for reference by froos in: [#791](https://codeberg.org/uzu/strudel/pulls/791) +- 2023-11-06T22:40:44+01:00 samples loading shortcuts: by froos in: [#788](https://codeberg.org/uzu/strudel/pulls/788) +- 2023-11-05T22:47:48+01:00 Fix scope pos + document by froos in: [#786](https://codeberg.org/uzu/strudel/pulls/786) +- 2023-11-05T22:10:25+01:00 Implement optional hover tooltip with function documentation by Ghost in: [#783](https://codeberg.org/uzu/strudel/pulls/783) +- 2023-11-05T16:46:06+01:00 Add function params in reference tab by Ghost in: [#785](https://codeberg.org/uzu/strudel/pulls/785) +- 2023-11-05T12:42:00+01:00 fix: style issues by froos in: [#781](https://codeberg.org/uzu/strudel/pulls/781) +- 2023-11-05T12:21:28+01:00 add xfade by froos in: [#780](https://codeberg.org/uzu/strudel/pulls/780) +- 2023-11-02T09:30:26+01:00 Update to Astro 3 by froos in: [#775](https://codeberg.org/uzu/strudel/pulls/775) +- 2023-11-02T08:57:14+01:00 add vscode bindings by Ghost in: [#773](https://codeberg.org/uzu/strudel/pulls/773) +- 2023-11-02T08:31:30+01:00 fix: share copy to clipboard + alert by froos in: [#774](https://codeberg.org/uzu/strudel/pulls/774) +- 2023-11-01T22:22:34+01:00 Fix chunk, add fastChunk and repeatCycles by yaxu in: [#712](https://codeberg.org/uzu/strudel/pulls/712) +- 2023-11-01T22:12:49+01:00 Document adsr function by Ghost in: [#767](https://codeberg.org/uzu/strudel/pulls/767) +- 2023-11-01T22:11:49+01:00 Add pick and squeeze functions by Ghost in: [#771](https://codeberg.org/uzu/strudel/pulls/771) +- 2023-11-01T22:04:00+01:00 Update vite pwa by froos in: [#772](https://codeberg.org/uzu/strudel/pulls/772) + +## october 2023 + +- 2023-10-28T23:55:07+02:00 replace strudel.tidalcycles.org with strudel.cc by froos in: [#768](https://codeberg.org/uzu/strudel/pulls/768) +- 2023-10-28T12:52:37+02:00 Document striate function by Ghost in: [#766](https://codeberg.org/uzu/strudel/pulls/766) +- 2023-10-27T23:06:20+02:00 fix zen mode logo overlap by froos in: [#760](https://codeberg.org/uzu/strudel/pulls/760) +- 2023-10-27T23:01:18+02:00 fix: scale offset by froos in: [#764](https://codeberg.org/uzu/strudel/pulls/764) +- 2023-10-27T21:59:35+02:00 Fix addivite synthesis phases by froos in: [#762](https://codeberg.org/uzu/strudel/pulls/762) +- 2023-10-26T16:28:16+02:00 Hydra integration by froos in: [#759](https://codeberg.org/uzu/strudel/pulls/759) +- 2023-10-26T14:14:27+02:00 add play function by froos in: [#758](https://codeberg.org/uzu/strudel/pulls/758) +- 2023-10-26T13:11:00+02:00 Add shabda shortcut by Ghost in: [#740](https://codeberg.org/uzu/strudel/pulls/740) +- 2023-10-26T13:07:23+02:00 mini notation: international alphabets support by Ghost in: [#751](https://codeberg.org/uzu/strudel/pulls/751) +- 2023-10-22T23:00:52+02:00 hopefully fix trainling slashes bug by froos in: [#753](https://codeberg.org/uzu/strudel/pulls/753) +- 2023-10-21T23:38:50+02:00 Fix krill build command in README by Ghost in: [#748](https://codeberg.org/uzu/strudel/pulls/748) +- 2023-10-21T00:20:50+02:00 completely revert config mess by froos in: [#745](https://codeberg.org/uzu/strudel/pulls/745) +- 2023-10-20T22:41:39+02:00 fix: try different trailing slash behavior by froos in: [#744](https://codeberg.org/uzu/strudel/pulls/744) +- 2023-10-20T22:34:03+02:00 fix: trailing slash confusion by froos in: [#743](https://codeberg.org/uzu/strudel/pulls/743) +- 2023-10-20T12:07:04+02:00 [Bug Fix] chooseWith: prevent pattern from stopping audio when selection is >= 1 or < 0 by Ghost in: [#741](https://codeberg.org/uzu/strudel/pulls/741) +- 2023-10-20T11:34:26+02:00 Recipes by froos in: [#742](https://codeberg.org/uzu/strudel/pulls/742) +- 2023-10-13T12:57:24+02:00 vite-vanilla-repl readme fix by froos in: [#737](https://codeberg.org/uzu/strudel/pulls/737) +- 2023-10-10T00:17:59+02:00 Add support for using samples as impulse response buffers for the reverb by Ghost in: [#717](https://codeberg.org/uzu/strudel/pulls/717) +- 2023-10-09T21:43:42+02:00 fix: reverb sampleRate by froos in: [#732](https://codeberg.org/uzu/strudel/pulls/732) +- 2023-10-09T21:34:33+02:00 fix: reverb roomsize not required by froos in: [#731](https://codeberg.org/uzu/strudel/pulls/731) +- 2023-10-08T13:54:52+02:00 Compressor by froos in: [#729](https://codeberg.org/uzu/strudel/pulls/729) +- 2023-10-08T13:25:57+02:00 fix: hashes in urls by froos in: [#728](https://codeberg.org/uzu/strudel/pulls/728) +- 2023-10-07T15:48:06+02:00 consume n with scale by froos in: [#727](https://codeberg.org/uzu/strudel/pulls/727) +- 2023-10-07T00:27:21+02:00 fix: reverb regenerate loophole by froos in: [#726](https://codeberg.org/uzu/strudel/pulls/726) +- 2023-10-05T00:04:17+02:00 Better convolution reverb by generating impulse responses by Ghost in: [#718](https://codeberg.org/uzu/strudel/pulls/718) +- 2023-10-04T10:31:53+02:00 Slider afterthoughts by froos in: [#723](https://codeberg.org/uzu/strudel/pulls/723) +- 2023-10-03T16:39:06+02:00 Add 'white', 'pink' and 'brown' oscillators + refactor synth by Ghost in: [#713](https://codeberg.org/uzu/strudel/pulls/713) +- 2023-10-01T14:20:50+02:00 support mininotation '..' range operator, fixes #715 by yaxu in: [#716](https://codeberg.org/uzu/strudel/pulls/716) +- 2023-10-01T14:15:09+02:00 widgets by froos in: [#714](https://codeberg.org/uzu/strudel/pulls/714) + +## september 2023 + +- 2023-09-28T11:03:09+02:00 Midi in by froos in: [#699](https://codeberg.org/uzu/strudel/pulls/699) +- 2023-09-27T22:53:49+02:00 add midi clock support by froos in: [#710](https://codeberg.org/uzu/strudel/pulls/710) +- 2023-09-25T23:36:10+02:00 Update bournemouth.mdx by Ghost in: [#708](https://codeberg.org/uzu/strudel/pulls/708) +- 2023-09-25T23:06:30+02:00 add dough function for raw dsp by froos in: [#707](https://codeberg.org/uzu/strudel/pulls/707) +- 2023-09-17T15:53:27+02:00 Update tauri.yml workflow file by Ghost in: [#705](https://codeberg.org/uzu/strudel/pulls/705) +- 2023-09-17T11:05:06+02:00 Adding vibrato to base oscillators by Ghost in: [#693](https://codeberg.org/uzu/strudel/pulls/693) +- 2023-09-17T08:27:36+02:00 Adding loop points and thus wavetable synthesis by Ghost in: [#698](https://codeberg.org/uzu/strudel/pulls/698) +- 2023-09-16T02:03:49+02:00 Adding filter envelopes and filter order selection by Ghost in: [#692](https://codeberg.org/uzu/strudel/pulls/692) +- 2023-09-09T11:19:58+02:00 Add logging from tauri by Ghost in: [#697](https://codeberg.org/uzu/strudel/pulls/697) +- 2023-09-05T00:33:54+02:00 Direct OSC Support in Tauri by Ghost in: [#694](https://codeberg.org/uzu/strudel/pulls/694) +- 2023-09-03T22:19:22+02:00 fix MIDI CC messages by Ghost in: [#690](https://codeberg.org/uzu/strudel/pulls/690) +- 2023-09-03T10:22:15+02:00 add sleep timer + improve message iterating by Ghost in: [#688](https://codeberg.org/uzu/strudel/pulls/688) + +## august 2023 + +- 2023-08-31T13:00:31+02:00 ZZFX Synth support by Ghost in: [#684](https://codeberg.org/uzu/strudel/pulls/684) +- 2023-08-31T12:36:37+02:00 Wave Selection and Global Envelope on the FM Synth Modulator by Ghost in: [#683](https://codeberg.org/uzu/strudel/pulls/683) +- 2023-08-31T05:52:17+02:00 Create Midi Integration for Tauri Desktop app by Ghost in: [#685](https://codeberg.org/uzu/strudel/pulls/685) +- 2023-08-31T05:32:16+02:00 teletext theme + fonts by froos in: [#681](https://codeberg.org/uzu/strudel/pulls/681) +- 2023-08-31T05:20:55+02:00 control osc partial count with n by froos in: [#674](https://codeberg.org/uzu/strudel/pulls/674) +- 2023-08-27T22:18:06+02:00 add emoji support by froos in: [#680](https://codeberg.org/uzu/strudel/pulls/680) +- 2023-08-27T16:12:32+02:00 Pianoroll improvements by froos in: [#679](https://codeberg.org/uzu/strudel/pulls/679) +- 2023-08-26T21:22:17+02:00 Scope by froos in: [#677](https://codeberg.org/uzu/strudel/pulls/677) +- 2023-08-23T21:50:50+02:00 Midi time fixes by Ghost in: [#668](https://codeberg.org/uzu/strudel/pulls/668) +- 2023-08-20T23:19:08+02:00 basic fm by froos in: [#669](https://codeberg.org/uzu/strudel/pulls/669) +- 2023-08-18T23:56:20+02:00 togglable panel position by froos in: [#667](https://codeberg.org/uzu/strudel/pulls/667) +- 2023-08-18T15:59:20+02:00 fix osc bundle timestamp glitches caused by drifting clock by Ghost in: [#666](https://codeberg.org/uzu/strudel/pulls/666) +- 2023-08-17T11:36:07+02:00 superdough: encapsulates web audio output by froos in: [#664](https://codeberg.org/uzu/strudel/pulls/664) +- 2023-08-11T00:06:21+02:00 fix: always run previous trigger by froos in: [#660](https://codeberg.org/uzu/strudel/pulls/660) +- 2023-08-10T23:54:58+02:00 fix: welcome message for latestCode by froos in: [#659](https://codeberg.org/uzu/strudel/pulls/659) +- 2023-08-07T07:45:26+02:00 [Bug Fix] Midi: Don't treat note 0 as false by Ghost in: [#657](https://codeberg.org/uzu/strudel/pulls/657) + +## july 2023 + +- 2023-07-29T09:06:18+02:00 [Bug Fix] Account for numeral notation when converting to midi by Ghost in: [#656](https://codeberg.org/uzu/strudel/pulls/656) +- 2023-07-23T22:18:49+02:00 ireal voicings by froos in: [#653](https://codeberg.org/uzu/strudel/pulls/653) +- 2023-07-22T09:30:21+02:00 Understand pitch by froos in: [#652](https://codeberg.org/uzu/strudel/pulls/652) +- 2023-07-17T23:42:59+02:00 update vitest by froos in: [#651](https://codeberg.org/uzu/strudel/pulls/651) +- 2023-07-17T23:34:33+02:00 stateless voicings + tonleiter lib by froos in: [#647](https://codeberg.org/uzu/strudel/pulls/647) +- 2023-07-17T17:57:17+02:00 FIXES: TODO in rotateChroma by Ghost in: [#650](https://codeberg.org/uzu/strudel/pulls/650) +- 2023-07-10T19:07:45+02:00 slice: list mode by froos in: [#645](https://codeberg.org/uzu/strudel/pulls/645) +- 2023-07-04T23:50:30+02:00 Delete old packages by froos in: [#639](https://codeberg.org/uzu/strudel/pulls/639) +- 2023-07-04T23:38:42+02:00 Adaptive Highlighting by froos in: [#634](https://codeberg.org/uzu/strudel/pulls/634) +- 2023-07-04T21:55:57+02:00 More work on highlight IDs by Ghost in: [#636](https://codeberg.org/uzu/strudel/pulls/636) +- 2023-07-04T18:44:48+02:00 snapshot tests: sort haps by part by froos in: [#637](https://codeberg.org/uzu/strudel/pulls/637) + +## juny 2023 + +- 2023-06-30T22:47:40+02:00 fix: update canvas size on window resize by froos in: [#631](https://codeberg.org/uzu/strudel/pulls/631) +- 2023-06-30T22:45:41+02:00 fix: out of range error by froos in: [#630](https://codeberg.org/uzu/strudel/pulls/630) +- 2023-06-30T08:14:40+02:00 fix: midi clock drift by froos in: [#627](https://codeberg.org/uzu/strudel/pulls/627) +- 2023-06-29T22:02:28+02:00 desktop: play samples from disk by froos in: [#621](https://codeberg.org/uzu/strudel/pulls/621) +- 2023-06-29T21:59:43+02:00 cps dependent functions by froos in: [#620](https://codeberg.org/uzu/strudel/pulls/620) +- 2023-06-26T22:45:04+02:00 Fix typo on packages.mdx by Ghost in: [#520](https://codeberg.org/uzu/strudel/pulls/520) +- 2023-06-26T22:35:02+02:00 patterning ui settings by froos in: [#606](https://codeberg.org/uzu/strudel/pulls/606) +- 2023-06-26T22:32:46+02:00 add spiral viz by froos in: [#614](https://codeberg.org/uzu/strudel/pulls/614) +- 2023-06-26T22:17:46+02:00 tauri desktop app by Ghost in: [#613](https://codeberg.org/uzu/strudel/pulls/613) +- 2023-06-23T09:59:43+02:00 fix: doc links by froos in: [#612](https://codeberg.org/uzu/strudel/pulls/612) +- 2023-06-23T09:55:18+02:00 clip now works like legato in tidal by froos in: [#598](https://codeberg.org/uzu/strudel/pulls/598) +- 2023-06-18T10:36:19+02:00 fix: flatten scale lists by froos in: [#605](https://codeberg.org/uzu/strudel/pulls/605) +- 2023-06-18T10:36:17+02:00 tonal fixes by froos in: [#607](https://codeberg.org/uzu/strudel/pulls/607) +- 2023-06-15T12:51:40+02:00 editor: enable line wrapping by Ghost in: [#581](https://codeberg.org/uzu/strudel/pulls/581) +- 2023-06-15T10:22:46+02:00 add ratio function by froos in: [#602](https://codeberg.org/uzu/strudel/pulls/602) +- 2023-06-12T23:24:29+02:00 enable auto-completion by Ghost in: [#588](https://codeberg.org/uzu/strudel/pulls/588) +- 2023-06-11T22:04:17+02:00 improve cursor by froos in: [#597](https://codeberg.org/uzu/strudel/pulls/597) +- 2023-06-11T20:00:45+02:00 Solmization added by Ghost in: [#570](https://codeberg.org/uzu/strudel/pulls/570) +- 2023-06-11T19:45:00+02:00 fix: division by zero by froos in: [#591](https://codeberg.org/uzu/strudel/pulls/591) +- 2023-06-11T19:44:43+02:00 fix: allow f for flat notes like tidal by froos in: [#593](https://codeberg.org/uzu/strudel/pulls/593) +- 2023-06-11T19:44:41+02:00 Fix option dot by froos in: [#596](https://codeberg.org/uzu/strudel/pulls/596) +- 2023-06-09T21:02:12+02:00 New Workshop by froos in: [#587](https://codeberg.org/uzu/strudel/pulls/587) +- 2023-06-09T17:31:58+02:00 Music metadata by Ghost in: [#580](https://codeberg.org/uzu/strudel/pulls/580) +- 2023-06-08T09:33:34+02:00 learn/tonal: fix typo in "scaleTran[s]pose" by Ghost in: [#585](https://codeberg.org/uzu/strudel/pulls/585) +- 2023-06-07T20:19:11+02:00 repl: add option to display line numbers by Ghost in: [#582](https://codeberg.org/uzu/strudel/pulls/582) +- 2023-06-05T21:35:49+02:00 Vanilla JS Refactoring by froos in: [#563](https://codeberg.org/uzu/strudel/pulls/563) + +## may 2023 + +- 2023-05-05T08:34:37+02:00 Patchday by froos in: [#559](https://codeberg.org/uzu/strudel/pulls/559) +- 2023-05-02T21:48:33+02:00 add basic triads and guidetone voicings by froos in: [#557](https://codeberg.org/uzu/strudel/pulls/557) + +## april 2023 + +- 2023-04-28T12:46:56+02:00 fix: make soundfonts import dynamic by froos in: [#556](https://codeberg.org/uzu/strudel/pulls/556) +- 2023-04-22T15:43:22+02:00 fix: colorable highlighting by froos in: [#553](https://codeberg.org/uzu/strudel/pulls/553) +- 2023-04-06T00:11:02+02:00 fix: load soundfonts in prebake by froos in: [#550](https://codeberg.org/uzu/strudel/pulls/550) + +## march 2023 + +- 2023-03-29T22:23:07+02:00 fix: reset time on stop by froos in: [#548](https://codeberg.org/uzu/strudel/pulls/548) +- 2023-03-29T22:16:38+02:00 fix: allow whitespace at the end of a mini pattern by froos in: [#547](https://codeberg.org/uzu/strudel/pulls/547) +- 2023-03-24T22:10:56+01:00 add firacode font by froos in: [#544](https://codeberg.org/uzu/strudel/pulls/544) +- 2023-03-24T12:54:20+01:00 feat: add loader bar to animate loading state by froos in: [#542](https://codeberg.org/uzu/strudel/pulls/542) +- 2023-03-23T22:39:27+01:00 do not reset cps before eval #517 by froos in: [#539](https://codeberg.org/uzu/strudel/pulls/539) +- 2023-03-23T22:27:31+01:00 improve initial loading + wait before eval by froos in: [#538](https://codeberg.org/uzu/strudel/pulls/538) +- 2023-03-23T21:40:20+01:00 fix period key for dvorak + remove duplicated code by froos in: [#537](https://codeberg.org/uzu/strudel/pulls/537) +- 2023-03-23T11:44:56+01:00 Update lerna by froos in: [#535](https://codeberg.org/uzu/strudel/pulls/535) +- 2023-03-23T10:21:55+01:00 feat: add freq support to gm soundfonts by froos in: [#534](https://codeberg.org/uzu/strudel/pulls/534) +- 2023-03-23T10:18:58+01:00 Maintain random seed state in parser, not globally by Ghost in: [#531](https://codeberg.org/uzu/strudel/pulls/531) +- 2023-03-21T22:35:18+01:00 FIXES: alias pm for polymeter by Ghost in: [#527](https://codeberg.org/uzu/strudel/pulls/527) +- 2023-03-21T22:29:07+01:00 fix(footer): fix link to tidalcycles by julienbouquillon in: [#529](https://codeberg.org/uzu/strudel/pulls/529) +- 2023-03-18T20:25:21+01:00 Update intro.mdx by Ghost in: [#525](https://codeberg.org/uzu/strudel/pulls/525) +- 2023-03-18T20:24:38+01:00 Update samples.mdx by Ghost in: [#524](https://codeberg.org/uzu/strudel/pulls/524) +- 2023-03-17T09:03:11+01:00 fix: envelopes in chrome by froos in: [#521](https://codeberg.org/uzu/strudel/pulls/521) +- 2023-03-16T16:13:30+01:00 registerSound API + improved sounds tab + regroup soundfonts by froos in: [#516](https://codeberg.org/uzu/strudel/pulls/516) +- 2023-03-14T21:54:53+01:00 add 2 illegible fonts by froos in: [#518](https://codeberg.org/uzu/strudel/pulls/518) +- 2023-03-06T22:55:00+01:00 Update README.md by Ghost in: [#474](https://codeberg.org/uzu/strudel/pulls/474) +- 2023-03-05T14:52:30+01:00 add arrange function by froos in: [#508](https://codeberg.org/uzu/strudel/pulls/508) +- 2023-03-05T14:29:08+01:00 update react to 18 by froos in: [#514](https://codeberg.org/uzu/strudel/pulls/514) +- 2023-03-04T19:06:18+01:00 Support list syntax in mininotation by yaxu in: [#512](https://codeberg.org/uzu/strudel/pulls/512) +- 2023-03-03T12:40:23+01:00 can now use : as a replacement for space in scales by froos in: [#502](https://codeberg.org/uzu/strudel/pulls/502) +- 2023-03-02T15:44:41+01:00 Reinstate slice and splice by yaxu in: [#500](https://codeberg.org/uzu/strudel/pulls/500) +- 2023-03-02T14:49:30+01:00 fix: nano-repl highlighting by froos in: [#501](https://codeberg.org/uzu/strudel/pulls/501) +- 2023-03-02T14:17:13+01:00 Add control aliases by yaxu in: [#497](https://codeberg.org/uzu/strudel/pulls/497) +- 2023-03-01T09:27:27+01:00 implement cps in scheduler by froos in: [#493](https://codeberg.org/uzu/strudel/pulls/493) + +## february 2023 + +- 2023-02-28T23:06:29+01:00 react style fixes by froos in: [#491](https://codeberg.org/uzu/strudel/pulls/491) +- 2023-02-28T22:57:20+01:00 refactor react package by froos in: [#490](https://codeberg.org/uzu/strudel/pulls/490) +- 2023-02-27T23:47:34+01:00 add algolia creds + optimize sidebar for crawling by froos in: [#488](https://codeberg.org/uzu/strudel/pulls/488) +- 2023-02-27T19:28:10+01:00 fix app height by froos in: [#485](https://codeberg.org/uzu/strudel/pulls/485) +- 2023-02-27T16:04:21+01:00 Revert "Another attempt at composable functions - WIP (#390)" by froos in: [#484](https://codeberg.org/uzu/strudel/pulls/484) +- 2023-02-27T15:45:20+01:00 Update mini-notation.mdx by yaxu in: [#365](https://codeberg.org/uzu/strudel/pulls/365) +- 2023-02-27T12:52:09+01:00 docs: packages + offline by froos in: [#482](https://codeberg.org/uzu/strudel/pulls/482) +- 2023-02-25T14:26:49+01:00 Fix array args by froos in: [#480](https://codeberg.org/uzu/strudel/pulls/480) +- 2023-02-25T12:33:22+01:00 midi cc support by froos in: [#478](https://codeberg.org/uzu/strudel/pulls/478) +- 2023-02-23T00:11:05+01:00 fix: hash links by froos in: [#473](https://codeberg.org/uzu/strudel/pulls/473) +- 2023-02-22T22:54:39+01:00 settings tab with vim / emacs modes + additional themes and fonts by froos in: [#467](https://codeberg.org/uzu/strudel/pulls/467) +- 2023-02-22T22:53:22+01:00 Update input-output.mdx by Ghost in: [#471](https://codeberg.org/uzu/strudel/pulls/471) +- 2023-02-22T22:52:50+01:00 FIXES: freqs instead of pitches by Ghost in: [#464](https://codeberg.org/uzu/strudel/pulls/464) +- 2023-02-22T20:01:00+01:00 fix: osc should not return a promise by froos in: [#472](https://codeberg.org/uzu/strudel/pulls/472) +- 2023-02-22T12:51:31+01:00 slice and splice by yaxu in: [#466](https://codeberg.org/uzu/strudel/pulls/466) +- 2023-02-18T01:00:19+01:00 weave and weaveWith by yaxu in: [#465](https://codeberg.org/uzu/strudel/pulls/465) +- 2023-02-17T00:15:21+01:00 Composable functions by yaxu in: [#390](https://codeberg.org/uzu/strudel/pulls/390) +- 2023-02-16T20:38:45+01:00 FIXES: Warning about jsxBracketSameLine deprecation by Ghost in: [#461](https://codeberg.org/uzu/strudel/pulls/461) +- 2023-02-14T22:11:02+01:00 Update synths.mdx by Ghost in: [#438](https://codeberg.org/uzu/strudel/pulls/438) +- 2023-02-14T19:54:42+01:00 Update mini-notation.mdx by Ghost in: [#437](https://codeberg.org/uzu/strudel/pulls/437) +- 2023-02-14T19:54:25+01:00 Update code.mdx by Ghost in: [#436](https://codeberg.org/uzu/strudel/pulls/436) +- 2023-02-13T00:43:29+01:00 Fix anchors by froos in: [#433](https://codeberg.org/uzu/strudel/pulls/433) +- 2023-02-11T21:02:11+01:00 autocomplete preparations by froos in: [#427](https://codeberg.org/uzu/strudel/pulls/427) +- 2023-02-10T23:14:48+01:00 Themes by froos in: [#431](https://codeberg.org/uzu/strudel/pulls/431) +- 2023-02-09T19:22:56+01:00 minirepl: add keyboard shortcuts by froos in: [#429](https://codeberg.org/uzu/strudel/pulls/429) +- 2023-02-09T08:56:42+01:00 add cdn.freesound to cache list by froos in: [#425](https://codeberg.org/uzu/strudel/pulls/425) +- 2023-02-08T20:36:00+01:00 add more offline caching by froos in: [#421](https://codeberg.org/uzu/strudel/pulls/421) +- 2023-02-07T22:08:01+01:00 add caching strategy for missing file types + cache all samples loaded from github by froos in: [#419](https://codeberg.org/uzu/strudel/pulls/419) +- 2023-02-06T23:29:57+01:00 PWA with offline support by froos in: [#417](https://codeberg.org/uzu/strudel/pulls/417) +- 2023-02-05T17:27:32+01:00 improve samples doc by froos in: [#411](https://codeberg.org/uzu/strudel/pulls/411) +- 2023-02-05T17:27:10+01:00 google gtfo by froos in: [#413](https://codeberg.org/uzu/strudel/pulls/413) +- 2023-02-05T16:27:59+01:00 improve effects doc by froos in: [#409](https://codeberg.org/uzu/strudel/pulls/409) +- 2023-02-05T14:56:03+01:00 Update effects.mdx by Ghost in: [#410](https://codeberg.org/uzu/strudel/pulls/410) +- 2023-02-03T19:54:47+01:00 add shabda doc by froos in: [#407](https://codeberg.org/uzu/strudel/pulls/407) +- 2023-02-02T21:45:56+01:00 fix: share url on subpath by froos in: [#405](https://codeberg.org/uzu/strudel/pulls/405) +- 2023-02-02T21:35:45+01:00 update csound + fix sound output by froos in: [#404](https://codeberg.org/uzu/strudel/pulls/404) +- 2023-02-02T19:53:36+01:00 pin @csound/browser to 6.18.3 + bump by froos in: [#403](https://codeberg.org/uzu/strudel/pulls/403) +- 2023-02-01T22:47:27+01:00 release webaudio by froos in: [#400](https://codeberg.org/uzu/strudel/pulls/400) +- 2023-02-01T22:45:16+01:00 can now await initAudio + initAudioOnFirstClick by froos in: [#399](https://codeberg.org/uzu/strudel/pulls/399) +- 2023-02-01T22:32:18+01:00 fix: minirepl styles by froos in: [#398](https://codeberg.org/uzu/strudel/pulls/398) +- 2023-02-01T22:17:19+01:00 proper builds + use pnpm workspaces by froos in: [#396](https://codeberg.org/uzu/strudel/pulls/396) +- 2023-02-01T16:49:55+01:00 add pattern methods hurry, press and pressBy by yaxu in: [#397](https://codeberg.org/uzu/strudel/pulls/397) + +## january 2023 + +- 2023-01-27T14:40:40+01:00 Add tidal-drum-patterns to examples by Ghost in: [#379](https://codeberg.org/uzu/strudel/pulls/379) +- 2023-01-27T14:39:56+01:00 add ribbon + test + docs by froos in: [#388](https://codeberg.org/uzu/strudel/pulls/388) +- 2023-01-27T12:10:37+01:00 Notes are not essential :) by yaxu in: [#393](https://codeberg.org/uzu/strudel/pulls/393) +- 2023-01-21T17:18:13+01:00 document csound by froos in: [#391](https://codeberg.org/uzu/strudel/pulls/391) +- 2023-01-19T12:04:51+01:00 Rename a to angle by froos in: [#387](https://codeberg.org/uzu/strudel/pulls/387) +- 2023-01-19T11:49:39+01:00 add run + test + docs by froos in: [#386](https://codeberg.org/uzu/strudel/pulls/386) +- 2023-01-19T11:32:56+01:00 docs: use note instead of n to mitigate confusion by froos in: [#385](https://codeberg.org/uzu/strudel/pulls/385) +- 2023-01-18T17:10:09+01:00 update my-patterns instructions by froos in: [#384](https://codeberg.org/uzu/strudel/pulls/384) +- 2023-01-15T23:19:43+01:00 Draw fixes by froos in: [#377](https://codeberg.org/uzu/strudel/pulls/377) +- 2023-01-14T11:07:08+01:00 improve new draw logic by froos in: [#372](https://codeberg.org/uzu/strudel/pulls/372) +- 2023-01-12T14:40:59+01:00 document more functions + change arp join by froos in: [#369](https://codeberg.org/uzu/strudel/pulls/369) +- 2023-01-10T00:03:47+01:00 add https to url by Ghost in: [#364](https://codeberg.org/uzu/strudel/pulls/364) +- 2023-01-09T23:37:34+01:00 doc structuring by froos in: [#360](https://codeberg.org/uzu/strudel/pulls/360) +- 2023-01-09T23:23:28+01:00 Support for multiple mininotation operators by yaxu in: [#350](https://codeberg.org/uzu/strudel/pulls/350) +- 2023-01-09T00:40:15+01:00 Fix .out(), renaming webaudio's out() to webaudio() by yaxu in: [#361](https://codeberg.org/uzu/strudel/pulls/361) +- 2023-01-06T22:02:31+01:00 docs: tidal comparison + add global fx + add missing sampler fx by froos in: [#356](https://codeberg.org/uzu/strudel/pulls/356) +- 2023-01-06T12:31:32+01:00 Fix Bjorklund by yaxu in: [#343](https://codeberg.org/uzu/strudel/pulls/343) +- 2023-01-04T20:29:35+01:00 Fix prebake base path by froos in: [#345](https://codeberg.org/uzu/strudel/pulls/345) +- 2023-01-04T19:55:49+01:00 fixes #346 by froos in: [#347](https://codeberg.org/uzu/strudel/pulls/347) +- 2023-01-02T21:28:07+01:00 Patternify euclid, fast, slow and polymeter step parameters in mininotation by yaxu in: [#341](https://codeberg.org/uzu/strudel/pulls/341) +- 2023-01-02T00:30:16+01:00 more animate functions + mini repl fix by froos in: [#340](https://codeberg.org/uzu/strudel/pulls/340) +- 2023-01-01T12:34:11+01:00 move /my-patterns to /swatch by yaxu in: [#338](https://codeberg.org/uzu/strudel/pulls/338) +- 2023-01-01T12:22:55+01:00 animation options by froos in: [#337](https://codeberg.org/uzu/strudel/pulls/337) + +## december 2022 + +- 2022-12-31T22:42:49+01:00 Tidy parser, implement polymeters by yaxu in: [#336](https://codeberg.org/uzu/strudel/pulls/336) +- 2022-12-31T16:51:53+01:00 animate mvp by froos in: [#335](https://codeberg.org/uzu/strudel/pulls/335) +- 2022-12-30T20:16:10+01:00 testing + docs docs by froos in: [#334](https://codeberg.org/uzu/strudel/pulls/334) +- 2022-12-29T21:11:16+01:00 Embed mode improvements by froos in: [#333](https://codeberg.org/uzu/strudel/pulls/333) +- 2022-12-29T14:06:20+01:00 fix: can now multiply floats in mini notation by froos in: [#332](https://codeberg.org/uzu/strudel/pulls/332) +- 2022-12-29T13:50:07+01:00 improve displaying 's' in pianoroll by froos in: [#331](https://codeberg.org/uzu/strudel/pulls/331) +- 2022-12-28T17:35:35+01:00 my-patterns: fix paths + update readme by froos in: [#330](https://codeberg.org/uzu/strudel/pulls/330) +- 2022-12-28T17:11:40+01:00 my-patterns build + deploy by froos in: [#329](https://codeberg.org/uzu/strudel/pulls/329) +- 2022-12-28T15:43:31+01:00 add my-patterns by froos in: [#328](https://codeberg.org/uzu/strudel/pulls/328) +- 2022-12-28T14:47:14+01:00 add examples route by froos in: [#327](https://codeberg.org/uzu/strudel/pulls/327) +- 2022-12-28T14:44:31+01:00 fix: workaround Object.assign globalThis by froos in: [#326](https://codeberg.org/uzu/strudel/pulls/326) +- 2022-12-26T23:29:47+01:00 mini repl improvements by froos in: [#324](https://codeberg.org/uzu/strudel/pulls/324) +- 2022-12-26T23:00:34+01:00 support notes without octave by froos in: [#323](https://codeberg.org/uzu/strudel/pulls/323) +- 2022-12-26T12:37:36+01:00 tutorial updates by Ghost in: [#320](https://codeberg.org/uzu/strudel/pulls/320) +- 2022-12-23T18:26:30+01:00 Reference tab sort by froos in: [#318](https://codeberg.org/uzu/strudel/pulls/318) +- 2022-12-23T00:49:56+01:00 Astro build by froos in: [#315](https://codeberg.org/uzu/strudel/pulls/315) +- 2022-12-19T21:02:37+01:00 object support for .scale by froos in: [#307](https://codeberg.org/uzu/strudel/pulls/307) +- 2022-12-19T21:02:22+01:00 Jsdoc component by froos in: [#312](https://codeberg.org/uzu/strudel/pulls/312) +- 2022-12-19T20:31:46+01:00 fix: copy share link to clipboard was broken for some browers by froos in: [#311](https://codeberg.org/uzu/strudel/pulls/311) +- 2022-12-19T12:11:24+01:00 ICLC2023 paper WIP by yaxu in: [#306](https://codeberg.org/uzu/strudel/pulls/306) +- 2022-12-15T21:23:22+01:00 support freq in pianoroll by froos in: [#308](https://codeberg.org/uzu/strudel/pulls/308) +- 2022-12-13T22:07:27+01:00 Updated csoundm to use the register facility . by gogins in: [#303](https://codeberg.org/uzu/strudel/pulls/303) +- 2022-12-13T21:57:03+01:00 add lint + prettier check before test by froos in: [#305](https://codeberg.org/uzu/strudel/pulls/305) +- 2022-12-13T21:21:44+01:00 add freq support to sampler by froos in: [#301](https://codeberg.org/uzu/strudel/pulls/301) +- 2022-12-12T00:48:41+01:00 fix whitespace trimming by froos in: [#300](https://codeberg.org/uzu/strudel/pulls/300) +- 2022-12-12T00:21:53+01:00 .defragmentHaps() for merging touching haps that share a whole and value by yaxu in: [#299](https://codeberg.org/uzu/strudel/pulls/299) +- 2022-12-11T23:17:49+01:00 remove whitespace from highlighted region by froos in: [#298](https://codeberg.org/uzu/strudel/pulls/298) +- 2022-12-11T22:03:26+01:00 update vitest by froos in: [#297](https://codeberg.org/uzu/strudel/pulls/297) +- 2022-12-11T21:44:16+01:00 can now add bare numbers to numeral object props by froos in: [#287](https://codeberg.org/uzu/strudel/pulls/287) +- 2022-12-11T21:27:58+01:00 Move stuff to new register function by froos in: [#295](https://codeberg.org/uzu/strudel/pulls/295) +- 2022-12-11T20:07:12+01:00 add prettier task by froos in: [#296](https://codeberg.org/uzu/strudel/pulls/296) +- 2022-12-10T15:39:04+01:00 Reorganise pattern.mjs with a 'toplevel first' regime by yaxu in: [#286](https://codeberg.org/uzu/strudel/pulls/286) +- 2022-12-10T11:56:16+01:00 Fancy hap show, include part in snapshots by yaxu in: [#291](https://codeberg.org/uzu/strudel/pulls/291) +- 2022-12-07T20:07:55+01:00 Switch 'operators' from .whatHow to .what.how by yaxu in: [#285](https://codeberg.org/uzu/strudel/pulls/285) +- 2022-12-04T12:51:01+01:00 implement collect + arp function by froos in: [#281](https://codeberg.org/uzu/strudel/pulls/281) +- 2022-12-02T13:38:27+01:00 do not recompile orc by froos in: [#278](https://codeberg.org/uzu/strudel/pulls/278) +- 2022-12-02T12:49:26+01:00 add basic csound output by froos in: [#275](https://codeberg.org/uzu/strudel/pulls/275) +- 2022-12-02T12:18:41+01:00 add licenses / credits to all tunes + remove some by froos in: [#277](https://codeberg.org/uzu/strudel/pulls/277) +- 2022-12-02T11:45:02+01:00 Support sending CRC16 bytes with serial messages by yaxu in: [#276](https://codeberg.org/uzu/strudel/pulls/276) + +## november 2022 + +- 2022-11-29T23:41:39+01:00 release version bumps by froos in: [#273](https://codeberg.org/uzu/strudel/pulls/273) +- 2022-11-29T23:34:50+01:00 add eslint by froos in: [#271](https://codeberg.org/uzu/strudel/pulls/271) +- 2022-11-29T23:34:26+01:00 tonal update with fixed memory leak by froos in: [#272](https://codeberg.org/uzu/strudel/pulls/272) +- 2022-11-22T09:51:26+01:00 Tidying up core by yaxu in: [#256](https://codeberg.org/uzu/strudel/pulls/256) +- 2022-11-21T22:15:48+01:00 fix performance bottleneck by froos in: [#266](https://codeberg.org/uzu/strudel/pulls/266) +- 2022-11-17T11:08:38+01:00 fix tutorial bugs by froos in: [#263](https://codeberg.org/uzu/strudel/pulls/263) +- 2022-11-16T13:15:28+01:00 Binaries by froos in: [#254](https://codeberg.org/uzu/strudel/pulls/254) +- 2022-11-13T20:20:32+01:00 Repl refactoring by froos in: [#255](https://codeberg.org/uzu/strudel/pulls/255) +- 2022-11-08T23:35:11+01:00 Webaudio build by froos in: [#250](https://codeberg.org/uzu/strudel/pulls/250) +- 2022-11-08T22:43:32+01:00 new transpiler based on acorn by froos in: [#249](https://codeberg.org/uzu/strudel/pulls/249) +- 2022-11-06T19:03:19+01:00 General purpose scheduler by froos in: [#248](https://codeberg.org/uzu/strudel/pulls/248) +- 2022-11-06T11:05:23+01:00 snapshot tests on shared snippets by froos in: [#243](https://codeberg.org/uzu/strudel/pulls/243) +- 2022-11-06T11:03:42+01:00 Some tunes by froos in: [#247](https://codeberg.org/uzu/strudel/pulls/247) +- 2022-11-06T00:37:11+01:00 patchday by froos in: [#246](https://codeberg.org/uzu/strudel/pulls/246) +- 2022-11-04T20:28:23+01:00 Readme + TLC by froos in: [#244](https://codeberg.org/uzu/strudel/pulls/244) +- 2022-11-03T15:16:04+01:00 in source example tests by froos in: [#242](https://codeberg.org/uzu/strudel/pulls/242) +- 2022-11-02T23:16:43+01:00 feat: support github: links by froos in: [#240](https://codeberg.org/uzu/strudel/pulls/240) +- 2022-11-02T21:26:44+01:00 Load samples from url by froos in: [#239](https://codeberg.org/uzu/strudel/pulls/239) +- 2022-11-02T11:42:32+01:00 Object arithmetic by froos in: [#238](https://codeberg.org/uzu/strudel/pulls/238) +- 2022-11-01T00:36:14+01:00 Tidal drum machines by froos in: [#237](https://codeberg.org/uzu/strudel/pulls/237) +- 2022-10-31T21:39:23+01:00 fx on stereo speakers by froos in: [#236](https://codeberg.org/uzu/strudel/pulls/236) + +## october 2022 + +- 2022-10-30T19:10:33+01:00 add vcsl sample library by froos in: [#235](https://codeberg.org/uzu/strudel/pulls/235) +- 2022-10-30T00:23:10+02:00 Fix zero length queries WIP by yaxu in: [#234](https://codeberg.org/uzu/strudel/pulls/234) +- 2022-10-29T17:54:05+02:00 Out by default by froos in: [#232](https://codeberg.org/uzu/strudel/pulls/232) +- 2022-10-26T23:53:49+02:00 Patternify range by yaxu in: [#231](https://codeberg.org/uzu/strudel/pulls/231) +- 2022-10-26T21:42:12+02:00 Just another docs branch by froos in: [#228](https://codeberg.org/uzu/strudel/pulls/228) +- 2022-10-26T21:41:12+02:00 Refactor tunes away from tone by froos in: [#230](https://codeberg.org/uzu/strudel/pulls/230) +- 2022-10-20T09:26:28+02:00 Core util tests by Ghost in: [#226](https://codeberg.org/uzu/strudel/pulls/226) +- 2022-10-06T22:35:45+02:00 fix fastgap for events that go across cycle boundaries by yaxu in: [#225](https://codeberg.org/uzu/strudel/pulls/225) + +## september 2022 + +- 2022-09-25T21:15:36+02:00 Reverb by froos in: [#224](https://codeberg.org/uzu/strudel/pulls/224) +- 2022-09-25T00:27:26+02:00 focus tweak for squeezeJoin - another go at fixing #216 by yaxu in: [#221](https://codeberg.org/uzu/strudel/pulls/221) +- 2022-09-24T23:17:21+02:00 support negative speeds by froos in: [#222](https://codeberg.org/uzu/strudel/pulls/222) +- 2022-09-24T21:55:15+02:00 Feedback Delay by froos in: [#213](https://codeberg.org/uzu/strudel/pulls/213) +- 2022-09-23T12:06:17+02:00 Fix squeeze join by yaxu in: [#220](https://codeberg.org/uzu/strudel/pulls/220) +- 2022-09-22T21:23:11+02:00 encapsulate webaudio output by froos in: [#219](https://codeberg.org/uzu/strudel/pulls/219) +- 2022-09-22T19:18:18+02:00 samples now have envelopes by froos in: [#218](https://codeberg.org/uzu/strudel/pulls/218) +- 2022-09-22T00:03:30+02:00 sampler features + fixes by froos in: [#217](https://codeberg.org/uzu/strudel/pulls/217) +- 2022-09-19T23:32:55+02:00 Just another docs PR by froos in: [#215](https://codeberg.org/uzu/strudel/pulls/215) +- 2022-09-17T23:47:43+02:00 Even more docs by froos in: [#212](https://codeberg.org/uzu/strudel/pulls/212) +- 2022-09-17T15:36:53+02:00 Webaudio guide by froos in: [#207](https://codeberg.org/uzu/strudel/pulls/207) +- 2022-09-16T00:21:29+02:00 Coarse crush shape by froos in: [#205](https://codeberg.org/uzu/strudel/pulls/205) +- 2022-09-15T21:04:28+02:00 add vowel to .out by froos in: [#201](https://codeberg.org/uzu/strudel/pulls/201) +- 2022-09-15T16:55:52+02:00 add rollup-plugin-visualizer to build by froos in: [#200](https://codeberg.org/uzu/strudel/pulls/200) +- 2022-09-14T23:46:39+02:00 document random functions by froos in: [#199](https://codeberg.org/uzu/strudel/pulls/199) +- 2022-09-09T22:04:40+02:00 Fix numbers in sampler by froos in: [#196](https://codeberg.org/uzu/strudel/pulls/196) + +## august 2022 + +- 2022-08-14T17:40:41+02:00 change "stride"/"offset" of successive degradeBy/chooseIn by Ghost in: [#185](https://codeberg.org/uzu/strudel/pulls/185) +- 2022-08-14T16:04:14+02:00 Soundfont file support by froos in: [#183](https://codeberg.org/uzu/strudel/pulls/183) +- 2022-08-14T15:55:50+02:00 fix regression: old way of setting frequencies was broken by froos in: [#190](https://codeberg.org/uzu/strudel/pulls/190) +- 2022-08-14T15:45:53+02:00 wait for prebake to finish before evaluating by froos in: [#189](https://codeberg.org/uzu/strudel/pulls/189) +- 2022-08-14T11:31:00+02:00 Fix codemirror bug by froos in: [#186](https://codeberg.org/uzu/strudel/pulls/186) +- 2022-08-13T16:29:53+02:00 scheduler improvements by froos in: [#181](https://codeberg.org/uzu/strudel/pulls/181) +- 2022-08-12T23:10:36+02:00 replace mocha with vitest by froos in: [#175](https://codeberg.org/uzu/strudel/pulls/175) +- 2022-08-07T00:59:07+02:00 incorporate elements of randomness to the mini notation by Ghost in: [#165](https://codeberg.org/uzu/strudel/pulls/165) +- 2022-08-06T23:32:16+02:00 fix some annoying bugs by froos in: [#177](https://codeberg.org/uzu/strudel/pulls/177) +- 2022-08-06T00:27:17+02:00 Replace react-codemirror6 with @uiw/react-codemirror by froos in: [#173](https://codeberg.org/uzu/strudel/pulls/173) +- 2022-08-04T22:19:46+02:00 add more shapeshifter flags by froos in: [#99](https://codeberg.org/uzu/strudel/pulls/99) +- 2022-08-04T22:06:38+02:00 Amend shapeshifter to allow use of dynamic import by Ghost in: [#171](https://codeberg.org/uzu/strudel/pulls/171) +- 2022-08-02T23:43:07+02:00 Talk fixes by froos in: [#164](https://codeberg.org/uzu/strudel/pulls/164) +- 2022-08-02T23:04:34+02:00 Pianoroll fixes by froos in: [#163](https://codeberg.org/uzu/strudel/pulls/163) +- 2022-08-02T22:57:43+02:00 fix: jsdoc comments by froos in: [#169](https://codeberg.org/uzu/strudel/pulls/169) + +## july 2022 + +- 2022-07-30T23:51:11+02:00 add chooseInWith/chooseCycles by yaxu in: [#166](https://codeberg.org/uzu/strudel/pulls/166) +- 2022-07-28T19:26:42+02:00 update to tutorial documentation by Ghost in: [#162](https://codeberg.org/uzu/strudel/pulls/162) +- 2022-07-12T18:58:47+02:00 add webdirt drum samples to prebake for general availability by Ghost in: [#150](https://codeberg.org/uzu/strudel/pulls/150) +- 2022-07-12T08:34:17+02:00 Final update to demo.pdf by yaxu in: [#151](https://codeberg.org/uzu/strudel/pulls/151) + +## june 2022 + +- 2022-06-28T21:54:35+02:00 Sampler optimizations and more by froos in: [#148](https://codeberg.org/uzu/strudel/pulls/148) +- 2022-06-26T12:58:53+02:00 can now generate short link for sharing by froos in: [#146](https://codeberg.org/uzu/strudel/pulls/146) +- 2022-06-24T22:16:04+02:00 flash effect on ctrl enter by froos in: [#144](https://codeberg.org/uzu/strudel/pulls/144) +- 2022-06-22T20:18:17+02:00 Pianoroll Object Support by froos in: [#142](https://codeberg.org/uzu/strudel/pulls/142) +- 2022-06-21T22:57:28+02:00 Serial twiddles by yaxu in: [#141](https://codeberg.org/uzu/strudel/pulls/141) +- 2022-06-21T22:20:05+02:00 Soundfont Support by froos in: [#139](https://codeberg.org/uzu/strudel/pulls/139) +- 2022-06-21T14:11:50+02:00 Fix createParam() by yaxu in: [#140](https://codeberg.org/uzu/strudel/pulls/140) +- 2022-06-18T23:24:42+02:00 Webaudio rewrite by froos in: [#138](https://codeberg.org/uzu/strudel/pulls/138) +- 2022-06-16T21:58:38+02:00 add onTrigger helper by froos in: [#136](https://codeberg.org/uzu/strudel/pulls/136) +- 2022-06-16T20:48:23+02:00 Scheduler improvements by froos in: [#134](https://codeberg.org/uzu/strudel/pulls/134) +- 2022-06-16T20:48:07+02:00 remove cycle + delta from onTrigger by froos in: [#135](https://codeberg.org/uzu/strudel/pulls/135) +- 2022-06-13T21:28:27+02:00 add createParam + createParams by froos in: [#110](https://codeberg.org/uzu/strudel/pulls/110) +- 2022-06-13T21:27:09+02:00 Pianoroll enhancements by froos in: [#131](https://codeberg.org/uzu/strudel/pulls/131) +- 2022-06-05T13:06:03+02:00 Fix link to contributing to tutorial docs by Ghost in: [#129](https://codeberg.org/uzu/strudel/pulls/129) +- 2022-06-02T00:20:45+02:00 Webdirt by froos in: [#121](https://codeberg.org/uzu/strudel/pulls/121) +- 2022-06-01T23:56:04+02:00 fix: #122 ctrl enter would add newline by froos in: [#124](https://codeberg.org/uzu/strudel/pulls/124) +- 2022-06-01T18:21:56+02:00 fix: #108 by froos in: [#123](https://codeberg.org/uzu/strudel/pulls/123) + +## may 2022 + +- 2022-05-29T09:54:59+02:00 In source doc by froos in: [#117](https://codeberg.org/uzu/strudel/pulls/117) +- 2022-05-20T11:49:10+02:00 react package + vite build by froos in: [#116](https://codeberg.org/uzu/strudel/pulls/116) +- 2022-05-15T22:29:26+02:00 Osc timing improvements by yaxu in: [#113](https://codeberg.org/uzu/strudel/pulls/113) +- 2022-05-15T22:28:24+02:00 loopAt by yaxu in: [#114](https://codeberg.org/uzu/strudel/pulls/114) +- 2022-05-09T20:09:47+02:00 `.brak()`, `.inside()` and `.outside()` by yaxu in: [#112](https://codeberg.org/uzu/strudel/pulls/112) +- 2022-05-06T15:18:41+02:00 In source doc by yaxu in: [#105](https://codeberg.org/uzu/strudel/pulls/105) +- 2022-05-04T22:59:31+02:00 Embed style by froos in: [#109](https://codeberg.org/uzu/strudel/pulls/109) +- 2022-05-03T01:40:22+02:00 Reset, Restart and other composers by froos in: [#88](https://codeberg.org/uzu/strudel/pulls/88) +- 2022-05-02T22:47:21+02:00 /embed package: web component for repl by froos in: [#106](https://codeberg.org/uzu/strudel/pulls/106) +- 2022-05-02T22:05:34+02:00 Tune tests by froos in: [#104](https://codeberg.org/uzu/strudel/pulls/104) +- 2022-05-01T14:33:11+02:00 Codemirror 6 by froos in: [#97](https://codeberg.org/uzu/strudel/pulls/97) + +## april 2022 + +- 2022-04-28T23:45:53+02:00 Work on Codemirror 6 highlighting by Ghost in: [#102](https://codeberg.org/uzu/strudel/pulls/102) +- 2022-04-28T15:46:06+02:00 Change to Affero GPL by yaxu in: [#101](https://codeberg.org/uzu/strudel/pulls/101) +- 2022-04-26T00:13:07+02:00 Paper by froos in: [#98](https://codeberg.org/uzu/strudel/pulls/98) +- 2022-04-25T22:10:21+02:00 Fiddles with cat/stack by yaxu in: [#90](https://codeberg.org/uzu/strudel/pulls/90) +- 2022-04-22T13:08:11+02:00 Add pattern composers, implements #82 by yaxu in: [#83](https://codeberg.org/uzu/strudel/pulls/83) +- 2022-04-21T20:57:45+02:00 Tidy up a couple of old files by Ghost in: [#84](https://codeberg.org/uzu/strudel/pulls/84) +- 2022-04-21T15:21:29+02:00 add `striate()` by yaxu in: [#76](https://codeberg.org/uzu/strudel/pulls/76) +- 2022-04-20T20:17:27+02:00 Webaudio in REPL by froos in: [#77](https://codeberg.org/uzu/strudel/pulls/77) +- 2022-04-19T15:31:34+02:00 Basic webserial support by yaxu in: [#80](https://codeberg.org/uzu/strudel/pulls/80) +- 2022-04-17T19:29:49+02:00 Try to fix appLeft / appRight by yaxu in: [#75](https://codeberg.org/uzu/strudel/pulls/75) +- 2022-04-16T13:26:57+02:00 More random functions by yaxu in: [#74](https://codeberg.org/uzu/strudel/pulls/74) +- 2022-04-16T11:13:26+02:00 Port `perlin` noise, `rangex`, and `palindrome` by yaxu in: [#73](https://codeberg.org/uzu/strudel/pulls/73) +- 2022-04-16T10:26:07+02:00 webaudio package by froos in: [#26](https://codeberg.org/uzu/strudel/pulls/26) +- 2022-04-15T20:18:06+02:00 More randomness, fix `rand`, and add `brand`, `irand` and `choose` by yaxu in: [#70](https://codeberg.org/uzu/strudel/pulls/70) +- 2022-04-15T11:29:51+02:00 First effort at rand() by yaxu in: [#69](https://codeberg.org/uzu/strudel/pulls/69) +- 2022-04-14T17:41:18+02:00 use new fixed version of osc-js package by froos in: [#68](https://codeberg.org/uzu/strudel/pulls/68) +- 2022-04-14T00:09:18+02:00 Speech output by froos in: [#67](https://codeberg.org/uzu/strudel/pulls/67) +- 2022-04-13T23:55:33+02:00 Separate out strudel.mjs, make index.mjs aggregate module by yaxu in: [#62](https://codeberg.org/uzu/strudel/pulls/62) +- 2022-04-13T17:26:45+02:00 More functions by yaxu in: [#61](https://codeberg.org/uzu/strudel/pulls/61) +- 2022-04-13T10:04:29+02:00 More functions by yaxu in: [#56](https://codeberg.org/uzu/strudel/pulls/56) +- 2022-04-12T17:04:04+02:00 OSC and SuperDirt support by yaxu in: [#27](https://codeberg.org/uzu/strudel/pulls/27) +- 2022-04-12T13:24:14+02:00 Implement `chop()` by yaxu in: [#50](https://codeberg.org/uzu/strudel/pulls/50) +- 2022-04-12T12:37:32+02:00 First run at squeezeBind, ref #32 by yaxu in: [#48](https://codeberg.org/uzu/strudel/pulls/48) +- 2022-04-12T00:03:37+02:00 Fix polymeter by yaxu in: [#44](https://codeberg.org/uzu/strudel/pulls/44) +- 2022-04-11T22:39:44+02:00 Compose by froos in: [#40](https://codeberg.org/uzu/strudel/pulls/40) +- 2022-04-11T21:49:35+02:00 Update tutorial.mdx by Ghost in: [#38](https://codeberg.org/uzu/strudel/pulls/38) +- 2022-04-11T08:43:44+02:00 Update tutorial.mdx by Ghost in: [#37](https://codeberg.org/uzu/strudel/pulls/37) + +## march 2022 + +- 2022-03-28T17:27:22+02:00 Add chunk, chunkBack and iterBack by yaxu in: [#25](https://codeberg.org/uzu/strudel/pulls/25) +- 2022-03-28T11:48:22+02:00 packaging by froos in: [#24](https://codeberg.org/uzu/strudel/pulls/24) +- 2022-03-22T12:06:48+01:00 Update package.json by Ghost in: [#23](https://codeberg.org/uzu/strudel/pulls/23) +- 2022-03-06T20:35:20+01:00 added _asNumber + interprete numbers as midi by froos in: [#21](https://codeberg.org/uzu/strudel/pulls/21) + +## february 2022 + +- 2022-02-28T00:32:29+01:00 Fix resolveState by yaxu in: [#22](https://codeberg.org/uzu/strudel/pulls/22) +- 2022-02-27T20:52:52+01:00 Stateful queries and events (WIP) by yaxu in: [#14](https://codeberg.org/uzu/strudel/pulls/14) +- 2022-02-27T18:04:07+01:00 fix: 💄 Enhance visualisation of the Tutorial on mobile by Ghost in: [#19](https://codeberg.org/uzu/strudel/pulls/19) +- 2022-02-26T21:16:34+01:00 test: 📦 Add missing dependency and a CI check, to prevent oversights ;p by Ghost in: [#17](https://codeberg.org/uzu/strudel/pulls/17) +- 2022-02-26T13:29:19+01:00 higher latencyHint by froos in: [#16](https://codeberg.org/uzu/strudel/pulls/16) +- 2022-02-23T22:15:11+01:00 add apply and layer, and missing div/mul methods by yaxu in: [#15](https://codeberg.org/uzu/strudel/pulls/15) +- 2022-02-21T01:02:07+01:00 Add continuous signals (sine, cosine, saw, etc) by yaxu in: [#13](https://codeberg.org/uzu/strudel/pulls/13) +- 2022-02-19T21:30:04+01:00 Added mask() and struct() by yaxu in: [#11](https://codeberg.org/uzu/strudel/pulls/11) +- 2022-02-19T16:07:07+01:00 Failing test for `when` WIP by yaxu in: [#10](https://codeberg.org/uzu/strudel/pulls/10) +- 2022-02-10T17:21:31+01:00 Bugfix every, and create more top level functions by yaxu in: [#9](https://codeberg.org/uzu/strudel/pulls/9) +- 2022-02-10T00:51:21+01:00 timeCat by yaxu in: [#8](https://codeberg.org/uzu/strudel/pulls/8) +- 2022-02-07T23:07:58+01:00 fixed editor crash by froos in: [#7](https://codeberg.org/uzu/strudel/pulls/7) +- 2022-02-07T19:08:40+01:00 krill parser + improved repl by froos in: [#6](https://codeberg.org/uzu/strudel/pulls/6) +- 2022-02-06T00:59:16+01:00 Patternify all the things by yaxu in: [#5](https://codeberg.org/uzu/strudel/pulls/5) +- 2022-02-05T23:31:37+01:00 update readme for local dev by Ghost in: [#4](https://codeberg.org/uzu/strudel/pulls/4) +- 2022-02-05T22:36:06+01:00 Fix path by yaxu in: [#3](https://codeberg.org/uzu/strudel/pulls/3) +- 2022-02-05T21:52:51+01:00 repl + reify functions by froos in: [#2](https://codeberg.org/uzu/strudel/pulls/2) +[9:37:36] strudel % \ No newline at end of file diff --git a/warm.js b/warm.js index 0d148dee9..846d59a99 100644 --- a/warm.js +++ b/warm.js @@ -1,14 +1,30 @@ -fetch('https://codeberg.org/api/v1/repos/uzu/strudel/pulls?state=closed&page=1') - .then((res) => res.json()) - .then((pulls) => { - const r = pulls - .filter((pull) => pull.merged) - .sort((a, b) => new Date(b.closed_at) - new Date(a.closed_at)) - .map((pull) => `${pull.closed_at} ${pull.title} by ${pull.user.login || '?'} in: [#${pull.number}](${pull.url}) `) - .join('\n'); - console.log(r); - }); +// this script loads all merged PRs within the given page range +// it can be used to update the CHANGELOG.md file in a semi-automated way +// the problem: codeberg doesn't support loading merged PRs, so we have to filter them in memory +// luckily, we can sort after "recentupdate", which means we can do incremental changelog generation +// todo: support setting a "last_updated" date, so the script would automatically check how far it has to go -/* +async function main() { + let pageStart = 1; + let pageEnd = 1; + let prs = []; + for (let p = pageStart; p <= pageEnd; p++) { + console.log(`load page ${p}/${pageEnd}`); + const res = await fetch( + `https://codeberg.org/api/v1/repos/uzu/strudel/pulls?state=closed&sort=recentupdate&page=${p}`, + ); + const pulls = await res.json(); + const merged = pulls.filter((pull) => pull.merged); + prs = prs.concat(merged); + } + const output = prs + .sort((a, b) => new Date(b.closed_at) - new Date(a.closed_at)) + .map( + (pull) => `- ${pull.closed_at} ${pull.title} by @${pull.user.login || '?'} in: [#${pull.number}](${pull.url}) `, + ) + .join('\n'); + console.log('-------------'); + console.log(output); +} - */ +main(); From 3d13955c41cf9fa4e6ffafa1262d0d53b95c17a5 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 16 Jan 2026 10:08:41 +0100 Subject: [PATCH 78/79] fix: prefix usernames with @ --- CHANGELOG.md | 1854 +++++++++++++++++++++++++------------------------- 1 file changed, 927 insertions(+), 927 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3daf4e6cf..587343e43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,1076 +5,1076 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly ## january 2026 -- 2026-01-15T16:59:14+01:00 mondo fix: add registered functions to scope automatically by daslyfe in: [#1896](https://codeberg.org/uzu/strudel/pulls/1896) -- 2026-01-15T16:58:14+01:00 Added docs for pattern search by JohnBjrk in: [#1905](https://codeberg.org/uzu/strudel/pulls/1905) -- 2026-01-15T16:57:19+01:00 Update kabelsalat dependency by jeromew in: [#1911](https://codeberg.org/uzu/strudel/pulls/1911) -- 2026-01-15T00:24:39+01:00 Bug Fix: Set pooled values immediately instead of scheduling by glossing in: [#1907](https://codeberg.org/uzu/strudel/pulls/1907) -- 2026-01-14T20:29:16+01:00 Feat: Kabelsalat integration by glossing in: [#1876](https://codeberg.org/uzu/strudel/pulls/1876) -- 2026-01-14T19:07:49+01:00 Feat: MIDI Keyboard 🎹🐈 by glossing in: [#1828](https://codeberg.org/uzu/strudel/pulls/1828) -- 2026-01-14T18:14:52+01:00 Bug Fix: Fix race condition between worklet termination and port messages by glossing in: [#1897](https://codeberg.org/uzu/strudel/pulls/1897) -- 2026-01-13T04:06:52+01:00 Add search/filter in patterns tab by JohnBjrk in: [#1842](https://codeberg.org/uzu/strudel/pulls/1842) -- 2026-01-13T00:18:10+01:00 Add shortcut for navigating through labels! by daslyfe in: [#1807](https://codeberg.org/uzu/strudel/pulls/1807) -- 2026-01-12T00:17:37+01:00 add warm.strudel.cc to faq by yaxu in: [#1891](https://codeberg.org/uzu/strudel/pulls/1891) -- 2026-01-11T19:00:25+01:00 Fix sounds example to work in the REPL by JesCoding in: [#1851](https://codeberg.org/uzu/strudel/pulls/1851) -- 2026-01-11T13:52:02+01:00 Improve hint text when sound search has no results by floy in: [#1883](https://codeberg.org/uzu/strudel/pulls/1883) -- 2026-01-11T13:19:46+01:00 New page FAQ in "More" by scrappy_fiddler in: [#1753](https://codeberg.org/uzu/strudel/pulls/1753) -- 2026-01-11T12:45:07+01:00 fix: remove faulty default readme by froos in: [#1889](https://codeberg.org/uzu/strudel/pulls/1889) -- 2026-01-11T12:15:34+01:00 fix/self-hosted-config by alienmind in: [#1880](https://codeberg.org/uzu/strudel/pulls/1880) -- 2026-01-11T12:07:48+01:00 Feat: Support External AudioContext Injection by 1d10t in: [#1833](https://codeberg.org/uzu/strudel/pulls/1833) -- 2026-01-11T11:37:37+01:00 fix: add trem to top level by froos in: [#1887](https://codeberg.org/uzu/strudel/pulls/1887) -- 2026-01-11T11:37:18+01:00 fix: export start cycle min 0 by froos in: [#1888](https://codeberg.org/uzu/strudel/pulls/1888) -- 2026-01-11T11:05:44+01:00 fix: repl package init audio properly by froos in: [#1836](https://codeberg.org/uzu/strudel/pulls/1836) -- 2026-01-11T06:51:24+01:00 Fix: show reload dialog when uploading prebake script by daslyfe in: [#1886](https://codeberg.org/uzu/strudel/pulls/1886) -- 2026-01-11T06:01:42+01:00 fixes Serial onTrigger() params #1633 by gueejla in: [#1885](https://codeberg.org/uzu/strudel/pulls/1885) -- 2026-01-10T23:12:48+01:00 Perf: Targeted node pools by glossing in: [#1810](https://codeberg.org/uzu/strudel/pulls/1810) -- 2026-01-10T20:52:40+01:00 Allow top level distortions for the purpose of FX by glossing in: [#1884](https://codeberg.org/uzu/strudel/pulls/1884) -- 2026-01-09T03:43:37+01:00 Bake in scaling by `freq` for FM with a gain node by glossing in: [#1878](https://codeberg.org/uzu/strudel/pulls/1878) -- 2026-01-09T02:53:38+01:00 Bug fix: Properly handle subcontrols by glossing in: [#1877](https://codeberg.org/uzu/strudel/pulls/1877) -- 2026-01-07T20:06:18+01:00 Feat: Add ability to turn mini parsing off with mini-off decorator by glossing in: [#1786](https://codeberg.org/uzu/strudel/pulls/1786) -- 2026-01-07T19:22:24+01:00 Bug Fix: Update loopStart/End to not be offset by glossing in: [#1826](https://codeberg.org/uzu/strudel/pulls/1826) -- 2026-01-06T06:35:49+01:00 Update modulator docstrings and allow ids to be patterns by glossing in: [#1874](https://codeberg.org/uzu/strudel/pulls/1874) -- 2026-01-04T17:14:11+01:00 Fix doc link in @strudel/osc README.md by forrcaho in: [#1872](https://codeberg.org/uzu/strudel/pulls/1872) -- 2026-01-04T02:01:07+01:00 Make stretch modulatable by glossing in: [#1870](https://codeberg.org/uzu/strudel/pulls/1870) -- 2026-01-02T18:44:53+01:00 Make pan modulatable by glossing in: [#1865](https://codeberg.org/uzu/strudel/pulls/1865) -- 2026-01-01T21:42:23+01:00 Fix transpilation example to have same mini-notation by JesCoding in: [#1850](https://codeberg.org/uzu/strudel/pulls/1850) -- 2026-01-01T21:39:05+01:00 fix: missing punctuation by eddyflux in: [#1860](https://codeberg.org/uzu/strudel/pulls/1860) -- 2026-01-01T20:20:34+01:00 Fix formatting of docstring by glossing in: [#1864](https://codeberg.org/uzu/strudel/pulls/1864) -- 2026-01-01T19:52:15+01:00 Feat: FX Chains by glossing in: [#1861](https://codeberg.org/uzu/strudel/pulls/1861) +- 2026-01-15T16:59:14+01:00 mondo fix: add registered functions to scope automatically by @daslyfe in: [#1896](https://codeberg.org/uzu/strudel/pulls/1896) +- 2026-01-15T16:58:14+01:00 Added docs for pattern search by @JohnBjrk in: [#1905](https://codeberg.org/uzu/strudel/pulls/1905) +- 2026-01-15T16:57:19+01:00 Update kabelsalat dependency by @jeromew in: [#1911](https://codeberg.org/uzu/strudel/pulls/1911) +- 2026-01-15T00:24:39+01:00 Bug Fix: Set pooled values immediately instead of scheduling by @glossing in: [#1907](https://codeberg.org/uzu/strudel/pulls/1907) +- 2026-01-14T20:29:16+01:00 Feat: Kabelsalat integration by @glossing in: [#1876](https://codeberg.org/uzu/strudel/pulls/1876) +- 2026-01-14T19:07:49+01:00 Feat: MIDI Keyboard 🎹🐈 by @glossing in: [#1828](https://codeberg.org/uzu/strudel/pulls/1828) +- 2026-01-14T18:14:52+01:00 Bug Fix: Fix race condition between worklet termination and port messages by @glossing in: [#1897](https://codeberg.org/uzu/strudel/pulls/1897) +- 2026-01-13T04:06:52+01:00 Add search/filter in patterns tab by @JohnBjrk in: [#1842](https://codeberg.org/uzu/strudel/pulls/1842) +- 2026-01-13T00:18:10+01:00 Add shortcut for navigating through labels! by @daslyfe in: [#1807](https://codeberg.org/uzu/strudel/pulls/1807) +- 2026-01-12T00:17:37+01:00 add warm.strudel.cc to faq by @yaxu in: [#1891](https://codeberg.org/uzu/strudel/pulls/1891) +- 2026-01-11T19:00:25+01:00 Fix sounds example to work in the REPL by @JesCoding in: [#1851](https://codeberg.org/uzu/strudel/pulls/1851) +- 2026-01-11T13:52:02+01:00 Improve hint text when sound search has no results by @floy in: [#1883](https://codeberg.org/uzu/strudel/pulls/1883) +- 2026-01-11T13:19:46+01:00 New page FAQ in "More" by @scrappy_fiddler in: [#1753](https://codeberg.org/uzu/strudel/pulls/1753) +- 2026-01-11T12:45:07+01:00 fix: remove faulty default readme by @froos in: [#1889](https://codeberg.org/uzu/strudel/pulls/1889) +- 2026-01-11T12:15:34+01:00 fix/self-hosted-config by @alienmind in: [#1880](https://codeberg.org/uzu/strudel/pulls/1880) +- 2026-01-11T12:07:48+01:00 Feat: Support External AudioContext Injection by @1d10t in: [#1833](https://codeberg.org/uzu/strudel/pulls/1833) +- 2026-01-11T11:37:37+01:00 fix: add trem to top level by @froos in: [#1887](https://codeberg.org/uzu/strudel/pulls/1887) +- 2026-01-11T11:37:18+01:00 fix: export start cycle min 0 by @froos in: [#1888](https://codeberg.org/uzu/strudel/pulls/1888) +- 2026-01-11T11:05:44+01:00 fix: repl package init audio properly by @froos in: [#1836](https://codeberg.org/uzu/strudel/pulls/1836) +- 2026-01-11T06:51:24+01:00 Fix: show reload dialog when uploading prebake script by @daslyfe in: [#1886](https://codeberg.org/uzu/strudel/pulls/1886) +- 2026-01-11T06:01:42+01:00 fixes Serial onTrigger() params #1633 by @gueejla in: [#1885](https://codeberg.org/uzu/strudel/pulls/1885) +- 2026-01-10T23:12:48+01:00 Perf: Targeted node pools by @glossing in: [#1810](https://codeberg.org/uzu/strudel/pulls/1810) +- 2026-01-10T20:52:40+01:00 Allow top level distortions for the purpose of FX by @glossing in: [#1884](https://codeberg.org/uzu/strudel/pulls/1884) +- 2026-01-09T03:43:37+01:00 Bake in scaling by `freq` for FM with a gain node by @glossing in: [#1878](https://codeberg.org/uzu/strudel/pulls/1878) +- 2026-01-09T02:53:38+01:00 Bug fix: Properly handle subcontrols by @glossing in: [#1877](https://codeberg.org/uzu/strudel/pulls/1877) +- 2026-01-07T20:06:18+01:00 Feat: Add ability to turn mini parsing off with mini-off decorator by @glossing in: [#1786](https://codeberg.org/uzu/strudel/pulls/1786) +- 2026-01-07T19:22:24+01:00 Bug Fix: Update loopStart/End to not be offset by @glossing in: [#1826](https://codeberg.org/uzu/strudel/pulls/1826) +- 2026-01-06T06:35:49+01:00 Update modulator docstrings and allow ids to be patterns by @glossing in: [#1874](https://codeberg.org/uzu/strudel/pulls/1874) +- 2026-01-04T17:14:11+01:00 Fix doc link in @strudel/osc README.md by @forrcaho in: [#1872](https://codeberg.org/uzu/strudel/pulls/1872) +- 2026-01-04T02:01:07+01:00 Make stretch modulatable by @glossing in: [#1870](https://codeberg.org/uzu/strudel/pulls/1870) +- 2026-01-02T18:44:53+01:00 Make pan modulatable by @glossing in: [#1865](https://codeberg.org/uzu/strudel/pulls/1865) +- 2026-01-01T21:42:23+01:00 Fix transpilation example to have same mini-notation by @JesCoding in: [#1850](https://codeberg.org/uzu/strudel/pulls/1850) +- 2026-01-01T21:39:05+01:00 fix: missing punctuation by @eddyflux in: [#1860](https://codeberg.org/uzu/strudel/pulls/1860) +- 2026-01-01T20:20:34+01:00 Fix formatting of docstring by @glossing in: [#1864](https://codeberg.org/uzu/strudel/pulls/1864) +- 2026-01-01T19:52:15+01:00 Feat: FX Chains by @glossing in: [#1861](https://codeberg.org/uzu/strudel/pulls/1861) ## december 2025 -- 2025-12-29T21:59:11+01:00 Bugfix: Fix modulator clamping when min/max not specified by glossing in: [#1859](https://codeberg.org/uzu/strudel/pulls/1859) -- 2025-12-29T20:54:11+01:00 Feature: LFOs and Envelopes by glossing in: [#1507](https://codeberg.org/uzu/strudel/pulls/1507) -- 2025-12-29T16:07:18+01:00 Fix AudioContext change detection. Use AudioNode.context by jeromew in: [#1858](https://codeberg.org/uzu/strudel/pulls/1858) -- 2025-12-28T22:58:38+01:00 Say that @license should use SPDX identifier by Wuzzy in: [#1817](https://codeberg.org/uzu/strudel/pulls/1817) -- 2025-12-28T22:56:07+01:00 Expose Vim object in order to create custom keybindings by JohnBjrk in: [#1816](https://codeberg.org/uzu/strudel/pulls/1816) -- 2025-12-28T14:20:03+01:00 dough repl fixes by froos in: [#1855](https://codeberg.org/uzu/strudel/pulls/1855) -- 2025-12-28T13:40:29+01:00 add basic dough repl by froos in: [#1749](https://codeberg.org/uzu/strudel/pulls/1749) -- 2025-12-20T22:27:52+01:00 Document "-" in mini-notation by Wuzzy in: [#1818](https://codeberg.org/uzu/strudel/pulls/1818) -- 2025-12-20T22:20:27+01:00 simplify envValAtTime and remove asymmetric behavior (fix #1653) by pulu in: [#1815](https://codeberg.org/uzu/strudel/pulls/1815) -- 2025-12-19T08:11:50+01:00 fix: visual block selection mode for vim bindings by Dsm0 in: [#1839](https://codeberg.org/uzu/strudel/pulls/1839) -- 2025-12-19T01:03:53+01:00 [perf] Add audiograph `await debugAudiograph()` feature by jeromew in: [#1763](https://codeberg.org/uzu/strudel/pulls/1763) -- 2025-12-19T00:45:41+01:00 Feature: non-realtime exporting by Ghost in: [#1674](https://codeberg.org/uzu/strudel/pulls/1674) -- 2025-12-14T19:33:37+01:00 Fix: wrong warning in build environments by jeromew in: [#1835](https://codeberg.org/uzu/strudel/pulls/1835) -- 2025-12-14T15:09:12+01:00 delta -> per / perx / cyclesPer refinements by yaxu in: [#1832](https://codeberg.org/uzu/strudel/pulls/1832) -- 2025-12-14T01:07:36+01:00 Improved randomness by glossing in: [#1505](https://codeberg.org/uzu/strudel/pulls/1505) -- 2025-12-12T10:28:27+01:00 Add delta signal for representing the duration of events in patterns that are combined with it by yaxu in: [#1831](https://codeberg.org/uzu/strudel/pulls/1831) -- 2025-12-11T18:00:49+01:00 Feature: stateful timeline function for jumping between timelines by yaxu in: [#1669](https://codeberg.org/uzu/strudel/pulls/1669) -- 2025-12-11T16:37:58+01:00 Updates relating to LLM, github, etc by yaxu in: [#1830](https://codeberg.org/uzu/strudel/pulls/1830) -- 2025-12-10T15:32:44+01:00 fix .as so it doesn't set undefined values by yaxu in: [#1827](https://codeberg.org/uzu/strudel/pulls/1827) -- 2025-12-08T19:27:31+01:00 [perf] propagate `onceEnded` and `releaseAudioNode` by jeromew in: [#1809](https://codeberg.org/uzu/strudel/pulls/1809) -- 2025-12-07T21:51:40+01:00 Feat: Add channel support to midi in by glossing in: [#1775](https://codeberg.org/uzu/strudel/pulls/1775) -- 2025-12-07T21:23:43+01:00 Feat: Transient shaper by glossing in: [#1777](https://codeberg.org/uzu/strudel/pulls/1777) -- 2025-12-07T19:15:43+01:00 Add vel as a synonym for velocity & update a few docstrings by glossing in: [#1781](https://codeberg.org/uzu/strudel/pulls/1781) -- 2025-12-07T18:53:04+01:00 [perf] fix phaser leak of unused biquads by jeromew in: [#1800](https://codeberg.org/uzu/strudel/pulls/1800) -- 2025-12-07T18:42:50+01:00 Bug fix: Remove failing tests due to shabda removal by glossing in: [#1820](https://codeberg.org/uzu/strudel/pulls/1820) -- 2025-12-03T18:27:28+01:00 Feature: Eight FMs by glossing in: [#1628](https://codeberg.org/uzu/strudel/pulls/1628) -- 2025-12-03T17:35:05+01:00 [perf] release unused AudioBufferSourceNode + releaseAudioNode by jeromew in: [#1805](https://codeberg.org/uzu/strudel/pulls/1805) +- 2025-12-29T21:59:11+01:00 Bugfix: Fix modulator clamping when min/max not specified by @glossing in: [#1859](https://codeberg.org/uzu/strudel/pulls/1859) +- 2025-12-29T20:54:11+01:00 Feature: LFOs and Envelopes by @glossing in: [#1507](https://codeberg.org/uzu/strudel/pulls/1507) +- 2025-12-29T16:07:18+01:00 Fix AudioContext change detection. Use AudioNode.context by @jeromew in: [#1858](https://codeberg.org/uzu/strudel/pulls/1858) +- 2025-12-28T22:58:38+01:00 Say that @license should use SPDX identifier by @Wuzzy in: [#1817](https://codeberg.org/uzu/strudel/pulls/1817) +- 2025-12-28T22:56:07+01:00 Expose Vim object in order to create custom keybindings by @JohnBjrk in: [#1816](https://codeberg.org/uzu/strudel/pulls/1816) +- 2025-12-28T14:20:03+01:00 dough repl fixes by @froos in: [#1855](https://codeberg.org/uzu/strudel/pulls/1855) +- 2025-12-28T13:40:29+01:00 add basic dough repl by @froos in: [#1749](https://codeberg.org/uzu/strudel/pulls/1749) +- 2025-12-20T22:27:52+01:00 Document "-" in mini-notation by @Wuzzy in: [#1818](https://codeberg.org/uzu/strudel/pulls/1818) +- 2025-12-20T22:20:27+01:00 simplify envValAtTime and remove asymmetric behavior (fix #1653) by @pulu in: [#1815](https://codeberg.org/uzu/strudel/pulls/1815) +- 2025-12-19T08:11:50+01:00 fix: visual block selection mode for vim bindings by @Dsm0 in: [#1839](https://codeberg.org/uzu/strudel/pulls/1839) +- 2025-12-19T01:03:53+01:00 [perf] Add audiograph `await debugAudiograph()` feature by @jeromew in: [#1763](https://codeberg.org/uzu/strudel/pulls/1763) +- 2025-12-19T00:45:41+01:00 Feature: non-realtime exporting by @Ghost in: [#1674](https://codeberg.org/uzu/strudel/pulls/1674) +- 2025-12-14T19:33:37+01:00 Fix: wrong warning in build environments by @jeromew in: [#1835](https://codeberg.org/uzu/strudel/pulls/1835) +- 2025-12-14T15:09:12+01:00 delta -> per / perx / cyclesPer refinements by @yaxu in: [#1832](https://codeberg.org/uzu/strudel/pulls/1832) +- 2025-12-14T01:07:36+01:00 Improved randomness by @glossing in: [#1505](https://codeberg.org/uzu/strudel/pulls/1505) +- 2025-12-12T10:28:27+01:00 Add delta signal for representing the duration of events in patterns that are combined with it by @yaxu in: [#1831](https://codeberg.org/uzu/strudel/pulls/1831) +- 2025-12-11T18:00:49+01:00 Feature: stateful timeline function for jumping between timelines by @yaxu in: [#1669](https://codeberg.org/uzu/strudel/pulls/1669) +- 2025-12-11T16:37:58+01:00 Updates relating to LLM, github, etc by @yaxu in: [#1830](https://codeberg.org/uzu/strudel/pulls/1830) +- 2025-12-10T15:32:44+01:00 fix .as so it doesn't set undefined values by @yaxu in: [#1827](https://codeberg.org/uzu/strudel/pulls/1827) +- 2025-12-08T19:27:31+01:00 [perf] propagate `onceEnded` and `releaseAudioNode` by @jeromew in: [#1809](https://codeberg.org/uzu/strudel/pulls/1809) +- 2025-12-07T21:51:40+01:00 Feat: Add channel support to midi in by @glossing in: [#1775](https://codeberg.org/uzu/strudel/pulls/1775) +- 2025-12-07T21:23:43+01:00 Feat: Transient shaper by @glossing in: [#1777](https://codeberg.org/uzu/strudel/pulls/1777) +- 2025-12-07T19:15:43+01:00 Add vel as a synonym for velocity & update a few docstrings by @glossing in: [#1781](https://codeberg.org/uzu/strudel/pulls/1781) +- 2025-12-07T18:53:04+01:00 [perf] fix phaser leak of unused biquads by @jeromew in: [#1800](https://codeberg.org/uzu/strudel/pulls/1800) +- 2025-12-07T18:42:50+01:00 Bug fix: Remove failing tests due to shabda removal by @glossing in: [#1820](https://codeberg.org/uzu/strudel/pulls/1820) +- 2025-12-03T18:27:28+01:00 Feature: Eight FMs by @glossing in: [#1628](https://codeberg.org/uzu/strudel/pulls/1628) +- 2025-12-03T17:35:05+01:00 [perf] release unused AudioBufferSourceNode + releaseAudioNode by @jeromew in: [#1805](https://codeberg.org/uzu/strudel/pulls/1805) - **2025-12-01 strudel.cc deployed** ## november 2025 -- 2025-11-29T01:00:42+01:00 added export to getSuperdoughAudioController() so that its possible to route superdough audio through other webaudio applications. by ndr0n in: [#1796](https://codeberg.org/uzu/strudel/pulls/1796) -- 2025-11-28T23:26:20+01:00 add revv() for reversing whole patterns by yaxu in: [#1791](https://codeberg.org/uzu/strudel/pulls/1791) -- 2025-11-28T20:19:16+01:00 [perf] Disconnect lfos for phaser and filters by glossing in: [#1787](https://codeberg.org/uzu/strudel/pulls/1787) -- 2025-11-27T23:08:52+01:00 fix: return silence when no pattern is returned by froos in: [#1795](https://codeberg.org/uzu/strudel/pulls/1795) -- 2025-11-27T22:47:03+01:00 fix(tool/dbpatch): add missing package name by peterpf in: [#1765](https://codeberg.org/uzu/strudel/pulls/1765) -- 2025-11-27T22:38:05+01:00 add CHANGELOG.md + basic script to generate by froos in: [#1794](https://codeberg.org/uzu/strudel/pulls/1794) -- 2025-11-27T22:03:53+01:00 [perf] in `noise`, let noiseMix do the disconnect when it exists by jeromew in: [#1783](https://codeberg.org/uzu/strudel/pulls/1783) -- 2025-11-27T22:01:01+01:00 Bug Fix: Retries for sounds tab by glossing in: [#1754](https://codeberg.org/uzu/strudel/pulls/1754) -- 2025-11-27T20:36:46+01:00 [hydra] return the hydra object when await initHydra(..) is called by jeromew in: [#1784](https://codeberg.org/uzu/strudel/pulls/1784) -- 2025-11-27T20:36:14+01:00 Use errorLogger for query and tonal errors by glossing in: [#1782](https://codeberg.org/uzu/strudel/pulls/1782) -- 2025-11-27T20:27:10+01:00 [perf] level 5 `connect-leak` on `vowel` by jeromew in: [#1779](https://codeberg.org/uzu/strudel/pulls/1779) -- 2025-11-26T08:23:38+01:00 feat: add prebake script import button for loading .strudel files by daslyfe in: [#1774](https://codeberg.org/uzu/strudel/pulls/1774) -- 2025-11-26T07:39:28+01:00 Fix Sampler port trampling by Dayglo in: [#1717](https://codeberg.org/uzu/strudel/pulls/1717) -- 2025-11-25T20:59:09+01:00 Feat: Hook up octave and fix example by glossing in: [#1773](https://codeberg.org/uzu/strudel/pulls/1773) -- 2025-11-25T20:48:09+01:00 [perf] fix `connect-leak` in `tremolo` param by jeromew in: [#1780](https://codeberg.org/uzu/strudel/pulls/1780) -- 2025-11-24T17:51:20+01:00 filter modulation improvements! by daslyfe in: [#1769](https://codeberg.org/uzu/strudel/pulls/1769) -- 2025-11-24T01:20:53+01:00 Add o as a synonym for orbit by daslyfe in: [#1766](https://codeberg.org/uzu/strudel/pulls/1766) -- 2025-11-23T22:23:26+01:00 [perf] fix `connect-leak` in `fm` modulation by jeromew in: [#1758](https://codeberg.org/uzu/strudel/pulls/1758) -- 2025-11-23T09:47:24+01:00 Fix interoperability issue between `all` and `await initHydra()` by jeromew in: [#1663](https://codeberg.org/uzu/strudel/pulls/1663) -- 2025-11-23T04:23:06+01:00 Bug fix: Swap l/r gains with temp variable by glossing in: [#1768](https://codeberg.org/uzu/strudel/pulls/1768) -- 2025-11-23T00:52:28+01:00 FIX: prevent LFO filter modulation from popping from negative values by daslyfe in: [#1767](https://codeberg.org/uzu/strudel/pulls/1767) -- 2025-11-23T00:03:32+01:00 prefix "S" for solo by froos in: [#1481](https://codeberg.org/uzu/strudel/pulls/1481) -- 2025-11-21T01:56:11+01:00 Bug Fix: Use frac due to negative frequencies from FM by glossing in: [#1759](https://codeberg.org/uzu/strudel/pulls/1759) -- 2025-11-20T19:48:16+01:00 [perf] fix `connect-leak` added by #1742 when noise() is not used by jeromew in: [#1757](https://codeberg.org/uzu/strudel/pulls/1757) -- 2025-11-20T14:51:00+01:00 [perf] fix `connect-leak` in `delay` effect by jeromew in: [#1755](https://codeberg.org/uzu/strudel/pulls/1755) -- 2025-11-20T14:49:41+01:00 [perf] fix `connect leak` when .noise() is in the mix by jeromew in: [#1742](https://codeberg.org/uzu/strudel/pulls/1742) -- 2025-11-18T23:52:45+01:00 wchooseCycles has now notes in an example by scrappy_fiddler in: [#1748](https://codeberg.org/uzu/strudel/pulls/1748) -- 2025-11-17T05:31:54+01:00 Feature: Partials by glossing in: [#1659](https://codeberg.org/uzu/strudel/pulls/1659) -- 2025-11-16T22:06:14+01:00 README: update superdough documentation by TristanMlct in: [#1741](https://codeberg.org/uzu/strudel/pulls/1741) -- 2025-11-16T22:00:43+01:00 Feature: Envelope worklet by glossing in: [#1524](https://codeberg.org/uzu/strudel/pulls/1524) -- 2025-11-16T21:08:54+01:00 Worklet optimizations by glossing in: [#1730](https://codeberg.org/uzu/strudel/pulls/1730) -- 2025-11-15T14:59:30+01:00 [perf] disconnect Offline AudioNode connections in generateReverb by jeromew in: [#1740](https://codeberg.org/uzu/strudel/pulls/1740) -- 2025-11-15T14:57:47+01:00 [perf] disconnect `send` effect AudioNode when `room` is used by jeromew in: [#1736](https://codeberg.org/uzu/strudel/pulls/1736) -- 2025-11-12T21:22:34+01:00 [supradough] fix: unstable filter by froos in: [#1593](https://codeberg.org/uzu/strudel/pulls/1593) -- 2025-11-12T21:12:07+01:00 Fix link syntax in `project-start` by Kissaki in: [#1724](https://codeberg.org/uzu/strudel/pulls/1724) -- 2025-11-12T21:06:13+01:00 Fix web README sample code by Kissaki in: [#1725](https://codeberg.org/uzu/strudel/pulls/1725) -- 2025-11-12T20:59:39+01:00 Fix typo: 'studel' -> 'strudel' by drhayes in: [#1726](https://codeberg.org/uzu/strudel/pulls/1726) -- 2025-11-12T15:23:41+01:00 fix for node 24 support in tests - #1718 by ausav in: [#1719](https://codeberg.org/uzu/strudel/pulls/1719) -- 2025-11-11T09:00:49+01:00 soundAlias example fix by PepsiiMan in: [#1720](https://codeberg.org/uzu/strudel/pulls/1720) -- 2025-11-10T08:18:36+01:00 fix: Make Supradough package build by munshkr in: [#1711](https://codeberg.org/uzu/strudel/pulls/1711) -- 2025-11-10T08:18:00+01:00 added docs for spaces in scale names by ondras in: [#1715](https://codeberg.org/uzu/strudel/pulls/1715) -- 2025-11-10T02:44:01+01:00 Feature: LFOs for Filters by glossing in: [#1636](https://codeberg.org/uzu/strudel/pulls/1636) -- 2025-11-05T17:07:00+01:00 improvement: sync midi messages to audio context clock by daslyfe in: [#1708](https://codeberg.org/uzu/strudel/pulls/1708) -- 2025-11-04T19:36:14+01:00 Add stick button mappings to gamepad implementation and improve docs by kaosuryoko in: [#1696](https://codeberg.org/uzu/strudel/pulls/1696) -- 2025-11-04T19:29:35+01:00 Refactor sound stopping and triggering logic in SoundsTab component by IJOL in: [#1688](https://codeberg.org/uzu/strudel/pulls/1688) -- 2025-11-04T19:13:21+01:00 Add setting to toggle pattern auto-start on pattern change by moumar in: [#1690](https://codeberg.org/uzu/strudel/pulls/1690) -- 2025-11-04T18:58:50+01:00 Voicings JSDoc by sharkeys_lunchbox in: [#1686](https://codeberg.org/uzu/strudel/pulls/1686) -- 2025-11-01T07:50:40+01:00 FIX: Loading local samples uses too much memory by daslyfe in: [#1706](https://codeberg.org/uzu/strudel/pulls/1706) +- 2025-11-29T01:00:42+01:00 added export to getSuperdoughAudioController() so that its possible to route superdough audio through other webaudio applications. by @ndr0n in: [#1796](https://codeberg.org/uzu/strudel/pulls/1796) +- 2025-11-28T23:26:20+01:00 add revv() for reversing whole patterns by @yaxu in: [#1791](https://codeberg.org/uzu/strudel/pulls/1791) +- 2025-11-28T20:19:16+01:00 [perf] Disconnect lfos for phaser and filters by @glossing in: [#1787](https://codeberg.org/uzu/strudel/pulls/1787) +- 2025-11-27T23:08:52+01:00 fix: return silence when no pattern is returned by @froos in: [#1795](https://codeberg.org/uzu/strudel/pulls/1795) +- 2025-11-27T22:47:03+01:00 fix(tool/dbpatch): add missing package name by @peterpf in: [#1765](https://codeberg.org/uzu/strudel/pulls/1765) +- 2025-11-27T22:38:05+01:00 add CHANGELOG.md + basic script to generate by @froos in: [#1794](https://codeberg.org/uzu/strudel/pulls/1794) +- 2025-11-27T22:03:53+01:00 [perf] in `noise`, let noiseMix do the disconnect when it exists by @jeromew in: [#1783](https://codeberg.org/uzu/strudel/pulls/1783) +- 2025-11-27T22:01:01+01:00 Bug Fix: Retries for sounds tab by @glossing in: [#1754](https://codeberg.org/uzu/strudel/pulls/1754) +- 2025-11-27T20:36:46+01:00 [hydra] return the hydra object when await initHydra(..) is called by @jeromew in: [#1784](https://codeberg.org/uzu/strudel/pulls/1784) +- 2025-11-27T20:36:14+01:00 Use errorLogger for query and tonal errors by @glossing in: [#1782](https://codeberg.org/uzu/strudel/pulls/1782) +- 2025-11-27T20:27:10+01:00 [perf] level 5 `connect-leak` on `vowel` by @jeromew in: [#1779](https://codeberg.org/uzu/strudel/pulls/1779) +- 2025-11-26T08:23:38+01:00 feat: add prebake script import button for loading .strudel files by @daslyfe in: [#1774](https://codeberg.org/uzu/strudel/pulls/1774) +- 2025-11-26T07:39:28+01:00 Fix Sampler port trampling by @Dayglo in: [#1717](https://codeberg.org/uzu/strudel/pulls/1717) +- 2025-11-25T20:59:09+01:00 Feat: Hook up octave and fix example by @glossing in: [#1773](https://codeberg.org/uzu/strudel/pulls/1773) +- 2025-11-25T20:48:09+01:00 [perf] fix `connect-leak` in `tremolo` param by @jeromew in: [#1780](https://codeberg.org/uzu/strudel/pulls/1780) +- 2025-11-24T17:51:20+01:00 filter modulation improvements! by @daslyfe in: [#1769](https://codeberg.org/uzu/strudel/pulls/1769) +- 2025-11-24T01:20:53+01:00 Add o as a synonym for orbit by @daslyfe in: [#1766](https://codeberg.org/uzu/strudel/pulls/1766) +- 2025-11-23T22:23:26+01:00 [perf] fix `connect-leak` in `fm` modulation by @jeromew in: [#1758](https://codeberg.org/uzu/strudel/pulls/1758) +- 2025-11-23T09:47:24+01:00 Fix interoperability issue between `all` and `await initHydra()` by @jeromew in: [#1663](https://codeberg.org/uzu/strudel/pulls/1663) +- 2025-11-23T04:23:06+01:00 Bug fix: Swap l/r gains with temp variable by @glossing in: [#1768](https://codeberg.org/uzu/strudel/pulls/1768) +- 2025-11-23T00:52:28+01:00 FIX: prevent LFO filter modulation from popping from negative values by @daslyfe in: [#1767](https://codeberg.org/uzu/strudel/pulls/1767) +- 2025-11-23T00:03:32+01:00 prefix "S" for solo by @froos in: [#1481](https://codeberg.org/uzu/strudel/pulls/1481) +- 2025-11-21T01:56:11+01:00 Bug Fix: Use frac due to negative frequencies from FM by @glossing in: [#1759](https://codeberg.org/uzu/strudel/pulls/1759) +- 2025-11-20T19:48:16+01:00 [perf] fix `connect-leak` added by #1742 when noise() is not used by @jeromew in: [#1757](https://codeberg.org/uzu/strudel/pulls/1757) +- 2025-11-20T14:51:00+01:00 [perf] fix `connect-leak` in `delay` effect by @jeromew in: [#1755](https://codeberg.org/uzu/strudel/pulls/1755) +- 2025-11-20T14:49:41+01:00 [perf] fix `connect leak` when .noise() is in the mix by @jeromew in: [#1742](https://codeberg.org/uzu/strudel/pulls/1742) +- 2025-11-18T23:52:45+01:00 wchooseCycles has now notes in an example by @scrappy_fiddler in: [#1748](https://codeberg.org/uzu/strudel/pulls/1748) +- 2025-11-17T05:31:54+01:00 Feature: Partials by @glossing in: [#1659](https://codeberg.org/uzu/strudel/pulls/1659) +- 2025-11-16T22:06:14+01:00 README: update superdough documentation by @TristanMlct in: [#1741](https://codeberg.org/uzu/strudel/pulls/1741) +- 2025-11-16T22:00:43+01:00 Feature: Envelope worklet by @glossing in: [#1524](https://codeberg.org/uzu/strudel/pulls/1524) +- 2025-11-16T21:08:54+01:00 Worklet optimizations by @glossing in: [#1730](https://codeberg.org/uzu/strudel/pulls/1730) +- 2025-11-15T14:59:30+01:00 [perf] disconnect Offline AudioNode connections in generateReverb by @jeromew in: [#1740](https://codeberg.org/uzu/strudel/pulls/1740) +- 2025-11-15T14:57:47+01:00 [perf] disconnect `send` effect AudioNode when `room` is used by @jeromew in: [#1736](https://codeberg.org/uzu/strudel/pulls/1736) +- 2025-11-12T21:22:34+01:00 [supradough] fix: unstable filter by @froos in: [#1593](https://codeberg.org/uzu/strudel/pulls/1593) +- 2025-11-12T21:12:07+01:00 Fix link syntax in `project-start` by @Kissaki in: [#1724](https://codeberg.org/uzu/strudel/pulls/1724) +- 2025-11-12T21:06:13+01:00 Fix web README sample code by @Kissaki in: [#1725](https://codeberg.org/uzu/strudel/pulls/1725) +- 2025-11-12T20:59:39+01:00 Fix typo: 'studel' -> 'strudel' by @drhayes in: [#1726](https://codeberg.org/uzu/strudel/pulls/1726) +- 2025-11-12T15:23:41+01:00 fix for node 24 support in tests - #1718 by @ausav in: [#1719](https://codeberg.org/uzu/strudel/pulls/1719) +- 2025-11-11T09:00:49+01:00 soundAlias example fix by @PepsiiMan in: [#1720](https://codeberg.org/uzu/strudel/pulls/1720) +- 2025-11-10T08:18:36+01:00 fix: Make Supradough package build by @munshkr in: [#1711](https://codeberg.org/uzu/strudel/pulls/1711) +- 2025-11-10T08:18:00+01:00 added docs for spaces in scale names by @ondras in: [#1715](https://codeberg.org/uzu/strudel/pulls/1715) +- 2025-11-10T02:44:01+01:00 Feature: LFOs for Filters by @glossing in: [#1636](https://codeberg.org/uzu/strudel/pulls/1636) +- 2025-11-05T17:07:00+01:00 improvement: sync midi messages to audio context clock by @daslyfe in: [#1708](https://codeberg.org/uzu/strudel/pulls/1708) +- 2025-11-04T19:36:14+01:00 Add stick button mappings to gamepad implementation and improve docs by @kaosuryoko in: [#1696](https://codeberg.org/uzu/strudel/pulls/1696) +- 2025-11-04T19:29:35+01:00 Refactor sound stopping and triggering logic in SoundsTab component by @IJOL in: [#1688](https://codeberg.org/uzu/strudel/pulls/1688) +- 2025-11-04T19:13:21+01:00 Add setting to toggle pattern auto-start on pattern change by @moumar in: [#1690](https://codeberg.org/uzu/strudel/pulls/1690) +- 2025-11-04T18:58:50+01:00 Voicings JSDoc by @sharkeys_lunchbox in: [#1686](https://codeberg.org/uzu/strudel/pulls/1686) +- 2025-11-01T07:50:40+01:00 FIX: Loading local samples uses too much memory by @daslyfe in: [#1706](https://codeberg.org/uzu/strudel/pulls/1706) ## october 2025 -- 2025-10-28T22:58:24+01:00 Bug Fix: Handle scale-for-notes when n also supplied by glossing in: [#1625](https://codeberg.org/uzu/strudel/pulls/1625) -- 2025-10-28T22:51:16+01:00 Repurpose vim shortcuts for usability by dtricks in: [#1624](https://codeberg.org/uzu/strudel/pulls/1624) -- 2025-10-28T22:35:21+01:00 Add support for euclidian in mondo with `bd&3:8` by TristanCacqueray in: [#1630](https://codeberg.org/uzu/strudel/pulls/1630) -- 2025-10-27T10:42:07+01:00 Use bunny cdn for all samples and json files by yaxu in: [#1701](https://codeberg.org/uzu/strudel/pulls/1701) +- 2025-10-28T22:58:24+01:00 Bug Fix: Handle scale-for-notes when n also supplied by @glossing in: [#1625](https://codeberg.org/uzu/strudel/pulls/1625) +- 2025-10-28T22:51:16+01:00 Repurpose vim shortcuts for usability by @dtricks in: [#1624](https://codeberg.org/uzu/strudel/pulls/1624) +- 2025-10-28T22:35:21+01:00 Add support for euclidian in mondo with `bd&3:8` by @TristanCacqueray in: [#1630](https://codeberg.org/uzu/strudel/pulls/1630) +- 2025-10-27T10:42:07+01:00 Use bunny cdn for all samples and json files by @yaxu in: [#1701](https://codeberg.org/uzu/strudel/pulls/1701) - **2025-10-27 @strudel/core@1.2.5** -- 2025-10-26T22:52:54+01:00 degithub - switch some samples to bunnycdn by yaxu in: [#1697](https://codeberg.org/uzu/strudel/pulls/1697) -- 2025-10-26T17:09:22+01:00 Fix ZZFX example by moumar in: [#1685](https://codeberg.org/uzu/strudel/pulls/1685) -- 2025-10-23T15:56:04+02:00 Make osc port and host configurable. Changes dependencies. by yaxu in: [#1682](https://codeberg.org/uzu/strudel/pulls/1682) -- 2025-10-23T03:47:31+02:00 Adds back shape to superdough by glossing in: [#1672](https://codeberg.org/uzu/strudel/pulls/1672) -- 2025-10-22T22:15:19+02:00 Fix sampler.mjs githubPath by jeromew in: [#1684](https://codeberg.org/uzu/strudel/pulls/1684) -- 2025-10-22T16:20:50+02:00 Fix onPaint for widgets by yaxu in: [#1658](https://codeberg.org/uzu/strudel/pulls/1658) -- 2025-10-22T15:19:12+02:00 Fix a bug introduced by #4e17cfbdd6 by milliganf in: [#1679](https://codeberg.org/uzu/strudel/pulls/1679) -- 2025-10-20T22:37:15+02:00 feature/autocomplete-sound-names by drdozer in: [#1564](https://codeberg.org/uzu/strudel/pulls/1564) -- 2025-10-20T21:58:12+02:00 add replicate + use it for ! in mondo by JoStro in: [#1436](https://codeberg.org/uzu/strudel/pulls/1436) -- 2025-10-18T04:29:20+02:00 Bug Fix: Wavetable: phase wrapping at 1 and detune by glossing in: [#1620](https://codeberg.org/uzu/strudel/pulls/1620) -- 2025-10-16T20:26:28+02:00 github samples: default to "samples" if repository is not specified by prezmop in: [#1644](https://codeberg.org/uzu/strudel/pulls/1644) -- 2025-10-16T17:33:39+02:00 Docs: add example of custom chained function by dariusk in: [#1642](https://codeberg.org/uzu/strudel/pulls/1642) -- 2025-10-14T12:39:48+02:00 textbox by yaxu in: [#1650](https://codeberg.org/uzu/strudel/pulls/1650) -- 2025-10-13T07:26:51+02:00 Feature: Distortion Modes by glossing in: [#1561](https://codeberg.org/uzu/strudel/pulls/1561) -- 2025-10-13T07:05:57+02:00 Feature: Wavetable FM by glossing in: [#1623](https://codeberg.org/uzu/strudel/pulls/1623) -- 2025-10-12T20:43:42+02:00 fix: repair REPL sample sources and URL concat (#1640) by erikfox in: [#1646](https://codeberg.org/uzu/strudel/pulls/1646) -- 2025-10-10T11:25:02+02:00 Add control-metadata by yaxu in: [#1634](https://codeberg.org/uzu/strudel/pulls/1634) -- 2025-10-07T22:59:39+02:00 Fix MQTT: change the trigger handler to match new hap by jurrchen in: [#1629](https://codeberg.org/uzu/strudel/pulls/1629) -- 2025-10-05T21:42:19+02:00 Fix case sensitivity for synonym search by vvolhejn in: [#1618](https://codeberg.org/uzu/strudel/pulls/1618) -- 2025-10-01T08:56:35+02:00 Optimize wavetable synth by glossing in: [#1613](https://codeberg.org/uzu/strudel/pulls/1613) -- 2025-10-01T02:02:33+02:00 fix: pattern switching by daslyfe in: [#1616](https://codeberg.org/uzu/strudel/pulls/1616) +- 2025-10-26T22:52:54+01:00 degithub - switch some samples to bunnycdn by @yaxu in: [#1697](https://codeberg.org/uzu/strudel/pulls/1697) +- 2025-10-26T17:09:22+01:00 Fix ZZFX example by @moumar in: [#1685](https://codeberg.org/uzu/strudel/pulls/1685) +- 2025-10-23T15:56:04+02:00 Make osc port and host configurable. Changes dependencies. by @yaxu in: [#1682](https://codeberg.org/uzu/strudel/pulls/1682) +- 2025-10-23T03:47:31+02:00 Adds back shape to superdough by @glossing in: [#1672](https://codeberg.org/uzu/strudel/pulls/1672) +- 2025-10-22T22:15:19+02:00 Fix sampler.mjs githubPath by @jeromew in: [#1684](https://codeberg.org/uzu/strudel/pulls/1684) +- 2025-10-22T16:20:50+02:00 Fix onPaint for widgets by @yaxu in: [#1658](https://codeberg.org/uzu/strudel/pulls/1658) +- 2025-10-22T15:19:12+02:00 Fix a bug introduced by #4e17cfbdd6 by @milliganf in: [#1679](https://codeberg.org/uzu/strudel/pulls/1679) +- 2025-10-20T22:37:15+02:00 feature/autocomplete-sound-names by @drdozer in: [#1564](https://codeberg.org/uzu/strudel/pulls/1564) +- 2025-10-20T21:58:12+02:00 add replicate + use it for ! in mondo by @JoStro in: [#1436](https://codeberg.org/uzu/strudel/pulls/1436) +- 2025-10-18T04:29:20+02:00 Bug Fix: Wavetable: phase wrapping at 1 and detune by @glossing in: [#1620](https://codeberg.org/uzu/strudel/pulls/1620) +- 2025-10-16T20:26:28+02:00 github samples: default to "samples" if repository is not specified by @prezmop in: [#1644](https://codeberg.org/uzu/strudel/pulls/1644) +- 2025-10-16T17:33:39+02:00 Docs: add example of custom chained function by @dariusk in: [#1642](https://codeberg.org/uzu/strudel/pulls/1642) +- 2025-10-14T12:39:48+02:00 textbox by @yaxu in: [#1650](https://codeberg.org/uzu/strudel/pulls/1650) +- 2025-10-13T07:26:51+02:00 Feature: Distortion Modes by @glossing in: [#1561](https://codeberg.org/uzu/strudel/pulls/1561) +- 2025-10-13T07:05:57+02:00 Feature: Wavetable FM by @glossing in: [#1623](https://codeberg.org/uzu/strudel/pulls/1623) +- 2025-10-12T20:43:42+02:00 fix: repair REPL sample sources and URL concat (#1640) by @erikfox in: [#1646](https://codeberg.org/uzu/strudel/pulls/1646) +- 2025-10-10T11:25:02+02:00 Add control-metadata by @yaxu in: [#1634](https://codeberg.org/uzu/strudel/pulls/1634) +- 2025-10-07T22:59:39+02:00 Fix MQTT: change the trigger handler to match new hap by @jurrchen in: [#1629](https://codeberg.org/uzu/strudel/pulls/1629) +- 2025-10-05T21:42:19+02:00 Fix case sensitivity for synonym search by @vvolhejn in: [#1618](https://codeberg.org/uzu/strudel/pulls/1618) +- 2025-10-01T08:56:35+02:00 Optimize wavetable synth by @glossing in: [#1613](https://codeberg.org/uzu/strudel/pulls/1613) +- 2025-10-01T02:02:33+02:00 fix: pattern switching by @daslyfe in: [#1616](https://codeberg.org/uzu/strudel/pulls/1616) ## september 2025 -- 2025-09-29T02:10:54+02:00 fix wavetable JSON by daslyfe in: [#1611](https://codeberg.org/uzu/strudel/pulls/1611) -- 2025-09-28T21:28:16+02:00 rename wavetable controls to match existing naming conventions by daslyfe in: [#1610](https://codeberg.org/uzu/strudel/pulls/1610) -- 2025-09-27T23:28:13+02:00 Feature: Wavetable synth improvements by glossing in: [#1607](https://codeberg.org/uzu/strudel/pulls/1607) -- 2025-09-27T21:43:10+02:00 wavetable improvements by daslyfe in: [#1608](https://codeberg.org/uzu/strudel/pulls/1608) -- 2025-09-26T08:48:46+02:00 create orbit based DJ filter by daslyfe in: [#1603](https://codeberg.org/uzu/strudel/pulls/1603) -- 2025-09-26T08:15:49+02:00 Feature: Wavetable synth by glossing in: [#1525](https://codeberg.org/uzu/strudel/pulls/1525) -- 2025-09-23T13:28:20+02:00 fix: time signal by daslyfe in: [#1583](https://codeberg.org/uzu/strudel/pulls/1583) -- 2025-09-21T16:16:06+02:00 mondo: fix all + setcpm + setcps by froos in: [#1600](https://codeberg.org/uzu/strudel/pulls/1600) -- 2025-09-19T21:59:43+02:00 fix: osc error message by froos in: [#1597](https://codeberg.org/uzu/strudel/pulls/1597) -- 2025-09-18T21:09:56+02:00 osc: --debug flag to see incoming messages by froos in: [#1595](https://codeberg.org/uzu/strudel/pulls/1595) -- 2025-09-17T14:12:10+02:00 simplify osc usage by froos in: [#1588](https://codeberg.org/uzu/strudel/pulls/1588) -- 2025-09-16T16:59:58+02:00 dev: logger errors to console in dev mode by daslyfe in: [#1585](https://codeberg.org/uzu/strudel/pulls/1585) -- 2025-09-16T03:19:37+02:00 Bug Fix / Feature: Updates to `duck` to avoid clicks and allow configuration over release/attack by glossing in: [#1514](https://codeberg.org/uzu/strudel/pulls/1514) -- 2025-09-15T23:36:31+02:00 Feat: Enhance `scale` function to quantize notes to a named scale by glossing in: [#1492](https://codeberg.org/uzu/strudel/pulls/1492) -- 2025-09-15T22:52:14+02:00 add tic80 font by froos in: [#1579](https://codeberg.org/uzu/strudel/pulls/1579) -- 2025-09-15T00:00:19+02:00 supradough: fix delay + add some jsdoc types by froos in: [#1578](https://codeberg.org/uzu/strudel/pulls/1578) -- 2025-09-14T12:42:58+02:00 added plyWith/plyWithClassic functions by Dsm0 in: [#1571](https://codeberg.org/uzu/strudel/pulls/1571) -- 2025-09-14T10:39:12+02:00 feat: sound alias by Options in: [#1494](https://codeberg.org/uzu/strudel/pulls/1494) -- 2025-09-14T01:20:15+02:00 Bug Fix: Allow penv values to be falsy by glossing in: [#1559](https://codeberg.org/uzu/strudel/pulls/1559) -- 2025-09-14T01:10:48+02:00 Update website/src/pages/workshop/first-sounds.mdx by fesmith in: [#1566](https://codeberg.org/uzu/strudel/pulls/1566) -- 2025-09-14T01:07:47+02:00 fix: autocomplete-styles + html rendering by froos in: [#1570](https://codeberg.org/uzu/strudel/pulls/1570) -- 2025-09-14T00:49:17+02:00 Feature: Synonyms in autocomplete and reference by glossing in: [#1535](https://codeberg.org/uzu/strudel/pulls/1535) -- 2025-09-13T20:01:48+02:00 Docs: add xen package examples by dudymas in: [#1446](https://codeberg.org/uzu/strudel/pulls/1446) -- 2025-09-13T19:51:10+02:00 Update website/src/pages/learn/code.mdx by anecondev in: [#1391](https://codeberg.org/uzu/strudel/pulls/1391) -- 2025-09-11T22:52:30+02:00 supradough poc by froos in: [#1362](https://codeberg.org/uzu/strudel/pulls/1362) -- 2025-09-11T17:29:35+02:00 fix: exclude mondough dependencies by froos in: [#1563](https://codeberg.org/uzu/strudel/pulls/1563) -- 2025-09-11T00:27:21+02:00 add basicSetup for keybindings by Dsm0 in: [#1462](https://codeberg.org/uzu/strudel/pulls/1462) -- 2025-09-10T17:25:26+02:00 feat: add delete user samples button for convenience by daslyfe in: [#1556](https://codeberg.org/uzu/strudel/pulls/1556) -- 2025-09-08T08:54:01+02:00 Fix formatting of REPL footnote by ddbeck in: [#1547](https://codeberg.org/uzu/strudel/pulls/1547) -- 2025-09-08T05:38:08+02:00 fix: OSC by daslyfe in: [#1557](https://codeberg.org/uzu/strudel/pulls/1557) -- 2025-09-07T22:47:13+02:00 Add examples for ? and | operators to documentation by james-collapse in: [#1532](https://codeberg.org/uzu/strudel/pulls/1532) -- 2025-09-07T21:48:19+02:00 Signal flow documentation by glossing in: [#1504](https://codeberg.org/uzu/strudel/pulls/1504) -- 2025-09-07T21:27:29+02:00 Allow flattening of dirs with sample server by glossing in: [#1529](https://codeberg.org/uzu/strudel/pulls/1529) -- 2025-09-07T21:05:24+02:00 fix: prevent orbit clicking by defining max number of channels in an orbit by daslyfe in: [#1552](https://codeberg.org/uzu/strudel/pulls/1552) -- 2025-09-02T08:42:42+02:00 Padding for tooltips, preserving linebreaks in descriptions, not closing autocompletes on click by glossing in: [#1521](https://codeberg.org/uzu/strudel/pulls/1521) -- 2025-09-01T17:50:11+02:00 Update "restore defaults" to not delete patterns by glossing in: [#1519](https://codeberg.org/uzu/strudel/pulls/1519) +- 2025-09-29T02:10:54+02:00 fix wavetable JSON by @daslyfe in: [#1611](https://codeberg.org/uzu/strudel/pulls/1611) +- 2025-09-28T21:28:16+02:00 rename wavetable controls to match existing naming conventions by @daslyfe in: [#1610](https://codeberg.org/uzu/strudel/pulls/1610) +- 2025-09-27T23:28:13+02:00 Feature: Wavetable synth improvements by @glossing in: [#1607](https://codeberg.org/uzu/strudel/pulls/1607) +- 2025-09-27T21:43:10+02:00 wavetable improvements by @daslyfe in: [#1608](https://codeberg.org/uzu/strudel/pulls/1608) +- 2025-09-26T08:48:46+02:00 create orbit based DJ filter by @daslyfe in: [#1603](https://codeberg.org/uzu/strudel/pulls/1603) +- 2025-09-26T08:15:49+02:00 Feature: Wavetable synth by @glossing in: [#1525](https://codeberg.org/uzu/strudel/pulls/1525) +- 2025-09-23T13:28:20+02:00 fix: time signal by @daslyfe in: [#1583](https://codeberg.org/uzu/strudel/pulls/1583) +- 2025-09-21T16:16:06+02:00 mondo: fix all + setcpm + setcps by @froos in: [#1600](https://codeberg.org/uzu/strudel/pulls/1600) +- 2025-09-19T21:59:43+02:00 fix: osc error message by @froos in: [#1597](https://codeberg.org/uzu/strudel/pulls/1597) +- 2025-09-18T21:09:56+02:00 osc: --debug flag to see incoming messages by @froos in: [#1595](https://codeberg.org/uzu/strudel/pulls/1595) +- 2025-09-17T14:12:10+02:00 simplify osc usage by @froos in: [#1588](https://codeberg.org/uzu/strudel/pulls/1588) +- 2025-09-16T16:59:58+02:00 dev: logger errors to console in dev mode by @daslyfe in: [#1585](https://codeberg.org/uzu/strudel/pulls/1585) +- 2025-09-16T03:19:37+02:00 Bug Fix / Feature: Updates to `duck` to avoid clicks and allow configuration over release/attack by @glossing in: [#1514](https://codeberg.org/uzu/strudel/pulls/1514) +- 2025-09-15T23:36:31+02:00 Feat: Enhance `scale` function to quantize notes to a named scale by @glossing in: [#1492](https://codeberg.org/uzu/strudel/pulls/1492) +- 2025-09-15T22:52:14+02:00 add tic80 font by @froos in: [#1579](https://codeberg.org/uzu/strudel/pulls/1579) +- 2025-09-15T00:00:19+02:00 supradough: fix delay + add some jsdoc types by @froos in: [#1578](https://codeberg.org/uzu/strudel/pulls/1578) +- 2025-09-14T12:42:58+02:00 added plyWith/plyWithClassic functions by @Dsm0 in: [#1571](https://codeberg.org/uzu/strudel/pulls/1571) +- 2025-09-14T10:39:12+02:00 feat: sound alias by @Options in: [#1494](https://codeberg.org/uzu/strudel/pulls/1494) +- 2025-09-14T01:20:15+02:00 Bug Fix: Allow penv values to be falsy by @glossing in: [#1559](https://codeberg.org/uzu/strudel/pulls/1559) +- 2025-09-14T01:10:48+02:00 Update website/src/pages/workshop/first-sounds.mdx by @fesmith in: [#1566](https://codeberg.org/uzu/strudel/pulls/1566) +- 2025-09-14T01:07:47+02:00 fix: autocomplete-styles + html rendering by @froos in: [#1570](https://codeberg.org/uzu/strudel/pulls/1570) +- 2025-09-14T00:49:17+02:00 Feature: Synonyms in autocomplete and reference by @glossing in: [#1535](https://codeberg.org/uzu/strudel/pulls/1535) +- 2025-09-13T20:01:48+02:00 Docs: add xen package examples by @dudymas in: [#1446](https://codeberg.org/uzu/strudel/pulls/1446) +- 2025-09-13T19:51:10+02:00 Update website/src/pages/learn/code.mdx by @anecondev in: [#1391](https://codeberg.org/uzu/strudel/pulls/1391) +- 2025-09-11T22:52:30+02:00 supradough poc by @froos in: [#1362](https://codeberg.org/uzu/strudel/pulls/1362) +- 2025-09-11T17:29:35+02:00 fix: exclude mondough dependencies by @froos in: [#1563](https://codeberg.org/uzu/strudel/pulls/1563) +- 2025-09-11T00:27:21+02:00 add basicSetup for keybindings by @Dsm0 in: [#1462](https://codeberg.org/uzu/strudel/pulls/1462) +- 2025-09-10T17:25:26+02:00 feat: add delete user samples button for convenience by @daslyfe in: [#1556](https://codeberg.org/uzu/strudel/pulls/1556) +- 2025-09-08T08:54:01+02:00 Fix formatting of REPL footnote by @ddbeck in: [#1547](https://codeberg.org/uzu/strudel/pulls/1547) +- 2025-09-08T05:38:08+02:00 fix: OSC by @daslyfe in: [#1557](https://codeberg.org/uzu/strudel/pulls/1557) +- 2025-09-07T22:47:13+02:00 Add examples for ? and | operators to documentation by james-@collapse in: [#1532](https://codeberg.org/uzu/strudel/pulls/1532) +- 2025-09-07T21:48:19+02:00 Signal flow documentation by @glossing in: [#1504](https://codeberg.org/uzu/strudel/pulls/1504) +- 2025-09-07T21:27:29+02:00 Allow flattening of dirs with sample server by @glossing in: [#1529](https://codeberg.org/uzu/strudel/pulls/1529) +- 2025-09-07T21:05:24+02:00 fix: prevent orbit clicking by defining max number of channels in an orbit by @daslyfe in: [#1552](https://codeberg.org/uzu/strudel/pulls/1552) +- 2025-09-02T08:42:42+02:00 Padding for tooltips, preserving linebreaks in descriptions, not closing autocompletes on click by @glossing in: [#1521](https://codeberg.org/uzu/strudel/pulls/1521) +- 2025-09-01T17:50:11+02:00 Update "restore defaults" to not delete patterns by @glossing in: [#1519](https://codeberg.org/uzu/strudel/pulls/1519) ## august 2025 -- 2025-08-31T19:10:04+02:00 feat: add the ability to control the speed and start time of the reverb IR by daslyfe in: [#1501](https://codeberg.org/uzu/strudel/pulls/1501) -- 2025-08-25T02:31:22+02:00 Bug Fix: Duck on Mobile / Safari by glossing in: [#1503](https://codeberg.org/uzu/strudel/pulls/1503) -- 2025-08-23T18:39:53+02:00 fix benchmarks by yaxu in: [#1517](https://codeberg.org/uzu/strudel/pulls/1517) -- 2025-08-21T20:57:31+02:00 add --json flag to @strudel/sampler to generate a strudel.json by froos in: [#1513](https://codeberg.org/uzu/strudel/pulls/1513) -- 2025-08-21T10:04:28+02:00 remove hs2js postinstall by froos in: [#1510](https://codeberg.org/uzu/strudel/pulls/1510) -- 2025-08-20T15:15:34+02:00 doc: scrub, duckorbit, duckattack, duckdepth + fix: arp, arpWidth, hush by fyynn in: [#1502](https://codeberg.org/uzu/strudel/pulls/1502) -- 2025-08-20T12:31:37+02:00 fix: repl autocomplete not rendering correctly by robase in: [#1480](https://codeberg.org/uzu/strudel/pulls/1480) -- 2025-08-20T12:10:02+02:00 BUG FIX: make 'midin' initialization work with multiple controllers by cbabraham in: [#1469](https://codeberg.org/uzu/strudel/pulls/1469) -- 2025-08-17T23:18:46+02:00 euclidish by yaxu in: [#1482](https://codeberg.org/uzu/strudel/pulls/1482) -- 2025-08-17T06:37:23+02:00 feat: Create a duck (sidechain) orbit effect by daslyfe in: [#1470](https://codeberg.org/uzu/strudel/pulls/1470) -- 2025-08-17T04:40:15+02:00 Bug Fix: Restore `log` functionality after onTrigger arg removal by glossing in: [#1491](https://codeberg.org/uzu/strudel/pulls/1491) -- 2025-08-17T04:33:39+02:00 Bug Fix: Handle zero appearing first in FM's ADSR by glossing in: [#1496](https://codeberg.org/uzu/strudel/pulls/1496) -- 2025-08-17T04:27:19+02:00 Bug Fix: FM (and vibrato) for Supersaws by glossing in: [#1495](https://codeberg.org/uzu/strudel/pulls/1495) -- 2025-08-04T07:51:31+02:00 Fix incorrect stack Mini Notation by samyk in: [#1484](https://codeberg.org/uzu/strudel/pulls/1484) -- 2025-08-03T18:57:45+02:00 fix: regression caused by incorrectly exported alias for transpose and scaleTranspose by daslyfe in: [#1489](https://codeberg.org/uzu/strudel/pulls/1489) -- 2025-08-03T18:34:13+02:00 Add `strans` and `scaleTrans` as synonyms of `scaleTranspose` by TodePond in: [#1488](https://codeberg.org/uzu/strudel/pulls/1488) -- 2025-08-02T18:18:28+02:00 Add `trans` alias for `transpose` by TodePond in: [#1487](https://codeberg.org/uzu/strudel/pulls/1487) -- 2025-08-02T03:27:26+02:00 feat: Create Accurate 909 bass drum synthesizer by daslyfe in: [#1478](https://codeberg.org/uzu/strudel/pulls/1478) -- 2025-08-02T03:23:49+02:00 feat: Add fmwave control and ability to fm with noise by daslyfe in: [#1472](https://codeberg.org/uzu/strudel/pulls/1472) +- 2025-08-31T19:10:04+02:00 feat: add the ability to control the speed and start time of the reverb IR by @daslyfe in: [#1501](https://codeberg.org/uzu/strudel/pulls/1501) +- 2025-08-25T02:31:22+02:00 Bug Fix: Duck on Mobile / Safari by @glossing in: [#1503](https://codeberg.org/uzu/strudel/pulls/1503) +- 2025-08-23T18:39:53+02:00 fix benchmarks by @yaxu in: [#1517](https://codeberg.org/uzu/strudel/pulls/1517) +- 2025-08-21T20:57:31+02:00 add --json flag to @strudel/sampler to generate a strudel.json by @froos in: [#1513](https://codeberg.org/uzu/strudel/pulls/1513) +- 2025-08-21T10:04:28+02:00 remove hs2js postinstall by @froos in: [#1510](https://codeberg.org/uzu/strudel/pulls/1510) +- 2025-08-20T15:15:34+02:00 doc: scrub, duckorbit, duckattack, duckdepth + fix: arp, arpWidth, hush by @fyynn in: [#1502](https://codeberg.org/uzu/strudel/pulls/1502) +- 2025-08-20T12:31:37+02:00 fix: repl autocomplete not rendering correctly by @robase in: [#1480](https://codeberg.org/uzu/strudel/pulls/1480) +- 2025-08-20T12:10:02+02:00 BUG FIX: make 'midin' initialization work with multiple controllers by @cbabraham in: [#1469](https://codeberg.org/uzu/strudel/pulls/1469) +- 2025-08-17T23:18:46+02:00 euclidish by @yaxu in: [#1482](https://codeberg.org/uzu/strudel/pulls/1482) +- 2025-08-17T06:37:23+02:00 feat: Create a duck (sidechain) orbit effect by @daslyfe in: [#1470](https://codeberg.org/uzu/strudel/pulls/1470) +- 2025-08-17T04:40:15+02:00 Bug Fix: Restore `log` functionality after onTrigger arg removal by @glossing in: [#1491](https://codeberg.org/uzu/strudel/pulls/1491) +- 2025-08-17T04:33:39+02:00 Bug Fix: Handle zero appearing first in FM's ADSR by @glossing in: [#1496](https://codeberg.org/uzu/strudel/pulls/1496) +- 2025-08-17T04:27:19+02:00 Bug Fix: FM (and vibrato) for Supersaws by @glossing in: [#1495](https://codeberg.org/uzu/strudel/pulls/1495) +- 2025-08-04T07:51:31+02:00 Fix incorrect stack Mini Notation by @samyk in: [#1484](https://codeberg.org/uzu/strudel/pulls/1484) +- 2025-08-03T18:57:45+02:00 fix: regression caused by incorrectly exported alias for transpose and scaleTranspose by @daslyfe in: [#1489](https://codeberg.org/uzu/strudel/pulls/1489) +- 2025-08-03T18:34:13+02:00 Add `strans` and `scaleTrans` as synonyms of `scaleTranspose` by @TodePond in: [#1488](https://codeberg.org/uzu/strudel/pulls/1488) +- 2025-08-02T18:18:28+02:00 Add `trans` alias for `transpose` by @TodePond in: [#1487](https://codeberg.org/uzu/strudel/pulls/1487) +- 2025-08-02T03:27:26+02:00 feat: Create Accurate 909 bass drum synthesizer by @daslyfe in: [#1478](https://codeberg.org/uzu/strudel/pulls/1478) +- 2025-08-02T03:23:49+02:00 feat: Add fmwave control and ability to fm with noise by @daslyfe in: [#1472](https://codeberg.org/uzu/strudel/pulls/1472) ## july 2025 -- 2025-07-30T00:22:41+02:00 hotfix: uzu kit JSON should be in the repo to avoid offline loading errors by daslyfe in: [#1485](https://codeberg.org/uzu/strudel/pulls/1485) -- 2025-07-24T05:28:23+02:00 feat: make uzu-drumkit the default drumkit by daslyfe in: [#1422](https://codeberg.org/uzu/strudel/pulls/1422) -- 2025-07-21T07:16:19+02:00 FIX: PWM modulation by daslyfe in: [#1467](https://codeberg.org/uzu/strudel/pulls/1467) -- 2025-07-19T17:16:22+02:00 Tremolo modulation by Ghost in: [#1095](https://codeberg.org/uzu/strudel/pulls/1095) -- 2025-07-15T09:39:33+02:00 fix: can now use def in mondough by froos in: [#1461](https://codeberg.org/uzu/strudel/pulls/1461) -- 2025-07-11T11:10:24+02:00 fixed keybinding presedence issue by Dsm0 in: [#1456](https://codeberg.org/uzu/strudel/pulls/1456) -- 2025-07-11T11:09:05+02:00 added multicursor support on ctrl/cmd + click by Dsm0 in: [#1457](https://codeberg.org/uzu/strudel/pulls/1457) -- 2025-07-09T09:39:46+02:00 added tab-indent setting by Dsm0 in: [#1454](https://codeberg.org/uzu/strudel/pulls/1454) -- 2025-07-08T15:48:41+02:00 ontrigger-refactoring by froos in: [#1442](https://codeberg.org/uzu/strudel/pulls/1442) -- 2025-07-07T23:14:24+02:00 fix: remove first gm_synth_bass_1, as it doesn't work in safari by froos in: [#1452](https://codeberg.org/uzu/strudel/pulls/1452) -- 2025-07-07T00:06:16+02:00 fix: minor doc changes by Aurel300 in: [#1435](https://codeberg.org/uzu/strudel/pulls/1435) -- 2025-07-05T12:53:45+02:00 Fix randrun and deps including shuffle. Fixes #1441 by yaxu in: [#1447](https://codeberg.org/uzu/strudel/pulls/1447) -- 2025-07-05T12:15:52+02:00 add setDefault + resetDefaults to superdough by froos in: [#1433](https://codeberg.org/uzu/strudel/pulls/1433) -- 2025-07-04T22:36:19+02:00 disable fm for supersaw by froos in: [#1443](https://codeberg.org/uzu/strudel/pulls/1443) +- 2025-07-30T00:22:41+02:00 hotfix: uzu kit JSON should be in the repo to avoid offline loading errors by @daslyfe in: [#1485](https://codeberg.org/uzu/strudel/pulls/1485) +- 2025-07-24T05:28:23+02:00 feat: make uzu-drumkit the default drumkit by @daslyfe in: [#1422](https://codeberg.org/uzu/strudel/pulls/1422) +- 2025-07-21T07:16:19+02:00 FIX: PWM modulation by @daslyfe in: [#1467](https://codeberg.org/uzu/strudel/pulls/1467) +- 2025-07-19T17:16:22+02:00 Tremolo modulation by @Ghost in: [#1095](https://codeberg.org/uzu/strudel/pulls/1095) +- 2025-07-15T09:39:33+02:00 fix: can now use def in mondough by @froos in: [#1461](https://codeberg.org/uzu/strudel/pulls/1461) +- 2025-07-11T11:10:24+02:00 fixed keybinding presedence issue by @Dsm0 in: [#1456](https://codeberg.org/uzu/strudel/pulls/1456) +- 2025-07-11T11:09:05+02:00 added multicursor support on ctrl/cmd + click by @Dsm0 in: [#1457](https://codeberg.org/uzu/strudel/pulls/1457) +- 2025-07-09T09:39:46+02:00 added tab-indent setting by @Dsm0 in: [#1454](https://codeberg.org/uzu/strudel/pulls/1454) +- 2025-07-08T15:48:41+02:00 ontrigger-refactoring by @froos in: [#1442](https://codeberg.org/uzu/strudel/pulls/1442) +- 2025-07-07T23:14:24+02:00 fix: remove first gm_synth_bass_1, as it doesn't work in safari by @froos in: [#1452](https://codeberg.org/uzu/strudel/pulls/1452) +- 2025-07-07T00:06:16+02:00 fix: minor doc changes by @Aurel300 in: [#1435](https://codeberg.org/uzu/strudel/pulls/1435) +- 2025-07-05T12:53:45+02:00 Fix randrun and deps including shuffle. Fixes #1441 by @yaxu in: [#1447](https://codeberg.org/uzu/strudel/pulls/1447) +- 2025-07-05T12:15:52+02:00 add setDefault + resetDefaults to superdough by @froos in: [#1433](https://codeberg.org/uzu/strudel/pulls/1433) +- 2025-07-04T22:36:19+02:00 disable fm for supersaw by @froos in: [#1443](https://codeberg.org/uzu/strudel/pulls/1443) ## june 2025 -- 2025-06-30T13:28:10+02:00 corrected minor spelling mistake (#1425) by tj-mueller in: [#1434](https://codeberg.org/uzu/strudel/pulls/1434) -- 2025-06-30T05:26:11+02:00 Add browser cache explanation in samples.mdx by Ghost in: [#1369](https://codeberg.org/uzu/strudel/pulls/1369) -- 2025-06-30T05:18:42+02:00 add-release-notes by froos in: [#1432](https://codeberg.org/uzu/strudel/pulls/1432) -- 2025-06-28T20:30:49+02:00 feat: delaytime in cycles by Ghost in: [#1341](https://codeberg.org/uzu/strudel/pulls/1341) -- 2025-06-28T13:44:49+02:00 Case insensitive search in the reference tab by kdiab in: [#1420](https://codeberg.org/uzu/strudel/pulls/1420) -- 2025-06-28T00:04:13+02:00 add unjoin, into and chunkinto by yaxu in: [#1418](https://codeberg.org/uzu/strudel/pulls/1418) -- 2025-06-26T15:29:46+02:00 mondo notation by froos in: [#1311](https://codeberg.org/uzu/strudel/pulls/1311) -- 2025-06-24T06:14:15+02:00 allow calling `all` multiple times by froos in: [#1417](https://codeberg.org/uzu/strudel/pulls/1417) -- 2025-06-24T05:53:22+02:00 tonal: allow scales without tonic (default to C) by Ghost in: [#1092](https://codeberg.org/uzu/strudel/pulls/1092) -- 2025-06-20T20:00:12+02:00 website intro: fix whitespace and code hosting name by trofi in: [#1400](https://codeberg.org/uzu/strudel/pulls/1400) -- 2025-06-19T10:15:07+02:00 fix stepcat #1396 by yaxu in: [#1398](https://codeberg.org/uzu/strudel/pulls/1398) -- 2025-06-19T09:52:38+02:00 deprecate cpm + refactor docs to use setcpm by froos in: [#1397](https://codeberg.org/uzu/strudel/pulls/1397) -- 2025-06-19T02:49:09+02:00 feat: 3 new codemirror themes by daslyfe in: [#1394](https://codeberg.org/uzu/strudel/pulls/1394) -- 2025-06-14T16:23:00+02:00 link back to tech manual in wiki by yaxu in: [#1382](https://codeberg.org/uzu/strudel/pulls/1382) -- 2025-06-14T14:55:37+02:00 degithub-links by froos in: [#1380](https://codeberg.org/uzu/strudel/pulls/1380) -- 2025-06-13T15:24:42+02:00 fix euclidLegatoRot by bwagner in: [#1378](https://codeberg.org/uzu/strudel/pulls/1378) -- 2025-06-13T10:07:51+02:00 remove-ms by yaxu in: [#1377](https://codeberg.org/uzu/strudel/pulls/1377) -- 2025-06-12T10:25:48+02:00 Share fat URL by Ghost in: [#1375](https://codeberg.org/uzu/strudel/pulls/1375) -- 2025-06-05T20:39:16+02:00 feat: onTriggerTime for interfacing with random APIs and doing illegal things on event time by Ghost in: [#1364](https://codeberg.org/uzu/strudel/pulls/1364) -- 2025-06-05T01:08:18+02:00 feat: berlin noise by Ghost in: [#1363](https://codeberg.org/uzu/strudel/pulls/1363) +- 2025-06-30T13:28:10+02:00 corrected minor spelling mistake (#1425) by tj-@mueller in: [#1434](https://codeberg.org/uzu/strudel/pulls/1434) +- 2025-06-30T05:26:11+02:00 Add browser cache explanation in samples.mdx by @Ghost in: [#1369](https://codeberg.org/uzu/strudel/pulls/1369) +- 2025-06-30T05:18:42+02:00 add-release-notes by @froos in: [#1432](https://codeberg.org/uzu/strudel/pulls/1432) +- 2025-06-28T20:30:49+02:00 feat: delaytime in cycles by @Ghost in: [#1341](https://codeberg.org/uzu/strudel/pulls/1341) +- 2025-06-28T13:44:49+02:00 Case insensitive search in the reference tab by @kdiab in: [#1420](https://codeberg.org/uzu/strudel/pulls/1420) +- 2025-06-28T00:04:13+02:00 add unjoin, into and chunkinto by @yaxu in: [#1418](https://codeberg.org/uzu/strudel/pulls/1418) +- 2025-06-26T15:29:46+02:00 mondo notation by @froos in: [#1311](https://codeberg.org/uzu/strudel/pulls/1311) +- 2025-06-24T06:14:15+02:00 allow calling `all` multiple times by @froos in: [#1417](https://codeberg.org/uzu/strudel/pulls/1417) +- 2025-06-24T05:53:22+02:00 tonal: allow scales without tonic (default to C) by @Ghost in: [#1092](https://codeberg.org/uzu/strudel/pulls/1092) +- 2025-06-20T20:00:12+02:00 website intro: fix whitespace and code hosting name by @trofi in: [#1400](https://codeberg.org/uzu/strudel/pulls/1400) +- 2025-06-19T10:15:07+02:00 fix stepcat #1396 by @yaxu in: [#1398](https://codeberg.org/uzu/strudel/pulls/1398) +- 2025-06-19T09:52:38+02:00 deprecate cpm + refactor docs to use setcpm by @froos in: [#1397](https://codeberg.org/uzu/strudel/pulls/1397) +- 2025-06-19T02:49:09+02:00 feat: 3 new codemirror themes by @daslyfe in: [#1394](https://codeberg.org/uzu/strudel/pulls/1394) +- 2025-06-14T16:23:00+02:00 link back to tech manual in wiki by @yaxu in: [#1382](https://codeberg.org/uzu/strudel/pulls/1382) +- 2025-06-14T14:55:37+02:00 degithub-links by @froos in: [#1380](https://codeberg.org/uzu/strudel/pulls/1380) +- 2025-06-13T15:24:42+02:00 fix euclidLegatoRot by @bwagner in: [#1378](https://codeberg.org/uzu/strudel/pulls/1378) +- 2025-06-13T10:07:51+02:00 remove-ms by @yaxu in: [#1377](https://codeberg.org/uzu/strudel/pulls/1377) +- 2025-06-12T10:25:48+02:00 Share fat URL by @Ghost in: [#1375](https://codeberg.org/uzu/strudel/pulls/1375) +- 2025-06-05T20:39:16+02:00 feat: onTriggerTime for interfacing with random APIs and doing illegal things on event time by @Ghost in: [#1364](https://codeberg.org/uzu/strudel/pulls/1364) +- 2025-06-05T01:08:18+02:00 feat: berlin noise by @Ghost in: [#1363](https://codeberg.org/uzu/strudel/pulls/1363) ## may 2025 -- 2025-05-29T14:36:43+02:00 Fix bytebeat sample offset by Ghost in: [#1359](https://codeberg.org/uzu/strudel/pulls/1359) -- 2025-05-29T12:14:18+02:00 preserve stepcount in chunks by yaxu in: [#1358](https://codeberg.org/uzu/strudel/pulls/1358) -- 2025-05-29T02:34:30+02:00 Byte Beat improvements -> 2 by Ghost in: [#1357](https://codeberg.org/uzu/strudel/pulls/1357) -- 2025-05-28T16:40:32+02:00 Bytebeat improvements by Ghost in: [#1356](https://codeberg.org/uzu/strudel/pulls/1356) -- 2025-05-27T17:42:39+02:00 feat: Byte Beats! by Ghost in: [#1354](https://codeberg.org/uzu/strudel/pulls/1354) -- 2025-05-18T21:43:05+02:00 fix: typo on docs causing problems with autocompletion. by Ghost in: [#1350](https://codeberg.org/uzu/strudel/pulls/1350) -- 2025-05-15T01:12:07+02:00 feat: Create pulsewidth (pw) and pulsewidth lfo parameters by Ghost in: [#1343](https://codeberg.org/uzu/strudel/pulls/1343) -- 2025-05-14T18:25:17+02:00 feat: Multi Channel Orbits by Ghost in: [#1344](https://codeberg.org/uzu/strudel/pulls/1344) -- 2025-05-13T17:45:29+02:00 Fix typo by Ghost in: [#1346](https://codeberg.org/uzu/strudel/pulls/1346) -- 2025-05-02T00:01:27+02:00 Fix web + repl package builds by froos in: [#1339](https://codeberg.org/uzu/strudel/pulls/1339) -- 2025-05-01T23:50:57+02:00 fix: superdough worklets bundling by froos in: [#1338](https://codeberg.org/uzu/strudel/pulls/1338) +- 2025-05-29T14:36:43+02:00 Fix bytebeat sample offset by @Ghost in: [#1359](https://codeberg.org/uzu/strudel/pulls/1359) +- 2025-05-29T12:14:18+02:00 preserve stepcount in chunks by @yaxu in: [#1358](https://codeberg.org/uzu/strudel/pulls/1358) +- 2025-05-29T02:34:30+02:00 Byte Beat improvements -> 2 by @Ghost in: [#1357](https://codeberg.org/uzu/strudel/pulls/1357) +- 2025-05-28T16:40:32+02:00 Bytebeat improvements by @Ghost in: [#1356](https://codeberg.org/uzu/strudel/pulls/1356) +- 2025-05-27T17:42:39+02:00 feat: Byte Beats! by @Ghost in: [#1354](https://codeberg.org/uzu/strudel/pulls/1354) +- 2025-05-18T21:43:05+02:00 fix: typo on docs causing problems with autocompletion. by @Ghost in: [#1350](https://codeberg.org/uzu/strudel/pulls/1350) +- 2025-05-15T01:12:07+02:00 feat: Create pulsewidth (pw) and pulsewidth lfo parameters by @Ghost in: [#1343](https://codeberg.org/uzu/strudel/pulls/1343) +- 2025-05-14T18:25:17+02:00 feat: Multi Channel Orbits by @Ghost in: [#1344](https://codeberg.org/uzu/strudel/pulls/1344) +- 2025-05-13T17:45:29+02:00 Fix typo by @Ghost in: [#1346](https://codeberg.org/uzu/strudel/pulls/1346) +- 2025-05-02T00:01:27+02:00 Fix web + repl package builds by @froos in: [#1339](https://codeberg.org/uzu/strudel/pulls/1339) +- 2025-05-01T23:50:57+02:00 fix: superdough worklets bundling by @froos in: [#1338](https://codeberg.org/uzu/strudel/pulls/1338) ## april 2025 -- 2025-04-27T22:25:54+02:00 FIX: sound import order by Ghost in: [#1333](https://codeberg.org/uzu/strudel/pulls/1333) -- 2025-04-27T18:39:49+02:00 update docs to reflect import sounds tab change by hpunq in: [#1332](https://codeberg.org/uzu/strudel/pulls/1332) -- 2025-04-27T18:38:26+02:00 feat: Improve gain curve by Ghost in: [#1318](https://codeberg.org/uzu/strudel/pulls/1318) -- 2025-04-27T07:54:49+02:00 Add Icon to import sample button by Ghost in: [#1331](https://codeberg.org/uzu/strudel/pulls/1331) -- 2025-04-27T07:53:41+02:00 Add new "import-sounds" tab with explanation on folder import by hpunq in: [#1329](https://codeberg.org/uzu/strudel/pulls/1329) -- 2025-04-22T00:04:38+02:00 feat: new themes + theme improvements by Ghost in: [#1326](https://codeberg.org/uzu/strudel/pulls/1326) -- 2025-04-20T18:24:15+02:00 feat: Create scrub function for scrubbing an audio file by Ghost in: [#1321](https://codeberg.org/uzu/strudel/pulls/1321) -- 2025-04-18T07:17:39+02:00 fix: disable astro toolbar by default by Ghost in: [#1324](https://codeberg.org/uzu/strudel/pulls/1324) -- 2025-04-18T07:17:38+02:00 fix: udels header by Ghost in: [#1325](https://codeberg.org/uzu/strudel/pulls/1325) -- 2025-04-11T09:18:58+02:00 Send delta in OSC message in seconds, to match tidal/superdirt by yaxu in: [#1323](https://codeberg.org/uzu/strudel/pulls/1323) -- 2025-04-08T06:08:57+02:00 FIX: Multichannel Audio by Ghost in: [#1322](https://codeberg.org/uzu/strudel/pulls/1322) -- 2025-04-08T04:18:03+02:00 feat: add max polyphony feature for superdough by Ghost in: [#1317](https://codeberg.org/uzu/strudel/pulls/1317) -- 2025-04-05T21:12:05+02:00 enhancement: make error messages easier to read by Ghost in: [#1315](https://codeberg.org/uzu/strudel/pulls/1315) -- 2025-04-04T06:26:57+02:00 fix: replace empty spaces in registered sound keys by Ghost in: [#1319](https://codeberg.org/uzu/strudel/pulls/1319) +- 2025-04-27T22:25:54+02:00 FIX: sound import order by @Ghost in: [#1333](https://codeberg.org/uzu/strudel/pulls/1333) +- 2025-04-27T18:39:49+02:00 update docs to reflect import sounds tab change by @hpunq in: [#1332](https://codeberg.org/uzu/strudel/pulls/1332) +- 2025-04-27T18:38:26+02:00 feat: Improve gain curve by @Ghost in: [#1318](https://codeberg.org/uzu/strudel/pulls/1318) +- 2025-04-27T07:54:49+02:00 Add Icon to import sample button by @Ghost in: [#1331](https://codeberg.org/uzu/strudel/pulls/1331) +- 2025-04-27T07:53:41+02:00 Add new "import-sounds" tab with explanation on folder import by @hpunq in: [#1329](https://codeberg.org/uzu/strudel/pulls/1329) +- 2025-04-22T00:04:38+02:00 feat: new themes + theme improvements by @Ghost in: [#1326](https://codeberg.org/uzu/strudel/pulls/1326) +- 2025-04-20T18:24:15+02:00 feat: Create scrub function for scrubbing an audio file by @Ghost in: [#1321](https://codeberg.org/uzu/strudel/pulls/1321) +- 2025-04-18T07:17:39+02:00 fix: disable astro toolbar by default by @Ghost in: [#1324](https://codeberg.org/uzu/strudel/pulls/1324) +- 2025-04-18T07:17:38+02:00 fix: udels header by @Ghost in: [#1325](https://codeberg.org/uzu/strudel/pulls/1325) +- 2025-04-11T09:18:58+02:00 Send delta in OSC message in seconds, to match tidal/superdirt by @yaxu in: [#1323](https://codeberg.org/uzu/strudel/pulls/1323) +- 2025-04-08T06:08:57+02:00 FIX: Multichannel Audio by @Ghost in: [#1322](https://codeberg.org/uzu/strudel/pulls/1322) +- 2025-04-08T04:18:03+02:00 feat: add max polyphony feature for superdough by @Ghost in: [#1317](https://codeberg.org/uzu/strudel/pulls/1317) +- 2025-04-05T21:12:05+02:00 enhancement: make error messages easier to read by @Ghost in: [#1315](https://codeberg.org/uzu/strudel/pulls/1315) +- 2025-04-04T06:26:57+02:00 fix: replace empty spaces in registered sound keys by @Ghost in: [#1319](https://codeberg.org/uzu/strudel/pulls/1319) ## march 2025 -- 2025-03-26T17:01:05+01:00 small feat: Add alias for segment and ribbon by Ghost in: [#1314](https://codeberg.org/uzu/strudel/pulls/1314) -- 2025-03-26T14:54:18+01:00 Fix typo pattnr by Ghost in: [#1316](https://codeberg.org/uzu/strudel/pulls/1316) -- 2025-03-23T20:05:31+01:00 bugfix: Allow single param to be used in the as function by Ghost in: [#1312](https://codeberg.org/uzu/strudel/pulls/1312) -- 2025-03-20T23:35:18+01:00 Add MIDI Program Change, SysEx, NRPN, PitchBend and AfterTouch Output by nkymut in: [#1244](https://codeberg.org/uzu/strudel/pulls/1244) -- 2025-03-19T17:32:30+01:00 make soundfont base url configurable by Ghost in: [#1040](https://codeberg.org/uzu/strudel/pulls/1040) -- 2025-03-18T20:07:08+01:00 Add num samples from 0 up to 20 by yaxu in: [#1310](https://codeberg.org/uzu/strudel/pulls/1310) -- 2025-03-17T10:38:54+01:00 add num samples (edited numbers) by yaxu in: [#1309](https://codeberg.org/uzu/strudel/pulls/1309) -- 2025-03-08T22:17:47+01:00 @strudel/sampler improvements by froos in: [#1288](https://codeberg.org/uzu/strudel/pulls/1288) -- 2025-03-08T21:56:50+01:00 Add Gamepad module by nkymut in: [#1223](https://codeberg.org/uzu/strudel/pulls/1223) -- 2025-03-04T19:17:37+01:00 change behaviour of polymeter, and remove polymeterSteps by yaxu in: [#1302](https://codeberg.org/uzu/strudel/pulls/1302) -- 2025-03-04T03:36:57+01:00 feat: Create Pulse Oscillator with variable PWM by Ghost in: [#1304](https://codeberg.org/uzu/strudel/pulls/1304) -- 2025-03-02T17:08:31+01:00 feat: Theme improvements by Ghost in: [#1295](https://codeberg.org/uzu/strudel/pulls/1295) -- 2025-03-02T11:58:46+01:00 bugfix zoom stepcount by yaxu in: [#1301](https://codeberg.org/uzu/strudel/pulls/1301) +- 2025-03-26T17:01:05+01:00 small feat: Add alias for segment and ribbon by @Ghost in: [#1314](https://codeberg.org/uzu/strudel/pulls/1314) +- 2025-03-26T14:54:18+01:00 Fix typo pattnr by @Ghost in: [#1316](https://codeberg.org/uzu/strudel/pulls/1316) +- 2025-03-23T20:05:31+01:00 bugfix: Allow single param to be used in the as function by @Ghost in: [#1312](https://codeberg.org/uzu/strudel/pulls/1312) +- 2025-03-20T23:35:18+01:00 Add MIDI Program Change, SysEx, NRPN, PitchBend and AfterTouch Output by @nkymut in: [#1244](https://codeberg.org/uzu/strudel/pulls/1244) +- 2025-03-19T17:32:30+01:00 make soundfont base url configurable by @Ghost in: [#1040](https://codeberg.org/uzu/strudel/pulls/1040) +- 2025-03-18T20:07:08+01:00 Add num samples from 0 up to 20 by @yaxu in: [#1310](https://codeberg.org/uzu/strudel/pulls/1310) +- 2025-03-17T10:38:54+01:00 add num samples (edited numbers) by @yaxu in: [#1309](https://codeberg.org/uzu/strudel/pulls/1309) +- 2025-03-08T22:17:47+01:00 @strudel/sampler improvements by @froos in: [#1288](https://codeberg.org/uzu/strudel/pulls/1288) +- 2025-03-08T21:56:50+01:00 Add Gamepad module by @nkymut in: [#1223](https://codeberg.org/uzu/strudel/pulls/1223) +- 2025-03-04T19:17:37+01:00 change behaviour of polymeter, and remove polymeterSteps by @yaxu in: [#1302](https://codeberg.org/uzu/strudel/pulls/1302) +- 2025-03-04T03:36:57+01:00 feat: Create Pulse Oscillator with variable PWM by @Ghost in: [#1304](https://codeberg.org/uzu/strudel/pulls/1304) +- 2025-03-02T17:08:31+01:00 feat: Theme improvements by @Ghost in: [#1295](https://codeberg.org/uzu/strudel/pulls/1295) +- 2025-03-02T11:58:46+01:00 bugfix zoom stepcount by @yaxu in: [#1301](https://codeberg.org/uzu/strudel/pulls/1301) ## february 2025 -- 2025-02-28T16:01:20+01:00 Fix test error #1297 by nkymut in: [#1298](https://codeberg.org/uzu/strudel/pulls/1298) -- 2025-02-28T02:53:42+01:00 Hotfix: prevent undefined pattern code from crashing strudel on load by Ghost in: [#1297](https://codeberg.org/uzu/strudel/pulls/1297) -- 2025-02-27T08:24:58+01:00 Fix misplaced ending sentence by Ghost in: [#1296](https://codeberg.org/uzu/strudel/pulls/1296) -- 2025-02-23T10:54:13+01:00 Signpost licenses for source code and samples a bit more, ref #1277 by yaxu in: [#1289](https://codeberg.org/uzu/strudel/pulls/1289) -- 2025-02-23T10:52:27+01:00 Allow wchooseCycles probabilities to be patterned by yaxu in: [#1292](https://codeberg.org/uzu/strudel/pulls/1292) -- 2025-02-22T02:18:59+01:00 Create Pattern Page Pagination by Ghost in: [#1287](https://codeberg.org/uzu/strudel/pulls/1287) -- 2025-02-21T22:38:10+01:00 showcase tweaks by yaxu in: [#1291](https://codeberg.org/uzu/strudel/pulls/1291) -- 2025-02-11T16:34:24+01:00 Fixes inverted triangle wave by renaming it to `itri`, making non-inverted `tri` by yaxu in: [#1283](https://codeberg.org/uzu/strudel/pulls/1283) -- 2025-02-11T10:02:34+01:00 Fix `squeezejoin` and functions using it, including `bite` by yaxu in: [#1286](https://codeberg.org/uzu/strudel/pulls/1286) -- 2025-02-09T16:18:28+01:00 Rename repeat back to extend by yaxu in: [#1285](https://codeberg.org/uzu/strudel/pulls/1285) -- 2025-02-07T18:11:52+01:00 mqtt bugfix - connection check by yaxu in: [#1282](https://codeberg.org/uzu/strudel/pulls/1282) -- 2025-02-07T17:38:29+01:00 Bugfix: update mqtt connections dictionary by yaxu in: [#1281](https://codeberg.org/uzu/strudel/pulls/1281) -- 2025-02-07T11:39:54+01:00 make mqtt topic patternable by yaxu in: [#1280](https://codeberg.org/uzu/strudel/pulls/1280) -- 2025-02-07T11:07:32+01:00 midimaps by froos in: [#1274](https://codeberg.org/uzu/strudel/pulls/1274) -- 2025-02-06T15:59:03+01:00 MQTT - support adding hap duration and cps metadata to JSON messages by yaxu in: [#1279](https://codeberg.org/uzu/strudel/pulls/1279) -- 2025-02-05T16:10:54+01:00 [breaking change] Sample signals from query onset, rather than midpoint by yaxu in: [#1278](https://codeberg.org/uzu/strudel/pulls/1278) -- 2025-02-03T00:55:36+01:00 Stepwise documentation tweaks, with mridangam samples by yaxu in: [#1275](https://codeberg.org/uzu/strudel/pulls/1275) -- 2025-02-02T21:26:44+01:00 Polish, rename, and document stepwise functions by yaxu in: [#1262](https://codeberg.org/uzu/strudel/pulls/1262) -- 2025-02-01T22:57:00+01:00 Fix sf2 timing by froos in: [#1272](https://codeberg.org/uzu/strudel/pulls/1272) -- 2025-02-01T22:32:59+01:00 Add bank aliasing and case insensitivity by TodePond in: [#1245](https://codeberg.org/uzu/strudel/pulls/1245) +- 2025-02-28T16:01:20+01:00 Fix test error #1297 by @nkymut in: [#1298](https://codeberg.org/uzu/strudel/pulls/1298) +- 2025-02-28T02:53:42+01:00 Hotfix: prevent undefined pattern code from crashing strudel on load by @Ghost in: [#1297](https://codeberg.org/uzu/strudel/pulls/1297) +- 2025-02-27T08:24:58+01:00 Fix misplaced ending sentence by @Ghost in: [#1296](https://codeberg.org/uzu/strudel/pulls/1296) +- 2025-02-23T10:54:13+01:00 Signpost licenses for source code and samples a bit more, ref #1277 by @yaxu in: [#1289](https://codeberg.org/uzu/strudel/pulls/1289) +- 2025-02-23T10:52:27+01:00 Allow wchooseCycles probabilities to be patterned by @yaxu in: [#1292](https://codeberg.org/uzu/strudel/pulls/1292) +- 2025-02-22T02:18:59+01:00 Create Pattern Page Pagination by @Ghost in: [#1287](https://codeberg.org/uzu/strudel/pulls/1287) +- 2025-02-21T22:38:10+01:00 showcase tweaks by @yaxu in: [#1291](https://codeberg.org/uzu/strudel/pulls/1291) +- 2025-02-11T16:34:24+01:00 Fixes inverted triangle wave by renaming it to `itri`, making non-inverted `tri` by @yaxu in: [#1283](https://codeberg.org/uzu/strudel/pulls/1283) +- 2025-02-11T10:02:34+01:00 Fix `squeezejoin` and functions using it, including `bite` by @yaxu in: [#1286](https://codeberg.org/uzu/strudel/pulls/1286) +- 2025-02-09T16:18:28+01:00 Rename repeat back to extend by @yaxu in: [#1285](https://codeberg.org/uzu/strudel/pulls/1285) +- 2025-02-07T18:11:52+01:00 mqtt bugfix - connection check by @yaxu in: [#1282](https://codeberg.org/uzu/strudel/pulls/1282) +- 2025-02-07T17:38:29+01:00 Bugfix: update mqtt connections dictionary by @yaxu in: [#1281](https://codeberg.org/uzu/strudel/pulls/1281) +- 2025-02-07T11:39:54+01:00 make mqtt topic patternable by @yaxu in: [#1280](https://codeberg.org/uzu/strudel/pulls/1280) +- 2025-02-07T11:07:32+01:00 midimaps by @froos in: [#1274](https://codeberg.org/uzu/strudel/pulls/1274) +- 2025-02-06T15:59:03+01:00 MQTT - support adding hap duration and cps metadata to JSON messages by @yaxu in: [#1279](https://codeberg.org/uzu/strudel/pulls/1279) +- 2025-02-05T16:10:54+01:00 [breaking change] Sample signals from query onset, rather than midpoint by @yaxu in: [#1278](https://codeberg.org/uzu/strudel/pulls/1278) +- 2025-02-03T00:55:36+01:00 Stepwise documentation tweaks, with mridangam samples by @yaxu in: [#1275](https://codeberg.org/uzu/strudel/pulls/1275) +- 2025-02-02T21:26:44+01:00 Polish, rename, and document stepwise functions by @yaxu in: [#1262](https://codeberg.org/uzu/strudel/pulls/1262) +- 2025-02-01T22:57:00+01:00 Fix sf2 timing by @froos in: [#1272](https://codeberg.org/uzu/strudel/pulls/1272) +- 2025-02-01T22:32:59+01:00 Add bank aliasing and case insensitivity by @TodePond in: [#1245](https://codeberg.org/uzu/strudel/pulls/1245) ## january 2025 -- 2025-01-31T09:39:54+01:00 Add Device Motion module by nkymut in: [#1217](https://codeberg.org/uzu/strudel/pulls/1217) -- 2025-01-29T15:40:01+01:00 add "as" function + getControlName by froos in: [#1247](https://codeberg.org/uzu/strudel/pulls/1247) -- 2025-01-29T15:30:04+01:00 Theme glowup by froos in: [#1268](https://codeberg.org/uzu/strudel/pulls/1268) -- 2025-01-29T15:22:18+01:00 patchday by froos in: [#1264](https://codeberg.org/uzu/strudel/pulls/1264) -- 2025-01-28T00:00:03+01:00 Revert "Fix sometimes" by yaxu in: [#1267](https://codeberg.org/uzu/strudel/pulls/1267) -- 2025-01-24T15:32:48+01:00 add reference package by froos in: [#1252](https://codeberg.org/uzu/strudel/pulls/1252) -- 2025-01-24T15:16:55+01:00 support `all(pianoroll)` and `all(pianoroll({labels: true}))` by yaxu in: [#1234](https://codeberg.org/uzu/strudel/pulls/1234) -- 2025-01-24T12:13:49+01:00 MQTT - if password isn't provided, prompt for one by yaxu in: [#1249](https://codeberg.org/uzu/strudel/pulls/1249) -- 2025-01-21T06:24:03+01:00 fix docs for beat function by Ghost in: [#1248](https://codeberg.org/uzu/strudel/pulls/1248) -- 2025-01-18T23:27:51+01:00 understand voicings page by froos in: [#1230](https://codeberg.org/uzu/strudel/pulls/1230) -- 2025-01-17T19:27:00+01:00 Add binary and binaryN by Ghost in: [#1226](https://codeberg.org/uzu/strudel/pulls/1226) -- 2025-01-16T12:18:33+01:00 Fix sometimes by yaxu in: [#1243](https://codeberg.org/uzu/strudel/pulls/1243) -- 2025-01-16T05:55:46+01:00 "beat" function for "step sequencer" style rhythm notation by Ghost in: [#1237](https://codeberg.org/uzu/strudel/pulls/1237) -- 2025-01-14T14:39:15+01:00 Add stepBind, and some toplevel aliases for binds and withValue by yaxu in: [#1241](https://codeberg.org/uzu/strudel/pulls/1241) -- 2025-01-14T06:11:10+01:00 Add onKey function for custom key commands for patterns by Ghost in: [#1235](https://codeberg.org/uzu/strudel/pulls/1235) -- 2025-01-12T11:32:24+01:00 Update documentation for param value modification by Ghost in: [#1238](https://codeberg.org/uzu/strudel/pulls/1238) +- 2025-01-31T09:39:54+01:00 Add Device Motion module by @nkymut in: [#1217](https://codeberg.org/uzu/strudel/pulls/1217) +- 2025-01-29T15:40:01+01:00 add "as" function + getControlName by @froos in: [#1247](https://codeberg.org/uzu/strudel/pulls/1247) +- 2025-01-29T15:30:04+01:00 Theme glowup by @froos in: [#1268](https://codeberg.org/uzu/strudel/pulls/1268) +- 2025-01-29T15:22:18+01:00 patchday by @froos in: [#1264](https://codeberg.org/uzu/strudel/pulls/1264) +- 2025-01-28T00:00:03+01:00 Revert "Fix sometimes" by @yaxu in: [#1267](https://codeberg.org/uzu/strudel/pulls/1267) +- 2025-01-24T15:32:48+01:00 add reference package by @froos in: [#1252](https://codeberg.org/uzu/strudel/pulls/1252) +- 2025-01-24T15:16:55+01:00 support `all(pianoroll)` and `all(pianoroll({labels: true}))` by @yaxu in: [#1234](https://codeberg.org/uzu/strudel/pulls/1234) +- 2025-01-24T12:13:49+01:00 MQTT - if password isn't provided, prompt for one by @yaxu in: [#1249](https://codeberg.org/uzu/strudel/pulls/1249) +- 2025-01-21T06:24:03+01:00 fix docs for beat function by @Ghost in: [#1248](https://codeberg.org/uzu/strudel/pulls/1248) +- 2025-01-18T23:27:51+01:00 understand voicings page by @froos in: [#1230](https://codeberg.org/uzu/strudel/pulls/1230) +- 2025-01-17T19:27:00+01:00 Add binary and binaryN by @Ghost in: [#1226](https://codeberg.org/uzu/strudel/pulls/1226) +- 2025-01-16T12:18:33+01:00 Fix sometimes by @yaxu in: [#1243](https://codeberg.org/uzu/strudel/pulls/1243) +- 2025-01-16T05:55:46+01:00 "beat" function for "step sequencer" style rhythm notation by @Ghost in: [#1237](https://codeberg.org/uzu/strudel/pulls/1237) +- 2025-01-14T14:39:15+01:00 Add stepBind, and some toplevel aliases for binds and withValue by @yaxu in: [#1241](https://codeberg.org/uzu/strudel/pulls/1241) +- 2025-01-14T06:11:10+01:00 Add onKey function for custom key commands for patterns by @Ghost in: [#1235](https://codeberg.org/uzu/strudel/pulls/1235) +- 2025-01-12T11:32:24+01:00 Update documentation for param value modification by @Ghost in: [#1238](https://codeberg.org/uzu/strudel/pulls/1238) ## december 2024 -- 2024-12-29T13:16:08+01:00 Documentation for all/each, and bugfix for each by yaxu in: [#1233](https://codeberg.org/uzu/strudel/pulls/1233) -- 2024-12-29T11:29:52+01:00 Make `all()` post-stack again, and add `each()` for pre-stack by yaxu in: [#1229](https://codeberg.org/uzu/strudel/pulls/1229) -- 2024-12-27T22:16:54+01:00 suggested changes to voicings.mdx by Ghost in: [#1231](https://codeberg.org/uzu/strudel/pulls/1231) -- 2024-12-23T11:53:11+01:00 add basic spectrum function by froos in: [#1213](https://codeberg.org/uzu/strudel/pulls/1213) -- 2024-12-22T21:04:45+01:00 Fix regression for d1, p1, p(n) by yaxu in: [#1227](https://codeberg.org/uzu/strudel/pulls/1227) +- 2024-12-29T13:16:08+01:00 Documentation for all/each, and bugfix for each by @yaxu in: [#1233](https://codeberg.org/uzu/strudel/pulls/1233) +- 2024-12-29T11:29:52+01:00 Make `all()` post-stack again, and add `each()` for pre-stack by @yaxu in: [#1229](https://codeberg.org/uzu/strudel/pulls/1229) +- 2024-12-27T22:16:54+01:00 suggested changes to voicings.mdx by @Ghost in: [#1231](https://codeberg.org/uzu/strudel/pulls/1231) +- 2024-12-23T11:53:11+01:00 add basic spectrum function by @froos in: [#1213](https://codeberg.org/uzu/strudel/pulls/1213) +- 2024-12-22T21:04:45+01:00 Fix regression for d1, p1, p(n) by @yaxu in: [#1227](https://codeberg.org/uzu/strudel/pulls/1227) ## november 2024 -- 2024-11-30T10:09:36+01:00 Make cps patternable by eefano in: [#1001](https://codeberg.org/uzu/strudel/pulls/1001) -- 2024-11-30T10:07:56+01:00 MQTT support by yaxu in: [#1224](https://codeberg.org/uzu/strudel/pulls/1224) -- 2024-11-30T09:46:14+01:00 Apply `all` function to individual patterns rather than final stack by yaxu in: [#1209](https://codeberg.org/uzu/strudel/pulls/1209) -- 2024-11-20T16:32:51+01:00 REPL: solo and sync configuration by Ghost in: [#1214](https://codeberg.org/uzu/strudel/pulls/1214) +- 2024-11-30T10:09:36+01:00 Make cps patternable by @eefano in: [#1001](https://codeberg.org/uzu/strudel/pulls/1001) +- 2024-11-30T10:07:56+01:00 MQTT support by @yaxu in: [#1224](https://codeberg.org/uzu/strudel/pulls/1224) +- 2024-11-30T09:46:14+01:00 Apply `all` function to individual patterns rather than final stack by @yaxu in: [#1209](https://codeberg.org/uzu/strudel/pulls/1209) +- 2024-11-20T16:32:51+01:00 REPL: solo and sync configuration by @Ghost in: [#1214](https://codeberg.org/uzu/strudel/pulls/1214) ## october 2024 -- 2024-10-30T21:29:43+01:00 Add s_zip for 'cat'-ing patterns together step-by-step, bugfix `steps` by yaxu in: [#1208](https://codeberg.org/uzu/strudel/pulls/1208) -- 2024-10-30T21:28:32+01:00 Preserve tactus for 'degrade' and friends, and tidy up 'pick' and friends by yaxu in: [#1205](https://codeberg.org/uzu/strudel/pulls/1205) -- 2024-10-30T17:11:53+01:00 chore: Edit run locally instructions in README.md by Ghost in: [#1206](https://codeberg.org/uzu/strudel/pulls/1206) -- 2024-10-23T23:08:14+02:00 colorize console + tweak header by froos in: [#1203](https://codeberg.org/uzu/strudel/pulls/1203) -- 2024-10-22T22:55:00+02:00 markcss by froos in: [#1202](https://codeberg.org/uzu/strudel/pulls/1202) -- 2024-10-21T22:56:37+02:00 add 2 new ui settings by froos in: [#1200](https://codeberg.org/uzu/strudel/pulls/1200) -- 2024-10-21T20:22:52+02:00 Make panel hover behavior optional by Ghost in: [#1199](https://codeberg.org/uzu/strudel/pulls/1199) -- 2024-10-19T04:28:36+02:00 Menu Panel Improvements! by Ghost in: [#1193](https://codeberg.org/uzu/strudel/pulls/1193) -- 2024-10-19T01:10:06+02:00 update lockfile + minor versions by froos in: [#1198](https://codeberg.org/uzu/strudel/pulls/1198) +- 2024-10-30T21:29:43+01:00 Add s_zip for 'cat'-ing patterns together step-by-step, bugfix `steps` by @yaxu in: [#1208](https://codeberg.org/uzu/strudel/pulls/1208) +- 2024-10-30T21:28:32+01:00 Preserve tactus for 'degrade' and friends, and tidy up 'pick' and friends by @yaxu in: [#1205](https://codeberg.org/uzu/strudel/pulls/1205) +- 2024-10-30T17:11:53+01:00 chore: Edit run locally instructions in README.md by @Ghost in: [#1206](https://codeberg.org/uzu/strudel/pulls/1206) +- 2024-10-23T23:08:14+02:00 colorize console + tweak header by @froos in: [#1203](https://codeberg.org/uzu/strudel/pulls/1203) +- 2024-10-22T22:55:00+02:00 markcss by @froos in: [#1202](https://codeberg.org/uzu/strudel/pulls/1202) +- 2024-10-21T22:56:37+02:00 add 2 new ui settings by @froos in: [#1200](https://codeberg.org/uzu/strudel/pulls/1200) +- 2024-10-21T20:22:52+02:00 Make panel hover behavior optional by @Ghost in: [#1199](https://codeberg.org/uzu/strudel/pulls/1199) +- 2024-10-19T04:28:36+02:00 Menu Panel Improvements! by @Ghost in: [#1193](https://codeberg.org/uzu/strudel/pulls/1193) +- 2024-10-19T01:10:06+02:00 update lockfile + minor versions by @froos in: [#1198](https://codeberg.org/uzu/strudel/pulls/1198) ## september 2024 -- 2024-09-27T00:17:00+02:00 remove redundant example for cat, update snapshot by Ghost in: [#1189](https://codeberg.org/uzu/strudel/pulls/1189) -- 2024-09-25T13:18:19+02:00 Adding search bar (soundtab.jsx) by Ghost in: [#1185](https://codeberg.org/uzu/strudel/pulls/1185) -- 2024-09-23T17:18:34+02:00 Screenreader improvements by yaxu in: [#1158](https://codeberg.org/uzu/strudel/pulls/1158) -- 2024-09-20T22:26:41+02:00 Fix serial timing by yaxu in: [#1188](https://codeberg.org/uzu/strudel/pulls/1188) -- 2024-09-20T00:26:30+02:00 Add bite function by yaxu in: [#1187](https://codeberg.org/uzu/strudel/pulls/1187) -- 2024-09-14T13:30:53+02:00 better spacing in zen mode by froos in: [#1147](https://codeberg.org/uzu/strudel/pulls/1147) -- 2024-09-14T10:50:24+02:00 add filter + filterWhen + within by froos in: [#1039](https://codeberg.org/uzu/strudel/pulls/1039) -- 2024-09-14T10:49:21+02:00 refactor sampler by froos in: [#1101](https://codeberg.org/uzu/strudel/pulls/1101) -- 2024-09-14T10:43:17+02:00 handle midin device not found error by froos in: [#1146](https://codeberg.org/uzu/strudel/pulls/1146) -- 2024-09-13T21:59:23+02:00 Add a search bar to the REPL Reference tab by Ghost in: [#1165](https://codeberg.org/uzu/strudel/pulls/1165) -- 2024-09-13T21:58:47+02:00 Correct spelling mistakes by Ghost in: [#1183](https://codeberg.org/uzu/strudel/pulls/1183) -- 2024-09-07T23:41:29+02:00 Add seqPLoop from Tidal by yaxu in: [#1182](https://codeberg.org/uzu/strudel/pulls/1182) -- 2024-09-05T05:52:50+02:00 make phaser control match superdirt by Ghost in: [#1180](https://codeberg.org/uzu/strudel/pulls/1180) -- 2024-09-05T05:33:41+02:00 Revert "Make phaser control consistent with superdirt" by Ghost in: [#1179](https://codeberg.org/uzu/strudel/pulls/1179) -- 2024-09-05T05:29:12+02:00 Make phaser control consistent with superdirt by Ghost in: [#1178](https://codeberg.org/uzu/strudel/pulls/1178) -- 2024-09-03T04:37:15+02:00 fix sample speed when using splice and fit with superdirt by Ghost in: [#1172](https://codeberg.org/uzu/strudel/pulls/1172) -- 2024-09-01T16:02:24+02:00 Create audio target selector for OSC/Superdirt by Ghost in: [#1160](https://codeberg.org/uzu/strudel/pulls/1160) -- 2024-09-01T15:03:47+02:00 Fixes fit so it works after a chop or slice by yaxu in: [#1171](https://codeberg.org/uzu/strudel/pulls/1171) +- 2024-09-27T00:17:00+02:00 remove redundant example for cat, update snapshot by @Ghost in: [#1189](https://codeberg.org/uzu/strudel/pulls/1189) +- 2024-09-25T13:18:19+02:00 Adding search bar (soundtab.jsx) by @Ghost in: [#1185](https://codeberg.org/uzu/strudel/pulls/1185) +- 2024-09-23T17:18:34+02:00 Screenreader improvements by @yaxu in: [#1158](https://codeberg.org/uzu/strudel/pulls/1158) +- 2024-09-20T22:26:41+02:00 Fix serial timing by @yaxu in: [#1188](https://codeberg.org/uzu/strudel/pulls/1188) +- 2024-09-20T00:26:30+02:00 Add bite function by @yaxu in: [#1187](https://codeberg.org/uzu/strudel/pulls/1187) +- 2024-09-14T13:30:53+02:00 better spacing in zen mode by @froos in: [#1147](https://codeberg.org/uzu/strudel/pulls/1147) +- 2024-09-14T10:50:24+02:00 add filter + filterWhen + within by @froos in: [#1039](https://codeberg.org/uzu/strudel/pulls/1039) +- 2024-09-14T10:49:21+02:00 refactor sampler by @froos in: [#1101](https://codeberg.org/uzu/strudel/pulls/1101) +- 2024-09-14T10:43:17+02:00 handle midin device not found error by @froos in: [#1146](https://codeberg.org/uzu/strudel/pulls/1146) +- 2024-09-13T21:59:23+02:00 Add a search bar to the REPL Reference tab by @Ghost in: [#1165](https://codeberg.org/uzu/strudel/pulls/1165) +- 2024-09-13T21:58:47+02:00 Correct spelling mistakes by @Ghost in: [#1183](https://codeberg.org/uzu/strudel/pulls/1183) +- 2024-09-07T23:41:29+02:00 Add seqPLoop from Tidal by @yaxu in: [#1182](https://codeberg.org/uzu/strudel/pulls/1182) +- 2024-09-05T05:52:50+02:00 make phaser control match superdirt by @Ghost in: [#1180](https://codeberg.org/uzu/strudel/pulls/1180) +- 2024-09-05T05:33:41+02:00 Revert "Make phaser control consistent with superdirt" by @Ghost in: [#1179](https://codeberg.org/uzu/strudel/pulls/1179) +- 2024-09-05T05:29:12+02:00 Make phaser control consistent with superdirt by @Ghost in: [#1178](https://codeberg.org/uzu/strudel/pulls/1178) +- 2024-09-03T04:37:15+02:00 fix sample speed when using splice and fit with superdirt by @Ghost in: [#1172](https://codeberg.org/uzu/strudel/pulls/1172) +- 2024-09-01T16:02:24+02:00 Create audio target selector for OSC/Superdirt by @Ghost in: [#1160](https://codeberg.org/uzu/strudel/pulls/1160) +- 2024-09-01T15:03:47+02:00 Fixes fit so it works after a chop or slice by @yaxu in: [#1171](https://codeberg.org/uzu/strudel/pulls/1171) ## august 2024 -- 2024-08-30T14:24:08+02:00 polyJoin by yaxu in: [#1168](https://codeberg.org/uzu/strudel/pulls/1168) -- 2024-08-23T17:05:10+02:00 Add scramble and shuffle by yaxu in: [#1167](https://codeberg.org/uzu/strudel/pulls/1167) -- 2024-08-18T18:22:20+02:00 Improve + simplify neocyclist timing by Ghost in: [#1164](https://codeberg.org/uzu/strudel/pulls/1164) -- 2024-08-15T05:18:33+02:00 containerize/seperate out boolean checks for repl types/Repl logic into bespoke components. by Ghost in: [#1163](https://codeberg.org/uzu/strudel/pulls/1163) -- 2024-08-12T18:57:21+02:00 [CORS HOTFIX] by Ghost in: [#1162](https://codeberg.org/uzu/strudel/pulls/1162) -- 2024-08-09T05:11:28+02:00 Fix OSC clock jitter by Ghost in: [#1157](https://codeberg.org/uzu/strudel/pulls/1157) +- 2024-08-30T14:24:08+02:00 polyJoin by @yaxu in: [#1168](https://codeberg.org/uzu/strudel/pulls/1168) +- 2024-08-23T17:05:10+02:00 Add scramble and shuffle by @yaxu in: [#1167](https://codeberg.org/uzu/strudel/pulls/1167) +- 2024-08-18T18:22:20+02:00 Improve + simplify neocyclist timing by @Ghost in: [#1164](https://codeberg.org/uzu/strudel/pulls/1164) +- 2024-08-15T05:18:33+02:00 containerize/seperate out boolean checks for repl types/Repl logic into bespoke components. by @Ghost in: [#1163](https://codeberg.org/uzu/strudel/pulls/1163) +- 2024-08-12T18:57:21+02:00 [CORS HOTFIX] by @Ghost in: [#1162](https://codeberg.org/uzu/strudel/pulls/1162) +- 2024-08-09T05:11:28+02:00 Fix OSC clock jitter by @Ghost in: [#1157](https://codeberg.org/uzu/strudel/pulls/1157) ## july 2024 -- 2024-07-27T11:02:38+02:00 Fix loopAt tactus by yaxu in: [#1145](https://codeberg.org/uzu/strudel/pulls/1145) -- 2024-07-26T04:37:34+02:00 "stretch" function (phase vocoder) by Ghost in: [#1130](https://codeberg.org/uzu/strudel/pulls/1130) -- 2024-07-26T04:37:17+02:00 Udels (MultiFrame Strudel) Revisited by Ghost in: [#1132](https://codeberg.org/uzu/strudel/pulls/1132) -- 2024-07-24T11:40:28+02:00 Fix tactus marking in mininotation by yaxu in: [#1144](https://codeberg.org/uzu/strudel/pulls/1144) +- 2024-07-27T11:02:38+02:00 Fix loopAt tactus by @yaxu in: [#1145](https://codeberg.org/uzu/strudel/pulls/1145) +- 2024-07-26T04:37:34+02:00 "stretch" function (phase vocoder) by @Ghost in: [#1130](https://codeberg.org/uzu/strudel/pulls/1130) +- 2024-07-26T04:37:17+02:00 Udels (MultiFrame Strudel) Revisited by @Ghost in: [#1132](https://codeberg.org/uzu/strudel/pulls/1132) +- 2024-07-24T11:40:28+02:00 Fix tactus marking in mininotation by @yaxu in: [#1144](https://codeberg.org/uzu/strudel/pulls/1144) ## june 2024 -- 2024-06-25T18:13:28+02:00 export comment commands by froos in: [#1136](https://codeberg.org/uzu/strudel/pulls/1136) -- 2024-06-24T18:19:22+02:00 Chop chop by yaxu in: [#1078](https://codeberg.org/uzu/strudel/pulls/1078) -- 2024-06-18T23:58:08+02:00 Fix bug in Fraction.lcm by yaxu in: [#1133](https://codeberg.org/uzu/strudel/pulls/1133) -- 2024-06-18T05:32:12+02:00 Fix clock worker dependency path in module builds by Ghost in: [#1129](https://codeberg.org/uzu/strudel/pulls/1129) -- 2024-06-04T00:26:48+02:00 Labeled statements doc by froos in: [#1126](https://codeberg.org/uzu/strudel/pulls/1126) -- 2024-06-03T22:40:21+02:00 doc: visual functions + refactor onPaint by froos in: [#1125](https://codeberg.org/uzu/strudel/pulls/1125) -- 2024-06-02T18:36:29+02:00 Fix indexDB failing with large amount of files by Ghost in: [#1124](https://codeberg.org/uzu/strudel/pulls/1124) +- 2024-06-25T18:13:28+02:00 export comment commands by @froos in: [#1136](https://codeberg.org/uzu/strudel/pulls/1136) +- 2024-06-24T18:19:22+02:00 Chop chop by @yaxu in: [#1078](https://codeberg.org/uzu/strudel/pulls/1078) +- 2024-06-18T23:58:08+02:00 Fix bug in Fraction.lcm by @yaxu in: [#1133](https://codeberg.org/uzu/strudel/pulls/1133) +- 2024-06-18T05:32:12+02:00 Fix clock worker dependency path in module builds by @Ghost in: [#1129](https://codeberg.org/uzu/strudel/pulls/1129) +- 2024-06-04T00:26:48+02:00 Labeled statements doc by @froos in: [#1126](https://codeberg.org/uzu/strudel/pulls/1126) +- 2024-06-03T22:40:21+02:00 doc: visual functions + refactor onPaint by @froos in: [#1125](https://codeberg.org/uzu/strudel/pulls/1125) +- 2024-06-02T18:36:29+02:00 Fix indexDB failing with large amount of files by @Ghost in: [#1124](https://codeberg.org/uzu/strudel/pulls/1124) ## may 2024 -- 2024-05-31T12:17:34+02:00 Migrate tutorial fanchor by froos in: [#1122](https://codeberg.org/uzu/strudel/pulls/1122) -- 2024-05-31T10:46:47+02:00 [BUG FIX] Audio worklets sometimes dont load by Ghost in: [#1121](https://codeberg.org/uzu/strudel/pulls/1121) -- 2024-05-31T10:25:24+02:00 change fanchor to 0 by Ghost in: [#1107](https://codeberg.org/uzu/strudel/pulls/1107) -- 2024-05-30T14:39:30+02:00 fix: use full repl in web package by froos in: [#1119](https://codeberg.org/uzu/strudel/pulls/1119) -- 2024-05-30T09:36:32+02:00 can now access strudelMirror from repl by froos in: [#1117](https://codeberg.org/uzu/strudel/pulls/1117) -- 2024-05-29T13:06:34+02:00 Add the mousex and mousey signal by Ghost in: [#1112](https://codeberg.org/uzu/strudel/pulls/1112) -- 2024-05-29T13:02:00+02:00 Fixes drawPianoroll import in codemirror example by Ghost in: [#1116](https://codeberg.org/uzu/strudel/pulls/1116) -- 2024-05-28T22:43:46+02:00 clarify `off` in pattern-effects.mdx by Ghost in: [#1074](https://codeberg.org/uzu/strudel/pulls/1074) -- 2024-05-26T17:33:07+02:00 rollback phaser by Ghost in: [#1113](https://codeberg.org/uzu/strudel/pulls/1113) -- 2024-05-26T17:33:06+02:00 Fix audio worklets by Ghost in: [#1114](https://codeberg.org/uzu/strudel/pulls/1114) -- 2024-05-26T16:53:56+02:00 Calculate phaser modulation phase based on time by Ghost in: [#1110](https://codeberg.org/uzu/strudel/pulls/1110) -- 2024-05-23T15:06:01+02:00 Add analog-style ladder filter by Ghost in: [#1103](https://codeberg.org/uzu/strudel/pulls/1103) -- 2024-05-22T12:53:20+02:00 fix sampler on windows by Ghost in: [#1109](https://codeberg.org/uzu/strudel/pulls/1109) -- 2024-05-20T23:26:20+02:00 web package fixes by froos in: [#1044](https://codeberg.org/uzu/strudel/pulls/1044) -- 2024-05-20T22:41:28+02:00 Fix sampler windows by froos in: [#1108](https://codeberg.org/uzu/strudel/pulls/1108) -- 2024-05-19T12:07:26+02:00 hs2js package / tidal parser by froos in: [#870](https://codeberg.org/uzu/strudel/pulls/870) -- 2024-05-18T10:49:08+02:00 fix little dub tune example by Ghost in: [#1104](https://codeberg.org/uzu/strudel/pulls/1104) -- 2024-05-17T14:43:58+02:00 Samples tab improvements by Ghost in: [#1102](https://codeberg.org/uzu/strudel/pulls/1102) -- 2024-05-13T10:10:34+02:00 osc: couple of fixes by Ghost in: [#1093](https://codeberg.org/uzu/strudel/pulls/1093) -- 2024-05-13T06:31:20+02:00 Use sessionStorage for viewingPatternData and activePattern by Ghost in: [#1091](https://codeberg.org/uzu/strudel/pulls/1091) -- 2024-05-12T18:23:09+02:00 repl: set document.title from @title by Ghost in: [#1090](https://codeberg.org/uzu/strudel/pulls/1090) -- 2024-05-07T14:29:22+02:00 fix: missing events due to premature worklet cleanup by froos in: [#1089](https://codeberg.org/uzu/strudel/pulls/1089) -- 2024-05-03T11:52:57+02:00 Benchmarks by yaxu in: [#1079](https://codeberg.org/uzu/strudel/pulls/1079) -- 2024-05-03T08:46:52+02:00 fix: csound + dough timing by froos in: [#1086](https://codeberg.org/uzu/strudel/pulls/1086) -- 2024-05-03T00:37:32+02:00 Improve performance of ! (replicate) by yaxu in: [#1084](https://codeberg.org/uzu/strudel/pulls/1084) -- 2024-05-02T23:40:22+02:00 fix: url parsing with extra params by froos in: [#1083](https://codeberg.org/uzu/strudel/pulls/1083) +- 2024-05-31T12:17:34+02:00 Migrate tutorial fanchor by @froos in: [#1122](https://codeberg.org/uzu/strudel/pulls/1122) +- 2024-05-31T10:46:47+02:00 [BUG FIX] Audio worklets sometimes dont load by @Ghost in: [#1121](https://codeberg.org/uzu/strudel/pulls/1121) +- 2024-05-31T10:25:24+02:00 change fanchor to 0 by @Ghost in: [#1107](https://codeberg.org/uzu/strudel/pulls/1107) +- 2024-05-30T14:39:30+02:00 fix: use full repl in web package by @froos in: [#1119](https://codeberg.org/uzu/strudel/pulls/1119) +- 2024-05-30T09:36:32+02:00 can now access strudelMirror from repl by @froos in: [#1117](https://codeberg.org/uzu/strudel/pulls/1117) +- 2024-05-29T13:06:34+02:00 Add the mousex and mousey signal by @Ghost in: [#1112](https://codeberg.org/uzu/strudel/pulls/1112) +- 2024-05-29T13:02:00+02:00 Fixes drawPianoroll import in codemirror example by @Ghost in: [#1116](https://codeberg.org/uzu/strudel/pulls/1116) +- 2024-05-28T22:43:46+02:00 clarify `off` in pattern-effects.mdx by @Ghost in: [#1074](https://codeberg.org/uzu/strudel/pulls/1074) +- 2024-05-26T17:33:07+02:00 rollback phaser by @Ghost in: [#1113](https://codeberg.org/uzu/strudel/pulls/1113) +- 2024-05-26T17:33:06+02:00 Fix audio worklets by @Ghost in: [#1114](https://codeberg.org/uzu/strudel/pulls/1114) +- 2024-05-26T16:53:56+02:00 Calculate phaser modulation phase based on time by @Ghost in: [#1110](https://codeberg.org/uzu/strudel/pulls/1110) +- 2024-05-23T15:06:01+02:00 Add analog-style ladder filter by @Ghost in: [#1103](https://codeberg.org/uzu/strudel/pulls/1103) +- 2024-05-22T12:53:20+02:00 fix sampler on windows by @Ghost in: [#1109](https://codeberg.org/uzu/strudel/pulls/1109) +- 2024-05-20T23:26:20+02:00 web package fixes by @froos in: [#1044](https://codeberg.org/uzu/strudel/pulls/1044) +- 2024-05-20T22:41:28+02:00 Fix sampler windows by @froos in: [#1108](https://codeberg.org/uzu/strudel/pulls/1108) +- 2024-05-19T12:07:26+02:00 hs2js package / tidal parser by @froos in: [#870](https://codeberg.org/uzu/strudel/pulls/870) +- 2024-05-18T10:49:08+02:00 fix little dub tune example by @Ghost in: [#1104](https://codeberg.org/uzu/strudel/pulls/1104) +- 2024-05-17T14:43:58+02:00 Samples tab improvements by @Ghost in: [#1102](https://codeberg.org/uzu/strudel/pulls/1102) +- 2024-05-13T10:10:34+02:00 osc: couple of fixes by @Ghost in: [#1093](https://codeberg.org/uzu/strudel/pulls/1093) +- 2024-05-13T06:31:20+02:00 Use sessionStorage for viewingPatternData and activePattern by @Ghost in: [#1091](https://codeberg.org/uzu/strudel/pulls/1091) +- 2024-05-12T18:23:09+02:00 repl: set document.title from @title by @Ghost in: [#1090](https://codeberg.org/uzu/strudel/pulls/1090) +- 2024-05-07T14:29:22+02:00 fix: missing events due to premature worklet cleanup by @froos in: [#1089](https://codeberg.org/uzu/strudel/pulls/1089) +- 2024-05-03T11:52:57+02:00 Benchmarks by @yaxu in: [#1079](https://codeberg.org/uzu/strudel/pulls/1079) +- 2024-05-03T08:46:52+02:00 fix: csound + dough timing by @froos in: [#1086](https://codeberg.org/uzu/strudel/pulls/1086) +- 2024-05-03T00:37:32+02:00 Improve performance of ! (replicate) by @yaxu in: [#1084](https://codeberg.org/uzu/strudel/pulls/1084) +- 2024-05-02T23:40:22+02:00 fix: url parsing with extra params by @froos in: [#1083](https://codeberg.org/uzu/strudel/pulls/1083) ## april 2024 -- 2024-04-29T12:36:11+02:00 Tactus calculation toggle and breaking change to tactus calculation in fast/slow/hurry by yaxu in: [#1081](https://codeberg.org/uzu/strudel/pulls/1081) -- 2024-04-28T20:56:21+02:00 fix docs on alignment.mdx by Ghost in: [#1076](https://codeberg.org/uzu/strudel/pulls/1076) -- 2024-04-28T20:49:18+02:00 add signals to recap in first-effects.mdx by Ghost in: [#1073](https://codeberg.org/uzu/strudel/pulls/1073) -- 2024-04-28T20:44:57+02:00 fix translation issue in first-effects.mdx by Ghost in: [#1072](https://codeberg.org/uzu/strudel/pulls/1072) -- 2024-04-28T20:44:29+02:00 fix failing format test by Ghost in: [#1077](https://codeberg.org/uzu/strudel/pulls/1077) -- 2024-04-27T22:50:17+02:00 add nesting to `off` example variation in pattern-effects.mdx by Ghost in: [#1075](https://codeberg.org/uzu/strudel/pulls/1075) -- 2024-04-27T22:48:58+02:00 add `<...>` to first-sounds.mdx recap by Ghost in: [#1070](https://codeberg.org/uzu/strudel/pulls/1070) -- 2024-04-27T22:48:07+02:00 fix first sounds typo by Ghost in: [#1069](https://codeberg.org/uzu/strudel/pulls/1069) -- 2024-04-27T22:47:44+02:00 fix cr typo on first-sounds.mdx by Ghost in: [#1068](https://codeberg.org/uzu/strudel/pulls/1068) -- 2024-04-26T15:12:30+02:00 More tactus tidying by yaxu in: [#1071](https://codeberg.org/uzu/strudel/pulls/1071) -- 2024-04-23T23:37:21+02:00 Fix stepjoin by yaxu in: [#1067](https://codeberg.org/uzu/strudel/pulls/1067) -- 2024-04-23T23:32:00+02:00 clarify license by yaxu in: [#1064](https://codeberg.org/uzu/strudel/pulls/1064) -- 2024-04-23T15:14:30+02:00 Tactus tweaks - fixes for maintaining tactus and highlight locations by yaxu in: [#1065](https://codeberg.org/uzu/strudel/pulls/1065) -- 2024-04-21T23:57:57+02:00 fix OSC timing for recent scheduler updates by Ghost in: [#1062](https://codeberg.org/uzu/strudel/pulls/1062) -- 2024-04-21T22:17:07+02:00 Stepwise functions from Tidal by yaxu in: [#1060](https://codeberg.org/uzu/strudel/pulls/1060) -- 2024-04-21T11:03:55+02:00 Fix wchooseCycles not picking the whole pattern by Ghost in: [#1061](https://codeberg.org/uzu/strudel/pulls/1061) -- 2024-04-19T00:05:52+02:00 add swing + swingBy by froos in: [#1038](https://codeberg.org/uzu/strudel/pulls/1038) -- 2024-04-19T00:05:08+02:00 anonymous patterns + muting by froos in: [#1059](https://codeberg.org/uzu/strudel/pulls/1059) -- 2024-04-12T12:34:27+02:00 improve tutorial + custom samples doc by froos in: [#1053](https://codeberg.org/uzu/strudel/pulls/1053) -- 2024-04-12T12:31:49+02:00 fix: do not reset cc input values on each eval by froos in: [#1054](https://codeberg.org/uzu/strudel/pulls/1054) -- 2024-04-08T17:25:27+02:00 transpose: support all combinations of numbers and strings for notes and intervals by froos in: [#1048](https://codeberg.org/uzu/strudel/pulls/1048) -- 2024-04-08T10:46:18+02:00 Wax, wane, taper and taperlist by yaxu in: [#1042](https://codeberg.org/uzu/strudel/pulls/1042) -- 2024-04-06T23:44:57+02:00 Midi Time hotfix for scheduler updates by Ghost in: [#1047](https://codeberg.org/uzu/strudel/pulls/1047) -- 2024-04-05T12:48:03+02:00 pitchwheel visual by froos in: [#1041](https://codeberg.org/uzu/strudel/pulls/1041) -- 2024-04-05T12:47:19+02:00 fix cyclist fizzling out by froos in: [#1046](https://codeberg.org/uzu/strudel/pulls/1046) +- 2024-04-29T12:36:11+02:00 Tactus calculation toggle and breaking change to tactus calculation in fast/slow/hurry by @yaxu in: [#1081](https://codeberg.org/uzu/strudel/pulls/1081) +- 2024-04-28T20:56:21+02:00 fix docs on alignment.mdx by @Ghost in: [#1076](https://codeberg.org/uzu/strudel/pulls/1076) +- 2024-04-28T20:49:18+02:00 add signals to recap in first-effects.mdx by @Ghost in: [#1073](https://codeberg.org/uzu/strudel/pulls/1073) +- 2024-04-28T20:44:57+02:00 fix translation issue in first-effects.mdx by @Ghost in: [#1072](https://codeberg.org/uzu/strudel/pulls/1072) +- 2024-04-28T20:44:29+02:00 fix failing format test by @Ghost in: [#1077](https://codeberg.org/uzu/strudel/pulls/1077) +- 2024-04-27T22:50:17+02:00 add nesting to `off` example variation in pattern-effects.mdx by @Ghost in: [#1075](https://codeberg.org/uzu/strudel/pulls/1075) +- 2024-04-27T22:48:58+02:00 add `<...>` to first-sounds.mdx recap by @Ghost in: [#1070](https://codeberg.org/uzu/strudel/pulls/1070) +- 2024-04-27T22:48:07+02:00 fix first sounds typo by @Ghost in: [#1069](https://codeberg.org/uzu/strudel/pulls/1069) +- 2024-04-27T22:47:44+02:00 fix cr typo on first-sounds.mdx by @Ghost in: [#1068](https://codeberg.org/uzu/strudel/pulls/1068) +- 2024-04-26T15:12:30+02:00 More tactus tidying by @yaxu in: [#1071](https://codeberg.org/uzu/strudel/pulls/1071) +- 2024-04-23T23:37:21+02:00 Fix stepjoin by @yaxu in: [#1067](https://codeberg.org/uzu/strudel/pulls/1067) +- 2024-04-23T23:32:00+02:00 clarify license by @yaxu in: [#1064](https://codeberg.org/uzu/strudel/pulls/1064) +- 2024-04-23T15:14:30+02:00 Tactus tweaks - fixes for maintaining tactus and highlight locations by @yaxu in: [#1065](https://codeberg.org/uzu/strudel/pulls/1065) +- 2024-04-21T23:57:57+02:00 fix OSC timing for recent scheduler updates by @Ghost in: [#1062](https://codeberg.org/uzu/strudel/pulls/1062) +- 2024-04-21T22:17:07+02:00 Stepwise functions from Tidal by @yaxu in: [#1060](https://codeberg.org/uzu/strudel/pulls/1060) +- 2024-04-21T11:03:55+02:00 Fix wchooseCycles not picking the whole pattern by @Ghost in: [#1061](https://codeberg.org/uzu/strudel/pulls/1061) +- 2024-04-19T00:05:52+02:00 add swing + swingBy by @froos in: [#1038](https://codeberg.org/uzu/strudel/pulls/1038) +- 2024-04-19T00:05:08+02:00 anonymous patterns + muting by @froos in: [#1059](https://codeberg.org/uzu/strudel/pulls/1059) +- 2024-04-12T12:34:27+02:00 improve tutorial + custom samples doc by @froos in: [#1053](https://codeberg.org/uzu/strudel/pulls/1053) +- 2024-04-12T12:31:49+02:00 fix: do not reset cc input values on each eval by @froos in: [#1054](https://codeberg.org/uzu/strudel/pulls/1054) +- 2024-04-08T17:25:27+02:00 transpose: support all combinations of numbers and strings for notes and intervals by @froos in: [#1048](https://codeberg.org/uzu/strudel/pulls/1048) +- 2024-04-08T10:46:18+02:00 Wax, wane, taper and taperlist by @yaxu in: [#1042](https://codeberg.org/uzu/strudel/pulls/1042) +- 2024-04-06T23:44:57+02:00 Midi Time hotfix for scheduler updates by @Ghost in: [#1047](https://codeberg.org/uzu/strudel/pulls/1047) +- 2024-04-05T12:48:03+02:00 pitchwheel visual by @froos in: [#1041](https://codeberg.org/uzu/strudel/pulls/1041) +- 2024-04-05T12:47:19+02:00 fix cyclist fizzling out by @froos in: [#1046](https://codeberg.org/uzu/strudel/pulls/1046) ## march 2024 -- 2024-03-30T16:05:59+01:00 remove dangerous arithmetic feature by froos in: [#1030](https://codeberg.org/uzu/strudel/pulls/1030) -- 2024-03-30T16:05:27+01:00 Fix sampler paths by froos in: [#1034](https://codeberg.org/uzu/strudel/pulls/1034) -- 2024-03-30T14:43:08+01:00 local sample server cli by froos in: [#1033](https://codeberg.org/uzu/strudel/pulls/1033) -- 2024-03-29T17:14:28+01:00 add font file types to offline cache by froos in: [#1032](https://codeberg.org/uzu/strudel/pulls/1032) -- 2024-03-29T17:10:16+01:00 add closeBrackets setting by froos in: [#1031](https://codeberg.org/uzu/strudel/pulls/1031) -- 2024-03-29T14:55:06+01:00 Tactus tidy by yaxu in: [#1027](https://codeberg.org/uzu/strudel/pulls/1027) -- 2024-03-28T17:06:44+01:00 add setting for sync flag by froos in: [#1025](https://codeberg.org/uzu/strudel/pulls/1025) -- 2024-03-28T11:37:57+01:00 better theme integration for visuals + various fixes by froos in: [#1024](https://codeberg.org/uzu/strudel/pulls/1024) -- 2024-03-28T11:33:25+01:00 More fonts by froos in: [#1023](https://codeberg.org/uzu/strudel/pulls/1023) -- 2024-03-27T13:06:05+01:00 Feature: tactus marking by yaxu in: [#1021](https://codeberg.org/uzu/strudel/pulls/1021) -- 2024-03-25T06:02:02+01:00 hotfix for 1017 by Ghost in: [#1020](https://codeberg.org/uzu/strudel/pulls/1020) -- 2024-03-24T15:06:33+01:00 Document signals by Ghost in: [#1015](https://codeberg.org/uzu/strudel/pulls/1015) -- 2024-03-24T10:16:11+01:00 Repl sync fixes by Ghost in: [#1014](https://codeberg.org/uzu/strudel/pulls/1014) -- 2024-03-23T20:21:51+01:00 eliminate chromium clock jitter by froos in: [#1004](https://codeberg.org/uzu/strudel/pulls/1004) -- 2024-03-23T15:51:07+01:00 update undocumented script by froos in: [#1013](https://codeberg.org/uzu/strudel/pulls/1013) -- 2024-03-23T15:26:52+01:00 fix: await injectPatternMethods by froos in: [#1012](https://codeberg.org/uzu/strudel/pulls/1012) -- 2024-03-23T15:18:12+01:00 rename trig -> reset, trigzero -> restart by froos in: [#1010](https://codeberg.org/uzu/strudel/pulls/1010) -- 2024-03-23T12:30:03+01:00 Inline punchcard + spiral by froos in: [#1008](https://codeberg.org/uzu/strudel/pulls/1008) -- 2024-03-23T12:27:22+01:00 Color in hap value by froos in: [#1007](https://codeberg.org/uzu/strudel/pulls/1007) -- 2024-03-22T23:53:51+01:00 using strudel in your project guide + cleanup examples by froos in: [#1006](https://codeberg.org/uzu/strudel/pulls/1006) -- 2024-03-22T23:41:50+01:00 accidentals in scale degrees by eefano in: [#1000](https://codeberg.org/uzu/strudel/pulls/1000) -- 2024-03-21T22:53:55+01:00 supersaw oscillator by Ghost in: [#978](https://codeberg.org/uzu/strudel/pulls/978) -- 2024-03-21T13:00:04+01:00 remove canvas, externalize samples, delete junk by froos in: [#1003](https://codeberg.org/uzu/strudel/pulls/1003) -- 2024-03-18T11:37:55+01:00 Fix pure mini highlight by yaxu in: [#994](https://codeberg.org/uzu/strudel/pulls/994) -- 2024-03-18T07:12:14+01:00 inline viz / widgets package by froos in: [#989](https://codeberg.org/uzu/strudel/pulls/989) -- 2024-03-17T04:07:00+01:00 Labeled statements by froos in: [#991](https://codeberg.org/uzu/strudel/pulls/991) -- 2024-03-16T18:24:38+01:00 Beat-oriented functionality by yaxu in: [#976](https://codeberg.org/uzu/strudel/pulls/976) -- 2024-03-15T01:47:35+01:00 REPL sync between windows by Ghost in: [#900](https://codeberg.org/uzu/strudel/pulls/900) -- 2024-03-14T00:20:07+01:00 Update synths.mdx by Ghost in: [#984](https://codeberg.org/uzu/strudel/pulls/984) -- 2024-03-13T00:36:22+01:00 fix: share now shares what's visible instead of active by froos in: [#985](https://codeberg.org/uzu/strudel/pulls/985) -- 2024-03-10T01:18:57+01:00 use ireal as default voicing dict by froos in: [#967](https://codeberg.org/uzu/strudel/pulls/967) -- 2024-03-10T00:50:23+01:00 little fix for withVal by eefano in: [#980](https://codeberg.org/uzu/strudel/pulls/980) -- 2024-03-10T00:46:51+01:00 Velocity in value by froos in: [#974](https://codeberg.org/uzu/strudel/pulls/974) -- 2024-03-10T00:42:50+01:00 fix: clear hydra on reset by froos in: [#983](https://codeberg.org/uzu/strudel/pulls/983) -- 2024-03-10T00:38:43+01:00 move canvas related helpers from core to new draw package by froos in: [#971](https://codeberg.org/uzu/strudel/pulls/971) -- 2024-03-08T05:38:07+01:00 replace shape with distort in learn doc by Ghost in: [#982](https://codeberg.org/uzu/strudel/pulls/982) -- 2024-03-06T12:14:49+01:00 alias - for ~ by yaxu in: [#981](https://codeberg.org/uzu/strudel/pulls/981) -- 2024-03-04T16:04:23+01:00 Worklet Improvents / fixes by Ghost in: [#963](https://codeberg.org/uzu/strudel/pulls/963) -- 2024-03-01T17:30:19+01:00 Nested controls by froos in: [#973](https://codeberg.org/uzu/strudel/pulls/973) +- 2024-03-30T16:05:59+01:00 remove dangerous arithmetic feature by @froos in: [#1030](https://codeberg.org/uzu/strudel/pulls/1030) +- 2024-03-30T16:05:27+01:00 Fix sampler paths by @froos in: [#1034](https://codeberg.org/uzu/strudel/pulls/1034) +- 2024-03-30T14:43:08+01:00 local sample server cli by @froos in: [#1033](https://codeberg.org/uzu/strudel/pulls/1033) +- 2024-03-29T17:14:28+01:00 add font file types to offline cache by @froos in: [#1032](https://codeberg.org/uzu/strudel/pulls/1032) +- 2024-03-29T17:10:16+01:00 add closeBrackets setting by @froos in: [#1031](https://codeberg.org/uzu/strudel/pulls/1031) +- 2024-03-29T14:55:06+01:00 Tactus tidy by @yaxu in: [#1027](https://codeberg.org/uzu/strudel/pulls/1027) +- 2024-03-28T17:06:44+01:00 add setting for sync flag by @froos in: [#1025](https://codeberg.org/uzu/strudel/pulls/1025) +- 2024-03-28T11:37:57+01:00 better theme integration for visuals + various fixes by @froos in: [#1024](https://codeberg.org/uzu/strudel/pulls/1024) +- 2024-03-28T11:33:25+01:00 More fonts by @froos in: [#1023](https://codeberg.org/uzu/strudel/pulls/1023) +- 2024-03-27T13:06:05+01:00 Feature: tactus marking by @yaxu in: [#1021](https://codeberg.org/uzu/strudel/pulls/1021) +- 2024-03-25T06:02:02+01:00 hotfix for 1017 by @Ghost in: [#1020](https://codeberg.org/uzu/strudel/pulls/1020) +- 2024-03-24T15:06:33+01:00 Document signals by @Ghost in: [#1015](https://codeberg.org/uzu/strudel/pulls/1015) +- 2024-03-24T10:16:11+01:00 Repl sync fixes by @Ghost in: [#1014](https://codeberg.org/uzu/strudel/pulls/1014) +- 2024-03-23T20:21:51+01:00 eliminate chromium clock jitter by @froos in: [#1004](https://codeberg.org/uzu/strudel/pulls/1004) +- 2024-03-23T15:51:07+01:00 update undocumented script by @froos in: [#1013](https://codeberg.org/uzu/strudel/pulls/1013) +- 2024-03-23T15:26:52+01:00 fix: await injectPatternMethods by @froos in: [#1012](https://codeberg.org/uzu/strudel/pulls/1012) +- 2024-03-23T15:18:12+01:00 rename trig -> reset, trigzero -> restart by @froos in: [#1010](https://codeberg.org/uzu/strudel/pulls/1010) +- 2024-03-23T12:30:03+01:00 Inline punchcard + spiral by @froos in: [#1008](https://codeberg.org/uzu/strudel/pulls/1008) +- 2024-03-23T12:27:22+01:00 Color in hap value by @froos in: [#1007](https://codeberg.org/uzu/strudel/pulls/1007) +- 2024-03-22T23:53:51+01:00 using strudel in your project guide + cleanup examples by @froos in: [#1006](https://codeberg.org/uzu/strudel/pulls/1006) +- 2024-03-22T23:41:50+01:00 accidentals in scale degrees by @eefano in: [#1000](https://codeberg.org/uzu/strudel/pulls/1000) +- 2024-03-21T22:53:55+01:00 supersaw oscillator by @Ghost in: [#978](https://codeberg.org/uzu/strudel/pulls/978) +- 2024-03-21T13:00:04+01:00 remove canvas, externalize samples, delete junk by @froos in: [#1003](https://codeberg.org/uzu/strudel/pulls/1003) +- 2024-03-18T11:37:55+01:00 Fix pure mini highlight by @yaxu in: [#994](https://codeberg.org/uzu/strudel/pulls/994) +- 2024-03-18T07:12:14+01:00 inline viz / widgets package by @froos in: [#989](https://codeberg.org/uzu/strudel/pulls/989) +- 2024-03-17T04:07:00+01:00 Labeled statements by @froos in: [#991](https://codeberg.org/uzu/strudel/pulls/991) +- 2024-03-16T18:24:38+01:00 Beat-oriented functionality by @yaxu in: [#976](https://codeberg.org/uzu/strudel/pulls/976) +- 2024-03-15T01:47:35+01:00 REPL sync between windows by @Ghost in: [#900](https://codeberg.org/uzu/strudel/pulls/900) +- 2024-03-14T00:20:07+01:00 Update synths.mdx by @Ghost in: [#984](https://codeberg.org/uzu/strudel/pulls/984) +- 2024-03-13T00:36:22+01:00 fix: share now shares what's visible instead of active by @froos in: [#985](https://codeberg.org/uzu/strudel/pulls/985) +- 2024-03-10T01:18:57+01:00 use ireal as default voicing dict by @froos in: [#967](https://codeberg.org/uzu/strudel/pulls/967) +- 2024-03-10T00:50:23+01:00 little fix for withVal by @eefano in: [#980](https://codeberg.org/uzu/strudel/pulls/980) +- 2024-03-10T00:46:51+01:00 Velocity in value by @froos in: [#974](https://codeberg.org/uzu/strudel/pulls/974) +- 2024-03-10T00:42:50+01:00 fix: clear hydra on reset by @froos in: [#983](https://codeberg.org/uzu/strudel/pulls/983) +- 2024-03-10T00:38:43+01:00 move canvas related helpers from core to new draw package by @froos in: [#971](https://codeberg.org/uzu/strudel/pulls/971) +- 2024-03-08T05:38:07+01:00 replace shape with distort in learn doc by @Ghost in: [#982](https://codeberg.org/uzu/strudel/pulls/982) +- 2024-03-06T12:14:49+01:00 alias - for ~ by @yaxu in: [#981](https://codeberg.org/uzu/strudel/pulls/981) +- 2024-03-04T16:04:23+01:00 Worklet Improvents / fixes by @Ghost in: [#963](https://codeberg.org/uzu/strudel/pulls/963) +- 2024-03-01T17:30:19+01:00 Nested controls by @froos in: [#973](https://codeberg.org/uzu/strudel/pulls/973) ## february 2024 -- 2024-02-29T15:33:12+01:00 feat: can now invert euclid pulses with negative numbers by froos in: [#959](https://codeberg.org/uzu/strudel/pulls/959) -- 2024-02-29T15:31:23+01:00 pickOut(), pickRestart(), pickReset() by eefano in: [#950](https://codeberg.org/uzu/strudel/pulls/950) -- 2024-02-29T15:12:45+01:00 remove legacy legato + duration implementations by froos in: [#965](https://codeberg.org/uzu/strudel/pulls/965) -- 2024-02-29T08:47:53+01:00 fix for transpose(): preserve hap value object structure by eefano in: [#966](https://codeberg.org/uzu/strudel/pulls/966) -- 2024-02-29T08:32:00+01:00 add debounce to logger by froos in: [#968](https://codeberg.org/uzu/strudel/pulls/968) -- 2024-02-28T18:43:52+01:00 controls refactoring: simplify exports by froos in: [#962](https://codeberg.org/uzu/strudel/pulls/962) -- 2024-02-25T19:17:00+01:00 fix: reset global fx on pattern change by froos in: [#960](https://codeberg.org/uzu/strudel/pulls/960) -- 2024-02-25T14:15:30+01:00 fix midi issue on firefox and added quote error by Ghost in: [#936](https://codeberg.org/uzu/strudel/pulls/936) -- 2024-02-25T13:19:47+01:00 'Enable Bracket Matching' option in Codemirror by eefano in: [#956](https://codeberg.org/uzu/strudel/pulls/956) -- 2024-02-23T14:37:46+01:00 fix script importable packages (web + repl) by froos in: [#957](https://codeberg.org/uzu/strudel/pulls/957) -- 2024-02-21T16:17:37+01:00 account for cps in midi time duration by Ghost in: [#954](https://codeberg.org/uzu/strudel/pulls/954) -- 2024-02-21T10:27:12+01:00 Auto await samples by froos in: [#955](https://codeberg.org/uzu/strudel/pulls/955) -- 2024-02-08T13:16:15+01:00 remove cjs builds by froos in: [#945](https://codeberg.org/uzu/strudel/pulls/945) -- 2024-02-04T23:15:37+01:00 Minor documentation error: Update first-sounds.mdx by Ghost in: [#941](https://codeberg.org/uzu/strudel/pulls/941) +- 2024-02-29T15:33:12+01:00 feat: can now invert euclid pulses with negative numbers by @froos in: [#959](https://codeberg.org/uzu/strudel/pulls/959) +- 2024-02-29T15:31:23+01:00 pickOut(), pickRestart(), pickReset() by @eefano in: [#950](https://codeberg.org/uzu/strudel/pulls/950) +- 2024-02-29T15:12:45+01:00 remove legacy legato + duration implementations by @froos in: [#965](https://codeberg.org/uzu/strudel/pulls/965) +- 2024-02-29T08:47:53+01:00 fix for transpose(): preserve hap value object structure by @eefano in: [#966](https://codeberg.org/uzu/strudel/pulls/966) +- 2024-02-29T08:32:00+01:00 add debounce to logger by @froos in: [#968](https://codeberg.org/uzu/strudel/pulls/968) +- 2024-02-28T18:43:52+01:00 controls refactoring: simplify exports by @froos in: [#962](https://codeberg.org/uzu/strudel/pulls/962) +- 2024-02-25T19:17:00+01:00 fix: reset global fx on pattern change by @froos in: [#960](https://codeberg.org/uzu/strudel/pulls/960) +- 2024-02-25T14:15:30+01:00 fix midi issue on firefox and added quote error by @Ghost in: [#936](https://codeberg.org/uzu/strudel/pulls/936) +- 2024-02-25T13:19:47+01:00 'Enable Bracket Matching' option in Codemirror by @eefano in: [#956](https://codeberg.org/uzu/strudel/pulls/956) +- 2024-02-23T14:37:46+01:00 fix script importable packages (web + repl) by @froos in: [#957](https://codeberg.org/uzu/strudel/pulls/957) +- 2024-02-21T16:17:37+01:00 account for cps in midi time duration by @Ghost in: [#954](https://codeberg.org/uzu/strudel/pulls/954) +- 2024-02-21T10:27:12+01:00 Auto await samples by @froos in: [#955](https://codeberg.org/uzu/strudel/pulls/955) +- 2024-02-08T13:16:15+01:00 remove cjs builds by @froos in: [#945](https://codeberg.org/uzu/strudel/pulls/945) +- 2024-02-04T23:15:37+01:00 Minor documentation error: Update first-sounds.mdx by @Ghost in: [#941](https://codeberg.org/uzu/strudel/pulls/941) ## january 2024 -- 2024-01-24T16:48:57+01:00 fix: pianoroll sorting by froos in: [#938](https://codeberg.org/uzu/strudel/pulls/938) -- 2024-01-23T00:04:03+01:00 V1 release notes by froos in: [#935](https://codeberg.org/uzu/strudel/pulls/935) -- 2024-01-22T20:20:53+01:00 2 years blog post by froos in: [#929](https://codeberg.org/uzu/strudel/pulls/929) -- 2024-01-22T20:02:34+01:00 make 0.5hz cps the default by yaxu in: [#931](https://codeberg.org/uzu/strudel/pulls/931) -- 2024-01-22T00:52:01+01:00 Fix pattern tab not showing patterns without created date by Ghost in: [#934](https://codeberg.org/uzu/strudel/pulls/934) -- 2024-01-21T20:46:28+01:00 Add useful pattern selection behavior for performing. by Ghost in: [#897](https://codeberg.org/uzu/strudel/pulls/897) -- 2024-01-21T01:30:28+01:00 Refactor cps functions by froos in: [#933](https://codeberg.org/uzu/strudel/pulls/933) -- 2024-01-20T23:47:31+01:00 Make splice cps-aware by yaxu in: [#932](https://codeberg.org/uzu/strudel/pulls/932) -- 2024-01-19T18:50:57+01:00 community bakery by froos in: [#923](https://codeberg.org/uzu/strudel/pulls/923) -- 2024-01-19T18:49:54+01:00 add pickF and pickmodF by Ghost in: [#924](https://codeberg.org/uzu/strudel/pulls/924) -- 2024-01-19T15:10:48+01:00 Mini-notation additions towards tidal compatibility by yaxu in: [#926](https://codeberg.org/uzu/strudel/pulls/926) -- 2024-01-18T23:34:11+01:00 Blog improvements by froos in: [#919](https://codeberg.org/uzu/strudel/pulls/919) -- 2024-01-18T18:08:29+01:00 pick, pickmod, inhabit, inhabitmod by yaxu in: [#921](https://codeberg.org/uzu/strudel/pulls/921) -- 2024-01-18T18:04:27+01:00 Revert "`pick` now accepts lookup tables, with alternate cycle squeezing behaviour as new `inhabit` function" by yaxu in: [#920](https://codeberg.org/uzu/strudel/pulls/920) -- 2024-01-18T17:45:39+01:00 `pick` now accepts lookup tables, with alternate cycle squeezing behaviour as new `inhabit` function by yaxu in: [#918](https://codeberg.org/uzu/strudel/pulls/918) -- 2024-01-18T10:30:08+01:00 rename @strudel.cycles/* packages to @strudel/* by froos in: [#917](https://codeberg.org/uzu/strudel/pulls/917) -- 2024-01-18T06:54:33+01:00 pitch envelopes by froos in: [#913](https://codeberg.org/uzu/strudel/pulls/913) -- 2024-01-18T05:09:38+01:00 Fix: swatch/[name].png.js static path by Ghost in: [#916](https://codeberg.org/uzu/strudel/pulls/916) -- 2024-01-16T08:22:28+01:00 Add more vowel qualities for the vowels function by Ghost in: [#907](https://codeberg.org/uzu/strudel/pulls/907) -- 2024-01-14T23:56:36+01:00 adds a blog by froos in: [#911](https://codeberg.org/uzu/strudel/pulls/911) -- 2024-01-14T23:52:41+01:00 Remove hideHeader for better mobile UI and consistency by Ghost in: [#894](https://codeberg.org/uzu/strudel/pulls/894) -- 2024-01-14T22:43:06+01:00 Further Envelope improvements by Ghost in: [#868](https://codeberg.org/uzu/strudel/pulls/868) -- 2024-01-14T00:48:04+01:00 public sharing by froos in: [#910](https://codeberg.org/uzu/strudel/pulls/910) -- 2024-01-12T18:31:41+01:00 fix some build warnings by froos in: [#902](https://codeberg.org/uzu/strudel/pulls/902) -- 2024-01-12T18:01:55+01:00 prevent vite from complaining about additional exports in jsx files by Ghost in: [#891](https://codeberg.org/uzu/strudel/pulls/891) -- 2024-01-12T17:05:47+01:00 Update Vite version so hot reload works properly with newest pnpm version by Ghost in: [#892](https://codeberg.org/uzu/strudel/pulls/892) -- 2024-01-12T15:09:41+01:00 support , in < > by froos in: [#886](https://codeberg.org/uzu/strudel/pulls/886) -- 2024-01-10T13:55:39+01:00 fix: autocomplete / tooltip code example bug by froos in: [#898](https://codeberg.org/uzu/strudel/pulls/898) -- 2024-01-06T15:23:55+01:00 fix: invisible selection on vim + emacs mode by froos in: [#889](https://codeberg.org/uzu/strudel/pulls/889) -- 2024-01-05T22:29:20+01:00 scales can now be anchored by froos in: [#888](https://codeberg.org/uzu/strudel/pulls/888) -- 2024-01-04T11:21:42+01:00 add root mode for voicings by froos in: [#887](https://codeberg.org/uzu/strudel/pulls/887) -- 2024-01-01T18:32:17+01:00 Showcase by froos in: [#885](https://codeberg.org/uzu/strudel/pulls/885) -- 2024-01-01T14:22:11+01:00 bugfix: suspend and close exisiting audio context when changing interface by Ghost in: [#882](https://codeberg.org/uzu/strudel/pulls/882) -- 2024-01-01T14:21:52+01:00 add mastodon link by froos in: [#884](https://codeberg.org/uzu/strudel/pulls/884) +- 2024-01-24T16:48:57+01:00 fix: pianoroll sorting by @froos in: [#938](https://codeberg.org/uzu/strudel/pulls/938) +- 2024-01-23T00:04:03+01:00 V1 release notes by @froos in: [#935](https://codeberg.org/uzu/strudel/pulls/935) +- 2024-01-22T20:20:53+01:00 2 years blog post by @froos in: [#929](https://codeberg.org/uzu/strudel/pulls/929) +- 2024-01-22T20:02:34+01:00 make 0.5hz cps the default by @yaxu in: [#931](https://codeberg.org/uzu/strudel/pulls/931) +- 2024-01-22T00:52:01+01:00 Fix pattern tab not showing patterns without created date by @Ghost in: [#934](https://codeberg.org/uzu/strudel/pulls/934) +- 2024-01-21T20:46:28+01:00 Add useful pattern selection behavior for performing. by @Ghost in: [#897](https://codeberg.org/uzu/strudel/pulls/897) +- 2024-01-21T01:30:28+01:00 Refactor cps functions by @froos in: [#933](https://codeberg.org/uzu/strudel/pulls/933) +- 2024-01-20T23:47:31+01:00 Make splice cps-aware by @yaxu in: [#932](https://codeberg.org/uzu/strudel/pulls/932) +- 2024-01-19T18:50:57+01:00 community bakery by @froos in: [#923](https://codeberg.org/uzu/strudel/pulls/923) +- 2024-01-19T18:49:54+01:00 add pickF and pickmodF by @Ghost in: [#924](https://codeberg.org/uzu/strudel/pulls/924) +- 2024-01-19T15:10:48+01:00 Mini-notation additions towards tidal compatibility by @yaxu in: [#926](https://codeberg.org/uzu/strudel/pulls/926) +- 2024-01-18T23:34:11+01:00 Blog improvements by @froos in: [#919](https://codeberg.org/uzu/strudel/pulls/919) +- 2024-01-18T18:08:29+01:00 pick, pickmod, inhabit, inhabitmod by @yaxu in: [#921](https://codeberg.org/uzu/strudel/pulls/921) +- 2024-01-18T18:04:27+01:00 Revert "`pick` now accepts lookup tables, with alternate cycle squeezing behaviour as new `inhabit` function" by @yaxu in: [#920](https://codeberg.org/uzu/strudel/pulls/920) +- 2024-01-18T17:45:39+01:00 `pick` now accepts lookup tables, with alternate cycle squeezing behaviour as new `inhabit` function by @yaxu in: [#918](https://codeberg.org/uzu/strudel/pulls/918) +- 2024-01-18T10:30:08+01:00 rename @strudel.cycles/* packages to @strudel/* by @froos in: [#917](https://codeberg.org/uzu/strudel/pulls/917) +- 2024-01-18T06:54:33+01:00 pitch envelopes by @froos in: [#913](https://codeberg.org/uzu/strudel/pulls/913) +- 2024-01-18T05:09:38+01:00 Fix: swatch/[name].png.js static path by @Ghost in: [#916](https://codeberg.org/uzu/strudel/pulls/916) +- 2024-01-16T08:22:28+01:00 Add more vowel qualities for the vowels function by @Ghost in: [#907](https://codeberg.org/uzu/strudel/pulls/907) +- 2024-01-14T23:56:36+01:00 adds a blog by @froos in: [#911](https://codeberg.org/uzu/strudel/pulls/911) +- 2024-01-14T23:52:41+01:00 Remove hideHeader for better mobile UI and consistency by @Ghost in: [#894](https://codeberg.org/uzu/strudel/pulls/894) +- 2024-01-14T22:43:06+01:00 Further Envelope improvements by @Ghost in: [#868](https://codeberg.org/uzu/strudel/pulls/868) +- 2024-01-14T00:48:04+01:00 public sharing by @froos in: [#910](https://codeberg.org/uzu/strudel/pulls/910) +- 2024-01-12T18:31:41+01:00 fix some build warnings by @froos in: [#902](https://codeberg.org/uzu/strudel/pulls/902) +- 2024-01-12T18:01:55+01:00 prevent vite from complaining about additional exports in jsx files by @Ghost in: [#891](https://codeberg.org/uzu/strudel/pulls/891) +- 2024-01-12T17:05:47+01:00 Update Vite version so hot reload works properly with newest pnpm version by @Ghost in: [#892](https://codeberg.org/uzu/strudel/pulls/892) +- 2024-01-12T15:09:41+01:00 support , in < > by @froos in: [#886](https://codeberg.org/uzu/strudel/pulls/886) +- 2024-01-10T13:55:39+01:00 fix: autocomplete / tooltip code example bug by @froos in: [#898](https://codeberg.org/uzu/strudel/pulls/898) +- 2024-01-06T15:23:55+01:00 fix: invisible selection on vim + emacs mode by @froos in: [#889](https://codeberg.org/uzu/strudel/pulls/889) +- 2024-01-05T22:29:20+01:00 scales can now be anchored by @froos in: [#888](https://codeberg.org/uzu/strudel/pulls/888) +- 2024-01-04T11:21:42+01:00 add root mode for voicings by @froos in: [#887](https://codeberg.org/uzu/strudel/pulls/887) +- 2024-01-01T18:32:17+01:00 Showcase by @froos in: [#885](https://codeberg.org/uzu/strudel/pulls/885) +- 2024-01-01T14:22:11+01:00 bugfix: suspend and close exisiting audio context when changing interface by @Ghost in: [#882](https://codeberg.org/uzu/strudel/pulls/882) +- 2024-01-01T14:21:52+01:00 add mastodon link by @froos in: [#884](https://codeberg.org/uzu/strudel/pulls/884) ## december 2023 -- 2023-12-31T17:02:57+01:00 fix: make sure n is never undefined before nanFallback by froos in: [#881](https://codeberg.org/uzu/strudel/pulls/881) -- 2023-12-31T16:47:22+01:00 Error tolerance by froos in: [#880](https://codeberg.org/uzu/strudel/pulls/880) -- 2023-12-31T10:06:24+01:00 bugfix: sound select indexes out of bounds by Ghost in: [#871](https://codeberg.org/uzu/strudel/pulls/871) -- 2023-12-31T10:03:01+01:00 Audio device selection by Ghost in: [#854](https://codeberg.org/uzu/strudel/pulls/854) -- 2023-12-31T00:59:49+01:00 Dependency update by froos in: [#879](https://codeberg.org/uzu/strudel/pulls/879) -- 2023-12-29T16:53:41+01:00 move all examples to separate examples folder by froos in: [#878](https://codeberg.org/uzu/strudel/pulls/878) -- 2023-12-29T15:29:17+01:00 final vanillification by froos in: [#876](https://codeberg.org/uzu/strudel/pulls/876) -- 2023-12-27T18:38:09+01:00 Bug Fix #119: Clock drift by Ghost in: [#874](https://codeberg.org/uzu/strudel/pulls/874) -- 2023-12-27T13:17:03+01:00 main repl vanillification by froos in: [#873](https://codeberg.org/uzu/strudel/pulls/873) -- 2023-12-25T17:47:25+01:00 more work on vanilla repl: repl web component + package + MicroRepl by froos in: [#866](https://codeberg.org/uzu/strudel/pulls/866) -- 2023-12-15T00:11:35+01:00 Vanilla repl 3 by froos in: [#865](https://codeberg.org/uzu/strudel/pulls/865) -- 2023-12-14T21:28:49+01:00 Vanilla repl 2 by froos in: [#863](https://codeberg.org/uzu/strudel/pulls/863) -- 2023-12-12T21:49:23+01:00 fix: finally repair envelopes by froos in: [#861](https://codeberg.org/uzu/strudel/pulls/861) -- 2023-12-12T21:20:00+01:00 add missing trailing slashes by froos in: [#860](https://codeberg.org/uzu/strudel/pulls/860) -- 2023-12-12T19:08:31+01:00 Sound Import from local file system by Ghost in: [#839](https://codeberg.org/uzu/strudel/pulls/839) -- 2023-12-11T22:48:35+01:00 Pattern organization by froos in: [#858](https://codeberg.org/uzu/strudel/pulls/858) -- 2023-12-09T17:25:11+01:00 Export patterns + ui tweaks by froos in: [#855](https://codeberg.org/uzu/strudel/pulls/855) -- 2023-12-08T09:41:10+01:00 patterns tab: import patterns + style by froos in: [#852](https://codeberg.org/uzu/strudel/pulls/852) -- 2023-12-07T20:42:00+01:00 Patterns tab + Refactor Panel by froos in: [#769](https://codeberg.org/uzu/strudel/pulls/769) -- 2023-12-07T10:25:16+01:00 CHANGES: pnpm 8.1.3 to 8.11.0 by Ghost in: [#850](https://codeberg.org/uzu/strudel/pulls/850) -- 2023-12-07T09:35:14+01:00 Fix edge case with rehype-urls and trailing slashes in image file paths by Ghost in: [#849](https://codeberg.org/uzu/strudel/pulls/849) -- 2023-12-06T23:02:31+01:00 Fix examples page, piano() and a few workshop imgs by Ghost in: [#848](https://codeberg.org/uzu/strudel/pulls/848) -- 2023-12-06T22:30:59+01:00 fix: swatch png src by froos in: [#846](https://codeberg.org/uzu/strudel/pulls/846) -- 2023-12-06T22:19:30+01:00 fix: missing hash for links starting with / by froos in: [#845](https://codeberg.org/uzu/strudel/pulls/845) -- 2023-12-06T22:05:05+01:00 improve slashing + base href behavior by froos in: [#842](https://codeberg.org/uzu/strudel/pulls/842) -- 2023-12-06T21:26:49+01:00 Add in fixes from my fork to slashocalypse branch by Ghost in: [#843](https://codeberg.org/uzu/strudel/pulls/843) -- 2023-12-05T18:43:58+01:00 Prevent 404 on Algolia crawls by Ghost in: [#838](https://codeberg.org/uzu/strudel/pulls/838) -- 2023-12-05T18:26:47+01:00 Multichannel audio by Ghost in: [#820](https://codeberg.org/uzu/strudel/pulls/820) -- 2023-12-05T12:19:58+01:00 ADDS: JetBrains IDE files and directories to .gitignore by Ghost in: [#840](https://codeberg.org/uzu/strudel/pulls/840) -- 2023-12-05T12:19:27+01:00 CHANGES: github action pnpm version from 7 to 8.3.1 by Ghost in: [#835](https://codeberg.org/uzu/strudel/pulls/835) -- 2023-12-05T12:19:17+01:00 CHANGES: pin pnpm to version 8.3.1 by Ghost in: [#834](https://codeberg.org/uzu/strudel/pulls/834) -- 2023-12-05T12:19:06+01:00 CHANGES: github action checkout v2 -> v4 by Ghost in: [#837](https://codeberg.org/uzu/strudel/pulls/837) -- 2023-12-05T11:15:14+01:00 FIXES: palindrome abc -> abccba by Ghost in: [#831](https://codeberg.org/uzu/strudel/pulls/831) -- 2023-12-02T09:43:50+01:00 Fix a typo by Ghost in: [#830](https://codeberg.org/uzu/strudel/pulls/830) +- 2023-12-31T17:02:57+01:00 fix: make sure n is never undefined before nanFallback by @froos in: [#881](https://codeberg.org/uzu/strudel/pulls/881) +- 2023-12-31T16:47:22+01:00 Error tolerance by @froos in: [#880](https://codeberg.org/uzu/strudel/pulls/880) +- 2023-12-31T10:06:24+01:00 bugfix: sound select indexes out of bounds by @Ghost in: [#871](https://codeberg.org/uzu/strudel/pulls/871) +- 2023-12-31T10:03:01+01:00 Audio device selection by @Ghost in: [#854](https://codeberg.org/uzu/strudel/pulls/854) +- 2023-12-31T00:59:49+01:00 Dependency update by @froos in: [#879](https://codeberg.org/uzu/strudel/pulls/879) +- 2023-12-29T16:53:41+01:00 move all examples to separate examples folder by @froos in: [#878](https://codeberg.org/uzu/strudel/pulls/878) +- 2023-12-29T15:29:17+01:00 final vanillification by @froos in: [#876](https://codeberg.org/uzu/strudel/pulls/876) +- 2023-12-27T18:38:09+01:00 Bug Fix #119: Clock drift by @Ghost in: [#874](https://codeberg.org/uzu/strudel/pulls/874) +- 2023-12-27T13:17:03+01:00 main repl vanillification by @froos in: [#873](https://codeberg.org/uzu/strudel/pulls/873) +- 2023-12-25T17:47:25+01:00 more work on vanilla repl: repl web component + package + MicroRepl by @froos in: [#866](https://codeberg.org/uzu/strudel/pulls/866) +- 2023-12-15T00:11:35+01:00 Vanilla repl 3 by @froos in: [#865](https://codeberg.org/uzu/strudel/pulls/865) +- 2023-12-14T21:28:49+01:00 Vanilla repl 2 by @froos in: [#863](https://codeberg.org/uzu/strudel/pulls/863) +- 2023-12-12T21:49:23+01:00 fix: finally repair envelopes by @froos in: [#861](https://codeberg.org/uzu/strudel/pulls/861) +- 2023-12-12T21:20:00+01:00 add missing trailing slashes by @froos in: [#860](https://codeberg.org/uzu/strudel/pulls/860) +- 2023-12-12T19:08:31+01:00 Sound Import from local file system by @Ghost in: [#839](https://codeberg.org/uzu/strudel/pulls/839) +- 2023-12-11T22:48:35+01:00 Pattern organization by @froos in: [#858](https://codeberg.org/uzu/strudel/pulls/858) +- 2023-12-09T17:25:11+01:00 Export patterns + ui tweaks by @froos in: [#855](https://codeberg.org/uzu/strudel/pulls/855) +- 2023-12-08T09:41:10+01:00 patterns tab: import patterns + style by @froos in: [#852](https://codeberg.org/uzu/strudel/pulls/852) +- 2023-12-07T20:42:00+01:00 Patterns tab + Refactor Panel by @froos in: [#769](https://codeberg.org/uzu/strudel/pulls/769) +- 2023-12-07T10:25:16+01:00 CHANGES: pnpm 8.1.3 to 8.11.0 by @Ghost in: [#850](https://codeberg.org/uzu/strudel/pulls/850) +- 2023-12-07T09:35:14+01:00 Fix edge case with rehype-urls and trailing slashes in image file paths by @Ghost in: [#849](https://codeberg.org/uzu/strudel/pulls/849) +- 2023-12-06T23:02:31+01:00 Fix examples page, piano() and a few workshop imgs by @Ghost in: [#848](https://codeberg.org/uzu/strudel/pulls/848) +- 2023-12-06T22:30:59+01:00 fix: swatch png src by @froos in: [#846](https://codeberg.org/uzu/strudel/pulls/846) +- 2023-12-06T22:19:30+01:00 fix: missing hash for links starting with / by @froos in: [#845](https://codeberg.org/uzu/strudel/pulls/845) +- 2023-12-06T22:05:05+01:00 improve slashing + base href behavior by @froos in: [#842](https://codeberg.org/uzu/strudel/pulls/842) +- 2023-12-06T21:26:49+01:00 Add in fixes from my fork to slashocalypse branch by @Ghost in: [#843](https://codeberg.org/uzu/strudel/pulls/843) +- 2023-12-05T18:43:58+01:00 Prevent 404 on Algolia crawls by @Ghost in: [#838](https://codeberg.org/uzu/strudel/pulls/838) +- 2023-12-05T18:26:47+01:00 Multichannel audio by @Ghost in: [#820](https://codeberg.org/uzu/strudel/pulls/820) +- 2023-12-05T12:19:58+01:00 ADDS: JetBrains IDE files and directories to .gitignore by @Ghost in: [#840](https://codeberg.org/uzu/strudel/pulls/840) +- 2023-12-05T12:19:27+01:00 CHANGES: github action pnpm version from 7 to 8.3.1 by @Ghost in: [#835](https://codeberg.org/uzu/strudel/pulls/835) +- 2023-12-05T12:19:17+01:00 CHANGES: pin pnpm to version 8.3.1 by @Ghost in: [#834](https://codeberg.org/uzu/strudel/pulls/834) +- 2023-12-05T12:19:06+01:00 CHANGES: github action checkout v2 -> v4 by @Ghost in: [#837](https://codeberg.org/uzu/strudel/pulls/837) +- 2023-12-05T11:15:14+01:00 FIXES: palindrome abc -> abccba by @Ghost in: [#831](https://codeberg.org/uzu/strudel/pulls/831) +- 2023-12-02T09:43:50+01:00 Fix a typo by @Ghost in: [#830](https://codeberg.org/uzu/strudel/pulls/830) ## november 2023 -- 2023-11-30T10:42:41+01:00 Add and style algolia search by Ghost in: [#827](https://codeberg.org/uzu/strudel/pulls/827) -- 2023-11-25T15:50:44+01:00 Hydra fixes and improvements by Ghost in: [#818](https://codeberg.org/uzu/strudel/pulls/818) -- 2023-11-24T10:07:17+01:00 add options param to initHydra by Ghost in: [#808](https://codeberg.org/uzu/strudel/pulls/808) -- 2023-11-24T09:57:02+01:00 Improve documentation for synonym functions by Ghost in: [#800](https://codeberg.org/uzu/strudel/pulls/800) -- 2023-11-24T09:00:54+01:00 New noise type: "crackle" by Ghost in: [#806](https://codeberg.org/uzu/strudel/pulls/806) -- 2023-11-18T21:18:16+01:00 Color hsl by froos in: [#815](https://codeberg.org/uzu/strudel/pulls/815) -- 2023-11-17T23:18:23+01:00 fix: multiple repls by froos in: [#813](https://codeberg.org/uzu/strudel/pulls/813) -- 2023-11-17T20:52:25+01:00 upstream changes by yaxu in: [#809](https://codeberg.org/uzu/strudel/pulls/809) -- 2023-11-17T16:04:10+01:00 Add doc for euclidLegatoRot, wordfall and slider by Ghost in: [#801](https://codeberg.org/uzu/strudel/pulls/801) -- 2023-11-17T14:42:58+01:00 add option to disable active line highlighting in Code Settings by Ghost in: [#804](https://codeberg.org/uzu/strudel/pulls/804) -- 2023-11-17T14:37:52+01:00 tidal style d1 ... d9 functions + more by froos in: [#805](https://codeberg.org/uzu/strudel/pulls/805) -- 2023-11-15T20:12:23+01:00 remove unwanted cm6 outline for strudelTheme by Ghost in: [#802](https://codeberg.org/uzu/strudel/pulls/802) -- 2023-11-13T23:30:15+01:00 Create phaser effect by Ghost in: [#798](https://codeberg.org/uzu/strudel/pulls/798) -- 2023-11-10T12:17:35+01:00 support multiple named serial connections, change default baudrate by yaxu in: [#551](https://codeberg.org/uzu/strudel/pulls/551) -- 2023-11-09T09:27:57+01:00 Fix for #1. Enables named instruments for csoundm. by gogins in: [#662](https://codeberg.org/uzu/strudel/pulls/662) -- 2023-11-09T09:26:45+01:00 Adding vibrato to Superdough sampler by Ghost in: [#706](https://codeberg.org/uzu/strudel/pulls/706) -- 2023-11-09T08:46:03+01:00 Document pianoroll by Ghost in: [#784](https://codeberg.org/uzu/strudel/pulls/784) -- 2023-11-09T08:45:29+01:00 Update first-effects.mdx by Ghost in: [#795](https://codeberg.org/uzu/strudel/pulls/795) -- 2023-11-09T08:44:43+01:00 Update pattern-effects.mdx by Ghost in: [#796](https://codeberg.org/uzu/strudel/pulls/796) -- 2023-11-09T08:43:50+01:00 Update recap.mdx by Ghost in: [#797](https://codeberg.org/uzu/strudel/pulls/797) -- 2023-11-07T11:53:49+01:00 Update first-sounds.mdx by Ghost in: [#794](https://codeberg.org/uzu/strudel/pulls/794) -- 2023-11-06T23:17:32+01:00 don't use anchor links for reference by froos in: [#791](https://codeberg.org/uzu/strudel/pulls/791) -- 2023-11-06T22:40:44+01:00 samples loading shortcuts: by froos in: [#788](https://codeberg.org/uzu/strudel/pulls/788) -- 2023-11-05T22:47:48+01:00 Fix scope pos + document by froos in: [#786](https://codeberg.org/uzu/strudel/pulls/786) -- 2023-11-05T22:10:25+01:00 Implement optional hover tooltip with function documentation by Ghost in: [#783](https://codeberg.org/uzu/strudel/pulls/783) -- 2023-11-05T16:46:06+01:00 Add function params in reference tab by Ghost in: [#785](https://codeberg.org/uzu/strudel/pulls/785) -- 2023-11-05T12:42:00+01:00 fix: style issues by froos in: [#781](https://codeberg.org/uzu/strudel/pulls/781) -- 2023-11-05T12:21:28+01:00 add xfade by froos in: [#780](https://codeberg.org/uzu/strudel/pulls/780) -- 2023-11-02T09:30:26+01:00 Update to Astro 3 by froos in: [#775](https://codeberg.org/uzu/strudel/pulls/775) -- 2023-11-02T08:57:14+01:00 add vscode bindings by Ghost in: [#773](https://codeberg.org/uzu/strudel/pulls/773) -- 2023-11-02T08:31:30+01:00 fix: share copy to clipboard + alert by froos in: [#774](https://codeberg.org/uzu/strudel/pulls/774) -- 2023-11-01T22:22:34+01:00 Fix chunk, add fastChunk and repeatCycles by yaxu in: [#712](https://codeberg.org/uzu/strudel/pulls/712) -- 2023-11-01T22:12:49+01:00 Document adsr function by Ghost in: [#767](https://codeberg.org/uzu/strudel/pulls/767) -- 2023-11-01T22:11:49+01:00 Add pick and squeeze functions by Ghost in: [#771](https://codeberg.org/uzu/strudel/pulls/771) -- 2023-11-01T22:04:00+01:00 Update vite pwa by froos in: [#772](https://codeberg.org/uzu/strudel/pulls/772) +- 2023-11-30T10:42:41+01:00 Add and style algolia search by @Ghost in: [#827](https://codeberg.org/uzu/strudel/pulls/827) +- 2023-11-25T15:50:44+01:00 Hydra fixes and improvements by @Ghost in: [#818](https://codeberg.org/uzu/strudel/pulls/818) +- 2023-11-24T10:07:17+01:00 add options param to initHydra by @Ghost in: [#808](https://codeberg.org/uzu/strudel/pulls/808) +- 2023-11-24T09:57:02+01:00 Improve documentation for synonym functions by @Ghost in: [#800](https://codeberg.org/uzu/strudel/pulls/800) +- 2023-11-24T09:00:54+01:00 New noise type: "crackle" by @Ghost in: [#806](https://codeberg.org/uzu/strudel/pulls/806) +- 2023-11-18T21:18:16+01:00 Color hsl by @froos in: [#815](https://codeberg.org/uzu/strudel/pulls/815) +- 2023-11-17T23:18:23+01:00 fix: multiple repls by @froos in: [#813](https://codeberg.org/uzu/strudel/pulls/813) +- 2023-11-17T20:52:25+01:00 upstream changes by @yaxu in: [#809](https://codeberg.org/uzu/strudel/pulls/809) +- 2023-11-17T16:04:10+01:00 Add doc for euclidLegatoRot, wordfall and slider by @Ghost in: [#801](https://codeberg.org/uzu/strudel/pulls/801) +- 2023-11-17T14:42:58+01:00 add option to disable active line highlighting in Code Settings by @Ghost in: [#804](https://codeberg.org/uzu/strudel/pulls/804) +- 2023-11-17T14:37:52+01:00 tidal style d1 ... d9 functions + more by @froos in: [#805](https://codeberg.org/uzu/strudel/pulls/805) +- 2023-11-15T20:12:23+01:00 remove unwanted cm6 outline for strudelTheme by @Ghost in: [#802](https://codeberg.org/uzu/strudel/pulls/802) +- 2023-11-13T23:30:15+01:00 Create phaser effect by @Ghost in: [#798](https://codeberg.org/uzu/strudel/pulls/798) +- 2023-11-10T12:17:35+01:00 support multiple named serial connections, change default baudrate by @yaxu in: [#551](https://codeberg.org/uzu/strudel/pulls/551) +- 2023-11-09T09:27:57+01:00 Fix for #1. Enables named instruments for csoundm. by @gogins in: [#662](https://codeberg.org/uzu/strudel/pulls/662) +- 2023-11-09T09:26:45+01:00 Adding vibrato to Superdough sampler by @Ghost in: [#706](https://codeberg.org/uzu/strudel/pulls/706) +- 2023-11-09T08:46:03+01:00 Document pianoroll by @Ghost in: [#784](https://codeberg.org/uzu/strudel/pulls/784) +- 2023-11-09T08:45:29+01:00 Update first-effects.mdx by @Ghost in: [#795](https://codeberg.org/uzu/strudel/pulls/795) +- 2023-11-09T08:44:43+01:00 Update pattern-effects.mdx by @Ghost in: [#796](https://codeberg.org/uzu/strudel/pulls/796) +- 2023-11-09T08:43:50+01:00 Update recap.mdx by @Ghost in: [#797](https://codeberg.org/uzu/strudel/pulls/797) +- 2023-11-07T11:53:49+01:00 Update first-sounds.mdx by @Ghost in: [#794](https://codeberg.org/uzu/strudel/pulls/794) +- 2023-11-06T23:17:32+01:00 don't use anchor links for reference by @froos in: [#791](https://codeberg.org/uzu/strudel/pulls/791) +- 2023-11-06T22:40:44+01:00 samples loading shortcuts: by @froos in: [#788](https://codeberg.org/uzu/strudel/pulls/788) +- 2023-11-05T22:47:48+01:00 Fix scope pos + document by @froos in: [#786](https://codeberg.org/uzu/strudel/pulls/786) +- 2023-11-05T22:10:25+01:00 Implement optional hover tooltip with function documentation by @Ghost in: [#783](https://codeberg.org/uzu/strudel/pulls/783) +- 2023-11-05T16:46:06+01:00 Add function params in reference tab by @Ghost in: [#785](https://codeberg.org/uzu/strudel/pulls/785) +- 2023-11-05T12:42:00+01:00 fix: style issues by @froos in: [#781](https://codeberg.org/uzu/strudel/pulls/781) +- 2023-11-05T12:21:28+01:00 add xfade by @froos in: [#780](https://codeberg.org/uzu/strudel/pulls/780) +- 2023-11-02T09:30:26+01:00 Update to Astro 3 by @froos in: [#775](https://codeberg.org/uzu/strudel/pulls/775) +- 2023-11-02T08:57:14+01:00 add vscode bindings by @Ghost in: [#773](https://codeberg.org/uzu/strudel/pulls/773) +- 2023-11-02T08:31:30+01:00 fix: share copy to clipboard + alert by @froos in: [#774](https://codeberg.org/uzu/strudel/pulls/774) +- 2023-11-01T22:22:34+01:00 Fix chunk, add fastChunk and repeatCycles by @yaxu in: [#712](https://codeberg.org/uzu/strudel/pulls/712) +- 2023-11-01T22:12:49+01:00 Document adsr function by @Ghost in: [#767](https://codeberg.org/uzu/strudel/pulls/767) +- 2023-11-01T22:11:49+01:00 Add pick and squeeze functions by @Ghost in: [#771](https://codeberg.org/uzu/strudel/pulls/771) +- 2023-11-01T22:04:00+01:00 Update vite pwa by @froos in: [#772](https://codeberg.org/uzu/strudel/pulls/772) ## october 2023 -- 2023-10-28T23:55:07+02:00 replace strudel.tidalcycles.org with strudel.cc by froos in: [#768](https://codeberg.org/uzu/strudel/pulls/768) -- 2023-10-28T12:52:37+02:00 Document striate function by Ghost in: [#766](https://codeberg.org/uzu/strudel/pulls/766) -- 2023-10-27T23:06:20+02:00 fix zen mode logo overlap by froos in: [#760](https://codeberg.org/uzu/strudel/pulls/760) -- 2023-10-27T23:01:18+02:00 fix: scale offset by froos in: [#764](https://codeberg.org/uzu/strudel/pulls/764) -- 2023-10-27T21:59:35+02:00 Fix addivite synthesis phases by froos in: [#762](https://codeberg.org/uzu/strudel/pulls/762) -- 2023-10-26T16:28:16+02:00 Hydra integration by froos in: [#759](https://codeberg.org/uzu/strudel/pulls/759) -- 2023-10-26T14:14:27+02:00 add play function by froos in: [#758](https://codeberg.org/uzu/strudel/pulls/758) -- 2023-10-26T13:11:00+02:00 Add shabda shortcut by Ghost in: [#740](https://codeberg.org/uzu/strudel/pulls/740) -- 2023-10-26T13:07:23+02:00 mini notation: international alphabets support by Ghost in: [#751](https://codeberg.org/uzu/strudel/pulls/751) -- 2023-10-22T23:00:52+02:00 hopefully fix trainling slashes bug by froos in: [#753](https://codeberg.org/uzu/strudel/pulls/753) -- 2023-10-21T23:38:50+02:00 Fix krill build command in README by Ghost in: [#748](https://codeberg.org/uzu/strudel/pulls/748) -- 2023-10-21T00:20:50+02:00 completely revert config mess by froos in: [#745](https://codeberg.org/uzu/strudel/pulls/745) -- 2023-10-20T22:41:39+02:00 fix: try different trailing slash behavior by froos in: [#744](https://codeberg.org/uzu/strudel/pulls/744) -- 2023-10-20T22:34:03+02:00 fix: trailing slash confusion by froos in: [#743](https://codeberg.org/uzu/strudel/pulls/743) -- 2023-10-20T12:07:04+02:00 [Bug Fix] chooseWith: prevent pattern from stopping audio when selection is >= 1 or < 0 by Ghost in: [#741](https://codeberg.org/uzu/strudel/pulls/741) -- 2023-10-20T11:34:26+02:00 Recipes by froos in: [#742](https://codeberg.org/uzu/strudel/pulls/742) -- 2023-10-13T12:57:24+02:00 vite-vanilla-repl readme fix by froos in: [#737](https://codeberg.org/uzu/strudel/pulls/737) -- 2023-10-10T00:17:59+02:00 Add support for using samples as impulse response buffers for the reverb by Ghost in: [#717](https://codeberg.org/uzu/strudel/pulls/717) -- 2023-10-09T21:43:42+02:00 fix: reverb sampleRate by froos in: [#732](https://codeberg.org/uzu/strudel/pulls/732) -- 2023-10-09T21:34:33+02:00 fix: reverb roomsize not required by froos in: [#731](https://codeberg.org/uzu/strudel/pulls/731) -- 2023-10-08T13:54:52+02:00 Compressor by froos in: [#729](https://codeberg.org/uzu/strudel/pulls/729) -- 2023-10-08T13:25:57+02:00 fix: hashes in urls by froos in: [#728](https://codeberg.org/uzu/strudel/pulls/728) -- 2023-10-07T15:48:06+02:00 consume n with scale by froos in: [#727](https://codeberg.org/uzu/strudel/pulls/727) -- 2023-10-07T00:27:21+02:00 fix: reverb regenerate loophole by froos in: [#726](https://codeberg.org/uzu/strudel/pulls/726) -- 2023-10-05T00:04:17+02:00 Better convolution reverb by generating impulse responses by Ghost in: [#718](https://codeberg.org/uzu/strudel/pulls/718) -- 2023-10-04T10:31:53+02:00 Slider afterthoughts by froos in: [#723](https://codeberg.org/uzu/strudel/pulls/723) -- 2023-10-03T16:39:06+02:00 Add 'white', 'pink' and 'brown' oscillators + refactor synth by Ghost in: [#713](https://codeberg.org/uzu/strudel/pulls/713) -- 2023-10-01T14:20:50+02:00 support mininotation '..' range operator, fixes #715 by yaxu in: [#716](https://codeberg.org/uzu/strudel/pulls/716) -- 2023-10-01T14:15:09+02:00 widgets by froos in: [#714](https://codeberg.org/uzu/strudel/pulls/714) +- 2023-10-28T23:55:07+02:00 replace strudel.tidalcycles.org with strudel.cc by @froos in: [#768](https://codeberg.org/uzu/strudel/pulls/768) +- 2023-10-28T12:52:37+02:00 Document striate function by @Ghost in: [#766](https://codeberg.org/uzu/strudel/pulls/766) +- 2023-10-27T23:06:20+02:00 fix zen mode logo overlap by @froos in: [#760](https://codeberg.org/uzu/strudel/pulls/760) +- 2023-10-27T23:01:18+02:00 fix: scale offset by @froos in: [#764](https://codeberg.org/uzu/strudel/pulls/764) +- 2023-10-27T21:59:35+02:00 Fix addivite synthesis phases by @froos in: [#762](https://codeberg.org/uzu/strudel/pulls/762) +- 2023-10-26T16:28:16+02:00 Hydra integration by @froos in: [#759](https://codeberg.org/uzu/strudel/pulls/759) +- 2023-10-26T14:14:27+02:00 add play function by @froos in: [#758](https://codeberg.org/uzu/strudel/pulls/758) +- 2023-10-26T13:11:00+02:00 Add shabda shortcut by @Ghost in: [#740](https://codeberg.org/uzu/strudel/pulls/740) +- 2023-10-26T13:07:23+02:00 mini notation: international alphabets support by @Ghost in: [#751](https://codeberg.org/uzu/strudel/pulls/751) +- 2023-10-22T23:00:52+02:00 hopefully fix trainling slashes bug by @froos in: [#753](https://codeberg.org/uzu/strudel/pulls/753) +- 2023-10-21T23:38:50+02:00 Fix krill build command in README by @Ghost in: [#748](https://codeberg.org/uzu/strudel/pulls/748) +- 2023-10-21T00:20:50+02:00 completely revert config mess by @froos in: [#745](https://codeberg.org/uzu/strudel/pulls/745) +- 2023-10-20T22:41:39+02:00 fix: try different trailing slash behavior by @froos in: [#744](https://codeberg.org/uzu/strudel/pulls/744) +- 2023-10-20T22:34:03+02:00 fix: trailing slash confusion by @froos in: [#743](https://codeberg.org/uzu/strudel/pulls/743) +- 2023-10-20T12:07:04+02:00 [Bug Fix] chooseWith: prevent pattern from stopping audio when selection is >= 1 or < 0 by @Ghost in: [#741](https://codeberg.org/uzu/strudel/pulls/741) +- 2023-10-20T11:34:26+02:00 Recipes by @froos in: [#742](https://codeberg.org/uzu/strudel/pulls/742) +- 2023-10-13T12:57:24+02:00 vite-vanilla-repl readme fix by @froos in: [#737](https://codeberg.org/uzu/strudel/pulls/737) +- 2023-10-10T00:17:59+02:00 Add support for using samples as impulse response buffers for the reverb by @Ghost in: [#717](https://codeberg.org/uzu/strudel/pulls/717) +- 2023-10-09T21:43:42+02:00 fix: reverb sampleRate by @froos in: [#732](https://codeberg.org/uzu/strudel/pulls/732) +- 2023-10-09T21:34:33+02:00 fix: reverb roomsize not required by @froos in: [#731](https://codeberg.org/uzu/strudel/pulls/731) +- 2023-10-08T13:54:52+02:00 Compressor by @froos in: [#729](https://codeberg.org/uzu/strudel/pulls/729) +- 2023-10-08T13:25:57+02:00 fix: hashes in urls by @froos in: [#728](https://codeberg.org/uzu/strudel/pulls/728) +- 2023-10-07T15:48:06+02:00 consume n with scale by @froos in: [#727](https://codeberg.org/uzu/strudel/pulls/727) +- 2023-10-07T00:27:21+02:00 fix: reverb regenerate loophole by @froos in: [#726](https://codeberg.org/uzu/strudel/pulls/726) +- 2023-10-05T00:04:17+02:00 Better convolution reverb by generating impulse responses by @Ghost in: [#718](https://codeberg.org/uzu/strudel/pulls/718) +- 2023-10-04T10:31:53+02:00 Slider afterthoughts by @froos in: [#723](https://codeberg.org/uzu/strudel/pulls/723) +- 2023-10-03T16:39:06+02:00 Add 'white', 'pink' and 'brown' oscillators + refactor synth by @Ghost in: [#713](https://codeberg.org/uzu/strudel/pulls/713) +- 2023-10-01T14:20:50+02:00 support mininotation '..' range operator, fixes #715 by @yaxu in: [#716](https://codeberg.org/uzu/strudel/pulls/716) +- 2023-10-01T14:15:09+02:00 widgets by @froos in: [#714](https://codeberg.org/uzu/strudel/pulls/714) ## september 2023 -- 2023-09-28T11:03:09+02:00 Midi in by froos in: [#699](https://codeberg.org/uzu/strudel/pulls/699) -- 2023-09-27T22:53:49+02:00 add midi clock support by froos in: [#710](https://codeberg.org/uzu/strudel/pulls/710) -- 2023-09-25T23:36:10+02:00 Update bournemouth.mdx by Ghost in: [#708](https://codeberg.org/uzu/strudel/pulls/708) -- 2023-09-25T23:06:30+02:00 add dough function for raw dsp by froos in: [#707](https://codeberg.org/uzu/strudel/pulls/707) -- 2023-09-17T15:53:27+02:00 Update tauri.yml workflow file by Ghost in: [#705](https://codeberg.org/uzu/strudel/pulls/705) -- 2023-09-17T11:05:06+02:00 Adding vibrato to base oscillators by Ghost in: [#693](https://codeberg.org/uzu/strudel/pulls/693) -- 2023-09-17T08:27:36+02:00 Adding loop points and thus wavetable synthesis by Ghost in: [#698](https://codeberg.org/uzu/strudel/pulls/698) -- 2023-09-16T02:03:49+02:00 Adding filter envelopes and filter order selection by Ghost in: [#692](https://codeberg.org/uzu/strudel/pulls/692) -- 2023-09-09T11:19:58+02:00 Add logging from tauri by Ghost in: [#697](https://codeberg.org/uzu/strudel/pulls/697) -- 2023-09-05T00:33:54+02:00 Direct OSC Support in Tauri by Ghost in: [#694](https://codeberg.org/uzu/strudel/pulls/694) -- 2023-09-03T22:19:22+02:00 fix MIDI CC messages by Ghost in: [#690](https://codeberg.org/uzu/strudel/pulls/690) -- 2023-09-03T10:22:15+02:00 add sleep timer + improve message iterating by Ghost in: [#688](https://codeberg.org/uzu/strudel/pulls/688) +- 2023-09-28T11:03:09+02:00 Midi in by @froos in: [#699](https://codeberg.org/uzu/strudel/pulls/699) +- 2023-09-27T22:53:49+02:00 add midi clock support by @froos in: [#710](https://codeberg.org/uzu/strudel/pulls/710) +- 2023-09-25T23:36:10+02:00 Update bournemouth.mdx by @Ghost in: [#708](https://codeberg.org/uzu/strudel/pulls/708) +- 2023-09-25T23:06:30+02:00 add dough function for raw dsp by @froos in: [#707](https://codeberg.org/uzu/strudel/pulls/707) +- 2023-09-17T15:53:27+02:00 Update tauri.yml workflow file by @Ghost in: [#705](https://codeberg.org/uzu/strudel/pulls/705) +- 2023-09-17T11:05:06+02:00 Adding vibrato to base oscillators by @Ghost in: [#693](https://codeberg.org/uzu/strudel/pulls/693) +- 2023-09-17T08:27:36+02:00 Adding loop points and thus wavetable synthesis by @Ghost in: [#698](https://codeberg.org/uzu/strudel/pulls/698) +- 2023-09-16T02:03:49+02:00 Adding filter envelopes and filter order selection by @Ghost in: [#692](https://codeberg.org/uzu/strudel/pulls/692) +- 2023-09-09T11:19:58+02:00 Add logging from tauri by @Ghost in: [#697](https://codeberg.org/uzu/strudel/pulls/697) +- 2023-09-05T00:33:54+02:00 Direct OSC Support in Tauri by @Ghost in: [#694](https://codeberg.org/uzu/strudel/pulls/694) +- 2023-09-03T22:19:22+02:00 fix MIDI CC messages by @Ghost in: [#690](https://codeberg.org/uzu/strudel/pulls/690) +- 2023-09-03T10:22:15+02:00 add sleep timer + improve message iterating by @Ghost in: [#688](https://codeberg.org/uzu/strudel/pulls/688) ## august 2023 -- 2023-08-31T13:00:31+02:00 ZZFX Synth support by Ghost in: [#684](https://codeberg.org/uzu/strudel/pulls/684) -- 2023-08-31T12:36:37+02:00 Wave Selection and Global Envelope on the FM Synth Modulator by Ghost in: [#683](https://codeberg.org/uzu/strudel/pulls/683) -- 2023-08-31T05:52:17+02:00 Create Midi Integration for Tauri Desktop app by Ghost in: [#685](https://codeberg.org/uzu/strudel/pulls/685) -- 2023-08-31T05:32:16+02:00 teletext theme + fonts by froos in: [#681](https://codeberg.org/uzu/strudel/pulls/681) -- 2023-08-31T05:20:55+02:00 control osc partial count with n by froos in: [#674](https://codeberg.org/uzu/strudel/pulls/674) -- 2023-08-27T22:18:06+02:00 add emoji support by froos in: [#680](https://codeberg.org/uzu/strudel/pulls/680) -- 2023-08-27T16:12:32+02:00 Pianoroll improvements by froos in: [#679](https://codeberg.org/uzu/strudel/pulls/679) -- 2023-08-26T21:22:17+02:00 Scope by froos in: [#677](https://codeberg.org/uzu/strudel/pulls/677) -- 2023-08-23T21:50:50+02:00 Midi time fixes by Ghost in: [#668](https://codeberg.org/uzu/strudel/pulls/668) -- 2023-08-20T23:19:08+02:00 basic fm by froos in: [#669](https://codeberg.org/uzu/strudel/pulls/669) -- 2023-08-18T23:56:20+02:00 togglable panel position by froos in: [#667](https://codeberg.org/uzu/strudel/pulls/667) -- 2023-08-18T15:59:20+02:00 fix osc bundle timestamp glitches caused by drifting clock by Ghost in: [#666](https://codeberg.org/uzu/strudel/pulls/666) -- 2023-08-17T11:36:07+02:00 superdough: encapsulates web audio output by froos in: [#664](https://codeberg.org/uzu/strudel/pulls/664) -- 2023-08-11T00:06:21+02:00 fix: always run previous trigger by froos in: [#660](https://codeberg.org/uzu/strudel/pulls/660) -- 2023-08-10T23:54:58+02:00 fix: welcome message for latestCode by froos in: [#659](https://codeberg.org/uzu/strudel/pulls/659) -- 2023-08-07T07:45:26+02:00 [Bug Fix] Midi: Don't treat note 0 as false by Ghost in: [#657](https://codeberg.org/uzu/strudel/pulls/657) +- 2023-08-31T13:00:31+02:00 ZZFX Synth support by @Ghost in: [#684](https://codeberg.org/uzu/strudel/pulls/684) +- 2023-08-31T12:36:37+02:00 Wave Selection and Global Envelope on the FM Synth Modulator by @Ghost in: [#683](https://codeberg.org/uzu/strudel/pulls/683) +- 2023-08-31T05:52:17+02:00 Create Midi Integration for Tauri Desktop app by @Ghost in: [#685](https://codeberg.org/uzu/strudel/pulls/685) +- 2023-08-31T05:32:16+02:00 teletext theme + fonts by @froos in: [#681](https://codeberg.org/uzu/strudel/pulls/681) +- 2023-08-31T05:20:55+02:00 control osc partial count with n by @froos in: [#674](https://codeberg.org/uzu/strudel/pulls/674) +- 2023-08-27T22:18:06+02:00 add emoji support by @froos in: [#680](https://codeberg.org/uzu/strudel/pulls/680) +- 2023-08-27T16:12:32+02:00 Pianoroll improvements by @froos in: [#679](https://codeberg.org/uzu/strudel/pulls/679) +- 2023-08-26T21:22:17+02:00 Scope by @froos in: [#677](https://codeberg.org/uzu/strudel/pulls/677) +- 2023-08-23T21:50:50+02:00 Midi time fixes by @Ghost in: [#668](https://codeberg.org/uzu/strudel/pulls/668) +- 2023-08-20T23:19:08+02:00 basic fm by @froos in: [#669](https://codeberg.org/uzu/strudel/pulls/669) +- 2023-08-18T23:56:20+02:00 togglable panel position by @froos in: [#667](https://codeberg.org/uzu/strudel/pulls/667) +- 2023-08-18T15:59:20+02:00 fix osc bundle timestamp glitches caused by drifting clock by @Ghost in: [#666](https://codeberg.org/uzu/strudel/pulls/666) +- 2023-08-17T11:36:07+02:00 superdough: encapsulates web audio output by @froos in: [#664](https://codeberg.org/uzu/strudel/pulls/664) +- 2023-08-11T00:06:21+02:00 fix: always run previous trigger by @froos in: [#660](https://codeberg.org/uzu/strudel/pulls/660) +- 2023-08-10T23:54:58+02:00 fix: welcome message for latestCode by @froos in: [#659](https://codeberg.org/uzu/strudel/pulls/659) +- 2023-08-07T07:45:26+02:00 [Bug Fix] Midi: Don't treat note 0 as false by @Ghost in: [#657](https://codeberg.org/uzu/strudel/pulls/657) ## july 2023 -- 2023-07-29T09:06:18+02:00 [Bug Fix] Account for numeral notation when converting to midi by Ghost in: [#656](https://codeberg.org/uzu/strudel/pulls/656) -- 2023-07-23T22:18:49+02:00 ireal voicings by froos in: [#653](https://codeberg.org/uzu/strudel/pulls/653) -- 2023-07-22T09:30:21+02:00 Understand pitch by froos in: [#652](https://codeberg.org/uzu/strudel/pulls/652) -- 2023-07-17T23:42:59+02:00 update vitest by froos in: [#651](https://codeberg.org/uzu/strudel/pulls/651) -- 2023-07-17T23:34:33+02:00 stateless voicings + tonleiter lib by froos in: [#647](https://codeberg.org/uzu/strudel/pulls/647) -- 2023-07-17T17:57:17+02:00 FIXES: TODO in rotateChroma by Ghost in: [#650](https://codeberg.org/uzu/strudel/pulls/650) -- 2023-07-10T19:07:45+02:00 slice: list mode by froos in: [#645](https://codeberg.org/uzu/strudel/pulls/645) -- 2023-07-04T23:50:30+02:00 Delete old packages by froos in: [#639](https://codeberg.org/uzu/strudel/pulls/639) -- 2023-07-04T23:38:42+02:00 Adaptive Highlighting by froos in: [#634](https://codeberg.org/uzu/strudel/pulls/634) -- 2023-07-04T21:55:57+02:00 More work on highlight IDs by Ghost in: [#636](https://codeberg.org/uzu/strudel/pulls/636) -- 2023-07-04T18:44:48+02:00 snapshot tests: sort haps by part by froos in: [#637](https://codeberg.org/uzu/strudel/pulls/637) +- 2023-07-29T09:06:18+02:00 [Bug Fix] Account for numeral notation when converting to midi by @Ghost in: [#656](https://codeberg.org/uzu/strudel/pulls/656) +- 2023-07-23T22:18:49+02:00 ireal voicings by @froos in: [#653](https://codeberg.org/uzu/strudel/pulls/653) +- 2023-07-22T09:30:21+02:00 Understand pitch by @froos in: [#652](https://codeberg.org/uzu/strudel/pulls/652) +- 2023-07-17T23:42:59+02:00 update vitest by @froos in: [#651](https://codeberg.org/uzu/strudel/pulls/651) +- 2023-07-17T23:34:33+02:00 stateless voicings + tonleiter lib by @froos in: [#647](https://codeberg.org/uzu/strudel/pulls/647) +- 2023-07-17T17:57:17+02:00 FIXES: TODO in rotateChroma by @Ghost in: [#650](https://codeberg.org/uzu/strudel/pulls/650) +- 2023-07-10T19:07:45+02:00 slice: list mode by @froos in: [#645](https://codeberg.org/uzu/strudel/pulls/645) +- 2023-07-04T23:50:30+02:00 Delete old packages by @froos in: [#639](https://codeberg.org/uzu/strudel/pulls/639) +- 2023-07-04T23:38:42+02:00 Adaptive Highlighting by @froos in: [#634](https://codeberg.org/uzu/strudel/pulls/634) +- 2023-07-04T21:55:57+02:00 More work on highlight IDs by @Ghost in: [#636](https://codeberg.org/uzu/strudel/pulls/636) +- 2023-07-04T18:44:48+02:00 snapshot tests: sort haps by part by @froos in: [#637](https://codeberg.org/uzu/strudel/pulls/637) ## juny 2023 -- 2023-06-30T22:47:40+02:00 fix: update canvas size on window resize by froos in: [#631](https://codeberg.org/uzu/strudel/pulls/631) -- 2023-06-30T22:45:41+02:00 fix: out of range error by froos in: [#630](https://codeberg.org/uzu/strudel/pulls/630) -- 2023-06-30T08:14:40+02:00 fix: midi clock drift by froos in: [#627](https://codeberg.org/uzu/strudel/pulls/627) -- 2023-06-29T22:02:28+02:00 desktop: play samples from disk by froos in: [#621](https://codeberg.org/uzu/strudel/pulls/621) -- 2023-06-29T21:59:43+02:00 cps dependent functions by froos in: [#620](https://codeberg.org/uzu/strudel/pulls/620) -- 2023-06-26T22:45:04+02:00 Fix typo on packages.mdx by Ghost in: [#520](https://codeberg.org/uzu/strudel/pulls/520) -- 2023-06-26T22:35:02+02:00 patterning ui settings by froos in: [#606](https://codeberg.org/uzu/strudel/pulls/606) -- 2023-06-26T22:32:46+02:00 add spiral viz by froos in: [#614](https://codeberg.org/uzu/strudel/pulls/614) -- 2023-06-26T22:17:46+02:00 tauri desktop app by Ghost in: [#613](https://codeberg.org/uzu/strudel/pulls/613) -- 2023-06-23T09:59:43+02:00 fix: doc links by froos in: [#612](https://codeberg.org/uzu/strudel/pulls/612) -- 2023-06-23T09:55:18+02:00 clip now works like legato in tidal by froos in: [#598](https://codeberg.org/uzu/strudel/pulls/598) -- 2023-06-18T10:36:19+02:00 fix: flatten scale lists by froos in: [#605](https://codeberg.org/uzu/strudel/pulls/605) -- 2023-06-18T10:36:17+02:00 tonal fixes by froos in: [#607](https://codeberg.org/uzu/strudel/pulls/607) -- 2023-06-15T12:51:40+02:00 editor: enable line wrapping by Ghost in: [#581](https://codeberg.org/uzu/strudel/pulls/581) -- 2023-06-15T10:22:46+02:00 add ratio function by froos in: [#602](https://codeberg.org/uzu/strudel/pulls/602) -- 2023-06-12T23:24:29+02:00 enable auto-completion by Ghost in: [#588](https://codeberg.org/uzu/strudel/pulls/588) -- 2023-06-11T22:04:17+02:00 improve cursor by froos in: [#597](https://codeberg.org/uzu/strudel/pulls/597) -- 2023-06-11T20:00:45+02:00 Solmization added by Ghost in: [#570](https://codeberg.org/uzu/strudel/pulls/570) -- 2023-06-11T19:45:00+02:00 fix: division by zero by froos in: [#591](https://codeberg.org/uzu/strudel/pulls/591) -- 2023-06-11T19:44:43+02:00 fix: allow f for flat notes like tidal by froos in: [#593](https://codeberg.org/uzu/strudel/pulls/593) -- 2023-06-11T19:44:41+02:00 Fix option dot by froos in: [#596](https://codeberg.org/uzu/strudel/pulls/596) -- 2023-06-09T21:02:12+02:00 New Workshop by froos in: [#587](https://codeberg.org/uzu/strudel/pulls/587) -- 2023-06-09T17:31:58+02:00 Music metadata by Ghost in: [#580](https://codeberg.org/uzu/strudel/pulls/580) -- 2023-06-08T09:33:34+02:00 learn/tonal: fix typo in "scaleTran[s]pose" by Ghost in: [#585](https://codeberg.org/uzu/strudel/pulls/585) -- 2023-06-07T20:19:11+02:00 repl: add option to display line numbers by Ghost in: [#582](https://codeberg.org/uzu/strudel/pulls/582) -- 2023-06-05T21:35:49+02:00 Vanilla JS Refactoring by froos in: [#563](https://codeberg.org/uzu/strudel/pulls/563) +- 2023-06-30T22:47:40+02:00 fix: update canvas size on window resize by @froos in: [#631](https://codeberg.org/uzu/strudel/pulls/631) +- 2023-06-30T22:45:41+02:00 fix: out of range error by @froos in: [#630](https://codeberg.org/uzu/strudel/pulls/630) +- 2023-06-30T08:14:40+02:00 fix: midi clock drift by @froos in: [#627](https://codeberg.org/uzu/strudel/pulls/627) +- 2023-06-29T22:02:28+02:00 desktop: play samples from disk by @froos in: [#621](https://codeberg.org/uzu/strudel/pulls/621) +- 2023-06-29T21:59:43+02:00 cps dependent functions by @froos in: [#620](https://codeberg.org/uzu/strudel/pulls/620) +- 2023-06-26T22:45:04+02:00 Fix typo on packages.mdx by @Ghost in: [#520](https://codeberg.org/uzu/strudel/pulls/520) +- 2023-06-26T22:35:02+02:00 patterning ui settings by @froos in: [#606](https://codeberg.org/uzu/strudel/pulls/606) +- 2023-06-26T22:32:46+02:00 add spiral viz by @froos in: [#614](https://codeberg.org/uzu/strudel/pulls/614) +- 2023-06-26T22:17:46+02:00 tauri desktop app by @Ghost in: [#613](https://codeberg.org/uzu/strudel/pulls/613) +- 2023-06-23T09:59:43+02:00 fix: doc links by @froos in: [#612](https://codeberg.org/uzu/strudel/pulls/612) +- 2023-06-23T09:55:18+02:00 clip now works like legato in tidal by @froos in: [#598](https://codeberg.org/uzu/strudel/pulls/598) +- 2023-06-18T10:36:19+02:00 fix: flatten scale lists by @froos in: [#605](https://codeberg.org/uzu/strudel/pulls/605) +- 2023-06-18T10:36:17+02:00 tonal fixes by @froos in: [#607](https://codeberg.org/uzu/strudel/pulls/607) +- 2023-06-15T12:51:40+02:00 editor: enable line wrapping by @Ghost in: [#581](https://codeberg.org/uzu/strudel/pulls/581) +- 2023-06-15T10:22:46+02:00 add ratio function by @froos in: [#602](https://codeberg.org/uzu/strudel/pulls/602) +- 2023-06-12T23:24:29+02:00 enable auto-completion by @Ghost in: [#588](https://codeberg.org/uzu/strudel/pulls/588) +- 2023-06-11T22:04:17+02:00 improve cursor by @froos in: [#597](https://codeberg.org/uzu/strudel/pulls/597) +- 2023-06-11T20:00:45+02:00 Solmization added by @Ghost in: [#570](https://codeberg.org/uzu/strudel/pulls/570) +- 2023-06-11T19:45:00+02:00 fix: division by zero by @froos in: [#591](https://codeberg.org/uzu/strudel/pulls/591) +- 2023-06-11T19:44:43+02:00 fix: allow f for flat notes like tidal by @froos in: [#593](https://codeberg.org/uzu/strudel/pulls/593) +- 2023-06-11T19:44:41+02:00 Fix option dot by @froos in: [#596](https://codeberg.org/uzu/strudel/pulls/596) +- 2023-06-09T21:02:12+02:00 New Workshop by @froos in: [#587](https://codeberg.org/uzu/strudel/pulls/587) +- 2023-06-09T17:31:58+02:00 Music metadata by @Ghost in: [#580](https://codeberg.org/uzu/strudel/pulls/580) +- 2023-06-08T09:33:34+02:00 learn/tonal: fix typo in "scaleTran[s]pose" by @Ghost in: [#585](https://codeberg.org/uzu/strudel/pulls/585) +- 2023-06-07T20:19:11+02:00 repl: add option to display line numbers by @Ghost in: [#582](https://codeberg.org/uzu/strudel/pulls/582) +- 2023-06-05T21:35:49+02:00 Vanilla JS Refactoring by @froos in: [#563](https://codeberg.org/uzu/strudel/pulls/563) ## may 2023 -- 2023-05-05T08:34:37+02:00 Patchday by froos in: [#559](https://codeberg.org/uzu/strudel/pulls/559) -- 2023-05-02T21:48:33+02:00 add basic triads and guidetone voicings by froos in: [#557](https://codeberg.org/uzu/strudel/pulls/557) +- 2023-05-05T08:34:37+02:00 Patchday by @froos in: [#559](https://codeberg.org/uzu/strudel/pulls/559) +- 2023-05-02T21:48:33+02:00 add basic triads and guidetone voicings by @froos in: [#557](https://codeberg.org/uzu/strudel/pulls/557) ## april 2023 -- 2023-04-28T12:46:56+02:00 fix: make soundfonts import dynamic by froos in: [#556](https://codeberg.org/uzu/strudel/pulls/556) -- 2023-04-22T15:43:22+02:00 fix: colorable highlighting by froos in: [#553](https://codeberg.org/uzu/strudel/pulls/553) -- 2023-04-06T00:11:02+02:00 fix: load soundfonts in prebake by froos in: [#550](https://codeberg.org/uzu/strudel/pulls/550) +- 2023-04-28T12:46:56+02:00 fix: make soundfonts import dynamic by @froos in: [#556](https://codeberg.org/uzu/strudel/pulls/556) +- 2023-04-22T15:43:22+02:00 fix: colorable highlighting by @froos in: [#553](https://codeberg.org/uzu/strudel/pulls/553) +- 2023-04-06T00:11:02+02:00 fix: load soundfonts in prebake by @froos in: [#550](https://codeberg.org/uzu/strudel/pulls/550) ## march 2023 -- 2023-03-29T22:23:07+02:00 fix: reset time on stop by froos in: [#548](https://codeberg.org/uzu/strudel/pulls/548) -- 2023-03-29T22:16:38+02:00 fix: allow whitespace at the end of a mini pattern by froos in: [#547](https://codeberg.org/uzu/strudel/pulls/547) -- 2023-03-24T22:10:56+01:00 add firacode font by froos in: [#544](https://codeberg.org/uzu/strudel/pulls/544) -- 2023-03-24T12:54:20+01:00 feat: add loader bar to animate loading state by froos in: [#542](https://codeberg.org/uzu/strudel/pulls/542) -- 2023-03-23T22:39:27+01:00 do not reset cps before eval #517 by froos in: [#539](https://codeberg.org/uzu/strudel/pulls/539) -- 2023-03-23T22:27:31+01:00 improve initial loading + wait before eval by froos in: [#538](https://codeberg.org/uzu/strudel/pulls/538) -- 2023-03-23T21:40:20+01:00 fix period key for dvorak + remove duplicated code by froos in: [#537](https://codeberg.org/uzu/strudel/pulls/537) -- 2023-03-23T11:44:56+01:00 Update lerna by froos in: [#535](https://codeberg.org/uzu/strudel/pulls/535) -- 2023-03-23T10:21:55+01:00 feat: add freq support to gm soundfonts by froos in: [#534](https://codeberg.org/uzu/strudel/pulls/534) -- 2023-03-23T10:18:58+01:00 Maintain random seed state in parser, not globally by Ghost in: [#531](https://codeberg.org/uzu/strudel/pulls/531) -- 2023-03-21T22:35:18+01:00 FIXES: alias pm for polymeter by Ghost in: [#527](https://codeberg.org/uzu/strudel/pulls/527) -- 2023-03-21T22:29:07+01:00 fix(footer): fix link to tidalcycles by julienbouquillon in: [#529](https://codeberg.org/uzu/strudel/pulls/529) -- 2023-03-18T20:25:21+01:00 Update intro.mdx by Ghost in: [#525](https://codeberg.org/uzu/strudel/pulls/525) -- 2023-03-18T20:24:38+01:00 Update samples.mdx by Ghost in: [#524](https://codeberg.org/uzu/strudel/pulls/524) -- 2023-03-17T09:03:11+01:00 fix: envelopes in chrome by froos in: [#521](https://codeberg.org/uzu/strudel/pulls/521) -- 2023-03-16T16:13:30+01:00 registerSound API + improved sounds tab + regroup soundfonts by froos in: [#516](https://codeberg.org/uzu/strudel/pulls/516) -- 2023-03-14T21:54:53+01:00 add 2 illegible fonts by froos in: [#518](https://codeberg.org/uzu/strudel/pulls/518) -- 2023-03-06T22:55:00+01:00 Update README.md by Ghost in: [#474](https://codeberg.org/uzu/strudel/pulls/474) -- 2023-03-05T14:52:30+01:00 add arrange function by froos in: [#508](https://codeberg.org/uzu/strudel/pulls/508) -- 2023-03-05T14:29:08+01:00 update react to 18 by froos in: [#514](https://codeberg.org/uzu/strudel/pulls/514) -- 2023-03-04T19:06:18+01:00 Support list syntax in mininotation by yaxu in: [#512](https://codeberg.org/uzu/strudel/pulls/512) -- 2023-03-03T12:40:23+01:00 can now use : as a replacement for space in scales by froos in: [#502](https://codeberg.org/uzu/strudel/pulls/502) -- 2023-03-02T15:44:41+01:00 Reinstate slice and splice by yaxu in: [#500](https://codeberg.org/uzu/strudel/pulls/500) -- 2023-03-02T14:49:30+01:00 fix: nano-repl highlighting by froos in: [#501](https://codeberg.org/uzu/strudel/pulls/501) -- 2023-03-02T14:17:13+01:00 Add control aliases by yaxu in: [#497](https://codeberg.org/uzu/strudel/pulls/497) -- 2023-03-01T09:27:27+01:00 implement cps in scheduler by froos in: [#493](https://codeberg.org/uzu/strudel/pulls/493) +- 2023-03-29T22:23:07+02:00 fix: reset time on stop by @froos in: [#548](https://codeberg.org/uzu/strudel/pulls/548) +- 2023-03-29T22:16:38+02:00 fix: allow whitespace at the end of a mini pattern by @froos in: [#547](https://codeberg.org/uzu/strudel/pulls/547) +- 2023-03-24T22:10:56+01:00 add firacode font by @froos in: [#544](https://codeberg.org/uzu/strudel/pulls/544) +- 2023-03-24T12:54:20+01:00 feat: add loader bar to animate loading state by @froos in: [#542](https://codeberg.org/uzu/strudel/pulls/542) +- 2023-03-23T22:39:27+01:00 do not reset cps before eval #517 by @froos in: [#539](https://codeberg.org/uzu/strudel/pulls/539) +- 2023-03-23T22:27:31+01:00 improve initial loading + wait before eval by @froos in: [#538](https://codeberg.org/uzu/strudel/pulls/538) +- 2023-03-23T21:40:20+01:00 fix period key for dvorak + remove duplicated code by @froos in: [#537](https://codeberg.org/uzu/strudel/pulls/537) +- 2023-03-23T11:44:56+01:00 Update lerna by @froos in: [#535](https://codeberg.org/uzu/strudel/pulls/535) +- 2023-03-23T10:21:55+01:00 feat: add freq support to gm soundfonts by @froos in: [#534](https://codeberg.org/uzu/strudel/pulls/534) +- 2023-03-23T10:18:58+01:00 Maintain random seed state in parser, not globally by @Ghost in: [#531](https://codeberg.org/uzu/strudel/pulls/531) +- 2023-03-21T22:35:18+01:00 FIXES: alias pm for polymeter by @Ghost in: [#527](https://codeberg.org/uzu/strudel/pulls/527) +- 2023-03-21T22:29:07+01:00 fix(footer): fix link to tidalcycles by @julienbouquillon in: [#529](https://codeberg.org/uzu/strudel/pulls/529) +- 2023-03-18T20:25:21+01:00 Update intro.mdx by @Ghost in: [#525](https://codeberg.org/uzu/strudel/pulls/525) +- 2023-03-18T20:24:38+01:00 Update samples.mdx by @Ghost in: [#524](https://codeberg.org/uzu/strudel/pulls/524) +- 2023-03-17T09:03:11+01:00 fix: envelopes in chrome by @froos in: [#521](https://codeberg.org/uzu/strudel/pulls/521) +- 2023-03-16T16:13:30+01:00 registerSound API + improved sounds tab + regroup soundfonts by @froos in: [#516](https://codeberg.org/uzu/strudel/pulls/516) +- 2023-03-14T21:54:53+01:00 add 2 illegible fonts by @froos in: [#518](https://codeberg.org/uzu/strudel/pulls/518) +- 2023-03-06T22:55:00+01:00 Update README.md by @Ghost in: [#474](https://codeberg.org/uzu/strudel/pulls/474) +- 2023-03-05T14:52:30+01:00 add arrange function by @froos in: [#508](https://codeberg.org/uzu/strudel/pulls/508) +- 2023-03-05T14:29:08+01:00 update react to 18 by @froos in: [#514](https://codeberg.org/uzu/strudel/pulls/514) +- 2023-03-04T19:06:18+01:00 Support list syntax in mininotation by @yaxu in: [#512](https://codeberg.org/uzu/strudel/pulls/512) +- 2023-03-03T12:40:23+01:00 can now use : as a replacement for space in scales by @froos in: [#502](https://codeberg.org/uzu/strudel/pulls/502) +- 2023-03-02T15:44:41+01:00 Reinstate slice and splice by @yaxu in: [#500](https://codeberg.org/uzu/strudel/pulls/500) +- 2023-03-02T14:49:30+01:00 fix: nano-repl highlighting by @froos in: [#501](https://codeberg.org/uzu/strudel/pulls/501) +- 2023-03-02T14:17:13+01:00 Add control aliases by @yaxu in: [#497](https://codeberg.org/uzu/strudel/pulls/497) +- 2023-03-01T09:27:27+01:00 implement cps in scheduler by @froos in: [#493](https://codeberg.org/uzu/strudel/pulls/493) ## february 2023 -- 2023-02-28T23:06:29+01:00 react style fixes by froos in: [#491](https://codeberg.org/uzu/strudel/pulls/491) -- 2023-02-28T22:57:20+01:00 refactor react package by froos in: [#490](https://codeberg.org/uzu/strudel/pulls/490) -- 2023-02-27T23:47:34+01:00 add algolia creds + optimize sidebar for crawling by froos in: [#488](https://codeberg.org/uzu/strudel/pulls/488) -- 2023-02-27T19:28:10+01:00 fix app height by froos in: [#485](https://codeberg.org/uzu/strudel/pulls/485) -- 2023-02-27T16:04:21+01:00 Revert "Another attempt at composable functions - WIP (#390)" by froos in: [#484](https://codeberg.org/uzu/strudel/pulls/484) -- 2023-02-27T15:45:20+01:00 Update mini-notation.mdx by yaxu in: [#365](https://codeberg.org/uzu/strudel/pulls/365) -- 2023-02-27T12:52:09+01:00 docs: packages + offline by froos in: [#482](https://codeberg.org/uzu/strudel/pulls/482) -- 2023-02-25T14:26:49+01:00 Fix array args by froos in: [#480](https://codeberg.org/uzu/strudel/pulls/480) -- 2023-02-25T12:33:22+01:00 midi cc support by froos in: [#478](https://codeberg.org/uzu/strudel/pulls/478) -- 2023-02-23T00:11:05+01:00 fix: hash links by froos in: [#473](https://codeberg.org/uzu/strudel/pulls/473) -- 2023-02-22T22:54:39+01:00 settings tab with vim / emacs modes + additional themes and fonts by froos in: [#467](https://codeberg.org/uzu/strudel/pulls/467) -- 2023-02-22T22:53:22+01:00 Update input-output.mdx by Ghost in: [#471](https://codeberg.org/uzu/strudel/pulls/471) -- 2023-02-22T22:52:50+01:00 FIXES: freqs instead of pitches by Ghost in: [#464](https://codeberg.org/uzu/strudel/pulls/464) -- 2023-02-22T20:01:00+01:00 fix: osc should not return a promise by froos in: [#472](https://codeberg.org/uzu/strudel/pulls/472) -- 2023-02-22T12:51:31+01:00 slice and splice by yaxu in: [#466](https://codeberg.org/uzu/strudel/pulls/466) -- 2023-02-18T01:00:19+01:00 weave and weaveWith by yaxu in: [#465](https://codeberg.org/uzu/strudel/pulls/465) -- 2023-02-17T00:15:21+01:00 Composable functions by yaxu in: [#390](https://codeberg.org/uzu/strudel/pulls/390) -- 2023-02-16T20:38:45+01:00 FIXES: Warning about jsxBracketSameLine deprecation by Ghost in: [#461](https://codeberg.org/uzu/strudel/pulls/461) -- 2023-02-14T22:11:02+01:00 Update synths.mdx by Ghost in: [#438](https://codeberg.org/uzu/strudel/pulls/438) -- 2023-02-14T19:54:42+01:00 Update mini-notation.mdx by Ghost in: [#437](https://codeberg.org/uzu/strudel/pulls/437) -- 2023-02-14T19:54:25+01:00 Update code.mdx by Ghost in: [#436](https://codeberg.org/uzu/strudel/pulls/436) -- 2023-02-13T00:43:29+01:00 Fix anchors by froos in: [#433](https://codeberg.org/uzu/strudel/pulls/433) -- 2023-02-11T21:02:11+01:00 autocomplete preparations by froos in: [#427](https://codeberg.org/uzu/strudel/pulls/427) -- 2023-02-10T23:14:48+01:00 Themes by froos in: [#431](https://codeberg.org/uzu/strudel/pulls/431) -- 2023-02-09T19:22:56+01:00 minirepl: add keyboard shortcuts by froos in: [#429](https://codeberg.org/uzu/strudel/pulls/429) -- 2023-02-09T08:56:42+01:00 add cdn.freesound to cache list by froos in: [#425](https://codeberg.org/uzu/strudel/pulls/425) -- 2023-02-08T20:36:00+01:00 add more offline caching by froos in: [#421](https://codeberg.org/uzu/strudel/pulls/421) -- 2023-02-07T22:08:01+01:00 add caching strategy for missing file types + cache all samples loaded from github by froos in: [#419](https://codeberg.org/uzu/strudel/pulls/419) -- 2023-02-06T23:29:57+01:00 PWA with offline support by froos in: [#417](https://codeberg.org/uzu/strudel/pulls/417) -- 2023-02-05T17:27:32+01:00 improve samples doc by froos in: [#411](https://codeberg.org/uzu/strudel/pulls/411) -- 2023-02-05T17:27:10+01:00 google gtfo by froos in: [#413](https://codeberg.org/uzu/strudel/pulls/413) -- 2023-02-05T16:27:59+01:00 improve effects doc by froos in: [#409](https://codeberg.org/uzu/strudel/pulls/409) -- 2023-02-05T14:56:03+01:00 Update effects.mdx by Ghost in: [#410](https://codeberg.org/uzu/strudel/pulls/410) -- 2023-02-03T19:54:47+01:00 add shabda doc by froos in: [#407](https://codeberg.org/uzu/strudel/pulls/407) -- 2023-02-02T21:45:56+01:00 fix: share url on subpath by froos in: [#405](https://codeberg.org/uzu/strudel/pulls/405) -- 2023-02-02T21:35:45+01:00 update csound + fix sound output by froos in: [#404](https://codeberg.org/uzu/strudel/pulls/404) -- 2023-02-02T19:53:36+01:00 pin @csound/browser to 6.18.3 + bump by froos in: [#403](https://codeberg.org/uzu/strudel/pulls/403) -- 2023-02-01T22:47:27+01:00 release webaudio by froos in: [#400](https://codeberg.org/uzu/strudel/pulls/400) -- 2023-02-01T22:45:16+01:00 can now await initAudio + initAudioOnFirstClick by froos in: [#399](https://codeberg.org/uzu/strudel/pulls/399) -- 2023-02-01T22:32:18+01:00 fix: minirepl styles by froos in: [#398](https://codeberg.org/uzu/strudel/pulls/398) -- 2023-02-01T22:17:19+01:00 proper builds + use pnpm workspaces by froos in: [#396](https://codeberg.org/uzu/strudel/pulls/396) -- 2023-02-01T16:49:55+01:00 add pattern methods hurry, press and pressBy by yaxu in: [#397](https://codeberg.org/uzu/strudel/pulls/397) +- 2023-02-28T23:06:29+01:00 react style fixes by @froos in: [#491](https://codeberg.org/uzu/strudel/pulls/491) +- 2023-02-28T22:57:20+01:00 refactor react package by @froos in: [#490](https://codeberg.org/uzu/strudel/pulls/490) +- 2023-02-27T23:47:34+01:00 add algolia creds + optimize sidebar for crawling by @froos in: [#488](https://codeberg.org/uzu/strudel/pulls/488) +- 2023-02-27T19:28:10+01:00 fix app height by @froos in: [#485](https://codeberg.org/uzu/strudel/pulls/485) +- 2023-02-27T16:04:21+01:00 Revert "Another attempt at composable functions - WIP (#390)" by @froos in: [#484](https://codeberg.org/uzu/strudel/pulls/484) +- 2023-02-27T15:45:20+01:00 Update mini-notation.mdx by @yaxu in: [#365](https://codeberg.org/uzu/strudel/pulls/365) +- 2023-02-27T12:52:09+01:00 docs: packages + offline by @froos in: [#482](https://codeberg.org/uzu/strudel/pulls/482) +- 2023-02-25T14:26:49+01:00 Fix array args by @froos in: [#480](https://codeberg.org/uzu/strudel/pulls/480) +- 2023-02-25T12:33:22+01:00 midi cc support by @froos in: [#478](https://codeberg.org/uzu/strudel/pulls/478) +- 2023-02-23T00:11:05+01:00 fix: hash links by @froos in: [#473](https://codeberg.org/uzu/strudel/pulls/473) +- 2023-02-22T22:54:39+01:00 settings tab with vim / emacs modes + additional themes and fonts by @froos in: [#467](https://codeberg.org/uzu/strudel/pulls/467) +- 2023-02-22T22:53:22+01:00 Update input-output.mdx by @Ghost in: [#471](https://codeberg.org/uzu/strudel/pulls/471) +- 2023-02-22T22:52:50+01:00 FIXES: freqs instead of pitches by @Ghost in: [#464](https://codeberg.org/uzu/strudel/pulls/464) +- 2023-02-22T20:01:00+01:00 fix: osc should not return a promise by @froos in: [#472](https://codeberg.org/uzu/strudel/pulls/472) +- 2023-02-22T12:51:31+01:00 slice and splice by @yaxu in: [#466](https://codeberg.org/uzu/strudel/pulls/466) +- 2023-02-18T01:00:19+01:00 weave and weaveWith by @yaxu in: [#465](https://codeberg.org/uzu/strudel/pulls/465) +- 2023-02-17T00:15:21+01:00 Composable functions by @yaxu in: [#390](https://codeberg.org/uzu/strudel/pulls/390) +- 2023-02-16T20:38:45+01:00 FIXES: Warning about jsxBracketSameLine deprecation by @Ghost in: [#461](https://codeberg.org/uzu/strudel/pulls/461) +- 2023-02-14T22:11:02+01:00 Update synths.mdx by @Ghost in: [#438](https://codeberg.org/uzu/strudel/pulls/438) +- 2023-02-14T19:54:42+01:00 Update mini-notation.mdx by @Ghost in: [#437](https://codeberg.org/uzu/strudel/pulls/437) +- 2023-02-14T19:54:25+01:00 Update code.mdx by @Ghost in: [#436](https://codeberg.org/uzu/strudel/pulls/436) +- 2023-02-13T00:43:29+01:00 Fix anchors by @froos in: [#433](https://codeberg.org/uzu/strudel/pulls/433) +- 2023-02-11T21:02:11+01:00 autocomplete preparations by @froos in: [#427](https://codeberg.org/uzu/strudel/pulls/427) +- 2023-02-10T23:14:48+01:00 Themes by @froos in: [#431](https://codeberg.org/uzu/strudel/pulls/431) +- 2023-02-09T19:22:56+01:00 minirepl: add keyboard shortcuts by @froos in: [#429](https://codeberg.org/uzu/strudel/pulls/429) +- 2023-02-09T08:56:42+01:00 add cdn.freesound to cache list by @froos in: [#425](https://codeberg.org/uzu/strudel/pulls/425) +- 2023-02-08T20:36:00+01:00 add more offline caching by @froos in: [#421](https://codeberg.org/uzu/strudel/pulls/421) +- 2023-02-07T22:08:01+01:00 add caching strategy for missing file types + cache all samples loaded from github by @froos in: [#419](https://codeberg.org/uzu/strudel/pulls/419) +- 2023-02-06T23:29:57+01:00 PWA with offline support by @froos in: [#417](https://codeberg.org/uzu/strudel/pulls/417) +- 2023-02-05T17:27:32+01:00 improve samples doc by @froos in: [#411](https://codeberg.org/uzu/strudel/pulls/411) +- 2023-02-05T17:27:10+01:00 google gtfo by @froos in: [#413](https://codeberg.org/uzu/strudel/pulls/413) +- 2023-02-05T16:27:59+01:00 improve effects doc by @froos in: [#409](https://codeberg.org/uzu/strudel/pulls/409) +- 2023-02-05T14:56:03+01:00 Update effects.mdx by @Ghost in: [#410](https://codeberg.org/uzu/strudel/pulls/410) +- 2023-02-03T19:54:47+01:00 add shabda doc by @froos in: [#407](https://codeberg.org/uzu/strudel/pulls/407) +- 2023-02-02T21:45:56+01:00 fix: share url on subpath by @froos in: [#405](https://codeberg.org/uzu/strudel/pulls/405) +- 2023-02-02T21:35:45+01:00 update csound + fix sound output by @froos in: [#404](https://codeberg.org/uzu/strudel/pulls/404) +- 2023-02-02T19:53:36+01:00 pin @csound/browser to 6.18.3 + bump by @froos in: [#403](https://codeberg.org/uzu/strudel/pulls/403) +- 2023-02-01T22:47:27+01:00 release webaudio by @froos in: [#400](https://codeberg.org/uzu/strudel/pulls/400) +- 2023-02-01T22:45:16+01:00 can now await initAudio + initAudioOnFirstClick by @froos in: [#399](https://codeberg.org/uzu/strudel/pulls/399) +- 2023-02-01T22:32:18+01:00 fix: minirepl styles by @froos in: [#398](https://codeberg.org/uzu/strudel/pulls/398) +- 2023-02-01T22:17:19+01:00 proper builds + use pnpm workspaces by @froos in: [#396](https://codeberg.org/uzu/strudel/pulls/396) +- 2023-02-01T16:49:55+01:00 add pattern methods hurry, press and pressBy by @yaxu in: [#397](https://codeberg.org/uzu/strudel/pulls/397) ## january 2023 -- 2023-01-27T14:40:40+01:00 Add tidal-drum-patterns to examples by Ghost in: [#379](https://codeberg.org/uzu/strudel/pulls/379) -- 2023-01-27T14:39:56+01:00 add ribbon + test + docs by froos in: [#388](https://codeberg.org/uzu/strudel/pulls/388) -- 2023-01-27T12:10:37+01:00 Notes are not essential :) by yaxu in: [#393](https://codeberg.org/uzu/strudel/pulls/393) -- 2023-01-21T17:18:13+01:00 document csound by froos in: [#391](https://codeberg.org/uzu/strudel/pulls/391) -- 2023-01-19T12:04:51+01:00 Rename a to angle by froos in: [#387](https://codeberg.org/uzu/strudel/pulls/387) -- 2023-01-19T11:49:39+01:00 add run + test + docs by froos in: [#386](https://codeberg.org/uzu/strudel/pulls/386) -- 2023-01-19T11:32:56+01:00 docs: use note instead of n to mitigate confusion by froos in: [#385](https://codeberg.org/uzu/strudel/pulls/385) -- 2023-01-18T17:10:09+01:00 update my-patterns instructions by froos in: [#384](https://codeberg.org/uzu/strudel/pulls/384) -- 2023-01-15T23:19:43+01:00 Draw fixes by froos in: [#377](https://codeberg.org/uzu/strudel/pulls/377) -- 2023-01-14T11:07:08+01:00 improve new draw logic by froos in: [#372](https://codeberg.org/uzu/strudel/pulls/372) -- 2023-01-12T14:40:59+01:00 document more functions + change arp join by froos in: [#369](https://codeberg.org/uzu/strudel/pulls/369) -- 2023-01-10T00:03:47+01:00 add https to url by Ghost in: [#364](https://codeberg.org/uzu/strudel/pulls/364) -- 2023-01-09T23:37:34+01:00 doc structuring by froos in: [#360](https://codeberg.org/uzu/strudel/pulls/360) -- 2023-01-09T23:23:28+01:00 Support for multiple mininotation operators by yaxu in: [#350](https://codeberg.org/uzu/strudel/pulls/350) -- 2023-01-09T00:40:15+01:00 Fix .out(), renaming webaudio's out() to webaudio() by yaxu in: [#361](https://codeberg.org/uzu/strudel/pulls/361) -- 2023-01-06T22:02:31+01:00 docs: tidal comparison + add global fx + add missing sampler fx by froos in: [#356](https://codeberg.org/uzu/strudel/pulls/356) -- 2023-01-06T12:31:32+01:00 Fix Bjorklund by yaxu in: [#343](https://codeberg.org/uzu/strudel/pulls/343) -- 2023-01-04T20:29:35+01:00 Fix prebake base path by froos in: [#345](https://codeberg.org/uzu/strudel/pulls/345) -- 2023-01-04T19:55:49+01:00 fixes #346 by froos in: [#347](https://codeberg.org/uzu/strudel/pulls/347) -- 2023-01-02T21:28:07+01:00 Patternify euclid, fast, slow and polymeter step parameters in mininotation by yaxu in: [#341](https://codeberg.org/uzu/strudel/pulls/341) -- 2023-01-02T00:30:16+01:00 more animate functions + mini repl fix by froos in: [#340](https://codeberg.org/uzu/strudel/pulls/340) -- 2023-01-01T12:34:11+01:00 move /my-patterns to /swatch by yaxu in: [#338](https://codeberg.org/uzu/strudel/pulls/338) -- 2023-01-01T12:22:55+01:00 animation options by froos in: [#337](https://codeberg.org/uzu/strudel/pulls/337) +- 2023-01-27T14:40:40+01:00 Add tidal-drum-patterns to examples by @Ghost in: [#379](https://codeberg.org/uzu/strudel/pulls/379) +- 2023-01-27T14:39:56+01:00 add ribbon + test + docs by @froos in: [#388](https://codeberg.org/uzu/strudel/pulls/388) +- 2023-01-27T12:10:37+01:00 Notes are not essential :) by @yaxu in: [#393](https://codeberg.org/uzu/strudel/pulls/393) +- 2023-01-21T17:18:13+01:00 document csound by @froos in: [#391](https://codeberg.org/uzu/strudel/pulls/391) +- 2023-01-19T12:04:51+01:00 Rename a to angle by @froos in: [#387](https://codeberg.org/uzu/strudel/pulls/387) +- 2023-01-19T11:49:39+01:00 add run + test + docs by @froos in: [#386](https://codeberg.org/uzu/strudel/pulls/386) +- 2023-01-19T11:32:56+01:00 docs: use note instead of n to mitigate confusion by @froos in: [#385](https://codeberg.org/uzu/strudel/pulls/385) +- 2023-01-18T17:10:09+01:00 update my-patterns instructions by @froos in: [#384](https://codeberg.org/uzu/strudel/pulls/384) +- 2023-01-15T23:19:43+01:00 Draw fixes by @froos in: [#377](https://codeberg.org/uzu/strudel/pulls/377) +- 2023-01-14T11:07:08+01:00 improve new draw logic by @froos in: [#372](https://codeberg.org/uzu/strudel/pulls/372) +- 2023-01-12T14:40:59+01:00 document more functions + change arp join by @froos in: [#369](https://codeberg.org/uzu/strudel/pulls/369) +- 2023-01-10T00:03:47+01:00 add https to url by @Ghost in: [#364](https://codeberg.org/uzu/strudel/pulls/364) +- 2023-01-09T23:37:34+01:00 doc structuring by @froos in: [#360](https://codeberg.org/uzu/strudel/pulls/360) +- 2023-01-09T23:23:28+01:00 Support for multiple mininotation operators by @yaxu in: [#350](https://codeberg.org/uzu/strudel/pulls/350) +- 2023-01-09T00:40:15+01:00 Fix .out(), renaming webaudio's out() to webaudio() by @yaxu in: [#361](https://codeberg.org/uzu/strudel/pulls/361) +- 2023-01-06T22:02:31+01:00 docs: tidal comparison + add global fx + add missing sampler fx by @froos in: [#356](https://codeberg.org/uzu/strudel/pulls/356) +- 2023-01-06T12:31:32+01:00 Fix Bjorklund by @yaxu in: [#343](https://codeberg.org/uzu/strudel/pulls/343) +- 2023-01-04T20:29:35+01:00 Fix prebake base path by @froos in: [#345](https://codeberg.org/uzu/strudel/pulls/345) +- 2023-01-04T19:55:49+01:00 fixes #346 by @froos in: [#347](https://codeberg.org/uzu/strudel/pulls/347) +- 2023-01-02T21:28:07+01:00 Patternify euclid, fast, slow and polymeter step parameters in mininotation by @yaxu in: [#341](https://codeberg.org/uzu/strudel/pulls/341) +- 2023-01-02T00:30:16+01:00 more animate functions + mini repl fix by @froos in: [#340](https://codeberg.org/uzu/strudel/pulls/340) +- 2023-01-01T12:34:11+01:00 move /my-patterns to /swatch by @yaxu in: [#338](https://codeberg.org/uzu/strudel/pulls/338) +- 2023-01-01T12:22:55+01:00 animation options by @froos in: [#337](https://codeberg.org/uzu/strudel/pulls/337) ## december 2022 -- 2022-12-31T22:42:49+01:00 Tidy parser, implement polymeters by yaxu in: [#336](https://codeberg.org/uzu/strudel/pulls/336) -- 2022-12-31T16:51:53+01:00 animate mvp by froos in: [#335](https://codeberg.org/uzu/strudel/pulls/335) -- 2022-12-30T20:16:10+01:00 testing + docs docs by froos in: [#334](https://codeberg.org/uzu/strudel/pulls/334) -- 2022-12-29T21:11:16+01:00 Embed mode improvements by froos in: [#333](https://codeberg.org/uzu/strudel/pulls/333) -- 2022-12-29T14:06:20+01:00 fix: can now multiply floats in mini notation by froos in: [#332](https://codeberg.org/uzu/strudel/pulls/332) -- 2022-12-29T13:50:07+01:00 improve displaying 's' in pianoroll by froos in: [#331](https://codeberg.org/uzu/strudel/pulls/331) -- 2022-12-28T17:35:35+01:00 my-patterns: fix paths + update readme by froos in: [#330](https://codeberg.org/uzu/strudel/pulls/330) -- 2022-12-28T17:11:40+01:00 my-patterns build + deploy by froos in: [#329](https://codeberg.org/uzu/strudel/pulls/329) -- 2022-12-28T15:43:31+01:00 add my-patterns by froos in: [#328](https://codeberg.org/uzu/strudel/pulls/328) -- 2022-12-28T14:47:14+01:00 add examples route by froos in: [#327](https://codeberg.org/uzu/strudel/pulls/327) -- 2022-12-28T14:44:31+01:00 fix: workaround Object.assign globalThis by froos in: [#326](https://codeberg.org/uzu/strudel/pulls/326) -- 2022-12-26T23:29:47+01:00 mini repl improvements by froos in: [#324](https://codeberg.org/uzu/strudel/pulls/324) -- 2022-12-26T23:00:34+01:00 support notes without octave by froos in: [#323](https://codeberg.org/uzu/strudel/pulls/323) -- 2022-12-26T12:37:36+01:00 tutorial updates by Ghost in: [#320](https://codeberg.org/uzu/strudel/pulls/320) -- 2022-12-23T18:26:30+01:00 Reference tab sort by froos in: [#318](https://codeberg.org/uzu/strudel/pulls/318) -- 2022-12-23T00:49:56+01:00 Astro build by froos in: [#315](https://codeberg.org/uzu/strudel/pulls/315) -- 2022-12-19T21:02:37+01:00 object support for .scale by froos in: [#307](https://codeberg.org/uzu/strudel/pulls/307) -- 2022-12-19T21:02:22+01:00 Jsdoc component by froos in: [#312](https://codeberg.org/uzu/strudel/pulls/312) -- 2022-12-19T20:31:46+01:00 fix: copy share link to clipboard was broken for some browers by froos in: [#311](https://codeberg.org/uzu/strudel/pulls/311) -- 2022-12-19T12:11:24+01:00 ICLC2023 paper WIP by yaxu in: [#306](https://codeberg.org/uzu/strudel/pulls/306) -- 2022-12-15T21:23:22+01:00 support freq in pianoroll by froos in: [#308](https://codeberg.org/uzu/strudel/pulls/308) -- 2022-12-13T22:07:27+01:00 Updated csoundm to use the register facility . by gogins in: [#303](https://codeberg.org/uzu/strudel/pulls/303) -- 2022-12-13T21:57:03+01:00 add lint + prettier check before test by froos in: [#305](https://codeberg.org/uzu/strudel/pulls/305) -- 2022-12-13T21:21:44+01:00 add freq support to sampler by froos in: [#301](https://codeberg.org/uzu/strudel/pulls/301) -- 2022-12-12T00:48:41+01:00 fix whitespace trimming by froos in: [#300](https://codeberg.org/uzu/strudel/pulls/300) -- 2022-12-12T00:21:53+01:00 .defragmentHaps() for merging touching haps that share a whole and value by yaxu in: [#299](https://codeberg.org/uzu/strudel/pulls/299) -- 2022-12-11T23:17:49+01:00 remove whitespace from highlighted region by froos in: [#298](https://codeberg.org/uzu/strudel/pulls/298) -- 2022-12-11T22:03:26+01:00 update vitest by froos in: [#297](https://codeberg.org/uzu/strudel/pulls/297) -- 2022-12-11T21:44:16+01:00 can now add bare numbers to numeral object props by froos in: [#287](https://codeberg.org/uzu/strudel/pulls/287) -- 2022-12-11T21:27:58+01:00 Move stuff to new register function by froos in: [#295](https://codeberg.org/uzu/strudel/pulls/295) -- 2022-12-11T20:07:12+01:00 add prettier task by froos in: [#296](https://codeberg.org/uzu/strudel/pulls/296) -- 2022-12-10T15:39:04+01:00 Reorganise pattern.mjs with a 'toplevel first' regime by yaxu in: [#286](https://codeberg.org/uzu/strudel/pulls/286) -- 2022-12-10T11:56:16+01:00 Fancy hap show, include part in snapshots by yaxu in: [#291](https://codeberg.org/uzu/strudel/pulls/291) -- 2022-12-07T20:07:55+01:00 Switch 'operators' from .whatHow to .what.how by yaxu in: [#285](https://codeberg.org/uzu/strudel/pulls/285) -- 2022-12-04T12:51:01+01:00 implement collect + arp function by froos in: [#281](https://codeberg.org/uzu/strudel/pulls/281) -- 2022-12-02T13:38:27+01:00 do not recompile orc by froos in: [#278](https://codeberg.org/uzu/strudel/pulls/278) -- 2022-12-02T12:49:26+01:00 add basic csound output by froos in: [#275](https://codeberg.org/uzu/strudel/pulls/275) -- 2022-12-02T12:18:41+01:00 add licenses / credits to all tunes + remove some by froos in: [#277](https://codeberg.org/uzu/strudel/pulls/277) -- 2022-12-02T11:45:02+01:00 Support sending CRC16 bytes with serial messages by yaxu in: [#276](https://codeberg.org/uzu/strudel/pulls/276) +- 2022-12-31T22:42:49+01:00 Tidy parser, implement polymeters by @yaxu in: [#336](https://codeberg.org/uzu/strudel/pulls/336) +- 2022-12-31T16:51:53+01:00 animate mvp by @froos in: [#335](https://codeberg.org/uzu/strudel/pulls/335) +- 2022-12-30T20:16:10+01:00 testing + docs docs by @froos in: [#334](https://codeberg.org/uzu/strudel/pulls/334) +- 2022-12-29T21:11:16+01:00 Embed mode improvements by @froos in: [#333](https://codeberg.org/uzu/strudel/pulls/333) +- 2022-12-29T14:06:20+01:00 fix: can now multiply floats in mini notation by @froos in: [#332](https://codeberg.org/uzu/strudel/pulls/332) +- 2022-12-29T13:50:07+01:00 improve displaying 's' in pianoroll by @froos in: [#331](https://codeberg.org/uzu/strudel/pulls/331) +- 2022-12-28T17:35:35+01:00 my-patterns: fix paths + update readme by @froos in: [#330](https://codeberg.org/uzu/strudel/pulls/330) +- 2022-12-28T17:11:40+01:00 my-patterns build + deploy by @froos in: [#329](https://codeberg.org/uzu/strudel/pulls/329) +- 2022-12-28T15:43:31+01:00 add my-patterns by @froos in: [#328](https://codeberg.org/uzu/strudel/pulls/328) +- 2022-12-28T14:47:14+01:00 add examples route by @froos in: [#327](https://codeberg.org/uzu/strudel/pulls/327) +- 2022-12-28T14:44:31+01:00 fix: workaround Object.assign globalThis by @froos in: [#326](https://codeberg.org/uzu/strudel/pulls/326) +- 2022-12-26T23:29:47+01:00 mini repl improvements by @froos in: [#324](https://codeberg.org/uzu/strudel/pulls/324) +- 2022-12-26T23:00:34+01:00 support notes without octave by @froos in: [#323](https://codeberg.org/uzu/strudel/pulls/323) +- 2022-12-26T12:37:36+01:00 tutorial updates by @Ghost in: [#320](https://codeberg.org/uzu/strudel/pulls/320) +- 2022-12-23T18:26:30+01:00 Reference tab sort by @froos in: [#318](https://codeberg.org/uzu/strudel/pulls/318) +- 2022-12-23T00:49:56+01:00 Astro build by @froos in: [#315](https://codeberg.org/uzu/strudel/pulls/315) +- 2022-12-19T21:02:37+01:00 object support for .scale by @froos in: [#307](https://codeberg.org/uzu/strudel/pulls/307) +- 2022-12-19T21:02:22+01:00 Jsdoc component by @froos in: [#312](https://codeberg.org/uzu/strudel/pulls/312) +- 2022-12-19T20:31:46+01:00 fix: copy share link to clipboard was broken for some browers by @froos in: [#311](https://codeberg.org/uzu/strudel/pulls/311) +- 2022-12-19T12:11:24+01:00 ICLC2023 paper WIP by @yaxu in: [#306](https://codeberg.org/uzu/strudel/pulls/306) +- 2022-12-15T21:23:22+01:00 support freq in pianoroll by @froos in: [#308](https://codeberg.org/uzu/strudel/pulls/308) +- 2022-12-13T22:07:27+01:00 Updated csoundm to use the register facility . by @gogins in: [#303](https://codeberg.org/uzu/strudel/pulls/303) +- 2022-12-13T21:57:03+01:00 add lint + prettier check before test by @froos in: [#305](https://codeberg.org/uzu/strudel/pulls/305) +- 2022-12-13T21:21:44+01:00 add freq support to sampler by @froos in: [#301](https://codeberg.org/uzu/strudel/pulls/301) +- 2022-12-12T00:48:41+01:00 fix whitespace trimming by @froos in: [#300](https://codeberg.org/uzu/strudel/pulls/300) +- 2022-12-12T00:21:53+01:00 .defragmentHaps() for merging touching haps that share a whole and value by @yaxu in: [#299](https://codeberg.org/uzu/strudel/pulls/299) +- 2022-12-11T23:17:49+01:00 remove whitespace from highlighted region by @froos in: [#298](https://codeberg.org/uzu/strudel/pulls/298) +- 2022-12-11T22:03:26+01:00 update vitest by @froos in: [#297](https://codeberg.org/uzu/strudel/pulls/297) +- 2022-12-11T21:44:16+01:00 can now add bare numbers to numeral object props by @froos in: [#287](https://codeberg.org/uzu/strudel/pulls/287) +- 2022-12-11T21:27:58+01:00 Move stuff to new register function by @froos in: [#295](https://codeberg.org/uzu/strudel/pulls/295) +- 2022-12-11T20:07:12+01:00 add prettier task by @froos in: [#296](https://codeberg.org/uzu/strudel/pulls/296) +- 2022-12-10T15:39:04+01:00 Reorganise pattern.mjs with a 'toplevel first' regime by @yaxu in: [#286](https://codeberg.org/uzu/strudel/pulls/286) +- 2022-12-10T11:56:16+01:00 Fancy hap show, include part in snapshots by @yaxu in: [#291](https://codeberg.org/uzu/strudel/pulls/291) +- 2022-12-07T20:07:55+01:00 Switch 'operators' from .whatHow to .what.how by @yaxu in: [#285](https://codeberg.org/uzu/strudel/pulls/285) +- 2022-12-04T12:51:01+01:00 implement collect + arp function by @froos in: [#281](https://codeberg.org/uzu/strudel/pulls/281) +- 2022-12-02T13:38:27+01:00 do not recompile orc by @froos in: [#278](https://codeberg.org/uzu/strudel/pulls/278) +- 2022-12-02T12:49:26+01:00 add basic csound output by @froos in: [#275](https://codeberg.org/uzu/strudel/pulls/275) +- 2022-12-02T12:18:41+01:00 add licenses / credits to all tunes + remove some by @froos in: [#277](https://codeberg.org/uzu/strudel/pulls/277) +- 2022-12-02T11:45:02+01:00 Support sending CRC16 bytes with serial messages by @yaxu in: [#276](https://codeberg.org/uzu/strudel/pulls/276) ## november 2022 -- 2022-11-29T23:41:39+01:00 release version bumps by froos in: [#273](https://codeberg.org/uzu/strudel/pulls/273) -- 2022-11-29T23:34:50+01:00 add eslint by froos in: [#271](https://codeberg.org/uzu/strudel/pulls/271) -- 2022-11-29T23:34:26+01:00 tonal update with fixed memory leak by froos in: [#272](https://codeberg.org/uzu/strudel/pulls/272) -- 2022-11-22T09:51:26+01:00 Tidying up core by yaxu in: [#256](https://codeberg.org/uzu/strudel/pulls/256) -- 2022-11-21T22:15:48+01:00 fix performance bottleneck by froos in: [#266](https://codeberg.org/uzu/strudel/pulls/266) -- 2022-11-17T11:08:38+01:00 fix tutorial bugs by froos in: [#263](https://codeberg.org/uzu/strudel/pulls/263) -- 2022-11-16T13:15:28+01:00 Binaries by froos in: [#254](https://codeberg.org/uzu/strudel/pulls/254) -- 2022-11-13T20:20:32+01:00 Repl refactoring by froos in: [#255](https://codeberg.org/uzu/strudel/pulls/255) -- 2022-11-08T23:35:11+01:00 Webaudio build by froos in: [#250](https://codeberg.org/uzu/strudel/pulls/250) -- 2022-11-08T22:43:32+01:00 new transpiler based on acorn by froos in: [#249](https://codeberg.org/uzu/strudel/pulls/249) -- 2022-11-06T19:03:19+01:00 General purpose scheduler by froos in: [#248](https://codeberg.org/uzu/strudel/pulls/248) -- 2022-11-06T11:05:23+01:00 snapshot tests on shared snippets by froos in: [#243](https://codeberg.org/uzu/strudel/pulls/243) -- 2022-11-06T11:03:42+01:00 Some tunes by froos in: [#247](https://codeberg.org/uzu/strudel/pulls/247) -- 2022-11-06T00:37:11+01:00 patchday by froos in: [#246](https://codeberg.org/uzu/strudel/pulls/246) -- 2022-11-04T20:28:23+01:00 Readme + TLC by froos in: [#244](https://codeberg.org/uzu/strudel/pulls/244) -- 2022-11-03T15:16:04+01:00 in source example tests by froos in: [#242](https://codeberg.org/uzu/strudel/pulls/242) -- 2022-11-02T23:16:43+01:00 feat: support github: links by froos in: [#240](https://codeberg.org/uzu/strudel/pulls/240) -- 2022-11-02T21:26:44+01:00 Load samples from url by froos in: [#239](https://codeberg.org/uzu/strudel/pulls/239) -- 2022-11-02T11:42:32+01:00 Object arithmetic by froos in: [#238](https://codeberg.org/uzu/strudel/pulls/238) -- 2022-11-01T00:36:14+01:00 Tidal drum machines by froos in: [#237](https://codeberg.org/uzu/strudel/pulls/237) -- 2022-10-31T21:39:23+01:00 fx on stereo speakers by froos in: [#236](https://codeberg.org/uzu/strudel/pulls/236) +- 2022-11-29T23:41:39+01:00 release version bumps by @froos in: [#273](https://codeberg.org/uzu/strudel/pulls/273) +- 2022-11-29T23:34:50+01:00 add eslint by @froos in: [#271](https://codeberg.org/uzu/strudel/pulls/271) +- 2022-11-29T23:34:26+01:00 tonal update with fixed memory leak by @froos in: [#272](https://codeberg.org/uzu/strudel/pulls/272) +- 2022-11-22T09:51:26+01:00 Tidying up core by @yaxu in: [#256](https://codeberg.org/uzu/strudel/pulls/256) +- 2022-11-21T22:15:48+01:00 fix performance bottleneck by @froos in: [#266](https://codeberg.org/uzu/strudel/pulls/266) +- 2022-11-17T11:08:38+01:00 fix tutorial bugs by @froos in: [#263](https://codeberg.org/uzu/strudel/pulls/263) +- 2022-11-16T13:15:28+01:00 Binaries by @froos in: [#254](https://codeberg.org/uzu/strudel/pulls/254) +- 2022-11-13T20:20:32+01:00 Repl refactoring by @froos in: [#255](https://codeberg.org/uzu/strudel/pulls/255) +- 2022-11-08T23:35:11+01:00 Webaudio build by @froos in: [#250](https://codeberg.org/uzu/strudel/pulls/250) +- 2022-11-08T22:43:32+01:00 new transpiler based on acorn by @froos in: [#249](https://codeberg.org/uzu/strudel/pulls/249) +- 2022-11-06T19:03:19+01:00 General purpose scheduler by @froos in: [#248](https://codeberg.org/uzu/strudel/pulls/248) +- 2022-11-06T11:05:23+01:00 snapshot tests on shared snippets by @froos in: [#243](https://codeberg.org/uzu/strudel/pulls/243) +- 2022-11-06T11:03:42+01:00 Some tunes by @froos in: [#247](https://codeberg.org/uzu/strudel/pulls/247) +- 2022-11-06T00:37:11+01:00 patchday by @froos in: [#246](https://codeberg.org/uzu/strudel/pulls/246) +- 2022-11-04T20:28:23+01:00 Readme + TLC by @froos in: [#244](https://codeberg.org/uzu/strudel/pulls/244) +- 2022-11-03T15:16:04+01:00 in source example tests by @froos in: [#242](https://codeberg.org/uzu/strudel/pulls/242) +- 2022-11-02T23:16:43+01:00 feat: support github: links by @froos in: [#240](https://codeberg.org/uzu/strudel/pulls/240) +- 2022-11-02T21:26:44+01:00 Load samples from url by @froos in: [#239](https://codeberg.org/uzu/strudel/pulls/239) +- 2022-11-02T11:42:32+01:00 Object arithmetic by @froos in: [#238](https://codeberg.org/uzu/strudel/pulls/238) +- 2022-11-01T00:36:14+01:00 Tidal drum machines by @froos in: [#237](https://codeberg.org/uzu/strudel/pulls/237) +- 2022-10-31T21:39:23+01:00 fx on stereo speakers by @froos in: [#236](https://codeberg.org/uzu/strudel/pulls/236) ## october 2022 -- 2022-10-30T19:10:33+01:00 add vcsl sample library by froos in: [#235](https://codeberg.org/uzu/strudel/pulls/235) -- 2022-10-30T00:23:10+02:00 Fix zero length queries WIP by yaxu in: [#234](https://codeberg.org/uzu/strudel/pulls/234) -- 2022-10-29T17:54:05+02:00 Out by default by froos in: [#232](https://codeberg.org/uzu/strudel/pulls/232) -- 2022-10-26T23:53:49+02:00 Patternify range by yaxu in: [#231](https://codeberg.org/uzu/strudel/pulls/231) -- 2022-10-26T21:42:12+02:00 Just another docs branch by froos in: [#228](https://codeberg.org/uzu/strudel/pulls/228) -- 2022-10-26T21:41:12+02:00 Refactor tunes away from tone by froos in: [#230](https://codeberg.org/uzu/strudel/pulls/230) -- 2022-10-20T09:26:28+02:00 Core util tests by Ghost in: [#226](https://codeberg.org/uzu/strudel/pulls/226) -- 2022-10-06T22:35:45+02:00 fix fastgap for events that go across cycle boundaries by yaxu in: [#225](https://codeberg.org/uzu/strudel/pulls/225) +- 2022-10-30T19:10:33+01:00 add vcsl sample library by @froos in: [#235](https://codeberg.org/uzu/strudel/pulls/235) +- 2022-10-30T00:23:10+02:00 Fix zero length queries WIP by @yaxu in: [#234](https://codeberg.org/uzu/strudel/pulls/234) +- 2022-10-29T17:54:05+02:00 Out by default by @froos in: [#232](https://codeberg.org/uzu/strudel/pulls/232) +- 2022-10-26T23:53:49+02:00 Patternify range by @yaxu in: [#231](https://codeberg.org/uzu/strudel/pulls/231) +- 2022-10-26T21:42:12+02:00 Just another docs branch by @froos in: [#228](https://codeberg.org/uzu/strudel/pulls/228) +- 2022-10-26T21:41:12+02:00 Refactor tunes away from tone by @froos in: [#230](https://codeberg.org/uzu/strudel/pulls/230) +- 2022-10-20T09:26:28+02:00 Core util tests by @Ghost in: [#226](https://codeberg.org/uzu/strudel/pulls/226) +- 2022-10-06T22:35:45+02:00 fix fastgap for events that go across cycle boundaries by @yaxu in: [#225](https://codeberg.org/uzu/strudel/pulls/225) ## september 2022 -- 2022-09-25T21:15:36+02:00 Reverb by froos in: [#224](https://codeberg.org/uzu/strudel/pulls/224) -- 2022-09-25T00:27:26+02:00 focus tweak for squeezeJoin - another go at fixing #216 by yaxu in: [#221](https://codeberg.org/uzu/strudel/pulls/221) -- 2022-09-24T23:17:21+02:00 support negative speeds by froos in: [#222](https://codeberg.org/uzu/strudel/pulls/222) -- 2022-09-24T21:55:15+02:00 Feedback Delay by froos in: [#213](https://codeberg.org/uzu/strudel/pulls/213) -- 2022-09-23T12:06:17+02:00 Fix squeeze join by yaxu in: [#220](https://codeberg.org/uzu/strudel/pulls/220) -- 2022-09-22T21:23:11+02:00 encapsulate webaudio output by froos in: [#219](https://codeberg.org/uzu/strudel/pulls/219) -- 2022-09-22T19:18:18+02:00 samples now have envelopes by froos in: [#218](https://codeberg.org/uzu/strudel/pulls/218) -- 2022-09-22T00:03:30+02:00 sampler features + fixes by froos in: [#217](https://codeberg.org/uzu/strudel/pulls/217) -- 2022-09-19T23:32:55+02:00 Just another docs PR by froos in: [#215](https://codeberg.org/uzu/strudel/pulls/215) -- 2022-09-17T23:47:43+02:00 Even more docs by froos in: [#212](https://codeberg.org/uzu/strudel/pulls/212) -- 2022-09-17T15:36:53+02:00 Webaudio guide by froos in: [#207](https://codeberg.org/uzu/strudel/pulls/207) -- 2022-09-16T00:21:29+02:00 Coarse crush shape by froos in: [#205](https://codeberg.org/uzu/strudel/pulls/205) -- 2022-09-15T21:04:28+02:00 add vowel to .out by froos in: [#201](https://codeberg.org/uzu/strudel/pulls/201) -- 2022-09-15T16:55:52+02:00 add rollup-plugin-visualizer to build by froos in: [#200](https://codeberg.org/uzu/strudel/pulls/200) -- 2022-09-14T23:46:39+02:00 document random functions by froos in: [#199](https://codeberg.org/uzu/strudel/pulls/199) -- 2022-09-09T22:04:40+02:00 Fix numbers in sampler by froos in: [#196](https://codeberg.org/uzu/strudel/pulls/196) +- 2022-09-25T21:15:36+02:00 Reverb by @froos in: [#224](https://codeberg.org/uzu/strudel/pulls/224) +- 2022-09-25T00:27:26+02:00 focus tweak for squeezeJoin - another go at fixing #216 by @yaxu in: [#221](https://codeberg.org/uzu/strudel/pulls/221) +- 2022-09-24T23:17:21+02:00 support negative speeds by @froos in: [#222](https://codeberg.org/uzu/strudel/pulls/222) +- 2022-09-24T21:55:15+02:00 Feedback Delay by @froos in: [#213](https://codeberg.org/uzu/strudel/pulls/213) +- 2022-09-23T12:06:17+02:00 Fix squeeze join by @yaxu in: [#220](https://codeberg.org/uzu/strudel/pulls/220) +- 2022-09-22T21:23:11+02:00 encapsulate webaudio output by @froos in: [#219](https://codeberg.org/uzu/strudel/pulls/219) +- 2022-09-22T19:18:18+02:00 samples now have envelopes by @froos in: [#218](https://codeberg.org/uzu/strudel/pulls/218) +- 2022-09-22T00:03:30+02:00 sampler features + fixes by @froos in: [#217](https://codeberg.org/uzu/strudel/pulls/217) +- 2022-09-19T23:32:55+02:00 Just another docs PR by @froos in: [#215](https://codeberg.org/uzu/strudel/pulls/215) +- 2022-09-17T23:47:43+02:00 Even more docs by @froos in: [#212](https://codeberg.org/uzu/strudel/pulls/212) +- 2022-09-17T15:36:53+02:00 Webaudio guide by @froos in: [#207](https://codeberg.org/uzu/strudel/pulls/207) +- 2022-09-16T00:21:29+02:00 Coarse crush shape by @froos in: [#205](https://codeberg.org/uzu/strudel/pulls/205) +- 2022-09-15T21:04:28+02:00 add vowel to .out by @froos in: [#201](https://codeberg.org/uzu/strudel/pulls/201) +- 2022-09-15T16:55:52+02:00 add rollup-plugin-visualizer to build by @froos in: [#200](https://codeberg.org/uzu/strudel/pulls/200) +- 2022-09-14T23:46:39+02:00 document random functions by @froos in: [#199](https://codeberg.org/uzu/strudel/pulls/199) +- 2022-09-09T22:04:40+02:00 Fix numbers in sampler by @froos in: [#196](https://codeberg.org/uzu/strudel/pulls/196) ## august 2022 -- 2022-08-14T17:40:41+02:00 change "stride"/"offset" of successive degradeBy/chooseIn by Ghost in: [#185](https://codeberg.org/uzu/strudel/pulls/185) -- 2022-08-14T16:04:14+02:00 Soundfont file support by froos in: [#183](https://codeberg.org/uzu/strudel/pulls/183) -- 2022-08-14T15:55:50+02:00 fix regression: old way of setting frequencies was broken by froos in: [#190](https://codeberg.org/uzu/strudel/pulls/190) -- 2022-08-14T15:45:53+02:00 wait for prebake to finish before evaluating by froos in: [#189](https://codeberg.org/uzu/strudel/pulls/189) -- 2022-08-14T11:31:00+02:00 Fix codemirror bug by froos in: [#186](https://codeberg.org/uzu/strudel/pulls/186) -- 2022-08-13T16:29:53+02:00 scheduler improvements by froos in: [#181](https://codeberg.org/uzu/strudel/pulls/181) -- 2022-08-12T23:10:36+02:00 replace mocha with vitest by froos in: [#175](https://codeberg.org/uzu/strudel/pulls/175) -- 2022-08-07T00:59:07+02:00 incorporate elements of randomness to the mini notation by Ghost in: [#165](https://codeberg.org/uzu/strudel/pulls/165) -- 2022-08-06T23:32:16+02:00 fix some annoying bugs by froos in: [#177](https://codeberg.org/uzu/strudel/pulls/177) -- 2022-08-06T00:27:17+02:00 Replace react-codemirror6 with @uiw/react-codemirror by froos in: [#173](https://codeberg.org/uzu/strudel/pulls/173) -- 2022-08-04T22:19:46+02:00 add more shapeshifter flags by froos in: [#99](https://codeberg.org/uzu/strudel/pulls/99) -- 2022-08-04T22:06:38+02:00 Amend shapeshifter to allow use of dynamic import by Ghost in: [#171](https://codeberg.org/uzu/strudel/pulls/171) -- 2022-08-02T23:43:07+02:00 Talk fixes by froos in: [#164](https://codeberg.org/uzu/strudel/pulls/164) -- 2022-08-02T23:04:34+02:00 Pianoroll fixes by froos in: [#163](https://codeberg.org/uzu/strudel/pulls/163) -- 2022-08-02T22:57:43+02:00 fix: jsdoc comments by froos in: [#169](https://codeberg.org/uzu/strudel/pulls/169) +- 2022-08-14T17:40:41+02:00 change "stride"/"offset" of successive degradeBy/chooseIn by @Ghost in: [#185](https://codeberg.org/uzu/strudel/pulls/185) +- 2022-08-14T16:04:14+02:00 Soundfont file support by @froos in: [#183](https://codeberg.org/uzu/strudel/pulls/183) +- 2022-08-14T15:55:50+02:00 fix regression: old way of setting frequencies was broken by @froos in: [#190](https://codeberg.org/uzu/strudel/pulls/190) +- 2022-08-14T15:45:53+02:00 wait for prebake to finish before evaluating by @froos in: [#189](https://codeberg.org/uzu/strudel/pulls/189) +- 2022-08-14T11:31:00+02:00 Fix codemirror bug by @froos in: [#186](https://codeberg.org/uzu/strudel/pulls/186) +- 2022-08-13T16:29:53+02:00 scheduler improvements by @froos in: [#181](https://codeberg.org/uzu/strudel/pulls/181) +- 2022-08-12T23:10:36+02:00 replace mocha with vitest by @froos in: [#175](https://codeberg.org/uzu/strudel/pulls/175) +- 2022-08-07T00:59:07+02:00 incorporate elements of randomness to the mini notation by @Ghost in: [#165](https://codeberg.org/uzu/strudel/pulls/165) +- 2022-08-06T23:32:16+02:00 fix some annoying bugs by @froos in: [#177](https://codeberg.org/uzu/strudel/pulls/177) +- 2022-08-06T00:27:17+02:00 Replace react-codemirror6 with @uiw/react-codemirror by @froos in: [#173](https://codeberg.org/uzu/strudel/pulls/173) +- 2022-08-04T22:19:46+02:00 add more shapeshifter flags by @froos in: [#99](https://codeberg.org/uzu/strudel/pulls/99) +- 2022-08-04T22:06:38+02:00 Amend shapeshifter to allow use of dynamic import by @Ghost in: [#171](https://codeberg.org/uzu/strudel/pulls/171) +- 2022-08-02T23:43:07+02:00 Talk fixes by @froos in: [#164](https://codeberg.org/uzu/strudel/pulls/164) +- 2022-08-02T23:04:34+02:00 Pianoroll fixes by @froos in: [#163](https://codeberg.org/uzu/strudel/pulls/163) +- 2022-08-02T22:57:43+02:00 fix: jsdoc comments by @froos in: [#169](https://codeberg.org/uzu/strudel/pulls/169) ## july 2022 -- 2022-07-30T23:51:11+02:00 add chooseInWith/chooseCycles by yaxu in: [#166](https://codeberg.org/uzu/strudel/pulls/166) -- 2022-07-28T19:26:42+02:00 update to tutorial documentation by Ghost in: [#162](https://codeberg.org/uzu/strudel/pulls/162) -- 2022-07-12T18:58:47+02:00 add webdirt drum samples to prebake for general availability by Ghost in: [#150](https://codeberg.org/uzu/strudel/pulls/150) -- 2022-07-12T08:34:17+02:00 Final update to demo.pdf by yaxu in: [#151](https://codeberg.org/uzu/strudel/pulls/151) +- 2022-07-30T23:51:11+02:00 add chooseInWith/chooseCycles by @yaxu in: [#166](https://codeberg.org/uzu/strudel/pulls/166) +- 2022-07-28T19:26:42+02:00 update to tutorial documentation by @Ghost in: [#162](https://codeberg.org/uzu/strudel/pulls/162) +- 2022-07-12T18:58:47+02:00 add webdirt drum samples to prebake for general availability by @Ghost in: [#150](https://codeberg.org/uzu/strudel/pulls/150) +- 2022-07-12T08:34:17+02:00 Final update to demo.pdf by @yaxu in: [#151](https://codeberg.org/uzu/strudel/pulls/151) ## june 2022 -- 2022-06-28T21:54:35+02:00 Sampler optimizations and more by froos in: [#148](https://codeberg.org/uzu/strudel/pulls/148) -- 2022-06-26T12:58:53+02:00 can now generate short link for sharing by froos in: [#146](https://codeberg.org/uzu/strudel/pulls/146) -- 2022-06-24T22:16:04+02:00 flash effect on ctrl enter by froos in: [#144](https://codeberg.org/uzu/strudel/pulls/144) -- 2022-06-22T20:18:17+02:00 Pianoroll Object Support by froos in: [#142](https://codeberg.org/uzu/strudel/pulls/142) -- 2022-06-21T22:57:28+02:00 Serial twiddles by yaxu in: [#141](https://codeberg.org/uzu/strudel/pulls/141) -- 2022-06-21T22:20:05+02:00 Soundfont Support by froos in: [#139](https://codeberg.org/uzu/strudel/pulls/139) -- 2022-06-21T14:11:50+02:00 Fix createParam() by yaxu in: [#140](https://codeberg.org/uzu/strudel/pulls/140) -- 2022-06-18T23:24:42+02:00 Webaudio rewrite by froos in: [#138](https://codeberg.org/uzu/strudel/pulls/138) -- 2022-06-16T21:58:38+02:00 add onTrigger helper by froos in: [#136](https://codeberg.org/uzu/strudel/pulls/136) -- 2022-06-16T20:48:23+02:00 Scheduler improvements by froos in: [#134](https://codeberg.org/uzu/strudel/pulls/134) -- 2022-06-16T20:48:07+02:00 remove cycle + delta from onTrigger by froos in: [#135](https://codeberg.org/uzu/strudel/pulls/135) -- 2022-06-13T21:28:27+02:00 add createParam + createParams by froos in: [#110](https://codeberg.org/uzu/strudel/pulls/110) -- 2022-06-13T21:27:09+02:00 Pianoroll enhancements by froos in: [#131](https://codeberg.org/uzu/strudel/pulls/131) -- 2022-06-05T13:06:03+02:00 Fix link to contributing to tutorial docs by Ghost in: [#129](https://codeberg.org/uzu/strudel/pulls/129) -- 2022-06-02T00:20:45+02:00 Webdirt by froos in: [#121](https://codeberg.org/uzu/strudel/pulls/121) -- 2022-06-01T23:56:04+02:00 fix: #122 ctrl enter would add newline by froos in: [#124](https://codeberg.org/uzu/strudel/pulls/124) -- 2022-06-01T18:21:56+02:00 fix: #108 by froos in: [#123](https://codeberg.org/uzu/strudel/pulls/123) +- 2022-06-28T21:54:35+02:00 Sampler optimizations and more by @froos in: [#148](https://codeberg.org/uzu/strudel/pulls/148) +- 2022-06-26T12:58:53+02:00 can now generate short link for sharing by @froos in: [#146](https://codeberg.org/uzu/strudel/pulls/146) +- 2022-06-24T22:16:04+02:00 flash effect on ctrl enter by @froos in: [#144](https://codeberg.org/uzu/strudel/pulls/144) +- 2022-06-22T20:18:17+02:00 Pianoroll Object Support by @froos in: [#142](https://codeberg.org/uzu/strudel/pulls/142) +- 2022-06-21T22:57:28+02:00 Serial twiddles by @yaxu in: [#141](https://codeberg.org/uzu/strudel/pulls/141) +- 2022-06-21T22:20:05+02:00 Soundfont Support by @froos in: [#139](https://codeberg.org/uzu/strudel/pulls/139) +- 2022-06-21T14:11:50+02:00 Fix createParam() by @yaxu in: [#140](https://codeberg.org/uzu/strudel/pulls/140) +- 2022-06-18T23:24:42+02:00 Webaudio rewrite by @froos in: [#138](https://codeberg.org/uzu/strudel/pulls/138) +- 2022-06-16T21:58:38+02:00 add onTrigger helper by @froos in: [#136](https://codeberg.org/uzu/strudel/pulls/136) +- 2022-06-16T20:48:23+02:00 Scheduler improvements by @froos in: [#134](https://codeberg.org/uzu/strudel/pulls/134) +- 2022-06-16T20:48:07+02:00 remove cycle + delta from onTrigger by @froos in: [#135](https://codeberg.org/uzu/strudel/pulls/135) +- 2022-06-13T21:28:27+02:00 add createParam + createParams by @froos in: [#110](https://codeberg.org/uzu/strudel/pulls/110) +- 2022-06-13T21:27:09+02:00 Pianoroll enhancements by @froos in: [#131](https://codeberg.org/uzu/strudel/pulls/131) +- 2022-06-05T13:06:03+02:00 Fix link to contributing to tutorial docs by @Ghost in: [#129](https://codeberg.org/uzu/strudel/pulls/129) +- 2022-06-02T00:20:45+02:00 Webdirt by @froos in: [#121](https://codeberg.org/uzu/strudel/pulls/121) +- 2022-06-01T23:56:04+02:00 fix: #122 ctrl enter would add newline by @froos in: [#124](https://codeberg.org/uzu/strudel/pulls/124) +- 2022-06-01T18:21:56+02:00 fix: #108 by @froos in: [#123](https://codeberg.org/uzu/strudel/pulls/123) ## may 2022 -- 2022-05-29T09:54:59+02:00 In source doc by froos in: [#117](https://codeberg.org/uzu/strudel/pulls/117) -- 2022-05-20T11:49:10+02:00 react package + vite build by froos in: [#116](https://codeberg.org/uzu/strudel/pulls/116) -- 2022-05-15T22:29:26+02:00 Osc timing improvements by yaxu in: [#113](https://codeberg.org/uzu/strudel/pulls/113) -- 2022-05-15T22:28:24+02:00 loopAt by yaxu in: [#114](https://codeberg.org/uzu/strudel/pulls/114) -- 2022-05-09T20:09:47+02:00 `.brak()`, `.inside()` and `.outside()` by yaxu in: [#112](https://codeberg.org/uzu/strudel/pulls/112) -- 2022-05-06T15:18:41+02:00 In source doc by yaxu in: [#105](https://codeberg.org/uzu/strudel/pulls/105) -- 2022-05-04T22:59:31+02:00 Embed style by froos in: [#109](https://codeberg.org/uzu/strudel/pulls/109) -- 2022-05-03T01:40:22+02:00 Reset, Restart and other composers by froos in: [#88](https://codeberg.org/uzu/strudel/pulls/88) -- 2022-05-02T22:47:21+02:00 /embed package: web component for repl by froos in: [#106](https://codeberg.org/uzu/strudel/pulls/106) -- 2022-05-02T22:05:34+02:00 Tune tests by froos in: [#104](https://codeberg.org/uzu/strudel/pulls/104) -- 2022-05-01T14:33:11+02:00 Codemirror 6 by froos in: [#97](https://codeberg.org/uzu/strudel/pulls/97) +- 2022-05-29T09:54:59+02:00 In source doc by @froos in: [#117](https://codeberg.org/uzu/strudel/pulls/117) +- 2022-05-20T11:49:10+02:00 react package + vite build by @froos in: [#116](https://codeberg.org/uzu/strudel/pulls/116) +- 2022-05-15T22:29:26+02:00 Osc timing improvements by @yaxu in: [#113](https://codeberg.org/uzu/strudel/pulls/113) +- 2022-05-15T22:28:24+02:00 loopAt by @yaxu in: [#114](https://codeberg.org/uzu/strudel/pulls/114) +- 2022-05-09T20:09:47+02:00 `.brak()`, `.inside()` and `.outside()` by @yaxu in: [#112](https://codeberg.org/uzu/strudel/pulls/112) +- 2022-05-06T15:18:41+02:00 In source doc by @yaxu in: [#105](https://codeberg.org/uzu/strudel/pulls/105) +- 2022-05-04T22:59:31+02:00 Embed style by @froos in: [#109](https://codeberg.org/uzu/strudel/pulls/109) +- 2022-05-03T01:40:22+02:00 Reset, Restart and other composers by @froos in: [#88](https://codeberg.org/uzu/strudel/pulls/88) +- 2022-05-02T22:47:21+02:00 /embed package: web component for repl by @froos in: [#106](https://codeberg.org/uzu/strudel/pulls/106) +- 2022-05-02T22:05:34+02:00 Tune tests by @froos in: [#104](https://codeberg.org/uzu/strudel/pulls/104) +- 2022-05-01T14:33:11+02:00 Codemirror 6 by @froos in: [#97](https://codeberg.org/uzu/strudel/pulls/97) ## april 2022 -- 2022-04-28T23:45:53+02:00 Work on Codemirror 6 highlighting by Ghost in: [#102](https://codeberg.org/uzu/strudel/pulls/102) -- 2022-04-28T15:46:06+02:00 Change to Affero GPL by yaxu in: [#101](https://codeberg.org/uzu/strudel/pulls/101) -- 2022-04-26T00:13:07+02:00 Paper by froos in: [#98](https://codeberg.org/uzu/strudel/pulls/98) -- 2022-04-25T22:10:21+02:00 Fiddles with cat/stack by yaxu in: [#90](https://codeberg.org/uzu/strudel/pulls/90) -- 2022-04-22T13:08:11+02:00 Add pattern composers, implements #82 by yaxu in: [#83](https://codeberg.org/uzu/strudel/pulls/83) -- 2022-04-21T20:57:45+02:00 Tidy up a couple of old files by Ghost in: [#84](https://codeberg.org/uzu/strudel/pulls/84) -- 2022-04-21T15:21:29+02:00 add `striate()` by yaxu in: [#76](https://codeberg.org/uzu/strudel/pulls/76) -- 2022-04-20T20:17:27+02:00 Webaudio in REPL by froos in: [#77](https://codeberg.org/uzu/strudel/pulls/77) -- 2022-04-19T15:31:34+02:00 Basic webserial support by yaxu in: [#80](https://codeberg.org/uzu/strudel/pulls/80) -- 2022-04-17T19:29:49+02:00 Try to fix appLeft / appRight by yaxu in: [#75](https://codeberg.org/uzu/strudel/pulls/75) -- 2022-04-16T13:26:57+02:00 More random functions by yaxu in: [#74](https://codeberg.org/uzu/strudel/pulls/74) -- 2022-04-16T11:13:26+02:00 Port `perlin` noise, `rangex`, and `palindrome` by yaxu in: [#73](https://codeberg.org/uzu/strudel/pulls/73) -- 2022-04-16T10:26:07+02:00 webaudio package by froos in: [#26](https://codeberg.org/uzu/strudel/pulls/26) -- 2022-04-15T20:18:06+02:00 More randomness, fix `rand`, and add `brand`, `irand` and `choose` by yaxu in: [#70](https://codeberg.org/uzu/strudel/pulls/70) -- 2022-04-15T11:29:51+02:00 First effort at rand() by yaxu in: [#69](https://codeberg.org/uzu/strudel/pulls/69) -- 2022-04-14T17:41:18+02:00 use new fixed version of osc-js package by froos in: [#68](https://codeberg.org/uzu/strudel/pulls/68) -- 2022-04-14T00:09:18+02:00 Speech output by froos in: [#67](https://codeberg.org/uzu/strudel/pulls/67) -- 2022-04-13T23:55:33+02:00 Separate out strudel.mjs, make index.mjs aggregate module by yaxu in: [#62](https://codeberg.org/uzu/strudel/pulls/62) -- 2022-04-13T17:26:45+02:00 More functions by yaxu in: [#61](https://codeberg.org/uzu/strudel/pulls/61) -- 2022-04-13T10:04:29+02:00 More functions by yaxu in: [#56](https://codeberg.org/uzu/strudel/pulls/56) -- 2022-04-12T17:04:04+02:00 OSC and SuperDirt support by yaxu in: [#27](https://codeberg.org/uzu/strudel/pulls/27) -- 2022-04-12T13:24:14+02:00 Implement `chop()` by yaxu in: [#50](https://codeberg.org/uzu/strudel/pulls/50) -- 2022-04-12T12:37:32+02:00 First run at squeezeBind, ref #32 by yaxu in: [#48](https://codeberg.org/uzu/strudel/pulls/48) -- 2022-04-12T00:03:37+02:00 Fix polymeter by yaxu in: [#44](https://codeberg.org/uzu/strudel/pulls/44) -- 2022-04-11T22:39:44+02:00 Compose by froos in: [#40](https://codeberg.org/uzu/strudel/pulls/40) -- 2022-04-11T21:49:35+02:00 Update tutorial.mdx by Ghost in: [#38](https://codeberg.org/uzu/strudel/pulls/38) -- 2022-04-11T08:43:44+02:00 Update tutorial.mdx by Ghost in: [#37](https://codeberg.org/uzu/strudel/pulls/37) +- 2022-04-28T23:45:53+02:00 Work on Codemirror 6 highlighting by @Ghost in: [#102](https://codeberg.org/uzu/strudel/pulls/102) +- 2022-04-28T15:46:06+02:00 Change to Affero GPL by @yaxu in: [#101](https://codeberg.org/uzu/strudel/pulls/101) +- 2022-04-26T00:13:07+02:00 Paper by @froos in: [#98](https://codeberg.org/uzu/strudel/pulls/98) +- 2022-04-25T22:10:21+02:00 Fiddles with cat/stack by @yaxu in: [#90](https://codeberg.org/uzu/strudel/pulls/90) +- 2022-04-22T13:08:11+02:00 Add pattern composers, implements #82 by @yaxu in: [#83](https://codeberg.org/uzu/strudel/pulls/83) +- 2022-04-21T20:57:45+02:00 Tidy up a couple of old files by @Ghost in: [#84](https://codeberg.org/uzu/strudel/pulls/84) +- 2022-04-21T15:21:29+02:00 add `striate()` by @yaxu in: [#76](https://codeberg.org/uzu/strudel/pulls/76) +- 2022-04-20T20:17:27+02:00 Webaudio in REPL by @froos in: [#77](https://codeberg.org/uzu/strudel/pulls/77) +- 2022-04-19T15:31:34+02:00 Basic webserial support by @yaxu in: [#80](https://codeberg.org/uzu/strudel/pulls/80) +- 2022-04-17T19:29:49+02:00 Try to fix appLeft / appRight by @yaxu in: [#75](https://codeberg.org/uzu/strudel/pulls/75) +- 2022-04-16T13:26:57+02:00 More random functions by @yaxu in: [#74](https://codeberg.org/uzu/strudel/pulls/74) +- 2022-04-16T11:13:26+02:00 Port `perlin` noise, `rangex`, and `palindrome` by @yaxu in: [#73](https://codeberg.org/uzu/strudel/pulls/73) +- 2022-04-16T10:26:07+02:00 webaudio package by @froos in: [#26](https://codeberg.org/uzu/strudel/pulls/26) +- 2022-04-15T20:18:06+02:00 More randomness, fix `rand`, and add `brand`, `irand` and `choose` by @yaxu in: [#70](https://codeberg.org/uzu/strudel/pulls/70) +- 2022-04-15T11:29:51+02:00 First effort at rand() by @yaxu in: [#69](https://codeberg.org/uzu/strudel/pulls/69) +- 2022-04-14T17:41:18+02:00 use new fixed version of osc-js package by @froos in: [#68](https://codeberg.org/uzu/strudel/pulls/68) +- 2022-04-14T00:09:18+02:00 Speech output by @froos in: [#67](https://codeberg.org/uzu/strudel/pulls/67) +- 2022-04-13T23:55:33+02:00 Separate out strudel.mjs, make index.mjs aggregate module by @yaxu in: [#62](https://codeberg.org/uzu/strudel/pulls/62) +- 2022-04-13T17:26:45+02:00 More functions by @yaxu in: [#61](https://codeberg.org/uzu/strudel/pulls/61) +- 2022-04-13T10:04:29+02:00 More functions by @yaxu in: [#56](https://codeberg.org/uzu/strudel/pulls/56) +- 2022-04-12T17:04:04+02:00 OSC and SuperDirt support by @yaxu in: [#27](https://codeberg.org/uzu/strudel/pulls/27) +- 2022-04-12T13:24:14+02:00 Implement `chop()` by @yaxu in: [#50](https://codeberg.org/uzu/strudel/pulls/50) +- 2022-04-12T12:37:32+02:00 First run at squeezeBind, ref #32 by @yaxu in: [#48](https://codeberg.org/uzu/strudel/pulls/48) +- 2022-04-12T00:03:37+02:00 Fix polymeter by @yaxu in: [#44](https://codeberg.org/uzu/strudel/pulls/44) +- 2022-04-11T22:39:44+02:00 Compose by @froos in: [#40](https://codeberg.org/uzu/strudel/pulls/40) +- 2022-04-11T21:49:35+02:00 Update tutorial.mdx by @Ghost in: [#38](https://codeberg.org/uzu/strudel/pulls/38) +- 2022-04-11T08:43:44+02:00 Update tutorial.mdx by @Ghost in: [#37](https://codeberg.org/uzu/strudel/pulls/37) ## march 2022 -- 2022-03-28T17:27:22+02:00 Add chunk, chunkBack and iterBack by yaxu in: [#25](https://codeberg.org/uzu/strudel/pulls/25) -- 2022-03-28T11:48:22+02:00 packaging by froos in: [#24](https://codeberg.org/uzu/strudel/pulls/24) -- 2022-03-22T12:06:48+01:00 Update package.json by Ghost in: [#23](https://codeberg.org/uzu/strudel/pulls/23) -- 2022-03-06T20:35:20+01:00 added _asNumber + interprete numbers as midi by froos in: [#21](https://codeberg.org/uzu/strudel/pulls/21) +- 2022-03-28T17:27:22+02:00 Add chunk, chunkBack and iterBack by @yaxu in: [#25](https://codeberg.org/uzu/strudel/pulls/25) +- 2022-03-28T11:48:22+02:00 packaging by @froos in: [#24](https://codeberg.org/uzu/strudel/pulls/24) +- 2022-03-22T12:06:48+01:00 Update package.json by @Ghost in: [#23](https://codeberg.org/uzu/strudel/pulls/23) +- 2022-03-06T20:35:20+01:00 added _asNumber + interprete numbers as midi by @froos in: [#21](https://codeberg.org/uzu/strudel/pulls/21) ## february 2022 -- 2022-02-28T00:32:29+01:00 Fix resolveState by yaxu in: [#22](https://codeberg.org/uzu/strudel/pulls/22) -- 2022-02-27T20:52:52+01:00 Stateful queries and events (WIP) by yaxu in: [#14](https://codeberg.org/uzu/strudel/pulls/14) -- 2022-02-27T18:04:07+01:00 fix: 💄 Enhance visualisation of the Tutorial on mobile by Ghost in: [#19](https://codeberg.org/uzu/strudel/pulls/19) -- 2022-02-26T21:16:34+01:00 test: 📦 Add missing dependency and a CI check, to prevent oversights ;p by Ghost in: [#17](https://codeberg.org/uzu/strudel/pulls/17) -- 2022-02-26T13:29:19+01:00 higher latencyHint by froos in: [#16](https://codeberg.org/uzu/strudel/pulls/16) -- 2022-02-23T22:15:11+01:00 add apply and layer, and missing div/mul methods by yaxu in: [#15](https://codeberg.org/uzu/strudel/pulls/15) -- 2022-02-21T01:02:07+01:00 Add continuous signals (sine, cosine, saw, etc) by yaxu in: [#13](https://codeberg.org/uzu/strudel/pulls/13) -- 2022-02-19T21:30:04+01:00 Added mask() and struct() by yaxu in: [#11](https://codeberg.org/uzu/strudel/pulls/11) -- 2022-02-19T16:07:07+01:00 Failing test for `when` WIP by yaxu in: [#10](https://codeberg.org/uzu/strudel/pulls/10) -- 2022-02-10T17:21:31+01:00 Bugfix every, and create more top level functions by yaxu in: [#9](https://codeberg.org/uzu/strudel/pulls/9) -- 2022-02-10T00:51:21+01:00 timeCat by yaxu in: [#8](https://codeberg.org/uzu/strudel/pulls/8) -- 2022-02-07T23:07:58+01:00 fixed editor crash by froos in: [#7](https://codeberg.org/uzu/strudel/pulls/7) -- 2022-02-07T19:08:40+01:00 krill parser + improved repl by froos in: [#6](https://codeberg.org/uzu/strudel/pulls/6) -- 2022-02-06T00:59:16+01:00 Patternify all the things by yaxu in: [#5](https://codeberg.org/uzu/strudel/pulls/5) -- 2022-02-05T23:31:37+01:00 update readme for local dev by Ghost in: [#4](https://codeberg.org/uzu/strudel/pulls/4) -- 2022-02-05T22:36:06+01:00 Fix path by yaxu in: [#3](https://codeberg.org/uzu/strudel/pulls/3) -- 2022-02-05T21:52:51+01:00 repl + reify functions by froos in: [#2](https://codeberg.org/uzu/strudel/pulls/2) +- 2022-02-28T00:32:29+01:00 Fix resolveState by @yaxu in: [#22](https://codeberg.org/uzu/strudel/pulls/22) +- 2022-02-27T20:52:52+01:00 Stateful queries and events (WIP) by @yaxu in: [#14](https://codeberg.org/uzu/strudel/pulls/14) +- 2022-02-27T18:04:07+01:00 fix: 💄 Enhance visualisation of the Tutorial on mobile by @Ghost in: [#19](https://codeberg.org/uzu/strudel/pulls/19) +- 2022-02-26T21:16:34+01:00 test: 📦 Add missing dependency and a CI check, to prevent oversights ;p by @Ghost in: [#17](https://codeberg.org/uzu/strudel/pulls/17) +- 2022-02-26T13:29:19+01:00 higher latencyHint by @froos in: [#16](https://codeberg.org/uzu/strudel/pulls/16) +- 2022-02-23T22:15:11+01:00 add apply and layer, and missing div/mul methods by @yaxu in: [#15](https://codeberg.org/uzu/strudel/pulls/15) +- 2022-02-21T01:02:07+01:00 Add continuous signals (sine, cosine, saw, etc) by @yaxu in: [#13](https://codeberg.org/uzu/strudel/pulls/13) +- 2022-02-19T21:30:04+01:00 Added mask() and struct() by @yaxu in: [#11](https://codeberg.org/uzu/strudel/pulls/11) +- 2022-02-19T16:07:07+01:00 Failing test for `when` WIP by @yaxu in: [#10](https://codeberg.org/uzu/strudel/pulls/10) +- 2022-02-10T17:21:31+01:00 Bugfix every, and create more top level functions by @yaxu in: [#9](https://codeberg.org/uzu/strudel/pulls/9) +- 2022-02-10T00:51:21+01:00 timeCat by @yaxu in: [#8](https://codeberg.org/uzu/strudel/pulls/8) +- 2022-02-07T23:07:58+01:00 fixed editor crash by @froos in: [#7](https://codeberg.org/uzu/strudel/pulls/7) +- 2022-02-07T19:08:40+01:00 krill parser + improved repl by @froos in: [#6](https://codeberg.org/uzu/strudel/pulls/6) +- 2022-02-06T00:59:16+01:00 Patternify all the things by @yaxu in: [#5](https://codeberg.org/uzu/strudel/pulls/5) +- 2022-02-05T23:31:37+01:00 update readme for local dev by @Ghost in: [#4](https://codeberg.org/uzu/strudel/pulls/4) +- 2022-02-05T22:36:06+01:00 Fix path by @yaxu in: [#3](https://codeberg.org/uzu/strudel/pulls/3) +- 2022-02-05T21:52:51+01:00 repl + reify functions by @froos in: [#2](https://codeberg.org/uzu/strudel/pulls/2) [9:37:36] strudel % \ No newline at end of file From 2dc921e3756f6805d15d92ca28108c7b18921fda Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 16 Jan 2026 10:14:17 +0100 Subject: [PATCH 79/79] fix: add fun fact --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 587343e43..911463dec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1076,5 +1076,6 @@ NOTE: you can generate this with `node warm.js`. it might still not be perfectly - 2022-02-06T00:59:16+01:00 Patternify all the things by @yaxu in: [#5](https://codeberg.org/uzu/strudel/pulls/5) - 2022-02-05T23:31:37+01:00 update readme for local dev by @Ghost in: [#4](https://codeberg.org/uzu/strudel/pulls/4) - 2022-02-05T22:36:06+01:00 Fix path by @yaxu in: [#3](https://codeberg.org/uzu/strudel/pulls/3) -- 2022-02-05T21:52:51+01:00 repl + reify functions by @froos in: [#2](https://codeberg.org/uzu/strudel/pulls/2) -[9:37:36] strudel % \ No newline at end of file +- 2022-02-05T21:52:51+01:00 repl + reify functions by @froos in: [#2](https://codeberg.org/uzu/strudel/pulls/2) + +... hello from the bottom of this file! you seem to be interested in the history of strudel, so it's worth noting that the first [commit](https://codeberg.org/uzu/strudel/commit/38b5a0d5cdf28685b2b5e18d460772b70246207b) to the repo was actually on Jan 22, 2022, 09:24 PM GMT+1 by @yaxu which could be seen as strudel's birthday 🎂