// title: creating rhythms // author: Fredrik Olofsson // description: // from the book 'Creating Rhythms' by Stefan Hollos & J. Richard Hollos // http://abrazol.com/books/rhythm1 // ported from c to supercollider // related classes: Bjorklund // code: /* * COPYRIGHT * * markovgen.c * Copyright (C) 2014 Exstrom Laboratories LLC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * A copy of the GNU General Public License is available on the internet at: * http://www.gnu.org/copyleft/gpl.html * * or you can write to: * * The Free Software Foundation, Inc. * 675 Mass Ave * Cambridge, MA 02139, USA * * Exstrom Laboratories LLC contact: * stefan(AT)exstrom.com * * Exstrom Laboratories LLC * Longmont, CO 80503, USA * */ //ported to supercollider oct2017 //------------------------------------------------------------------------ // comp // generates all compositions of n //------------------------------------------------------------------------ ( ~comp= {|n| var res= List.new; var parts= Array.newClear(n-1); var compose= {|n, p, m| if(n==0, { res.add(parts.copyRange(0, m-1)++p); }, { parts[m]= p; compose.(n-1, 1, m+1); compose.(n-1, p+1, m); }); }; compose.(n-1, 1, 0); res; }; ) ~comp.(4).do{|x| x.postln}; ~comp.(5).do{|x| x.postln}; ~comp.(6).do{|x| x.postln}; ~comp.(7).do{|x| x.postln}; //------------------------------------------------------------------------ // compm // generates all compositions of n into m parts //------------------------------------------------------------------------ ( ~compm= {|n, m| var res= List.new; var parts= Array.newClear(n-1); var mp= m-1; var compose= {|n, p, m| if(n==0, { if(m==mp, { res.add(parts.copyRange(0, m-1)++p); }); }, { if(m0}, { p= mp*(1/np); if(1.0.randn, { if((n%l)==0, { res.add(b.copyRange(1, n)); }); }, { b[k]= b[k-l]; if(b[k]==1, { neckbin.(k+1, l); b[k]= 0; neckbin.(k+1, k); }, { neckbin.(k+1, l); }); }); }; b[0]= 1; neckbin.(1, 1); res; }; ) ~neck.(4).do{|x| x.postln}; ~neck.(5).do{|x| x.postln}; ~neck.(6).do{|x| x.postln}; //------------------------------------------------------------------------ // neckm // generates all binary necklaces of length n with m ones //------------------------------------------------------------------------ ( ~neckm= {|n, n1| var res= List.new; var b= Array.newClear(n+1); var neckbin= {|k, l, m| if(k>n, { if((n%l)==0 and:{m==n1}, { res.add(b.copyRange(1, n)); }); }, { b[k]= b[k-l]; if(b[k]==1, { neckbin.(k+1, l, m+1); b[k]= 0; neckbin.(k+1, k, m); }, { neckbin.(k+1, l, m); }); }); }; b[0]= 1; neckbin.(1, 1, 0); res; }; ) ~neckm.(4, 2).do{|x| x.postln}; ~neckm.(8, 2).do{|x| x.postln}; ~neckm.(8, 4).do{|x| x.postln}; //------------------------------------------------------------------------ // necka // generates binary necklaces of length n with allowed parts pi //------------------------------------------------------------------------ ( ~necka= {|n ...p| var res= List.new; var b= Array.newClear(n+1); var aparts= p; var allowed= {|p| aparts.includes(p)}; var neckbin= {|k, l, p| if(k>n, { if((n%l)==0 and:{allowed.(p) and:{p<=n}}, { res.add(b.copyRange(1, n)); }); }, { b[k]= b[k-l]; if(b[k]==1, { if(allowed.(p) or:{k==1}, {neckbin.(k+1, l, 1)}); b[k]= 0; neckbin.(k+1, k, p+1); }, { neckbin.(k+1, l, p+1); }); }); }; b[0]= 1; neckbin.(1, 1, 1); res; }; ) ~necka.(4, 2, 3, 4).do{|x| x.postln}; ~necka.(8, 2, 3, 4).do{|x| x.postln}; ~necka.(8, 4, 1).do{|x| x.postln}; //------------------------------------------------------------------------ // neckam // generates binary necklaces of length n with m ones and allowed parts pi //------------------------------------------------------------------------ ( ~neckam= {|n, n1 ...p| var res= List.new; var b= Array.newClear(n+1); var aparts= p; var allowed= {|p| aparts.includes(p)}; var neckbin= {|k, l, m, p| if(k>n, { if((n%l)==0 and:{allowed.(p) and:{p<=n and:{m==n1}}}, { res.add(b.copyRange(1, n)); }); }, { b[k]= b[k-l]; if(b[k]==1, { if(allowed.(p) or:{k==1}, {neckbin.(k+1, l, m+1, 1)}); b[k]= 0; neckbin.(k+1, k, m, p+1); }, { neckbin.(k+1, l, m, p+1); }); }); }; b[0]= 1; neckbin.(1, 1, 0, 1); res; }; ) ~neckam.(8, 4, 1, 3).do{|x| x.postln}; ~neckam.(16, 5, 2, 3, 4).do{|x| x.postln}; //------------------------------------------------------------------------ // part // generates all partitions of n //------------------------------------------------------------------------ ( ~part= {|n| var res= List.new; var parts= Array.newClear(n-1); var partitions= {|n, p, m| if(n==0, { res.add(parts.copyRange(0, m-1)++p); }, { if(n>0, { parts[m]= p; partitions.(n-p, p, m+1); partitions.(n-1, p+1, m); }); }); }; partitions.(n-1, 1, 0); res; }; ) ~part.(4).do{|x| x.postln}; ~part.(5).do{|x| x.postln}; ~part.(6).do{|x| x.postln}; //------------------------------------------------------------------------ // partm // generates all partitions of n into m parts //------------------------------------------------------------------------ ( ~partm= {|n, m| var res= List.new; var parts= Array.newClear(n-1); var mp= m-1; var partitions= {|n, p, m| if(n==0, { if(m==mp, { res.add(parts.copyRange(0, m-1)++p); }); }, { if(n>0, { if(m0, { if(allowed.(p), { parts[m]= p; partitions.(n-p, p, m+1); }); partitions.(n-1, p+1, m); }); }); }; partitions.(n-1, 1, 0); res; }; ) ~parta.(8, 2, 3).do{|x| x.postln}; ~parta.(8, 1, 4).do{|x| x.postln}; //------------------------------------------------------------------------ // partam // generates all partitions of n with m parts from the set (p1 p2 ...) //------------------------------------------------------------------------ ( ~partam= {|n, m ...p| var res= List.new; var parts= Array.newClear(n-1); var mp= m-1; var aparts= p; var allowed= {|p| aparts.includes(p)}; var partitions= {|n, p, m| if(n==0, { if(m==mp and:{allowed.(p)}, { res.add(parts.copyRange(0, m-1)++p); }); }, { if(n>0, { if(m=0 // to generate all permutations they must be ordered a10 and:{a[i]>=a[i+1]}}, { i= i-1; }); if(i==0, { running= false; }, { j= n; while({a[i]>=a[j]}, { j= j-1; }); m= a[j]; a[j]= a[i]; a[i]= m; j= i+1; k= n; while({jn, { if((n%l)==0, { l.do{|k| dbs[idbs+k]= if(b[k+1]==0, {0}, {1}); }; idbs= idbs+l; }); }, { b[k]= b[k-l]; if(b[k]==1, { neckbin.(k+1, l); b[k]= 0; neckbin.(k+1, k); }, { neckbin.(k+1, l); }); }); }; b[0]= 1; dbs= Array.newClear(ndbs); neckbin.(1, 1); dbs; }; ) ~debruijn.(3).do{|x| x.postln}; ~debruijn.(4).do{|x| x.postln}; //------------------------------------------------------------------------ // b2int // reads binary strings and converts them to interval notation //------------------------------------------------------------------------ ( ~b2int= {|line| var res= List.new; var nbit= line.size; var k, j= 0; while({jb, { res.add(1); b= b+q; }, { res.add(0); a= a+p; }); if(a==b and:{i 2^m-1 //------------------------------------------------------------------------ ( ~pfold= {|n, m, f| var res= List.new; var i= 1, j, k; var oddeven= {|n, a, b| //finds a and b such that n= 2^a*(2*b+1) var k= 0, l; l= n&(0-n); b= (n/l-1).div(2); while({l>1}, { l= l>>1; k= k+1; }); [k, b]; }; while({i<=n}, { #k, j= oddeven.(i, k, j); k= k%m; b= if(f&(1<0, 1, 0); if((2*j+1)%4>1, {b= 1-b}); res.add(b); i= i+1; }); res; }; ) ~pfold.(15, 4, 1); ~pfold.(31, 5, 0); ~pfold.(3, 4, 5); ~pfold.(4, 5, 6); //------------------------------------------------------------------------ // rndint // generates random numbers with specified correlation // m= range of numbers, 0 to m // s= starting number, 0 to m // c= degree of correlation // 0= total correlation (all numbers= s) // m= no correlation (each number is independent) // n= how many random numbers to generate //------------------------------------------------------------------------ ( ~rndint= {|m, s, c, n| var res= List.new; var i= 0, j; while({i0, { j= m; while({j>(m-c)}, { k= 1/j; if(1.0.rand<(s*k), {s= s-1}); j= j-1; }); k= 1/2; j= 0; while({j