Skip to content

Instantly share code, notes, and snippets.

@munificent
Created January 22, 2022 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save munificent/b92d602f86a9c72782abe1581115178a to your computer and use it in GitHub Desktop.
Save munificent/b92d602f86a9c72782abe1581115178a to your computer and use it in GitHub Desktop.
A script to help me pick gear to use for synth jams
import 'dart:math';
final gear = [
Machine('Guitar', 'sample'),
Machine('Piano', 'sample'),
Machine('YouTube', 'sample'),
Machine('Digitakt', 'synth sequencer fx'),
Machine('Digitone', 'synth sequencer fx'),
Machine('Peak', 'synth fx'),
Machine('DrumBrute Impact', 'drums'),
Machine('MB33', 'synth'),
Machine('MiniBrute II', 'synth sequencer'),
Machine('RackBrute', 'synth'),
Machine('Microcosm', 'fx'),
Machine('Echo Park', 'fx'),
Machine('Hall of Fame II', 'fx'),
Machine('MXR Bass DI', 'fx'),
Machine('RC-1 LoopStation', 'looper'),
];
/// Bias the counts some.
const counts = [1, 1, 2, 2, 2, 3];
final random = Random();
/// Completed jams, so that I don't repeat them.
final done = [
makeSetup(['DrumBrute Impact', 'MXR Bass DI']),
makeSetup(['Digitakt', 'Minibrute II']),
makeSetup(['Digitakt', 'Rackbrute']),
];
/// Gear I want to make sure gets used at least once before repeating other
/// gear.
final unused = ['Digitone', 'Microcosm', 'Peak'];
void main(List<String> arguments) {
print(pickMachines().join(' + '));
}
List<Machine> makeSetup(List<String> names) {
return names
.map((name) => gear.firstWhere((machine) => machine.name == name))
.toList();
}
List<Machine> pickMachines() {
while (true) {
var machines = gear.toList();
machines.shuffle();
var count = counts[random.nextInt(counts.length)];
machines = machines.sublist(0, count);
var reason = validate(machines);
if (reason != null) {
// print('[$reason] $machines');
continue;
}
machines.sort((a, b) => gear.indexOf(a).compareTo(gear.indexOf(b)));
return machines;
}
}
String? validate(List<Machine> machines) {
// Need a sampler if using samples.
if (machines.has('sample') && !machines.has('Digitakt')) {
return 'samples but no sampler';
}
// An unsequenced synth needs a sequencer.
if (machines.has('synth') &&
!machines.has('sequencer') &&
!machines.has('looper')) {
return 'no sequencer for synth';
}
// Always want some FX.
if (!machines.has('fx')) return 'too dry';
// Need a sound source.
if (!machines.has('synth') && !machines.has('drums')) return 'no sounds';
// Must use an unused important piece of gear.
if (!machines.hasAny(unused)) return 'no unused gear';
return null;
}
extension on List<Machine> {
bool has(String name) =>
any((machine) => machine.matches(name));
bool hasAny(Iterable<String> names) =>
any((machine) => names.any(machine.matches));
}
class Machine {
final String name;
final Set<String> features;
Machine(this.name, String features) : features = features.split(' ').toSet();
bool matches(String name) => this.name == name || features.contains(name);
@override
String toString() => name;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment