U-he preset randomizer / merger (open-source CLI tool)

Official support for: u-he.com
RELATED
PRODUCTS

Post

Yes, good point, Fannon, and "learn how to fix" is a good approach always. And for what it's worth, a randomizer might go to aural places you've never considered, at least aesthetically.

Post

Sometimes I need fresh input to leave the old paths of sound design. Here a randomizer can help a lot. I don't even want it to put out ready made sounds but a new view and new ideas.

That's why I also love my eurorack. There's often this happy accident.
EAT - SLEEP - SYNTH
http://soundcloud.com/pocvecem

Post

Fannon wrote: Wed May 29, 2024 4:54 pm Oh.. yeah, I hope no one is accusing a random algorithm of political incorrectness then :D
You can never be too careful these days, lol :?
That's a fun idea. I've just tried it and it was really simple to add. It's now available in v1.0.2. It results in some funny names, but sometimes it also picks up words that describe particular presets. In those cases, the names may lead to misleading expectations?
I think it's definitely an improvement! :tu:
I have a bunch of presets that use _ for space which gets treated as one long word, and also some that have undesired text indicating an instrument type, brackets for an edit/version or chord voicing (min), (min7) etc.

I don't know TS, but was testing out Cursor (AI VSC fork) and it gave me this modification to exclude _, (*), and a list of words. Random names don't need to be perfect, I'm just thinking about the low-hanging fruit like not having basses named bells, and keys named claps (inexact filtering might be better.)

Code: Select all

