Browse Source

more features and some debugging

master
spoonietunes 12 months ago
parent
commit
5c5b786a55
  1. 236
      auto-techno.py
  2. 114
      test.tidal

236
auto-techno.py

@ -3,27 +3,51 @@ @@ -3,27 +3,51 @@
# input an integer value as a seed
# and it spits out some techno ready to play
#
# use it in emacs like this:
# it will generate a random seed
#
# (defun autotechno()
# (interactive)
# (insert (shell-command-to-string (concat "/usr/bin/python ~/tidal-auto-techno/auto-techno.py " (number-to-string(random))))))
#
##################################################
########### SETTINGS #############################
# what are the lowest and highest bpm values you want?
lowestBpm = 90
lowestBpm = 92
highestBpm = 135
# force everything to happen within 1 bar
oneBar = 1
# stack name
# this doesn't matter, can be any string
stackName = "techno"
# force everything to happen within 1 bar
oneBar = 1
####### PERCUSSION ##############################
# 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
# how many percussive/rhythmic elements to generate?
percCount = 5
percMidiChanStart = 0
# perc note
# set a static note for percussion tracks
percNote = 0
# perc track names
percNames = ["kick", "hh", "sd", "cp", "?", "?", "bassline", "?", "?"]
# for use generating sequences of 0's and 1's
#
#
#
####### MELODY #################################
# NOTE about melodic sequences:
# as of October 04, 2021 all melodic sequences are all notes
# ie no rests. the rhythm/rests is determined by a "struct" value
# just like with percussion
# for melodic sequences, define the choices for range of the notes
# eg 12 is one octave, 24 is two, etc
@ -33,23 +57,19 @@ noteRange = [12,24,36] @@ -33,23 +57,19 @@ noteRange = [12,24,36]
shortestMelodic = 4
longestMelodic = 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
# 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
@ -77,43 +97,81 @@ print(bpm+"\n") @@ -77,43 +97,81 @@ print(bpm+"\n")
def genOnOff(limit):
def generateBinary(busyness):
"""
busy-ness (sic)
Create a list of 0's and 1's from which patterns can be
created. The higher the busyness, the more 1's in the list,
which in turn creates more events in the generated sequence
busyness range from 0 to 9, where 9 is most busy,
and 0 is no activity at all
"""
if (busyness == 0):
binary = [0]
elif (busyness == 1):
binary = [0,0,0,0,0,0,0,0,1]
elif (busyness == 2):
binary = [0,0,0,0,0,0,0,1,1]
elif (busyness == 3):
binary = [0,0,0,0,0,0,1,1,1]
elif (busyness == 4):
binary = [0,0,0,0,0,1,1,1,1]
elif (busyness == 5):
binary = [0,0,0,0,1,1,1,1,1]
elif (busyness == 6):
binary = [0,0,0,1,1,1,1,1,1]
elif (busyness == 7):
binary = [0,0,1,1,1,1,1,1,1]
elif (busyness == 8):
binary = [0,0,1,1,1,1,1,1,1,1]
elif (busyness == 9):
binary = [0,0,1,1,1,1,1,1,1,1,1]
return binary
#binary = [0,0,0,1]
def genOnOff(limit,busyness):
"generate a series of 0's and 1's"
zeroesOnes = ""
# here we can change the list of 0's and 1's
# the more 1's, the busier the rhythm will be
# and we want to set this per-track
# so...
#
for i in range(limit):
zeroesOnes = zeroesOnes + str(random.choice(binary))
zeroesOnes = ", struct \"{"+zeroesOnes+"}%16\""
zeroesOnes = zeroesOnes + str(random.choice(generateBinary(busyness)))
zeroesOnes = "$ struct \"{"+zeroesOnes+"}%16\""
print(zeroesOnes)
def euclid(divider):
"generate a euclidean rhythm for tidalcycles" #struct "[t(3,8)]"
"generate a euclidean rhythm for tidalcycles"
# like struct "[t(3,8)]"
# 3,8 10,16 4,16
#secondEuclid = str(random.choice(dividers))
secondEuclid = divider
firstEuclid = str(random.randrange(2,int(secondEuclid)))
firstEuclid = str(random.randrange(2,divider))
#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()):
#if (random.random() < random.random()):
if (1 > 0):
# 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))+">"
firstEuclid = "<"+str(random.randrange(2,divider))+" "+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)+")]\"")
print("$ struct \"[t("+str(firstEuclid)+","+str(secondEuclid)+")]\"")
def genNotes(melodicOneBar):
"""
@ -134,6 +192,46 @@ def genNotes(melodicOneBar): @@ -134,6 +192,46 @@ def genNotes(melodicOneBar):
print("n "+"\"{"+melody+"}%"+str(random.choice(melodicDivisions))+"\"")
def every():
bars = random.randint(2,16)
print("$ every "+str(bars)+" ")
def whenmod():
limit = 16
lower = random.randint(4,limit)
print("$ whenmod "+str(limit)+" "+str(lower)+" ")
def bite():
"""
Generate something like
bite 16 "{2*4 1*2 10*4 8*8}%16
"""
divisions = [4,8]
number = str(random.choice(divisions))
# generate like 1*4 8*4 2*2 1*2 9*1
repeatChoices = [1,2,4]
# how long should it be?
length = int(random.randint(4,16))
bit = ""
for i in range(length):
bit = str(random.randint(0,int(number)))+"*"+str(random.choice(repeatChoices))+" "+bit
# since bite will always be encapsulated by ( )
# eg whenmod 8 7 (bite 4 "2*4")
# we don't need to prepend with $ or ,
print("bite "+number+ " \"{"+bit+"}%"+number+"\"")
def funStuff():
"""
Generate variations like `whenmod 8 7 (scramble 4)`
"""
# here are some conditions:
# https://tidalcycles.org/docs/reference/conditions
# every N - whenmod N N - sometimesBy N - someCyclesBy N
# actually assemble the stack!
print("p \""+stackName+"\" ")
@ -142,50 +240,84 @@ print("p \""+stackName+"\" ") @@ -142,50 +240,84 @@ print("p \""+stackName+"\" ")
print("$ whenmod 8 7 (scramble 4)") #
# how many "fun" things to add?
def funThings():
funThings = random.randint(0,4)
for i in range(funThings):
#print(str(every) + "$ " + str(output))
every()
print(" (")
bite()
print(") ")
# uncomment this for some wildness
#funThings()
# the top of the stack
print("$ stack [")
# this is an empty track to make dealing with commas easier
print(" n \"0\"")
# just 4 to the floor in case you want it
print("-- four to the floor")
print(" (#gain 1) $ struct \"[t*4]\" $ n \"0\" # midichan 0,")
print(",struct \"[t*4]\" $ n 0 # midichan 0")
#print(",struct \"[t*4]\" $ n 0 # midichan 0")
# generate percussion tracks
percMidiChan = 1
# generate rhythm tracks
percMidiChan = 0
for i in range(percCount):
# choose how long the rhythm will be
if (oneBar == 1):
percLength = 16
print("-- "+percNames[percMidiChan]+" -----------------")
# this is here so there is the same thing at the start of
# each new track (so we know "whenmod" for instance always
# starts with $ and not ,)
print("degradeBy 0 ")
# insert some funStuff, maybe
if (random.choice([0,1]) > 0):
funThings()
# choose between regular or euclidean rhythms
if (random.choice([0,1]) == 0):
# GENERATE A SERIES OF 0's and 1's
# 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))
# how busy will it be?a
# choose a random value between 0 and 9
busyness = random.randrange(0,7)
generateBinary(busyness)
genOnOff(percLength,busyness)
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))
# GENERATE EUCLIDEAN RHYTHMS
euclid(random.choice(dividers))
print (" $ n "+str(percNote)+" # midichan "+str(percMidiChan)+",")
percMidiChan = percMidiChan + 1
# generate melodic tracks
melodicMidiChan = melodyMidiChanStart
#melodyMidiChanStart = 7
for i in range(melodyCount):
print("-- ?")
print("-----------------------")
print("degradeBy 0 ")
#print(", ")
busyness = random.choice([0,1,2,3,4,5,6,6,6,6,7,7,7,7,8,8,8,9,9])
if (oneBar == 1):
genOnOff(16)
genOnOff(16,(busyness))
print("$")
genNotes(1)
else:
genOnOff(16)
genOnOff(32,(busyness))
print("$")
genNotes(1)
print("# midichan "+str(melodicMidiChan)+" + n (-36)")
melodicMidiChan = melodicMidiChan + 1
print("]")
print("# sunvox")
print("] # sunvox")

114
test.tidal

@ -1,63 +1,59 @@ @@ -1,63 +1,59 @@
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)
some seeds I've liked:
1493546251137461290
1781197463452869364
14959707246264745
1411204103099713935
1157315305561367902
2275918688827233254
2209526836267835322 -- electro-ish
644793890351458335
803051260356546356
1061676950143263647
-- seed: -1061676950143263647
cps = (114/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
-- four to the floor
(#gain 1) $ struct "[t*4]" $ n "0" # midichan 0,
-- kick -----------------
degradeBy 0
$ every 3
(
bite 8 "{6*4 0*2 5*2 5*2 }%8"
)
$ struct "[t(2,4)]"
$ n 0 # midichan 0,
-- hh -----------------
degradeBy 0
$ struct "{1001110110100101}%16"
$ n 0 # midichan 1,
-- sd -----------------
degradeBy 0
$ struct "[t(5,8)]"
$ n 0 # midichan 2,
-- cp -----------------
degradeBy 0
$ struct "[t(7,8)]"
$ n 0 # midichan 3,
-- ? -----------------
degradeBy 0
$ every 3
(
bite 4 "{0*2 0*2 0*1 1*4 0*1 0*4 0*1 2*4 0*1 3*1 1*4 0*4 4*1 }%4"
)
$ every 4
(
bite 4 "{3*2 3*4 2*4 3*1 0*4 3*1 3*1 4*1 4*2 3*4 0*1 1*4 1*4 }%4"
)
$ struct "{1111000101111000}%16"
$ n 0 # midichan 4,
-----------------------
degradeBy 0
$ struct "{1101111111110111}%16"
$
n "{22 8 22 10 2 9 11 12 8 2 0 0 10 17 3 4 }%16"
# midichan 7 + n (-36)
] # sunvox

Loading…
Cancel
Save