GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/lib/modules.c Lines: 219 220 99.5 %
Date: 2020-09-12 17:36:58 Branches: 34 38 89.5 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <math.h>
3
#include "gwion_util.h"
4
#include "gwion_ast.h"
5
#include "gwion_env.h"
6
#include "vm.h"
7
#include "gwion.h"
8
#include "instr.h"
9
#include "object.h"
10
#include "operator.h"
11
#include "import.h"
12
#include "ugen.h"
13
#include "gwi.h"
14
#include "emit.h"
15
16
9
static DTOR(basic_dtor) {
17
9
  xfree(UGEN(o)->module.gen.data);
18
9
}
19
20
480000
static TICK(gain_tick) {
21
480000
  u->out = (u->in * *(m_float*)u->module.gen.data);
22
480000
}
23
24
1
static CTOR(gain_ctor) {
25
1
  ugen_ini(shred->info->vm->gwion, UGEN(o), 1, 1);
26
1
  ugen_gen(shred->info->vm->gwion, UGEN(o), gain_tick, (m_float*)xmalloc(SZ_FLOAT), 0);
27
1
  UGEN(o)->module.gen.tick = gain_tick;
28
1
  *(m_float*)UGEN(o)->module.gen.data = 1;
29
1
}
30
31
32
67
static MFUN(gain_get_gain) {
33
67
  *(m_float*)RETURN = *(m_float*)UGEN(o)->module.gen.data;
34
67
}
35
36
67
static MFUN(gain_set_gain) {
37
67
  *(m_float*)RETURN = *(m_float*)UGEN(o)->module.gen.data = *(m_float*)MEM(SZ_INT);
38
67
}
39
40
711
static GWION_IMPORT(gain) {
41
711
  GWI_OB(gwi_class_ini(gwi,  "Gain", "UGen"))
42
711
  gwi_class_xtor(gwi, gain_ctor, basic_dtor);
43
711
  gwi_func_ini(gwi, "float", "gain");
44
711
  GWI_BB(gwi_func_end(gwi, gain_get_gain, ae_flag_none))
45
711
  gwi_func_ini(gwi, "float", "gain");
46
711
  gwi_func_arg(gwi, "float", "arg0");
47
711
  GWI_BB(gwi_func_end(gwi, gain_set_gain, ae_flag_none))
48
711
  return gwi_class_end(gwi);
49
}
50
51
9
static TICK(impulse_tick) {
52
9
  u->out = *(m_float*)u->module.gen.data;
53
9
  *(m_float*)u->module.gen.data = 0;
54
9
}
55
56
4
static CTOR(impulse_ctor) {
57
4
  ugen_ini(shred->info->vm->gwion, UGEN(o), 0, 1);
58
4
  ugen_gen(shred->info->vm->gwion, UGEN(o), impulse_tick, (m_float*)xmalloc(SZ_FLOAT), 0);
59
4
  *(m_float*)UGEN(o)->module.gen.data = 0;
60
4
}
61
62
1
static MFUN(impulse_get_next) {
63
1
  *(m_float*)RETURN = *(m_float*)UGEN(o)->module.gen.data;
64
1
}
65
66
6
static MFUN(impulse_set_next) {
67
6
  *(m_float*)RETURN = (*(m_float*)UGEN(o)->module.gen.data = *(m_float*)MEM(SZ_INT));
68
6
}
69
70
711
static GWION_IMPORT(impulse) {
71
711
  GWI_OB(gwi_class_ini(gwi, "Impulse", "UGen"))
72
711
  gwi_class_xtor(gwi, impulse_ctor, basic_dtor);
73
711
  gwi_func_ini(gwi, "float", "next");
74
711
  GWI_BB(gwi_func_end(gwi, impulse_get_next, ae_flag_none))
75
711
  gwi_func_ini(gwi, "float", "next");
76
711
  gwi_func_arg(gwi, "float", "arg0");
77
711
  GWI_BB(gwi_func_end(gwi, impulse_set_next, ae_flag_none))
78
711
  return gwi_class_end(gwi);
79
}
80
81
2
static TICK(fullrect_tick) {
82
2
  u->out = fabs(u->in);
83
2
}
84
85
1
static CTOR(fullrect_ctor) {
86
1
  ugen_ini(shred->info->vm->gwion, UGEN(o), 1, 1);
87
1
  ugen_gen(shred->info->vm->gwion, UGEN(o), fullrect_tick, (m_float*)xmalloc(SZ_FLOAT), 0);
88
1
  *(m_float*)UGEN(o)->module.gen.data = 1;
89
1
}
90
91
711
static GWION_IMPORT(fullrect) {
92
711
  GWI_OB(gwi_class_ini(gwi, "FullRect", "UGen"))
93
711
  gwi_class_xtor(gwi, fullrect_ctor, basic_dtor);
94
711
  return gwi_class_end(gwi);
95
}
96
97
2
static TICK(halfrect_tick) {
98
2
  if(u->in > 0)
99
1
    u->out = u->in;
100
  else
101
1
    u->out = 0;
102
2
}
103
104
1
static CTOR(halfrect_ctor) {
105
1
  ugen_ini(shred->info->vm->gwion, UGEN(o), 1, 1);
106
1
  ugen_gen(shred->info->vm->gwion, UGEN(o), halfrect_tick, (m_float*)xmalloc(SZ_FLOAT), 0);
107
1
  *(m_float*)UGEN(o)->module.gen.data = 1;
108
1
}
109
110
711
static GWION_IMPORT(halfrect) {
111
711
  GWI_OB(gwi_class_ini(gwi, "HalfRect", "UGen"))
112
711
  gwi_class_xtor(gwi, halfrect_ctor, basic_dtor);
113
711
  return gwi_class_end(gwi);
114
}
115
116
1
static TICK(step_tick) {
117
1
  u->out = *(m_float*)u->module.gen.data;
118
1
}
119
120
1
static CTOR(step_ctor) {
121
1
  ugen_ini(shred->info->vm->gwion, UGEN(o), 0, 1);
122
1
  ugen_gen(shred->info->vm->gwion, UGEN(o), step_tick, (m_float*)xmalloc(SZ_FLOAT), 0);
123
1
  *(m_float*)UGEN(o)->module.gen.data = 0;
124
1
}
125
126
1
static MFUN(step_get_next) {
127
1
  *(m_float*)RETURN = *(m_float*)UGEN(o)->module.gen.data;
128
1
}
129
130
1
static MFUN(step_set_next) {
131
1
  *(m_float*)RETURN = *(m_float*)UGEN(o)->module.gen.data = *(m_float*)(shred->mem + SZ_INT);
132
1
}
133
134
711
static GWION_IMPORT(step) {
135
711
  GWI_OB(gwi_class_ini(gwi, "Step", "UGen"))
136
711
  gwi_class_xtor(gwi, step_ctor, basic_dtor);
137
711
  gwi_func_ini(gwi, "float", "next");
138
711
  GWI_BB(gwi_func_end(gwi, step_get_next, ae_flag_none))
139
711
  gwi_func_ini(gwi, "float", "next");
140
711
  gwi_func_arg(gwi, "float", "arg0");
141
711
  GWI_BB(gwi_func_end(gwi, step_set_next, ae_flag_none))
142
711
  return gwi_class_end(gwi);
143
}
144
145
4
static TICK(zerox_tick) {
146

4
  m_float in = (u->in < 0) ? -1 : (u->in > 0);
147
4
  m_float f = *(m_float*)u->module.gen.data;
148
4
  u->out = f == in ? 1 : 0;
149
4
  *(m_float*) u->module.gen.data = in;
150
4
}
151
152
1
static CTOR(zerox_ctor) {
153
1
  ugen_ini(shred->info->vm->gwion, UGEN(o), 1, 1);
154
1
  ugen_gen(shred->info->vm->gwion, UGEN(o), zerox_tick, (m_float*)xmalloc(SZ_FLOAT), 0);
155
1
  *(m_float*)UGEN(o)->module.gen.data = 1;
156
1
}
157
158
711
static GWION_IMPORT(zerox) {
159
711
  GWI_OB(gwi_class_ini(gwi, "ZeroX", "UGen"))
160
711
  gwi_class_xtor(gwi, zerox_ctor, basic_dtor);
161
711
  return gwi_class_end(gwi);
162
}
163
164
struct UUGen_ {
165
  M_Object  self;
166
  VM_Code   code;
167
  VM_Shred shred;
168
  void (*prep)(struct UUGen_*, const m_float);
169
};
170
171
1
ANN static void global_prep(struct UUGen_ *uu, const m_float in) {
172
1
  *(m_float*)uu->shred->mem = in;
173
1
}
174
175
3
ANN static void member_prep(struct UUGen_ *uu, const m_float in) {
176
3
  *(M_Object*)uu->shred->mem = uu->self;
177
3
  *(m_float*)(uu->shred->mem + SZ_INT) = in;
178
3
}
179
180
1
static TICK(id_tick) {
181
1
  u->out = u->in;
182
1
}
183
184
4
static TICK(usrugen_tick) {
185
4
  struct UUGen_ *uu = u->module.gen.data;
186
4
  uu->prep(uu, u->in);
187
4
  uu->shred->pc = 0;
188
4
  shredule(uu->shred->tick->shreduler, uu->shred, 0);
189
4
  vm_run(uu->shred->info->vm);
190
4
  uu->shred->reg -= SZ_FLOAT;
191
4
  u->out = *(m_float*)(uu->shred->reg);
192
4
}
193
194
2
static CTOR(usrugen_ctor) {
195
2
  struct UUGen_* uu = mp_calloc(shred->info->vm->gwion->mp, UUGen);
196
2
  uu->self = o;
197
2
  ugen_ini(shred->info->vm->gwion, UGEN(o), 1, 1);
198
2
  ugen_gen(shred->info->vm->gwion, UGEN(o), id_tick, uu, 0);
199
2
}
200
201
2
static DTOR(usrugen_dtor) {
202
2
  struct UUGen_ *uu = UGEN(o)->module.gen.data;
203
2
  if(uu->shred)
204
1
    free_vm_shred(uu->shred);
205
2
  mp_free(shred->info->vm->gwion->mp, UUGen, UGEN(o)->module.gen.data);
206
2
}
207
208
12
static OP_CHECK(opck_usrugen) {
209
12
  Exp_Binary *bin = (Exp_Binary*)data;
210
12
  const Arg_List arg = bin->lhs->info->type->e->d.func->def->base->args;
211

12
  if(!arg || arg->next)
212
2
    ERR_N(exp_self(bin)->pos, _("Tick function take one and only one argument"))
213
10
  if(isa(arg->type, env->gwion->type[et_float]) < 0)
214
1
    ERR_N(exp_self(bin)->pos, _("Tick functions argument must be of type float"))
215
9
  if(isa(bin->lhs->info->type->e->d.func->def->base->ret_type, env->gwion->type[et_float]) < 0)
216
1
    ERR_N(exp_self(bin)->pos, _("Tick function must return float"))
217
8
  if(bin->lhs->info->type->e->d.func->value_ref->from->owner_class)
218
6
    CHECK_BN(isa(bin->lhs->info->type->e->d.func->value_ref->from->owner_class,
219
      bin->rhs->info->type))
220
8
  return bin->rhs->info->type;
221
}
222
223
4
static INSTR(UURet) {
224
4
  shreduler_remove(shred->tick->shreduler, shred, 0);
225
4
}
226
227
3
ANN static void code_prepare(const VM_Code code) {
228
3
  m_bit *byte = code->bytecode;
229
57
  for(m_uint i = 0; i < vector_size(code->instr); ++i) {
230
54
    if(*(m_bit*)(byte + i *BYTECODE_SZ) == eFuncReturn) {
231
2
      *(m_bit*)(byte + i * BYTECODE_SZ)= eOP_MAX;
232
2
      *(f_instr*)(byte + (i*BYTECODE_SZ) + SZ_INT*2) = UURet;
233
    }
234
  }
235
3
}
236
237
1
static MFUN(default_tick) {
238
1
  struct UUGen_ *uu = UGEN(o)->module.gen.data;
239
1
  if(uu->shred) {
240
1
    free_vm_shred(uu->shred);
241
1
    uu->shred = NULL;
242
  }
243
1
  UGEN(o)->module.gen.tick = id_tick;
244
//  release(o, shred);
245
1
}
246
247
4
static INSTR(UsrUGenTick) {
248
4
  const m_uint offset = !instr->m_val ? SZ_INT : 0;
249
4
  shred->reg -= SZ_INT*2 - offset;
250
4
  const M_Object o = *(M_Object*)(shred->reg + SZ_INT - offset);
251
4
  if(!o)
252
    Except(shred, "[NullPtrException]");
253
4
  struct UUGen_ *uu = UGEN(o)->module.gen.data;
254
4
  if(uu->shred)
255
1
    free_vm_shred(uu->shred);
256
4
  UGEN(o)->module.gen.tick = usrugen_tick;
257
4
  const VM_Code code = *(VM_Code*)(shred->reg-offset);
258
4
  release(o, shred);
259
4
  if(!code)
260
1
    Except(shred, "[NullTickException]");
261
3
  uu->shred = new_vm_shred(shred->info->vm->gwion->mp, *(VM_Code*)(shred->reg-offset));
262
3
  ADD_REF(*(VM_Code*)(shred->reg - offset));
263
3
  uu->shred->info->vm = shred->info->vm;
264
3
  code_prepare(uu->shred->code);
265
3
  shreduler_ini(uu->shred->info->vm->shreduler, uu->shred);
266
3
  uu->prep = instr->m_val ? member_prep : global_prep;
267
3
  *(M_Object*)(shred->reg - SZ_INT) = o;
268
}
269
270
4
static OP_EMIT(opem_usrugen) {
271
4
  Exp_Binary *bin = (Exp_Binary*)data;
272
4
  const Instr instr = emit_add_instr(emit, UsrUGenTick);
273
4
  instr->m_val = !!bin->lhs->info->type->e->d.func->value_ref->from->owner_class;
274
4
  return instr;
275
}
276
277
711
static GWION_IMPORT(usrugen) {
278
711
  GWI_OB(gwi_class_ini(gwi, "UsrUGen", "UGen"))
279
711
  gwi_class_xtor(gwi, usrugen_ctor, usrugen_dtor);
280
711
  GWI_BB(gwi_func_ini(gwi, "int", "default_tick"))
281
711
  GWI_BB(gwi_func_end(gwi, default_tick, 0))
282
711
  GWI_BB(gwi_class_end(gwi))
283
711
  GWI_BB(gwi_oper_ini(gwi, "@function", "UsrUGen", "UsrUGen"))
284
711
  GWI_BB(gwi_oper_add(gwi, opck_usrugen))
285
711
  GWI_BB(gwi_oper_emi(gwi, opem_usrugen))
286
711
  GWI_BB(gwi_oper_end(gwi, "~=", NULL))
287
711
  return GW_OK;
288
}
289
290
711
GWION_IMPORT(modules) {
291
711
  GWI_BB(import_gain(gwi))
292
711
  GWI_BB(import_impulse(gwi))
293
711
  GWI_BB(import_fullrect(gwi))
294
711
  GWI_BB(import_halfrect(gwi))
295
711
  GWI_BB(import_step(gwi))
296
711
  GWI_BB(import_zerox(gwi))
297
711
  return import_usrugen(gwi);
298
}