export function getDictionaryOfNames(presetLibrary: PresetLibrary): string[] {
  const names: string[] = [];
  const excludedWords = new Set(["bass", "guitar", "piano", "lead", "unison", "sub", "strings", "keys", "flute", "organ", "brass", "bells", "pluck", "plucked", "epiano", "chorus", "stab", "chord", "chords", "drum", "synth", "kick", "snare", "clap", "hihat", "edit"]);

  for (const preset of presetLibrary.presets) {
    const splitName = preset.presetName.split(' ');
    for (const split of splitName) {
      if (
        split.length > 3 &&
        split.toUpperCase() !== split &&
        !split.includes('-') &&
        !split.includes('_') &&
        !split.includes('(') &&
        !split.includes(')') &&
        !excludedWords.has(split.toLowerCase())
      ) {
        names.push(split);
      }
    }
  }
  return names;
I also noticed some preset names would use the same word multiple times, so something like this could check for dupes.

Code: Select all

if (config.dictionary) {
      const names = getDictionaryOfNames(presetLibrary);
      if (names.length >= 3) {
        const uniqueNames = new Set<string>();
        while (uniqueNames.size < 3) {
          uniqueNames.add(getRandomArrayItem(names));
        }
        const [name1, name2, name3] = Array.from(uniqueNames);
        randomName = `${name1} ${name2} ${name3}`;
      } else {
        console.error(chalk.red('Error: Not enough unique names available for randomization.'));
        process.exit(1);
      }
I don't know if the examples are helpful getting the idea across, but I haven't figured out how to build and run changes locally yet so can't be of much else use with the code. :lol:

As for the "Error: No presets found..." issue with sub-folders, it looks like a bug with certain characters.

For example choosing:
/Local/!FAV/
Will try looking in:
/Local/!!FAV/
and return no results.

Also, I did a bit more digging into the categories. They've changed over time and the browser seems to shoehorn deprecated categories into the closest current equivalent.
i.e. Basses:Evolving goes into Bass:Rhythmic.

Since everything else is basically supported it might be helpful to add Features and Character as selection criteria for things like creating chords, mono/poly , bright/dark, dirty/clean, vintage/modern, phat/thin, synthetic/natural, soft/aggressive sounds.

I tested chords using the deprecated Pads:Chords category and it worked pretty well, but Categories: Pads, Features:Chords would return many more results. The presets were created with Pads:Chords metadata which showed as Pads:Synths in the browser but it doesn't map :chords to the chord tag.

Using PowerToys Text Extractor I made a list of all the categories that show up in Diva's browser (formatted how they'd show up in the CLI).

Code: Select all

Bass:Bass 
Bass:Acoustic 
Bass:Analogue 
Bass:Digital 
Bass:Dist+LoFi 
Bass:E-Bass 
Bass:Plucks 
Bass:Rhythmic 
Bass:Sub 
Bass:Sync 
Bass:Synth 
Bass:Vocal 

Pads:Pads 
Pads:Airy 
Pads:Analogue 
Pads:Brass 
Pads:Digital 
Pads:Dist+LoFi 
Pads:Drones 
Pads:Evolving 
Pads:Organs 
Pads:Rhythmic 
Pads:Soundscape 
Pads:Strings 
Pads:synth 
Pads:Vocal 
Pads:Winds 

Leads:Leads 
Leads:Analogue 
Leads:Brass 
Leads:Digital 
Leads:Dist+LoFi 
Leads:Guitars 
Leads:Plucks 
Leads:Rhythmic 
Leads:Strings 
Leads:Sync 
Leads:Synth 
Leads:Vocal 
Leads:Winds 

Keys:Keys 
Keys:Analogue 
Keys:Bells 
Keys:Brass 
Keys:Digital 
Keys:Dist+LoFi 
Keys:Guitars 
Keys:Mallets 
Keys:Organs 
Keys:Piano 
Keys:Plucks 
Keys:Strings 
Keys:Sync 
Keys:Synth 
Keys:Vocal 
Keys:Winds 

FX:FX 
FX:Ambient 
FX:Beeps 
FX:Dist+LoFi 
FX:Glitch 
FX:Hits 
FX:Noise 
FX:Rhythmic 
FX:Sirens 
FX:Sweeps 
FX:Tension 
FX:Vocal 
FX:Whooshes 

Drums:Drums 
Drums:Bells 
Drums:Big Drums 
Drums:Clicks 
Drums:Claps 
Drums:Cymbals 
Drums:Dist+LoFi 
Drums:HiHats 
Drums:Kicks 
Drums:Metal 
Drums:Percussion 
Drums:Snares 
Drums:Synth 
Drums:Toms 
Drums:Wood 

Seq+Arp:Seq+Arp 
Seq+Arp:Basslines
Seq+Arp:Dist+LoFi 
Seq+Arp:Drum Loops 
Seq+Arp:Effects 
Seq+Arp:Layered 
Seq+Arp:Melodic 
Seq+Arp:Plucks 
Seq+Arp:Pulsating 

Other:Other 
Other:Templates
I did the same for all the ones that were actually showing up for me (based on the actual preset metadata), and after comparing the lists with PowerToys Advanced Paste (GPT-4) these were left over:

Code: Select all

Bass:Distorted
Bass:Evolving
Bass:Lo-Fi
Bass:Plucked
Bass:Wobble

Basses:Distorted
Basses:Evolving
Basses:FX Bass
Basses:Plucked
Basses:Sub
Basses:Wobble

Drums & Percussive
Drums & Percussive:Bells
Drums & Percussive:Kicks
Drums & Percussive:Percussion
Drums & Percussive:Toms

Drums:Brushes
Drums:Clicks & Snips
Drums:Hats & Crashes
Drums:Scrapes & Brushes

FX:Beeps & Bloops
FX:Fly-By & Whoosh
FX:Glitch & Weird
FX:Hits & Impacts
FX:Nature & Ambient
FX:Nature & Space
FX:Noise & Rumble
FX:Sirens & Whistle
FX:Sweeps & Risers

Keys:Bowed
Keys:Chords
Keys:Chords & 5ths
Keys:Chords & Fifth
Keys:Classic
Keys:Layered
Keys:Pipes
Keys:Synthetic

Leads:Bowed
Leads:Chords
Leads:Chords & 5ths
Leads:Guitar
Leads:Plucked
Leads:PWM
Leads:Reeds
Leads:Sync Lead
Other:Initialize

Pads:Atonal
Pads:Breathy
Pads:Chords
Pads:Chords & 5ths

Plucks & Stabs:Chords & 5ths
Plucks & Stabs:Classic
Plucks & Stabs:Guitar & Strings
Plucks & Stabs:Guitars & Harps
Plucks & Stabs:Layered

Seq & Arp:Basslines
Seq & Arp:Drum Loops
Seq & Arp:Effects
Seq & Arp:Evolving
Seq & Arp:Layered
Seq & Arp:Melodic
Seq & Arp:Plucked

Sequences & Arps:Basslines
Sequences & Arps:Distorted & Noise
Sequences & Arps:Drum Patterns
Sequences & Arps:Effects
Sequences & Arps:Evolving
Sequences & Arps:Layered
Sequences & Arps:Melodic
Sequences & Arps:Melody & Leadlines
Sequences & Arps:Plucked

Stabs:Chords
Stabs:Classic
Stabs:Strings
Creating dummy presets could allow figuring out how the browser maps them, but having extra unique subcategories might be a benefit as they'd still be included in the same parent category (i.e. Pads:Chords in Pads), though grouping similar parent categories would help a lot so the presets aren't divided between duplicates.

i.e.
Basses: = Bass:
Drums & Percussive: = Drums:
Seq & Arp: = Seq+Arp
Sequences & Arps: = Seq+Arp:
:wink:

Post

AtomOfScent wrote: Tue Jun 04, 2024 12:37 pm I don't know if the examples are helpful getting the idea across, but I haven't figured out how to build and run changes locally yet so can't be of much else use with the code.
That's actually not really complicated. In the Readme, it's documented at the bottom. It's just checking out the git repository, `npm install` and then I would personally also install `npm i -g tsx` so you can directly run the TypeScript without a build step. Just run `tsx src/cli.ts` and you're good to go.

The code for getDictionaryOfNames actually works and looks good. Just tried it and I think it's an improvement. I'll probably keep it for the next patch update.

The other parts, I'm not sure if it's really worth it for complicating the code base. Also I'm not sure how well it should support special characters that often the u-he synths don't like well anyway. I think it would be better to avoid special characters in folder or file names in the first place.

Yes, the categories are a bit messed up with this, but that would now require a synth specific cleanup. Do you think it is a bigger problem?

I won't have much time to put into this project for the forseeable next time, but in case you can get this running locally, maybe you can do some PRs to propose changes? Seems like with AI assistance, it's now a much lower barrier of entry to this.
Find my (music) related software projects here: github.com/Fannon

Post

If there is a character you suggest I use so I can sort folders at the top let me know. I already changed from =folder= to !folder and lost all my favorites. :dog:
Neither are illegal characters for directory names in any OS but might need special handling in the code. U-he's browser wouldn't let me create folders with =, but was fine with !

I decided to try tackling the categories issue myself* by making a basic Python script that reads the metadata from all presets in a specific folder (selected or dropped on the UI), and populates it into a table with sortable columns:

Changes can be made, and written back into the original .h2p file
Image

Everything seems to work, I just want to add support for bulk editing the entries. Then it should be pretty easy to select every preset with 'Sequences & Arps:Basslines' and change to 'Seq+Arp:Bassliines' so they show up as expected in the CLI. :ud:

Also, you're right that it's probably time to figure out how to use GitHub and make PRs etc. This project is a good opportunity since the stakes are relatively low.

(*The whole thing was created with a one-shot prompt, except for DnD support which was a second shot. :borg: )

Post

AtomOfScent wrote: Wed Jun 05, 2024 1:06 am If there is a character you suggest I use so I can sort folders at the top let me know. I already changed from =folder= to !folder and lost all my favorites. :dog:
Neither are illegal characters for directory names in any OS but might need special handling in the code. U-he's browser wouldn't let me create folders with =, but was fine with !
Yes, ! should be OK actually. Probably the issue is with the glob pattern search, where ! has a special meaning and should be escaped.

Learning Git, GitHub + PRs is really useful. This is what opens up contributions to Open-Source, even if it's just smaller, easy stuff! A lot of developers really appreciate it when people put in effort on their side and start at least with some proposal, not just report an issue.

Regarding the category names: One approach could be to create (per Synth) a JSON file that contains a dictionary how to map from old to new names and thus reduce also duplicates. Then this would be easy to contribute, read out and apply (if existing for a synth).
Find my (music) related software projects here: github.com/Fannon

Post

v1.0.9 now brings the category names from existing files (thanks @AtomOfScent) and enabled binary mode by default for Repro. There it seems to work fine, and without it the effects are always wired / enabled the same default way.
Find my (music) related software projects here: github.com/Fannon

Post

The randomizer works well with Repro-1. I've just uploaded a smaller soundset for it:

Download here: https://github.com/Fannon/u-he-preset-r ... tag/v1.0.9
Or here directly: https://github.com/Fannon/u-he-preset-r ... .Vol.1.zip

2024-07-20 21_30_12-Release v1.0.9 · Fannon_u-he-preset-randomizer and 29 more pages - Personal - Mi.png
You do not have the required permissions to view the files attached to this post.
Find my (music) related software projects here: github.com/Fannon

Post

I made a fork to learn how to use Git and play around. :)
It seems to work well, but I've only really tested with Diva.

