-
Notifications
You must be signed in to change notification settings - Fork 1
/
multiply.c
131 lines (115 loc) · 2.96 KB
/
multiply.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "audio.h"
typedef struct {
mod_handle_t op1;
mod_handle_t op2;
} twoarg_data_t;
void multiply_fillblock(mod_handle_t handle, float* block, void* d)
{
twoarg_data_t* data = (twoarg_data_t*) d;
float* block1 = mod_rdblock(data->op1);
float* block2 = mod_rdblock(data->op2);
int i;
for (i = 0; i < BLOCK_SIZE; i++) {
block[i] = block1[i] * block2[i];
}
}
mod_handle_t multiply_create(mod_handle_t op1, mod_handle_t op2)
{
mod_handle_t handle = mod_create(multiply_fillblock, 0, sizeof(twoarg_data_t));
twoarg_data_t* data = mod_data(handle);
data->op1 = op1;
data->op2 = op2;
return handle;
}
void add_fillblock(mod_handle_t handle, float* block, void* d)
{
twoarg_data_t* data = (twoarg_data_t*) d;
float* block1 = mod_rdblock(data->op1);
float* block2 = mod_rdblock(data->op2);
int i;
for (i = 0; i < BLOCK_SIZE; i++) {
block[i] = block1[i] + block2[i];
}
}
mod_handle_t add_create(mod_handle_t op1, mod_handle_t op2)
{
mod_handle_t handle = mod_create(add_fillblock, 0, sizeof(twoarg_data_t));
twoarg_data_t* data = mod_data(handle);
data->op1 = op1;
data->op2 = op2;
return handle;
}
#define LN2 0.693147180559945309417
#define FACT_3 (3*2)
#define FACT_4 (4*3*2)
#define FACT_5 (5*4*3*2)
#define FACT_6 (6*5*4*3*2)
static char exp_table_ready = 0;
static float exp_table[TABLE_LEN];
void create_exp_table()
{
int i;
for (i = 0; i < TABLE_LEN; i++) {
float f = LN2 * i / TABLE_LEN;
float f2 = f * f;
float f3 = f2 * f;
float f4 = f3 * f;
float f5 = f4 * f;
float f6 = f5 * f;
exp_table[i] = 1 + f + f2 / 2 + f3 / FACT_3 + f4 / FACT_4 + f5 / FACT_5 + f6 / FACT_6;
}
exp_table_ready = 1;
}
float pow2(float ex)
{
int i = (int) ex;
if (ex < 0) {
float base = 1.0 / (1 << -i);
float fract = i - ex;
if (fract > 0) {
float x = table_lookup(exp_table, fract, 2);
base /= x;
}
return base;
} else {
float base = 1 << i;
float fract = ex - i;
if (fract > 0) {
float x = table_lookup(exp_table, fract, 2);
base *= x;
}
return base;
}
}
typedef struct {
mod_handle_t in;
float a;
float c;
} exp_data_t;
void exp_fillblock(mod_handle_t handle, float* block, void* d)
{
exp_data_t* data = (exp_data_t*) d;
float* in = mod_rdblock(data->in);
float a = data->a;
float c = data->c;
int i;
for (i = 0; i < BLOCK_SIZE; i++) {
float exponent = c * in[i];
block[i] = a * pow2(exponent);
}
}
/**
* Calculates a * 2^(c * in)
*/
mod_handle_t exp_create(mod_handle_t in, float a, float c)
{
if (!exp_table_ready) {
create_exp_table();
}
mod_handle_t handle = mod_create(exp_fillblock, 0, sizeof(exp_data_t));
exp_data_t* data = mod_data(handle);
data->in = in;
data->a = a;
data->c = c;
return handle;
}