github.com/noriah/catnip@v1.8.5/dsp/window/window.go (about) 1 // Package window provides Window Functions for singnal analysis 2 // 3 // See https://wikipedia.org/wiki/Window_function 4 package window 5 6 import "math" 7 8 // Function is a function that will do window things for you on a slice 9 type Function func(buf []float64) 10 11 // Rectangle is just do nothing 12 func Rectangle() Function { 13 return func(buf []float64) { 14 // do nothing 15 } 16 } 17 18 // CosSum modifies the buffer to conform to a cosine sum window following a0 19 func CosSum(a0 float64) Function { 20 return func(buf []float64) { 21 size := len(buf) 22 a1 := 1.0 - a0 23 coef := 2.0 * math.Pi / float64(size) 24 for n := 0; n < size; n++ { 25 buf[n] *= (a0 - (a1 * math.Cos(coef*float64(n)))) 26 } 27 } 28 } 29 30 // sinc(x) = sin(pi * x) / (pi * x) 31 func sinc(x float64) float64 { 32 if x == 0.0 { 33 return 0.0 34 } 35 piX := math.Pi * x 36 return math.Sin(piX) / piX 37 } 38 39 // Lanczos modifies the buffer to a Lanczos window 40 // 41 // w[n] = sinc((2n / N) - 1) 42 // 43 // N = size 44 // n = element 45 // k = 2 / N 46 // 47 // buf[n] = sinc(kn - 1) 48 // 49 // https://www.wikiwand.com/en/Window_function#/Other_windows 50 func Lanczos() Function { 51 return func(buf []float64) { 52 k := 2.0 / float64(len(buf)) 53 for n := range buf { 54 buf[n] *= sinc((k * float64(n)) - 1.0) 55 } 56 } 57 } 58 59 // HammingConst is the hamming window constant 60 const HammingConst = 25.0 / 46.0 61 62 // Hamming modifies the buffer to a Hamming window 63 func Hamming() Function { 64 return CosSum(HammingConst) 65 } 66 67 // Hann modifies the buffer to a Hann window 68 func Hann() Function { 69 return CosSum(0.5) 70 } 71 72 // Bartlett modifies the buffer to a Bartlett window 73 func Bartlett() Function { 74 return func(buf []float64) { 75 N := float64(len(buf)) 76 for n := range buf { 77 buf[n] *= (1.0 - (math.Abs(((2.0 * float64(n)) - N) / N))) 78 } 79 } 80 } 81 82 // Blackman modifies the buffer to a Blackman window 83 // 84 // N = size 85 // n = element 86 // a = 0.16 87 // a_0 = (1 - a) / 2 88 // a_1 = 1 / 2 89 // a_2 = a / 2 90 // w[n] = a_0 - a_1 * cos((2 * pi * n) / N) + a_2 * cos((4 * pi * n) / N) 91 func Blackman() Function { 92 return func(buf []float64) { 93 N := float64(len(buf)) 94 twoPi := 2.0 * math.Pi 95 96 for n := range buf { 97 twoPiX := twoPi * (float64(n) / N) 98 buf[n] *= 0.42 - (0.5 * math.Cos(twoPiX)) + (0.08 * math.Cos(2.0*twoPiX)) 99 } 100 } 101 } 102 103 // PlanckTaper modifies the buffer to a Planck-taper window 104 // 105 // not sure how i got this 106 func PlanckTaper(e float64) Function { 107 return func(buf []float64) { 108 size := len(buf) 109 eN := e * float64(size) 110 111 buf[0] *= 0 112 for n := 1; n < int(eN); n++ { 113 buf[n] *= 1.0 / (1.0 + math.Exp((eN/float64(n))-(eN/(eN-float64(n))))) 114 } 115 116 for n := 1; n <= size/2; n++ { 117 buf[size-n] *= buf[n-1] 118 } 119 } 120 }