commit
3ea58d1ef9
3 changed files with 254 additions and 0 deletions
@ -0,0 +1,191 @@
@@ -0,0 +1,191 @@
|
||||
#!/usr/bin/env python3 |
||||
# a deterministic techno generator for tidalcycles |
||||
# input an integer value as a seed |
||||
# and it spits out some techno ready to play |
||||
# |
||||
################################################## |
||||
########### SETTINGS ############################# |
||||
# what are the lowest and highest bpm values you want? |
||||
lowestBpm = 90 |
||||
highestBpm = 135 |
||||
|
||||
# stack name |
||||
stackName = "techno" |
||||
|
||||
# force everything to happen within 1 bar |
||||
oneBar = 1 |
||||
|
||||
# for euclidean rhythms, define the choices for the 2nd number |
||||
# eg "[t(3,NN)]" |
||||
dividers = [4,8,16] |
||||
# for melodic lines, what divisions do you want to choose from? |
||||
# eg 4 = quarter notes, 8 = eighth notes |
||||
# tip: adding more of the same number will weight the randomness toward that |
||||
melodicDivisions = [8,16,16,16] |
||||
# keep melodies within 1 bar |
||||
#melodicOneBar = 1 |
||||
|
||||
# for melodic sequences, define the choices for range of the notes |
||||
# eg 12 is one octave, 24 is two, etc |
||||
noteRange = [12,24,36] |
||||
# define the shortest and longest sequence you want |
||||
# eg if shortest is 7, there will be no melodic sequences shorter than 7 |
||||
shortestMelodic = 4 |
||||
longestMelodic = 16 |
||||
|
||||
# how many |
||||
# how many percussive/rhythmic elements to generate? |
||||
percCount = 5 |
||||
percMidiChanStart = 0 |
||||
# how many melodic elements to generate? |
||||
melodyCount = 1 |
||||
melodyMidiChanStart = 7 |
||||
|
||||
|
||||
# perc note |
||||
# set a static note for percussion tracks |
||||
percNote = 0 |
||||
# perc track names |
||||
percNames = ["kick", "hh", "sd", "cp", "cymbal", "?", "?", "?", "?"] |
||||
# for use generating sequences of 0's and 1's |
||||
binary = [0,0,0,1] |
||||
|
||||
## import stuff |
||||
import sys |
||||
import random |
||||
import math |
||||
|
||||
|
||||
################################################## |
||||
# this is the 1st argument given via command line |
||||
# this is used to calculate everything |
||||
# seeds should be 6 digits or longer |
||||
input = sys.argv[1] |
||||
|
||||
print("-- seed: " + str(input)) |
||||
|
||||
|
||||
########### THIS CHANGES EVERYTHING! ############# |
||||
# set the random seed based on user input |
||||
random.seed(input) |
||||
################################################## |
||||
|
||||
# generate a bpm between lowest and highest |
||||
# looks like: cps = (BPM/60/4) |
||||
bpm = "cps = ("+str(random.randrange(lowestBpm, highestBpm, 1))+"/60/4)" |
||||
print(bpm+"\n") |
||||
|
||||
|
||||
|
||||
def genOnOff(limit): |
||||
"generate a series of 0's and 1's" |
||||
zeroesOnes = "" |
||||
for i in range(limit): |
||||
zeroesOnes = zeroesOnes + str(random.choice(binary)) |
||||
zeroesOnes = ", struct \"{"+zeroesOnes+"}%16\"" |
||||
print(zeroesOnes) |
||||
|
||||
|
||||
def euclid(divider): |
||||
"generate a euclidean rhythm for tidalcycles" #struct "[t(3,8)]" |
||||
# 3,8 10,16 4,16 |
||||
#secondEuclid = str(random.choice(dividers)) |
||||
secondEuclid = divider |
||||
firstEuclid = str(random.randrange(2,int(secondEuclid))) |
||||
#print("firstEuclid:"+firstEuclid) |
||||
#print("secondEuclid:"+str(secondEuclid)) |
||||
|
||||
euclidSeed = random.random() |
||||
# decide whether there are going to be changes in the euclid seq |
||||
if (random.random() > random.random()): |
||||
# the first and the second euclid numbers will stay the same |
||||
# eg no <3 6 5> |
||||
#print("") |
||||
firstEuclid = firstEuclid |
||||
else: |
||||
# the first euclid number WILL sequence (eg <4,8>) |
||||
#firstEuclid = "<"+str(random.randrange(2,int(random.choice(dividers)))+" "+str(random.randrange(2,int(random.choice(dividers))))+">" |
||||
firstEuclid = "<"+str(random.randrange(2,16))+" "+str(random.randrange(2,16))+">" |
||||
# decide whether the second number will seq |
||||
if (random.random() > random.random()): |
||||
# we will do like [t(??,<16,8>)] |
||||
secondEuclid = "<"+str(random.choice(dividers))+" "+str(random.choice(dividers))+">" |
||||
# [t(<3 8>,16)] |
||||
|
||||
|
||||
print(", struct \"[t("+str(firstEuclid)+","+str(secondEuclid)+")]\"") |
||||
|
||||
def genNotes(melodicOneBar): |
||||
""" |
||||
Generate a series of numbers for use as midi notes |
||||
accepts 1 or 0, where 1 limits the melody to 16 16th notes |
||||
and 0 sets the melody to somewhere between the values |
||||
of shortestMelodic and longestMelodic |
||||
""" |
||||
# between let's say 4 notes and 16 notes |
||||
if (melodicOneBar == 1): |
||||
melodyLength = 16 |
||||
else: |
||||
melodyLength = random.randrange(shortestMelodic,longestMelodic) |
||||
|
||||
melody = "" |
||||
for i in range(melodyLength): |
||||
melody = str(random.randrange(0,random.choice(noteRange))) + " " + str(melody) |
||||
print("n "+"\"{"+melody+"}%"+str(random.choice(melodicDivisions))+"\"") |
||||
|
||||
|
||||
|
||||
# actually assemble the stack! |
||||
print("p \""+stackName+"\" ") |
||||
|
||||
# stack stuff like bite, scramble, etc. will go here |
||||
|
||||
print("$ whenmod 8 7 (scramble 4)") # |
||||
|
||||
|
||||
# the top of the stack |
||||
print("$ stack [") |
||||
|
||||
# this is an empty track to make dealing with commas easier |
||||
print(" n \"0\"") |
||||
|
||||
print(",struct \"[t*4]\" $ n 0 # midichan 0") |
||||
|
||||
# generate percussion tracks |
||||
percMidiChan = 1 |
||||
for i in range(percCount): |
||||
# choose how long the rhythm will be |
||||
if (oneBar == 1): |
||||
percLength = 16 |
||||
else: |
||||
percLength = int(random.randrange(4,16)) |
||||
#percSequence = genOnOff(percLength) |
||||
#print(","+str(genOnOff(10))) |
||||
#print(str(percSequence)) |
||||
print("-- "+percNames[percMidiChan]) |
||||
genOnOff(percLength) |
||||
print (" $ n "+str(percNote)) |
||||
print(" # midichan "+str(percMidiChan)) |
||||
percMidiChan = percMidiChan + 1 |
||||
|
||||
|
||||
# generate melodic tracks |
||||
melodicMidiChan = melodyMidiChanStart |
||||
#melodyMidiChanStart = 7 |
||||
for i in range(melodyCount): |
||||
print("-- ?") |
||||
#print(", ") |
||||
if (oneBar == 1): |
||||
genOnOff(16) |
||||
print("$") |
||||
genNotes(1) |
||||
else: |
||||
genOnOff(16) |
||||
print("$") |
||||
genNotes(1) |
||||
print("# midichan "+str(melodicMidiChan)+" + n (-36)") |
||||
melodicMidiChan = melodicMidiChan + 1 |
||||
|
||||
|
||||
print("]") |
||||
print("# sunvox") |
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
|
||||
cps = (120/60/4) |
||||
|
||||
hush |
||||
|
||||
p "techno" $ struct "[t(<3 6 5>,8)]" $ n "0" # midichan 0 # sunvox |
||||
|
||||
|
||||
p "techno" |
||||
$ every 5 (scramble 4) |
||||
$ every 11 (bite 4 "{0*4 4*4 2*4 1*4 0*4 2*4}%4") |
||||
$ stack [ |
||||
-- kick |
||||
st "[t t t t]" $ n "0" # midichan 0 |
||||
-- hh |
||||
,st "[~t~t~t~t]" $ n "0" # midichan 1 |
||||
-- sd |
||||
,st "[~ t ~ t]" $ n "0" # midichan 2 |
||||
-- cp |
||||
,st "{t~~t~}%16" $ n "0" # midichan 3 |
||||
-- ride |
||||
,st "{t~~~t~tt~}" $ n "0" # midichan 4 |
||||
-- bassline |
||||
, st "{1001 0011 1001 0101}%16" |
||||
$ n "{10 20 0 3 4 1 23 10 11}%16" |
||||
# midichan 7 |
||||
] |
||||
# sunvox |
||||
|
||||
|
||||
-- seed: 289431606803713161 |
||||
cps = (117/60/4) |
||||
|
||||
p "techno" |
||||
$ whenmod 8 7 (scramble 4) |
||||
$ stack [ |
||||
n "0" |
||||
-- kick |
||||
, struct "{1011001100011110}%16" |
||||
$ n 0 |
||||
# midichan 0 |
||||
-- hh |
||||
, struct "{1010111011110001}%16" |
||||
$ n 0 |
||||
# midichan 1 |
||||
-- sd |
||||
, struct "{1101001111100010}%16" |
||||
$ n 0 |
||||
# midichan 2 |
||||
-- cp |
||||
, struct "{0111000101010000}%16" |
||||
$ n 0 |
||||
# midichan 3 |
||||
-- cymbal |
||||
, struct "{0101101101111010}%16" |
||||
$ n 0 |
||||
# midichan 4 |
||||
-- ? |
||||
, |
||||
n "{34 22 6 29 3 3 30 2 27 21 23 3 3 7 24 19 }%16" |
||||
# midichan 7 |
||||
] |
||||
# sunvox |
Loading…
Reference in new issue