Quantcast
Channel: Wouter Hisschemöller » ActionScript
Viewing all articles
Browse latest Browse all 10

Euclidean rhythms update

$
0
0
E(5, 13) pattern

E(5, 13) pattern

There’s an error in the Euclidean rhythms generator I posted in January. A few days ago I got a comment by Thomas pointing out the app generates wrong patterns. And he’s absolutely right.

Here’s an updated version in which I rewrote the algorithm code. I checked it with several patterns and they all came out correct, so hopefully I have it right this time.

The new Flash app

Get Adobe Flash player

Download the source files here.

I didn’t update the download ZIP file in the original post. So if you tire of the regular Euclidean patterns you can still download the old version and use those quirky ‘not quite right’ patterns. :-)

The difference

The difference between the old and new version can be seen in the outcome of the algorithm for a pattern of thirteen steps with five notes. The old version generates as outcome:

E(5, 13) = [x..x..x..x.x.]

while it should be:

E(5, 13) = [x..x.x..x.x..]

and the correct calculation broken down in iterations:

[x][x][x][x][x][.][.][.][.][.][.][.][.]
[x.][x.][x.][x.][x.][.][.][.]
[x..][x..][x..][x.][x.]
[x..x.][x..x.][x..]

It appears the old code stops one iteration too early: The wrong pattern is the same as the one before last iteration. Here’s the ActionScript code of the new version. It might be more compact and optimized, but I find it clearer to follow this way.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package com.hisschemoller.utils
{
   /**
    * @author Wouter Hisschemoller
    * (c) May 18, 2011
    */
   public class EuclidGenerator
   {
       private var _pattern : Vector.<Boolean> = new Vector.<Boolean>( );
 
       public function EuclidGenerator ( total : int, hits : int )
       {
           if ( hits >= total || hits == 1 || hits == 0 )
           {
               _pattern = new Vector.<Boolean>( );
               if ( hits >= total )
               {
                   for ( var i : int = 0; i < total; i ++ )
                   {
                       _pattern.push( true );
                   }
               }
               else if ( total == 1 )
               {
                   _pattern.push( hits == 1 );
               }
               else
               {
                   for ( i = 0; i < total; i ++ )
                   {
                       _pattern.push( false );
                   }
               }
 
               return;
           }
 
           var bigArray : Vector.<Vector.<Boolean>> = new Vector.<Vector.<Boolean>>( );
           for ( i = 0; i < hits; i ++ )
           {
               var boolArray : Vector.<Boolean> = new Vector.<Boolean>( );
               boolArray.push( true );
               bigArray.push( boolArray );
           }
 
           var smallArray : Vector.<Vector.<Boolean>> = new Vector.<Vector.<Boolean>>( );
           for ( i = 0; i < ( total - hits ); i ++ )
           {
               boolArray = new Vector.<Boolean>( );
               boolArray.push( false );
               smallArray.push( boolArray );
           }
 
           _pattern = bjorklund( bigArray, smallArray );
       }
 
       public function get pattern () : Vector.<Boolean>
       {
           return _pattern;
       }
 
       private function bjorklund ( bigArray : Vector.<Vector.<Boolean>>, smallArray : Vector.<Vector.<Boolean>> ) : Vector.<Boolean>
       {
           /** Done, flatten arrays. */
           if ( smallArray.length <= 1 )
           {
               var resultList : Vector.<Boolean> = new Vector.<Boolean>( );
               for ( var i : int = 0; i < bigArray.length; i ++ )
               {
                   for ( var j : int = 0; j < bigArray[ i ].length; j ++ )
                   {
                       resultList.push( bigArray[ i ][ j ] );
                   }
               }
               for ( i = 0; i < smallArray.length; i ++ )
               {
                   for ( j = 0; j < smallArray[ i ].length; j ++ )
                   {
                       resultList.push( smallArray[i][j] );
                   }
               }
               return resultList;
           }
 
           var fullRounds : int = Math.floor( smallArray.length / bigArray.length );
           for ( i = 0; i < fullRounds; i ++ )
           {
               for ( j = 0; j < bigArray.length; j ++ )
               {
                   var sourceBoolArray : Vector.<Boolean> = smallArray[0];
                   for ( var k : int = 0; k < sourceBoolArray.length; k ++ )
                   {
                       bigArray[j].push( sourceBoolArray[k] );
                   }
                   smallArray.splice( 0, 1 );
               }
           }
 
           var remainder : int = smallArray.length % bigArray.length;
           for ( i = 0; i < remainder; i ++ )
           {
               sourceBoolArray = smallArray[0];
               for ( k = 0; k < sourceBoolArray.length; k ++ )
               {
                   bigArray[i].push( sourceBoolArray[k] );
               }
               smallArray.splice( 0, 1 );
           }
 
           /** Split result in two new arrays. */
           var newBigArray : Vector.<Vector.<Boolean>> = new Vector.<Vector.<Boolean>>( );
           var newSmallArray : Vector.<Vector.<Boolean>> = new Vector.<Vector.<Boolean>>( );
           for ( i = 0; i < bigArray.length; i ++ )
           {
               if ( remainder == 0 )
               {
                   newBigArray.push( bigArray[i] );
               }
               else
               {
                   if ( i < remainder )
                   {
                       newBigArray.push( bigArray[i] );
                   }
                   else
                   {
                       newSmallArray.push( bigArray[i] );
                   }
               }
           }
 
           return bjorklund( newBigArray, newSmallArray );
       }
   }
}

Viewing all articles
Browse latest Browse all 10

Latest Images

Trending Articles





Latest Images