{
   "is_private" : null,
   "id" : "1-5bD",
   "code" : "// more explanation at https://technogems.blogspot.com/2019/05/walsh-hadamart-transformations-in.html\r\n(\r\nvar walshfun;\r\nvar walshspectrum = Array.newClear(256).fill(0);\r\nvar total_result = [];\r\nvar resultbuffer = Buffer.new(s, 256*100*256*2);\r\n\r\ns.waitForBoot({\r\n    s.freeAllBuffers;\r\n    s.sync;\r\n\r\n    ~walsh_transform = {\r\n        | values, rescale=true|\r\n        var number = values.size;\r\n        var output = Array.newClear(number);\r\n        var temp = Array.newClear(number);\r\n        var scale = 1.0;\r\n        if ((number.nextPowerOfTwo != number), {\r\n            \"Error: length of values must be power of two.\".postln;\r\n            nil ;\r\n        }, /*else*/ {\r\n            /* Mainumber loop. Iteratively compute the hadamard transform */\r\n            var level = 1;\r\n            var stage = 2;\r\n            var work = values;\r\n            number.do({\r\n                |i|\r\n                if ((i.even), {\r\n                    work[i] = work[i] + work[i+1];\r\n                    work[i+1] = work[i] - (2*work[i+1]);\r\n                });\r\n            });\r\n\r\n            2.for(number.log2.ceil, {\r\n                |stage|\r\n                var m = 2.pow(level);\r\n                var jj = 0;\r\n                var k = 0;\r\n\r\n                while ({k < (number-1)}, {\r\n                    jj.forBy(jj+m-2, 2, {\r\n                        |j|\r\n                        output[k] = work[j] + work[j+m];\r\n                        output[k+1] = work[j] - work[j+m];\r\n                        output[k+2] = work[j+1] - work[j+m+1];\r\n                        output[k+3] = work[j+1] + work[j+m+1];\r\n                        k = k + 4;\r\n                    });\r\n\r\n                    jj = jj + (2*m);\r\n                });\r\n\r\n                // swap to prepare for next iteration\r\n                temp = work;\r\n                work = output;\r\n                output = temp;\r\n\r\n                level = level + 1;\r\n            });\r\n\r\n            if (rescale, {\r\n                work/number;\r\n            }, {\r\n                work;\r\n            });\r\n        });\r\n    };\r\n\r\n    // listen to the base functions (nothing spectacular here! they sound like PWM as expected)\r\n    total_result = 256.collect({\r\n        | walshidx |\r\n        var hundred_copies = [];\r\n        var localspectrum = walshspectrum.copy();\r\n        localspectrum[walshidx] = 1;\r\n        localspectrum = ~walsh_transform.value(values:localspectrum, rescale:false); // inverse transform\r\n        hundred_copies = 100.collect({\r\n            localspectrum;\r\n        }).flatten;\r\n        (hundred_copies*0.01);\r\n    });\r\n    total_result = total_result.flatten();\r\n    // now turn it into a stereo signal\r\n    resultbuffer = Buffer.loadCollection(s, total_result.stutter(2)/2, 2);\r\n\r\n    s.sync;\r\n\r\n    resultbuffer.play;\r\n\r\n});\r\n)",
   "labels" : [
      "pwm",
      "mathematics",
      "transform",
      "walshhadamard",
      "square wave"
   ],
   "ancestor_list" : [],
   "description" : "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.",
   "author" : "56228375",
   "name" : "Walsh-Hadamart transformations in supercollider"
}
