on 26 May'19 03:55 in

This code is accompanied by a blog article: https://technogems.blogspot.com/2019/05/walsh-hadamart-transformations-in.html . It's a straightforward implementation of walsh hadamard transformations. The Walsh-Hadamard transform mathematically decomposes a signal into PWM square waves. This is different from the Fourier transform which decomposes signals into sine waves. The Walsh-Hadamard transform also has the cool property that it is its own inverse (applying it twice gives you the original signal back - but scaled with some constant). This code only contains the transformation. It could be an interesting experiment to use this building block for making filters by manipulating the walsh spectrum.

```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```
```// more explanation at https://technogems.blogspot.com/2019/05/walsh-hadamart-transformations-in.html
(
var walshfun;
var walshspectrum = Array.newClear(256).fill(0);
var total_result = [];
var resultbuffer = Buffer.new(s, 256*100*256*2);

s.waitForBoot({
s.freeAllBuffers;
s.sync;

~walsh_transform = {
| values, rescale=true|
var number = values.size;
var output = Array.newClear(number);
var temp = Array.newClear(number);
var scale = 1.0;
if ((number.nextPowerOfTwo != number), {
"Error: length of values must be power of two.".postln;
nil ;
}, /*else*/ {
/* Mainumber loop. Iteratively compute the hadamard transform */
var level = 1;
var stage = 2;
var work = values;
number.do({
|i|
if ((i.even), {
work[i] = work[i] + work[i+1];
work[i+1] = work[i] - (2*work[i+1]);
});
});

2.for(number.log2.ceil, {
|stage|
var m = 2.pow(level);
var jj = 0;
var k = 0;

while ({k < (number-1)}, {
jj.forBy(jj+m-2, 2, {
|j|
output[k] = work[j] + work[j+m];
output[k+1] = work[j] - work[j+m];
output[k+2] = work[j+1] - work[j+m+1];
output[k+3] = work[j+1] + work[j+m+1];
k = k + 4;
});

jj = jj + (2*m);
});

// swap to prepare for next iteration
temp = work;
work = output;
output = temp;

level = level + 1;
});

if (rescale, {
work/number;
}, {
work;
});
});
};

// listen to the base functions (nothing spectacular here! they sound like PWM as expected)
total_result = 256.collect({
| walshidx |
var hundred_copies = [];
var localspectrum = walshspectrum.copy();
localspectrum[walshidx] = 1;
localspectrum = ~walsh_transform.value(values:localspectrum, rescale:false); // inverse transform
hundred_copies = 100.collect({
localspectrum;
}).flatten;
(hundred_copies*0.01);
});
total_result = total_result.flatten();
// now turn it into a stereo signal

s.sync;

resultbuffer.play;

});
)```
raw 2784 chars (focus & ctrl+a+c to copy)
reception