1 /*
2 * Randi
3 *
4 * This code has been extracted from the Csound opcode "randi".
5 * It has been modified to work as a Soundpipe module.
6 *
7 * Original Author(s): Barry Vercoe, John ffitch
8 * Year: 1991
9 * Location: OOps/ugens4.c
10 *
11 * Randi needs the ftbl Soundpipe module in order to work.
12 *
13 */
14
15 #include <stdlib.h>
16 #include <math.h>
17 #include "soundpipe.h"
18
19 #define sp_oneUp31Bit (4.656612875245796924105750827168e-10)
20
21 #define sp_randGab ((SPFLOAT) \
22 (((p->holdrand = p->holdrand * 214013 + 2531011) >> 1) \
23 & 0x7fffffff) * sp_oneUp31Bit)
24
25
sp_randi_create(sp_randi ** p)26 int sp_randi_create(sp_randi **p)
27 {
28 *p = malloc(sizeof(sp_randi));
29 return SP_OK;
30 }
31
sp_randi_destroy(sp_randi ** p)32 int sp_randi_destroy(sp_randi **p)
33 {
34 free(*p);
35 return SP_OK;
36 }
37
sp_randi_init(sp_data * sp,sp_randi * p)38 int sp_randi_init(sp_data *sp, sp_randi *p)
39 {
40 p->sicvt = 1.0 * SP_FT_MAXLEN / sp->sr;
41 p->phs = 0;
42 p->min = 0;
43 p->max = 1;
44 p->cps = 3;
45 p->mode = 3;
46 p->holdrand = sp_rand(sp);
47 p->fstval = 0;
48
49 int mode = (int)(p->mode);
50 switch (mode) {
51 case 1: /* immediate interpolation between kmin and 1st random number */
52 p->num1 = 0.0;
53 p->num2 = sp_randGab;
54 p->dfdmax = (p->num2 - p->num1) / SP_FT_MAXLEN * 1.0;
55 break;
56 case 2: /* immediate interpolation between ifirstval and 1st random number */
57 p->num1 = (p->max - p->min) ?
58 (p->fstval - p->min) / (p->max - p->min) : 0.0;
59 p->num2 = sp_randGab;
60 p->dfdmax = (p->num2 - p->num1) / SP_FT_MAXLEN * 1.0;
61 break;
62 case 3: /* immediate interpolation between 1st and 2nd random number */
63 p->num1 = sp_randGab;
64 p->num2 = sp_randGab;
65 p->dfdmax = (p->num2 - p->num1) / SP_FT_MAXLEN * 1.0;
66 break;
67 default: /* old behaviour as developped by Gabriel */
68 p->num1 = p->num2 = 0.0;
69 p->dfdmax = 0.0;
70 }
71 return SP_OK;
72 }
73
sp_randi_compute(sp_data * sp,sp_randi * p,SPFLOAT * in,SPFLOAT * out)74 int sp_randi_compute(sp_data *sp, sp_randi *p, SPFLOAT *in, SPFLOAT *out)
75 {
76 int32_t phs = p->phs, inc;
77 SPFLOAT cpsp;
78 SPFLOAT amp, min;
79
80 cpsp = p->cps;
81 min = p->min;
82 amp = (p->max - min);
83 inc = (int32_t)(cpsp * p->sicvt);
84
85 *out = (p->num1 + (SPFLOAT)phs * p->dfdmax) * amp + min;
86 phs += inc;
87 if (phs >= SP_FT_MAXLEN) {
88 phs &= SP_FT_PHMASK;
89 p->num1 = p->num2;
90 p->num2 = sp_randGab;
91 p->dfdmax = 1.0 * (p->num2 - p->num1) / SP_FT_MAXLEN;
92 }
93 p->phs = phs;
94
95 return SP_OK;
96 }
97