Main changes:
  • -Add Features and Character as optional modifiers.
    -Make Author and Categories multi-choice.
    -Use category abbreviations as prefixes instead of RND when using category modifier.
    -Removed time portion from 'Generated on' in description.
    -Increased CLI page size.
    -Added options to completion message so the CLI stays open when using tsx
By the way, I think there might be an issue with Zebra.
It seems the grid doesn't change for generated presets so the modules/order/routing stays the same as the last non-random preset loaded and can sound totally different based on that.

My guess is it's binary related so best to resave any generated preset you like which will hopefully write correct binary that reloads the current state.

Post

AtomOfScent wrote: Sun Jul 21, 2024 12:15 am I made a fork to learn how to use Git and play around. :)
Nice! If you like and feel confident, we could have a look at that together and merge it back into the main project?
AtomOfScent wrote: Sun Jul 21, 2024 12:15 am By the way, I think there might be an issue with Zebra.
It seems the grid doesn't change for generated presets so the modules/order/routing stays the same as the last non-random preset loaded and can sound totally different based on that.

My guess is it's binary related so best to resave any generated preset you like which will hopefully write correct binary that reloads the current state.
Yes, the wiring of the modules is in the binary section. You could try to enable "binary" mode in the CLI and see how well it works.

Right now, I don't see any way how to really randomize the parts of the binary section, except of picking a random binary section of a preset. Unfortunately the binary section seems to be not compatible with some parameter values, which leads to broken presets. But I haven't really figured out this relationship. It's different for different u-he synths. I think Zebralette 3 and Repro are fine with activating binary mode.
Find my (music) related software projects here: github.com/Fannon

