fixing cent deviation sign bug and adding path finder for rising version and other tweaks

dev
mwinter 5 months ago
parent 433678463f
commit edc2f1b3a0

@ -2,7 +2,7 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 89,
"id": "806f6f69-1e0b-4d34-aac9-695c8531cdb1", "id": "806f6f69-1e0b-4d34-aac9-695c8531cdb1",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
@ -79,7 +79,7 @@
"def edges(chords, min_symdiff, max_symdiff, max_chord_size): \n", "def edges(chords, min_symdiff, max_symdiff, max_chord_size): \n",
"\n", "\n",
" def reverse_movements(movements):\n", " def reverse_movements(movements):\n",
" return {value['destination']:{'destination':key, 'cent_difference':value['cent_difference']} for key, value in movements.items()}\n", " return {value['destination']:{'destination':key, 'cent_difference':value['cent_difference'] * -1} for key, value in movements.items()}\n",
"\n", "\n",
" def is_directly_tunable(intersection, diff):\n", " def is_directly_tunable(intersection, diff):\n",
" # this only works for now when intersection if one element - need to fix that\n", " # this only works for now when intersection if one element - need to fix that\n",
@ -166,7 +166,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 214,
"id": "4e3ef738-7f64-47c3-9129-0450fd031375", "id": "4e3ef738-7f64-47c3-9129-0450fd031375",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
@ -180,17 +180,17 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 215,
"id": "aea5215c-8551-4685-b761-11c2dc74cf22", "id": "aea5215c-8551-4685-b761-11c2dc74cf22",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"text/plain": [ "text/plain": [
"144" "260"
] ]
}, },
"execution_count": 7, "execution_count": 215,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -198,6 +198,7 @@
"source": [ "source": [
"from random import choice, choices\n", "from random import choice, choices\n",
"\n", "\n",
"# This is for the static version\n",
"def stochastic_hamiltonian(graph):\n", "def stochastic_hamiltonian(graph):\n",
" \n", " \n",
" def movement_size_weights(edges):\n", " def movement_size_weights(edges):\n",
@ -245,10 +246,12 @@
"\n", "\n",
" for e in edges:\n", " for e in edges:\n",
" yield 10 if not has_voice_crossing(e) else 0\n", " yield 10 if not has_voice_crossing(e) else 0\n",
"\n",
" def is_bass_rooted(chord):\n",
" return max([sum(abs(p) for p in collapse_pitch(pitch_difference(chord[0], p))) for p in chord[1:]]) == 1\n",
" \n", " \n",
" check_graph = graph.copy()\n", " check_graph = graph.copy()\n",
" #next_node = choice(list(graph.nodes()))\n", " next_node = choice([node for node in graph.nodes() if is_bass_rooted(node)])\n",
" next_node = list(graph.nodes())[0]\n",
" check_graph.remove_node(next_node)\n", " check_graph.remove_node(next_node)\n",
" for node in graph.nodes(data=True):\n", " for node in graph.nodes(data=True):\n",
" node[1]['count'] = 1\n", " node[1]['count'] = 1\n",
@ -280,6 +283,30 @@
"len(path)" "len(path)"
] ]
}, },
{
"cell_type": "code",
"execution_count": 25,
"id": "ac9e15be-5495-405c-9ce4-ae40d97c7814",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def is_super_compact(chord):\n",
" return max([sum(abs(p) for p in collapse_pitch(pitch_difference(c[0], c[1]))) for c in combinations(chord, 2)]) == 1\n",
" \n",
"[node for node in graph.nodes() if is_super_compact(node)]"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 11,
@ -372,6 +399,189 @@
"source": [ "source": [
"lprun -f edge_data edges(chord_set, 3, 3, 4)" "lprun -f edge_data edges(chord_set, 3, 3, 4)"
] ]
},
{
"cell_type": "code",
"execution_count": 180,
"id": "a76dc0f3-02e2-4739-9014-b53d3a590e3d",
"metadata": {},
"outputs": [],
"source": [
"dims = (2, 3, 5, 7, 11)\n",
"root = (0, 0, 0, 0, 0)\n",
"chord = (root,)\n",
"chord_set = chords(chord, root, 3, 3)\n",
"graph = generate_graph(chord_set, 2, 2, 3)"
]
},
{
"cell_type": "code",
"execution_count": 213,
"id": "6e4ecb10-344b-4721-b2f4-68de91d712db",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"((4, 0, 0, 0, -1), (3, 0, -1, 0, 0), (0, 0, 0, 0, 0))\n",
"0\n"
]
},
{
"data": {
"text/plain": [
"144"
]
},
"execution_count": 213,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from random import choice, choices\n",
"\n",
"# This is for the rising version / yitgadal\n",
"def stochastic_hamiltonian(graph):\n",
" \n",
" def movement_size_weights(edges):\n",
" \n",
" def max_cent_diff(edge):\n",
" res = max([v for val in edge[2]['movements'].values() if (v:=val['cent_difference']) is not None])\n",
" return res\n",
" \n",
" def min_cent_diff(edge):\n",
" res = [v for val in edge[2]['movements'].values() if (v:=val['cent_difference']) is not None]\n",
" res.remove(0)\n",
" return min(res)\n",
" \n",
" for e in edges:\n",
" yield 1000 if ((max_cent_diff(e) < 175) and (min_cent_diff(e)) >= 0) else 1\n",
"\n",
" def hamiltonian_weights(edges):\n",
" for e in edges:\n",
" yield 10 if e[1] not in [path_edge[0] for path_edge in path] else 1 / graph.nodes[e[1]]['count']\n",
" \n",
" def contrary_motion_weights(edges):\n",
"\n",
" def is_contrary(edge):\n",
" cent_diffs = [v for val in edge[2]['movements'].values() if (v:=val['cent_difference']) is not None]\n",
" cent_diffs.sort()\n",
" return (cent_diffs[0] < 0) and (cent_diffs[1] == 0) and (cent_diffs[2] > 0)\n",
"\n",
" for e in edges:\n",
" yield 2 if is_contrary(e) else 1\n",
" \n",
" def is_directly_tunable_weights(edges):\n",
" for e in edges:\n",
" yield 10 if e[2]['is_directly_tunable'] else 0\n",
"\n",
" def transposition_weight(edges):\n",
" for e in edges:\n",
" yield 1000 if 0 <= hs_array_to_cents(e[2]['transposition']) < 100 else 0\n",
"\n",
" def is_sustained_voice(edges, voice):\n",
" \n",
" def is_sustained(edge):\n",
" source = list(edge[0])\n",
" ordered_source = sorted(source, key=hs_array_to_fr) \n",
" destination = [transpose_pitch(edge[2]['movements'][p]['destination'], edge[2]['transposition']) for p in source]\n",
" ordered_destination = sorted(destination, key=hs_array_to_fr)\n",
" return ordered_source[voice] == ordered_destination[voice]\n",
"\n",
" for e in edges:\n",
" yield 10 if is_sustained(e) else 0\n",
"\n",
" def voice_crossing_weights(edges):\n",
" \n",
" def has_voice_crossing(edge):\n",
" source = list(edge[0])\n",
" ordered_source = sorted(source, key=hs_array_to_fr) \n",
" source_order = [ordered_source.index(p) for p in source]\n",
" destination = [transpose_pitch(edge[2]['movements'][p]['destination'], edge[2]['transposition']) for p in source]\n",
" ordered_destination = sorted(destination, key=hs_array_to_fr)\n",
" destination_order = [ordered_destination.index(p) for p in destination]\n",
" return source_order != destination_order\n",
"\n",
" for e in edges:\n",
" yield 10 if not has_voice_crossing(e) else 0\n",
"\n",
" def is_bass_rooted(chord):\n",
" return max([sum(abs(p) for p in collapse_pitch(pitch_difference(chord[0], p))) for p in chord[1:]]) == 1\n",
" \n",
" check_graph = graph.copy()\n",
" #next_node = choice([node for node in graph.nodes() if is_bass_rooted(node)])\n",
" next_node = choice(list(graph.nodes()))\n",
" print(next_node)\n",
" check_graph.remove_node(next_node)\n",
" for node in graph.nodes(data=True):\n",
" node[1]['count'] = 1\n",
" path = []\n",
" while (nx.number_of_nodes(check_graph) > 0) and (len(path) < 500):\n",
" out_edges = list(graph.out_edges(next_node, data=True))\n",
" #print([l for l in zip(movement_size_weights(out_edges), hamiltonian_weights(out_edges))])\n",
" factors = [\n",
" movement_size_weights(out_edges), \n",
" hamiltonian_weights(out_edges), \n",
" #contrary_motion_weights(out_edges), \n",
" #is_directly_tunable_weights(out_edges),\n",
" voice_crossing_weights(out_edges),\n",
" #transposition_weight(out_edges)\n",
" #is_sustained_voice(out_edges, 0)\n",
" ]\n",
" weights = [prod(a) for a in zip(*factors)]\n",
" #print(weights)\n",
" edge = choices(out_edges, weights=weights)[0]\n",
" #print(edge)\n",
" #edge = random.choice(out_edges)\n",
" next_node = edge[1]\n",
" node[1]['count'] += 1\n",
" path.append(edge)\n",
" if next_node in check_graph.nodes:\n",
" check_graph.remove_node(next_node)\n",
" print(len(check_graph.nodes()))\n",
" return path\n",
" \n",
"path = stochastic_hamiltonian(graph)\n",
"#for edge in path:\n",
"# print(edge)\n",
"write_chord_sequence(path_to_chords(path, root))\n",
"len(path)"
]
},
{
"cell_type": "code",
"execution_count": 212,
"id": "7b76d848-fe53-4b60-b414-46cfe570f78b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"((4, 0, 0, 0, -1), (2, -1, 0, 0, 0), (0, 0, 0, 0, 0))\n",
"0\n"
]
},
{
"data": {
"text/plain": [
"219"
]
},
"execution_count": 212,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"path = stochastic_hamiltonian(graph)\n",
"#for edge in path:\n",
"# print(edge)\n",
"write_chord_sequence(path_to_chords(path, root))\n",
"len(path)"
]
} }
], ],
"metadata": { "metadata": {

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding: utf-8 # coding: utf-8
# In[1]: # In[89]:
from itertools import chain, combinations, permutations, product from itertools import chain, combinations, permutations, product
@ -76,7 +76,7 @@ def chords(chord, root, min_chord_size, max_chord_size):
def edges(chords, min_symdiff, max_symdiff, max_chord_size): def edges(chords, min_symdiff, max_symdiff, max_chord_size):
def reverse_movements(movements): def reverse_movements(movements):
return {value['destination']:{'destination':key, 'cent_difference':value['cent_difference']} for key, value in movements.items()} return {value['destination']:{'destination':key, 'cent_difference':value['cent_difference'] * -1} for key, value in movements.items()}
def is_directly_tunable(intersection, diff): def is_directly_tunable(intersection, diff):
# this only works for now when intersection if one element - need to fix that # this only works for now when intersection if one element - need to fix that
@ -161,7 +161,7 @@ def write_chord_sequence(path):
file.close() file.close()
# In[2]: # In[214]:
dims = (2, 3, 5, 7, 11) dims = (2, 3, 5, 7, 11)
@ -171,11 +171,12 @@ chord_set = chords(chord, root, 3, 3)
graph = generate_graph(chord_set, 4, 4, 3) graph = generate_graph(chord_set, 4, 4, 3)
# In[7]: # In[215]:
from random import choice, choices from random import choice, choices
# This is for the static version
def stochastic_hamiltonian(graph): def stochastic_hamiltonian(graph):
def movement_size_weights(edges): def movement_size_weights(edges):
@ -224,9 +225,11 @@ def stochastic_hamiltonian(graph):
for e in edges: for e in edges:
yield 10 if not has_voice_crossing(e) else 0 yield 10 if not has_voice_crossing(e) else 0
def is_bass_rooted(chord):
return max([sum(abs(p) for p in collapse_pitch(pitch_difference(chord[0], p))) for p in chord[1:]]) == 1
check_graph = graph.copy() check_graph = graph.copy()
#next_node = choice(list(graph.nodes())) next_node = choice([node for node in graph.nodes() if is_bass_rooted(node)])
next_node = list(graph.nodes())[0]
check_graph.remove_node(next_node) check_graph.remove_node(next_node)
for node in graph.nodes(data=True): for node in graph.nodes(data=True):
node[1]['count'] = 1 node[1]['count'] = 1
@ -258,6 +261,15 @@ write_chord_sequence(path_to_chords(path, root))
len(path) len(path)
# In[25]:
def is_super_compact(chord):
return max([sum(abs(p) for p in collapse_pitch(pitch_difference(c[0], c[1]))) for c in combinations(chord, 2)]) == 1
[node for node in graph.nodes() if is_super_compact(node)]
# In[11]: # In[11]:
@ -275,3 +287,136 @@ chord_set = chords(chord, root, 3, 3)
lprun -f edge_data edges(chord_set, 3, 3, 4) lprun -f edge_data edges(chord_set, 3, 3, 4)
# In[180]:
dims = (2, 3, 5, 7, 11)
root = (0, 0, 0, 0, 0)
chord = (root,)
chord_set = chords(chord, root, 3, 3)
graph = generate_graph(chord_set, 2, 2, 3)
# In[213]:
from random import choice, choices
# This is for the rising version / yitgadal
def stochastic_hamiltonian(graph):
def movement_size_weights(edges):
def max_cent_diff(edge):
res = max([v for val in edge[2]['movements'].values() if (v:=val['cent_difference']) is not None])
return res
def min_cent_diff(edge):
res = [v for val in edge[2]['movements'].values() if (v:=val['cent_difference']) is not None]
res.remove(0)
return min(res)
for e in edges:
yield 1000 if ((max_cent_diff(e) < 175) and (min_cent_diff(e)) >= 0) else 1
def hamiltonian_weights(edges):
for e in edges:
yield 10 if e[1] not in [path_edge[0] for path_edge in path] else 1 / graph.nodes[e[1]]['count']
def contrary_motion_weights(edges):
def is_contrary(edge):
cent_diffs = [v for val in edge[2]['movements'].values() if (v:=val['cent_difference']) is not None]
cent_diffs.sort()
return (cent_diffs[0] < 0) and (cent_diffs[1] == 0) and (cent_diffs[2] > 0)
for e in edges:
yield 2 if is_contrary(e) else 1
def is_directly_tunable_weights(edges):
for e in edges:
yield 10 if e[2]['is_directly_tunable'] else 0
def transposition_weight(edges):
for e in edges:
yield 1000 if 0 <= hs_array_to_cents(e[2]['transposition']) < 100 else 0
def is_sustained_voice(edges, voice):
def is_sustained(edge):
source = list(edge[0])
ordered_source = sorted(source, key=hs_array_to_fr)
destination = [transpose_pitch(edge[2]['movements'][p]['destination'], edge[2]['transposition']) for p in source]
ordered_destination = sorted(destination, key=hs_array_to_fr)
return ordered_source[voice] == ordered_destination[voice]
for e in edges:
yield 10 if is_sustained(e) else 0
def voice_crossing_weights(edges):
def has_voice_crossing(edge):
source = list(edge[0])
ordered_source = sorted(source, key=hs_array_to_fr)
source_order = [ordered_source.index(p) for p in source]
destination = [transpose_pitch(edge[2]['movements'][p]['destination'], edge[2]['transposition']) for p in source]
ordered_destination = sorted(destination, key=hs_array_to_fr)
destination_order = [ordered_destination.index(p) for p in destination]
return source_order != destination_order
for e in edges:
yield 10 if not has_voice_crossing(e) else 0
def is_bass_rooted(chord):
return max([sum(abs(p) for p in collapse_pitch(pitch_difference(chord[0], p))) for p in chord[1:]]) == 1
check_graph = graph.copy()
#next_node = choice([node for node in graph.nodes() if is_bass_rooted(node)])
next_node = choice(list(graph.nodes()))
print(next_node)
check_graph.remove_node(next_node)
for node in graph.nodes(data=True):
node[1]['count'] = 1
path = []
while (nx.number_of_nodes(check_graph) > 0) and (len(path) < 500):
out_edges = list(graph.out_edges(next_node, data=True))
#print([l for l in zip(movement_size_weights(out_edges), hamiltonian_weights(out_edges))])
factors = [
movement_size_weights(out_edges),
hamiltonian_weights(out_edges),
#contrary_motion_weights(out_edges),
#is_directly_tunable_weights(out_edges),
voice_crossing_weights(out_edges),
#transposition_weight(out_edges)
#is_sustained_voice(out_edges, 0)
]
weights = [prod(a) for a in zip(*factors)]
#print(weights)
edge = choices(out_edges, weights=weights)[0]
#print(edge)
#edge = random.choice(out_edges)
next_node = edge[1]
node[1]['count'] += 1
path.append(edge)
if next_node in check_graph.nodes:
check_graph.remove_node(next_node)
print(len(check_graph.nodes()))
return path
path = stochastic_hamiltonian(graph)
#for edge in path:
# print(edge)
write_chord_sequence(path_to_chords(path, root))
len(path)
# In[212]:
path = stochastic_hamiltonian(graph)
#for edge in path:
# print(edge)
write_chord_sequence(path_to_chords(path, root))
len(path)

@ -6,6 +6,7 @@ SynthDef(\string_model, {arg freq, gate = 1, del, sustain, amp, dur, attack, rel
sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq),
Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}),
Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip; Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip;
//note that the delay cuts into the sustain portion of the tone!!!
Out.ar([0, 1], 0.75 * sig1 * amp * EnvGen.kr(Env.dadsr(del, attack, 0.3, 0.9, release, 0.9, -3), gate, doneAction: 2)); Out.ar([0, 1], 0.75 * sig1 * amp * EnvGen.kr(Env.dadsr(del, attack, 0.3, 0.9, release, 0.9, -3), gate, doneAction: 2));
}).add; }).add;
) )
@ -13,7 +14,7 @@ SynthDef(\string_model, {arg freq, gate = 1, del, sustain, amp, dur, attack, rel
( (
var primes, hsArrayToFreq, hsArrayDimDiff, file, seq, phraseLengths, musicData, patterns; var primes, hsArrayToFreq, hsArrayDimDiff, file, seq, phraseLengths, musicData, patterns;
thisThread.randSeed = 1923; thisThread.randSeed = 83924874938;
primes = [2, 3, 5, 7, 11]; primes = [2, 3, 5, 7, 11];
@ -35,14 +36,25 @@ seq = file.readAllString.interpret;
//seq = seq.collect({arg item; item.sort}); //seq = seq.collect({arg item; item.sort});
seq = seq.collect({arg chord, index; seq = seq.collect({arg chord, index;
var ref_ins; var ref_ins;
ref_ins = if(index == 0, {0}, {[seq[index - 1], chord].flop.collect({arg pair; pair[0] == pair[1]}).indexOf(true)}); ref_ins = if(index == 0, {
[0] // this should actually check which is the 'centered' pitch
}, {
[seq[index - 1], chord].postln.flop.collect({arg pair, p; if(pair[0] == pair[1], {p}, {-1})}).postln.removeEvery([-1])
});
chord.collect({arg pitch; chord.collect({arg pitch;
var dimDiff; var dimDiff;
[pitch, [ref_ins, hsArrayDimDiff.value(chord[ref_ins], pitch)]] ref_ins.postln;
if(ref_ins.size == 1, {
[pitch, [ref_ins[0], hsArrayDimDiff.value(chord[ref_ins[0]], pitch)]]
}, {
var min_ref_ins;
min_ref_ins = ref_ins.minItem({arg ins; (chord[ins].drop(1) - pitch.drop(1)).abs.sum});
[pitch, [min_ref_ins.postln, hsArrayDimDiff.value(chord[min_ref_ins], pitch)]]
});
}) })
}); });
seq.do({arg chord; chord; chord.collect({arg pitch; hsArrayToFreq.value(pitch[0])})}); seq.do({arg chord; chord; chord.collect({arg pitch; hsArrayToFreq.value(pitch[0])}).postln});
//seq.postln; //seq.postln;
@ -51,28 +63,33 @@ while({phraseLengths.sum < seq.size}, {phraseLengths = phraseLengths ++ [rrand(1
//phraseLengths.postln; //phraseLengths.postln;
musicData = seq.clumps(phraseLengths).collect({arg subSeq, seqIndex; musicData = seq.clumps(phraseLengths).collect({arg subSeq, seqIndex;
var baseRound, baseDurs, baseDelay, baseSubtract; var baseRound, baseDurs, minDelay, maxDelay, baseSubtract;
baseRound = 0.5; baseRound = 0.5;
//baseDurs = subSeq.size.collect({arg subSeqIndex; if(subSeqIndex != (subSeq.size - 1), {rrand(7.0, 10.0)}, {rrand(10.0, 15.0)})}).round(baseRound);
baseDurs = subSeq.size.collect({arg subSeqIndex; if(subSeqIndex != (subSeq.size - 1), {rrand(5.0, 7.0)}, {rrand(10.0, 15.0)})}).round(baseRound); baseDurs = subSeq.size.collect({arg subSeqIndex; if(subSeqIndex != (subSeq.size - 1), {rrand(5.0, 7.0)}, {rrand(10.0, 15.0)})}).round(baseRound);
baseDelay = rrand(1.0, 2.0); //baseDurs = subSeq.size.collect({arg subSeqIndex; if(subSeqIndex != (subSeq.size - 1), {rrand(5.0, 7.0)}, {rrand(15.0, 20.0)})}).round(baseRound);
baseSubtract = rrand(2.0, 4.0); //maxDelay = rrand(1.0, 3.0);
//maxDelay = 5;
minDelay = 0;
maxDelay = 0;
baseDurs[0] = baseDurs[0] + maxDelay;
baseSubtract = rrand(0.0, 3.0);
subSeq.flop.collect({arg voice, v; subSeq.flop.collect({arg voice, v;
var phrases, freqs, durs, delays, attacks, rels, sustains, amps, refs; var phrases, freqs, durs, delays, attacks, rels, sustains, amps, refs;
phrases = voice.separate({arg a, b; a[0] != b[0]}); phrases = voice.separate({arg a, b; a[0] != b[0]});
freqs = phrases.collect({arg phrase; if(phrase[0][0] != ["Rest"], {48.midicps * pow(2, (v * 2).clip(0, 1)) * hsArrayToFreq.value(phrase[0][0])}, {Rest(0)})}); freqs = phrases.collect({arg phrase; if(phrase[0][0] != ["Rest"], {45.midicps * pow(2, (v * 2).clip(0, 1)) * hsArrayToFreq.value(phrase[0][0])}, {Rest(0)})});
refs = phrases.collect({arg phrase; if(phrase[0][0] != ["Rest"], {phrase[0][1]}, {Rest(0)})}); refs = phrases.collect({arg phrase; if(phrase[0][0] != ["Rest"], {phrase[0][1]}, {Rest(0)})});
durs = baseDurs.clumps(phrases.collect({arg phrase; phrase.size})).collect({arg c; c.sum}); durs = baseDurs.clumps(phrases.collect({arg phrase; phrase.size})).collect({arg c; c.sum});
delays = durs.collect({arg dur; rrand(0.0, 0.0)}).round(baseRound); delays = durs.collect({arg dur, d; if((d == 0) && (refs[d][0] != v), {[rrand(minDelay, maxDelay), 0].wchoose([1, 1].normalizeSum)}, {0})}).round(baseRound);
//delays = durs.collect({arg dur, d; if((d == 0) && (refs[d][0] != v), {[baseDelay, rrand(2.0, 3.0)].wchoose([2, 1].normalizeSum)}, {0})}).round(baseRound); //delays = durs.collect({0}}).round(baseRound);
//delays = durs.collect({arg dur, d; if((d == 0) && (refs[d][0] != v), {baseDelay}, {0})}).round(baseRound);
//durs = durs + delays;
attacks = durs.collect({arg dur, d; if(d == 0, {rrand(3.0, 5.0)}, {rrand(1.0, 3.0)})}).round(baseRound); attacks = durs.collect({arg dur, d; if(d == 0, {rrand(3.0, 5.0)}, {rrand(1.0, 3.0)})}).round(baseRound);
rels = durs.collect({arg dur, d; if(d != (durs.size - 1), {rrand(1.0, 2.0)}, {rrand(3.0, 5.0)})}).round(baseRound); rels = durs.collect({arg dur, d; if(d != (durs.size - 1), {rrand(0.5, 1.0)}, {rrand(3.0, 5.0)})}).round(baseRound);
//sustains = durs.collect({arg dur, d; if(d != (durs.size - 1), {dur - rels[d] - delays[d]}, {dur - rels[d] - delays[d]})}).round(baseRound); sustains = durs.collect({arg dur, d;
//sustains = durs.collect({arg dur, d; if(d != (durs.size - 1), {dur}, {dur - rrand(3.0, 5.0)})}).round(baseRound); if(d != (durs.size - 1), {
sustains = durs.collect({arg dur, d; if(d != (durs.size - 1), {dur - rels[d] - delays[d] - 0.5}, {dur - rels[d] - delays[d] - baseSubtract - rrand(0.0, 2.0)})}).round(baseRound); dur - rels[d]
amps = freqs.collect({rrand(0.6, 0.7) / [1, 2, 2][v]}); }, {
dur - rels[d] - baseSubtract - rrand(0.0, 1.0)})
}).round(baseRound);
amps = freqs.collect({rrand(0.6, 0.7) / [1, 2, 2, 2][v]});
[freqs, durs, attacks, delays, sustains, rels, amps, refs].flop; [freqs, durs, attacks, delays, sustains, rels, amps, refs].flop;
}); });
}).flop.collect({arg voice; voice.flatten}); }).flop.collect({arg voice; voice.flatten});
@ -80,7 +97,7 @@ musicData = seq.clumps(phraseLengths).collect({arg subSeq, seqIndex;
musicData = musicData.collect({arg voice, v; musicData = musicData.collect({arg voice, v;
var clumps; var clumps;
//(v + "~~~~~~~~~~").postln; //(v + "~~~~~~~~~~").postln;
clumps = voice.separate({arg a, b; [true, a[0] != b[0]].wchoose([1, 1].normalizeSum)}); clumps = voice.separate({arg a, b; [true, a[0] != b[0]].wchoose([1, 2].normalizeSum)});
clumps = clumps.collect({arg clump; clumps = clumps.collect({arg clump;
if(clump.size == 1, {clump[0]}, { if(clump.size == 1, {clump[0]}, {
var mergedClump; var mergedClump;
@ -99,6 +116,7 @@ musicData = musicData.collect({arg voice, v;
musicData.collect({arg voice, v; musicData.collect({arg voice, v;
var freqs, durs, attacks, delays, sustains, rels, amps; var freqs, durs, attacks, delays, sustains, rels, amps;
# freqs, durs, attacks, delays, sustains, rels, amps = voice.flop; # freqs, durs, attacks, delays, sustains, rels, amps = voice.flop;
//# durs, attacks, delays, sustains, rels = [durs, attacks, delays, sustains, rels].collect({arg data; data / 16});
Pbind( Pbind(
\instrument, \string_model, \instrument, \string_model,
\freq, Pseq(freqs, 1), \freq, Pseq(freqs, 1),
@ -116,4 +134,4 @@ musicData = musicData.collect({arg voice, v;
~patterns.play ~patterns.play
) )
~patterns.play

@ -14,13 +14,13 @@ formatMusicData = {arg seq;
var freqs, durs, attacks, delays, sustains, rels, amps, refs, res; var freqs, durs, attacks, delays, sustains, rels, amps, refs, res;
# freqs, durs, attacks, delays, sustains, rels, amps, refs = partData.flop; # freqs, durs, attacks, delays, sustains, rels, amps, refs = partData.flop;
durs = (durs / 0.5).round.asInteger; durs = (durs / 0.5).round.asInteger;
sustains = ((sustains + delays + rels) / 0.5).round.asInteger; sustains = ((sustains + rels - 0.5) / 0.5).round.asInteger;
//sustains = (sustains / 0.5).round.asInteger; delays = (delays / 0.5).round.asInteger;
//[durs, sustains, delays, rels].flop.do({arg item; if(item[0] < item[1], {item.postln})}); res = [freqs, durs, delays, sustains, refs].flop.collect({arg data, i;
res = [freqs, durs, sustains, refs].flop.collect({arg data, i; var freq, dur, del, sus, ref;
var freq, dur, sus, ref; # freq, dur, del, sus, ref = data;
# freq, dur, sus, ref = data; del.collect({[-1, ref, i]}) ++ (sus - del).collect({[freq, ref, i]}) ++ (dur - sus).collect({[-1, ref, i]})
sus.collect({[freq, ref, i]}) ++ (dur - sus).collect({[-1, ref, i]}) //sus.collect({[freq, ref, i]}) ++ (dur - sus).collect({[-1, ref, i]})
}).flatten; }).flatten;
if(res.size > maxSize, {maxSize = res.size}); if(res.size > maxSize, {maxSize = res.size});
res res

Loading…
Cancel
Save