1 /*
2 * WalshHadamard.cpp
3 * xSC3ExtPlugins-Universal
4 *
5 * Created by Nick Collins on 10/04/2009.
6 * Copyright 2009 Nick Collins. All rights reserved.
7 *
8 */
9
10 ///#include "WalshHadamard.h"
11 #include "NCAnalysis.h"
12
13
14
15 //find maximum value within last x blocks
16 struct WalshHadamard : public Unit {
17 //float * store;
18 int m_log2, m_size, m_count; //
19 float * m_data;
20 };
21
22
23
24 extern "C"
25 {
26 //required interface functions
27 void WalshHadamard_next(WalshHadamard *unit, int wrongNumSamples);
28 void WalshHadamard_Ctor(WalshHadamard *unit);
29 void WalshHadamard_Dtor(WalshHadamard *unit);
30 }
31
32
33
34 //from music DSP list site: http://www.musicdsp.org/showArchiveComment.php?ArchiveID=18
35
36 void inline wht_bfly (float& a, float& b);
37 int inline l2 (long x);
38 void FWHT(float * data, int log2);
39
wht_bfly(float & a,float & b)40 void inline wht_bfly (float& a, float& b)
41 {
42 float tmp = a;
43 a += b;
44 b = tmp - b;
45 }
46
47 // just a integer log2
l2(long x)48 int inline l2 (long x)
49 {
50 int l2;
51 for (l2 = 0; x > 0; x >>=1)
52 {
53 ++ l2;
54 }
55
56 return (l2);
57 }
58
59 ////////////////////////////////////////////
60 // Fast in-place Walsh-Hadamard Transform //
61 ////////////////////////////////////////////
62
FWHT(float * data,int log2)63 void FWHT(float * data, int log2)
64 {
65 for (int i = 0; i < log2; ++i) {
66 for (int j = 0; j < (1 << log2); j += 1 << (i+1)) {
67
68 for (int k = 0; k < (1 << i); ++k) {
69 wht_bfly (data [j + k], data [j + k + (1 << i)]);
70 }
71
72 }
73 }
74 }
75
76
WalshHadamard_Ctor(WalshHadamard * unit)77 void WalshHadamard_Ctor( WalshHadamard* unit ) {
78
79 //int msamp= (int) ZIN0(1);
80 unit->m_size= 64;
81 unit->m_log2 = l2 (unit->m_size) - 1;
82 unit->m_data= (float*)RTAlloc(unit->mWorld, unit->m_size * sizeof(float));
83
84 unit->m_count=0;
85
86 SETCALC(WalshHadamard_next);
87
88 }
89
WalshHadamard_Dtor(WalshHadamard * unit)90 void WalshHadamard_Dtor(WalshHadamard *unit) {
91 RTFree(unit->mWorld, unit->m_data);
92 }
93
WalshHadamard_next(WalshHadamard * unit,int inNumSamples)94 void WalshHadamard_next( WalshHadamard *unit, int inNumSamples ) {
95
96 int j;
97 float *in = IN(0);
98 float* out = OUT(0);
99
100 //float *out = ZOUT(0);
101
102 //only to be used at .kr
103 //printf("samp to calc %d", inNumSamples);
104
105 //come back to while loop
106 // int siz = unit->m_size; //unit->mWorld->mFullRate.mBufLength;
107 // int left= siz- unit->m_count;
108
109 //ASSUMES block size of 64!
110
111 float * data= unit->m_data;
112
113 for(j=0; j<inNumSamples; ++j) {
114 data[j] = in[j];
115 }
116
117
118 //forwards WH
119 FWHT(data, unit->m_log2);
120
121 int which= ZIN0(1);
122
123 //processing (zero every other one)
124 for(j=0; j<which; ++j) {
125 //data[2*j+1] =0.0;
126 data[j] =0.0;
127 }
128
129 //inverse WH
130 FWHT(data, unit->m_log2);
131
132 //output
133 for(j=0; j<inNumSamples; ++j) {
134 out[j] = data[j]*0.015625;
135 }
136
137 // unit->m_count= left;
138
139 }
140
141
loadWalshHadamard(InterfaceTable * inTable)142 void loadWalshHadamard(InterfaceTable *inTable)
143 {
144
145 //ft= inTable;
146
147 DefineDtorCantAliasUnit(WalshHadamard);
148
149 }
150
151 //void datafun( WalshHadamard *unit) {
152 //
153 //}
154