Post

Fannon wrote: Sun Jul 21, 2024 3:31 am Nice! If you like and feel confident, we could have a look at that together and merge it back into the main project?
I'm heading to a music festival in a few days, but I'd love to the next week when I return. :)
Yes, the wiring of the modules is in the binary section. You could try to enable "binary" mode in the CLI and see how well it works.

Right now, I don't see any way how to really randomize the parts of the binary section, except of picking a random binary section of a preset. Unfortunately the binary section seems to be not compatible with some parameter values, which leads to broken presets. But I haven't really figured out this relationship. It's different for different u-he synths. I think Zebralette 3 and Repro are fine with activating binary mode.
I'll experiment a bit more since I think I usually didn't use binary with Zebra.

One thing I noticed is the preset format version is being randomized.Standardizing to 2.3 or 2.5 might help depending on what works better.

A possible way to make lemonade from lemons might be to add some existing presets with a variety of grid arrangements in the RANDOM dir. They could be loaded prior to the generated ones which would essentially hybridize them. Any interesting results could be saved (and hopefully recalled.)

I think Zebra will be trickiest to support. Maybe Urs could provide some insight, but it wouldn't be the end of the world if it doesn't work.

Post

AtomOfScent wrote: Sun Jul 21, 2024 2:13 pm I'll experiment a bit more since I think I usually didn't use binary with Zebra.
I'd be interested to learn how well it work for you.
AtomOfScent wrote: Sun Jul 21, 2024 2:13 pm One thing I noticed is the preset format version is being randomized.Standardizing to 2.3 or 2.5 might help depending on what works better.
Good catch, I haven't really considered that. It might make sense to always use the most recent format.
AtomOfScent wrote: Sun Jul 21, 2024 2:13 pm A possible way to make lemonade from lemons might be to add some existing presets with a variety of grid arrangements in the RANDOM dir. They could be loaded prior to the generated ones which would essentially hybridize them. Any interesting results could be saved (and hopefully recalled.)

I think Zebra will be trickiest to support. Maybe Urs could provide some insight, but it wouldn't be the end of the world if it doesn't work.
That's a nice idea. It would be some manual effort to systematically create those. I only see one problem here: The binary part includes everything that is not stored in simple parameter values. That means it's not just he wiring, but (I assume) also the MSEG curves, NMAP values, etc.

When Zebra 3 comes out and I find the time, I'd really like to look more into it. I'm a little bit afraid that randomizing Zebra 3 will be difficult for the same reasons as with Zebra 2.
Find my (music) related software projects here: github.com/Fannon

Post

Here is another free soundset for u-he Repro-5, with 42 presets and a sound demo:

Download here: https://github.com/Fannon/u-he-preset-r ... ag/v1.0.10

Like with the previous soundsets, I used the u-he-preset-randomizer tool and curated & modified the presets. No additional effects beyond master limiting some and audio-crackle in the beginning (sorry).
Find my (music) related software projects here: github.com/Fannon

Post

Ok, I just wanted to try this out for sake of curiosity and nerd-factor.

Use AI agents to checkout your u-he synth presets, search, filter and generate / merge / breed new patches. Let it analyze existing or created patches and figure out how they could sound or compare. This is just some local experiment.


2025-10-28 20_55_25-Diva _ Diva.png
You do not have the required permissions to view the files attached to this post.
Last edited by Fannon on Sat Nov 01, 2025 6:31 am, edited 2 times in total.
Find my (music) related software projects here: github.com/Fannon

Post

Fannon wrote: Tue Oct 28, 2025 8:01 pm Ok, I just wanted to try this out for sake of curiosity and nerd-factor.

Use AI agents to checkout your u-he synth presets, search, filter and generate / merge / breed new patches. Let it analyze existing or created patches and figure out how they could sound or compare. This is just some local experiment.
Cool! :tu:

Claude should do a great job understanding semantic relationships from metadata.
I wonder how close you could get to the same functionality using a Skill vs. MCP?

Post Reply

Return to “u-he”