comparison projects/heavy/samphold/SignalSamphold.h @ 160:5bcf04234f80 heavy-updated

- added -std=c99 to Makefile for user-supplied C files (required for heavy files) - changed heavy core render.cpp file to use latest API and removed all redundant functions (e.g. foleyDesigner/touchkey stuff) - use build_pd.sh to compile and run pd files (-h for usage instructions)
author chnrx <chris.heinrichs@gmail.com>
date Thu, 05 Nov 2015 18:58:26 +0000
parents
children
comparison
equal deleted inserted replaced
159:1e7db6610600 160:5bcf04234f80
1 /**
2 * Copyright (c) 2014, 2015, Enzien Audio Ltd.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #ifndef _SIGNAL_SAMPHOLD_H_
18 #define _SIGNAL_SAMPHOLD_H_
19
20 #include "HvBase.h"
21
22 typedef struct SignalSamphold {
23 hv_bufferf_t s;
24 } SignalSamphold;
25
26 hv_size_t sSamphold_init(SignalSamphold *o);
27
28 static inline void __hv_samphold_f(SignalSamphold *o, hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
29 #if HV_SIMD_AVX
30 #warning __hv_samphold_f() not implemented
31 #elif HV_SIMD_SSE
32 switch (_mm_movemask_ps(bIn1)) {
33 default:
34 case 0x0: *bOut = o->s; break;
35 case 0x1: {
36 *bOut = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(0,0,0,0));
37 o->s = *bOut;
38 break;
39 }
40 case 0x2: {
41 const __m128 x = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(1,1,1,1));
42 *bOut = _mm_blend_ps(o->s, x, 0xE);
43 o->s = x;
44 break;
45 }
46 case 0x3: {
47 const __m128 x = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(1,1,1,1));
48 *bOut = _mm_blend_ps(bIn0, x, 0xC);
49 o->s = x;
50 break;
51 }
52 case 0x4: {
53 const __m128 x = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(2,2,2,2));
54 *bOut = _mm_blend_ps(o->s, x, 0xC);
55 o->s = x;
56 break;
57 }
58 case 0x5: {
59 *bOut = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(2,2,0,0));
60 o->s = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(2,2,2,2));
61 break;
62 }
63 case 0x6: {
64 const __m128 x = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(2,2,1,0));
65 *bOut = _mm_blend_ps(o->s, x, 0xE);
66 o->s = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(2,2,2,2));
67 break;
68 }
69 case 0x7: {
70 const __m128 x = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(2,2,2,2));
71 *bOut = _mm_blend_ps(bIn0, x, 0x8);
72 o->s = x;
73 break;
74 }
75 case 0x8: {
76 const __m128 x = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,3,3,3));
77 *bOut = _mm_blend_ps(o->s, x, 0x8);
78 o->s = x;
79 break;
80 }
81 case 0x9: {
82 *bOut = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,0,0,0));
83 o->s = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,3,3,3));
84 break;
85 }
86 case 0xA: {
87 const __m128 x = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,1,1,0));
88 *bOut = _mm_blend_ps(o->s, x, 0xE);
89 o->s = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,3,3,3));
90 break;
91 }
92 case 0xB: {
93 *bOut = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,1,1,0));
94 o->s = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,3,3,3));
95 break;
96 }
97 case 0xC: {
98 *bOut = _mm_blend_ps(o->s, bIn0, 0xC);
99 o->s = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,3,3,3));
100 break;
101 }
102 case 0xD: {
103 *bOut = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,2,0,0));
104 o->s = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,3,3,3));
105 break;
106 }
107 case 0xE: {
108 *bOut = _mm_blend_ps(o->s, bIn0, 0xE);
109 o->s = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,3,3,3));
110 break;
111 }
112 case 0xF: {
113 *bOut = bIn0;
114 o->s = _mm_shuffle_ps(bIn0, bIn0, _MM_SHUFFLE(3,3,3,3));
115 break;
116 }
117 }
118 #elif HV_SIMD_NEON
119 uint32x4_t mmA = vandq_u32(
120 vreinterpretq_u32_f32(bIn1), (uint32x4_t) {0x1, 0x2, 0x4, 0x8}); // [0 1 2 3]
121 uint32x4_t mmB = vextq_u32(mmA, mmA, 2); // [2 3 0 1]
122 uint32x4_t mmC = vorrq_u32(mmA, mmB); // [0+2 1+3 0+2 1+3]
123 uint32x4_t mmD = vextq_u32(mmC, mmC, 3); // [1+3 0+2 1+3 0+2]
124 uint32x4_t mmE = vorrq_u32(mmC, mmD); // [0+1+2+3 ...]
125 uint32_t movemask = vgetq_lane_u32(mmE, 0);
126 switch (movemask) {
127 default:
128 case 0x0: *bOut = o->s; break;
129 case 0x1: {
130 *bOut = vdupq_n_f32(vgetq_lane_f32(bIn0,0));
131 o->s = *bOut;
132 break;
133 }
134 case 0x2: {
135 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,1));
136 *bOut = vextq_f32(o->s, x, 3);
137 o->s = x;
138 break;
139 }
140 case 0x3: {
141 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,1));
142 *bOut = vreinterpretq_f32_u32(vorrq_u32(
143 vandq_u32(vreinterpretq_u32_f32(bIn0), (uint32x4_t) {~0x0, 0x0, 0x0, 0x0}),
144 vandq_u32(vreinterpretq_u32_f32(x), (uint32x4_t) {0x0, ~0x0, ~0x0, ~0x0})));
145 o->s = x;
146 break;
147 }
148 case 0x4: {
149 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,2));
150 *bOut = vextq_f32(o->s, x, 2);
151 o->s = x;
152 break;
153 }
154 case 0x5: {
155 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,0));
156 const float32x4_t y = vdupq_n_f32(vgetq_lane_f32(bIn0,2));
157 *bOut = vreinterpretq_f32_u32(vorrq_u32(
158 vandq_u32(vreinterpretq_u32_f32(x), (uint32x4_t) {~0x0, ~0x0, 0x0, 0x0}),
159 vandq_u32(vreinterpretq_u32_f32(y), (uint32x4_t) {0x0, 0x0, ~0x0, ~0x0})));
160 o->s = y;
161 }
162 case 0x6: {
163 const float32x4_t y = vdupq_n_f32(vgetq_lane_f32(bIn0,3));
164 float32x4_t z = vreinterpretq_f32_u32(vorrq_u32(
165 vandq_u32(vreinterpretq_u32_f32(o->s), (uint32x4_t) {~0x0, 0x0, 0x0, 0x0}),
166 vandq_u32(vreinterpretq_u32_f32(bIn0), (uint32x4_t) {0x0, ~0x0, ~0x0, 0x0})));
167 *bOut = vreinterpretq_f32_u32(vorrq_u32(
168 vandq_u32(vreinterpretq_u32_f32(z), (uint32x4_t) {~0x0, ~0x0, ~0x0, 0x0}),
169 vandq_u32(vreinterpretq_u32_f32(y), (uint32x4_t) {0x0, 0x0, 0x0, ~0x0})));
170 o->s = y;
171 }
172 case 0x7: {
173 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,2));
174 *bOut = vreinterpretq_f32_u32(vorrq_u32(
175 vandq_u32(vreinterpretq_u32_f32(bIn0), (uint32x4_t) {~0x0, ~0x0, 0x0, 0x0}),
176 vandq_u32(vreinterpretq_u32_f32(x), (uint32x4_t) {0x0, 0x0, ~0x0, ~0x0})));
177 o->s = x;
178 break;
179 }
180 case 0x8: {
181 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,3));
182 *bOut = vextq_f32(o->s, x, 1);
183 o->s = x;
184 break;
185 }
186 case 0x9: {
187 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,0));
188 *bOut = vreinterpretq_f32_u32(vorrq_u32(
189 vandq_u32(vreinterpretq_u32_f32(x), (uint32x4_t) {~0x0, ~0x0, ~0x0, 0x0}),
190 vandq_u32(vreinterpretq_u32_f32(bIn0), (uint32x4_t) {0x0, 0x0, 0x0, ~0x0})));
191 o->s = vdupq_n_f32(vgetq_lane_f32(bIn0,3));
192 }
193 case 0xA: {
194 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,1));
195 const float32x4_t y = vdupq_n_f32(vgetq_lane_f32(bIn0,3));
196 float32x4_t z = vreinterpretq_f32_u32(vorrq_u32(
197 vandq_u32(vreinterpretq_u32_f32(o->s), (uint32x4_t) {~0x0, 0x0, 0x0, 0x0}),
198 vandq_u32(vreinterpretq_u32_f32(x), (uint32x4_t) {0x0, ~0x0, ~0x0, 0x0})));
199 *bOut = vreinterpretq_f32_u32(vorrq_u32(
200 vandq_u32(vreinterpretq_u32_f32(z), (uint32x4_t) {~0x0, ~0x0, ~0x0, 0x0}),
201 vandq_u32(vreinterpretq_u32_f32(y), (uint32x4_t) {0x0, 0x0, 0x0, ~0x0})));
202 o->s = y;
203 }
204 case 0xB: {
205 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,1));
206 *bOut = vreinterpretq_f32_u32(vorrq_u32(
207 vandq_u32(vreinterpretq_u32_f32(bIn0), (uint32x4_t) {~0x0, ~0x0, 0x0, ~0x0}),
208 vandq_u32(vreinterpretq_u32_f32(x), (uint32x4_t) {0x0, 0x0, ~0x0, 0x0})));
209 o->s = vdupq_n_f32(vgetq_lane_f32(bIn0,3));
210 break;
211 }
212 case 0xC: {
213 *bOut = vreinterpretq_f32_u32(vorrq_u32(
214 vandq_u32(vreinterpretq_u32_f32(o->s), (uint32x4_t) {~0x0, ~0x0, 0x0, 0x0}),
215 vandq_u32(vreinterpretq_u32_f32(bIn0), (uint32x4_t) {0x0, 0x0, ~0x0, ~0x0})));
216 o->s = vdupq_n_f32(vgetq_lane_f32(bIn0,3));
217 break;
218 }
219 case 0xD: {
220 const float32x4_t x = vdupq_n_f32(vgetq_lane_f32(bIn0,0));
221 *bOut = vreinterpretq_f32_u32(vorrq_u32(
222 vandq_u32(vreinterpretq_u32_f32(bIn0), (uint32x4_t) {~0x0, 0x0, ~0x0, ~0x0}),
223 vandq_u32(vreinterpretq_u32_f32(x), (uint32x4_t) {0x0, ~0x0, 0x0, 0x0})));
224 o->s = vdupq_n_f32(vgetq_lane_f32(bIn0,3));
225 }
226 case 0xE: {
227 *bOut = vreinterpretq_f32_u32(vorrq_u32(
228 vandq_u32(vreinterpretq_u32_f32(o->s), (uint32x4_t) {~0x0, 0x0, 0x0, 0x0}),
229 vandq_u32(vreinterpretq_u32_f32(bIn0), (uint32x4_t) {0x0, ~0x0, ~0x0, ~0x0})));
230 o->s = vdupq_n_f32(vgetq_lane_f32(bIn0,3));
231 break;
232 }
233 case 0xF: {
234 *bOut = bIn0;
235 o->s = vdupq_n_f32(vgetq_lane_f32(bIn0,3));
236 break;
237 }
238 }
239 #else // HV_SIMD_NONE
240 if (bIn1 != 0.0f) o->s = bIn0;
241 *bOut = o->s;
242 #endif
243 }
244
245 void sSamphold_onMessage(HvBase *_c, SignalSamphold *o, int letIndex,
246 const HvMessage *const m, void *sendMessage);
247
248 #endif // _SIGNAL_SAMPHOLD_H_