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