1
2 /*
3 * Diverse Bristol audio routines.
4 * Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21 /*#define BRISTOL_DBG */
22
23 /*
24 * Need to have basic template for an operator. Will consist of
25 *
26 * eswitchinit()
27 * operate()
28 * reset()
29 * destroy()
30 *
31 * destroy() is in the library.
32 *
33 * Operate will be called when all the inputs have been loaded, and the result
34 * will be an output buffer written to the next operator.
35 */
36
37 #include <stdlib.h>
38
39 #include "bristol.h"
40 #include "electroswitch.h"
41
42 /*
43 * The name of this operator, IO count, and IO names.
44 */
45 #define OPNAME "Electromod"
46 #define OPDESCRIPTION "Electronic Switch"
47 #define PCOUNT 0
48 #define IOCOUNT 4
49
50 #define ESWITCHMOD_IN_1 0
51 #define ESWITCHMOD_IN_2 1
52 #define ESWITCHMOD_CLOCK 2
53 #define ESWITCHMOD_OUT 3
54
55 /*
56 * Reset any local memory information.
57 */
destroy(bristolOP * operator)58 static int destroy(bristolOP *operator)
59 {
60 #ifdef BRISTOL_DBG
61 printf("reset(%x)\n", operator);
62 #endif
63
64 /*
65 * Unmalloc anything we added to this structure
66 */
67 bristolfree(operator->specs);
68
69 /*
70 * Free any local memory. We should also free ourselves, since we did the
71 * initial allocation.
72 */
73 cleanup(operator);
74 return(0);
75 }
76
77 /*
78 * Reset any local memory information.
79 */
reset(bristolOP * operator,bristolOPParams * param)80 static int reset(bristolOP *operator, bristolOPParams *param)
81 {
82 #ifdef BRISTOL_DBG
83 printf("eswitchreset(%x)\n", operator);
84 #endif
85
86 param->param[0].float_val = 1.0;
87 param->param[1].float_val = 1.0;
88 return(0);
89 }
90
91 /*
92 * Alter an internal parameter of an operator.
93 */
param(bristolOP * operator,bristolOPParams * param,unsigned char index,float value)94 static int param(bristolOP *operator, bristolOPParams *param,
95 unsigned char index, float value)
96 {
97 #ifdef BRISTOL_DBG
98 printf("eswitchparam(%x, %x, %i, %i)\n", operator, param, index, value);
99 #endif
100
101 param->param[index].float_val = value;
102
103 return(0);
104 }
105
106 /*
107 * Amplifier - takes input signal and mod signal, and mults them together.
108 */
operate(register bristolOP * operator,bristolVoice * voice,bristolOPParams * param,void * lcl)109 static int operate(register bristolOP *operator, bristolVoice *voice,
110 bristolOPParams *param,
111 void *lcl)
112 {
113 register int count;
114 register float *ib1, *ib2, *ob, *cbuf;
115 bristolESWITCHMOD *specs;
116
117 specs = (bristolESWITCHMOD *) operator->specs;
118 count = specs->spec.io[ESWITCHMOD_OUT].samplecount;
119
120 #ifdef BRISTOL_DBG
121 printf("eswitch(%x, %x, %i)\n", operator, param, count);
122 #endif
123
124 ib1 = specs->spec.io[ESWITCHMOD_IN_1].buf;
125 ib2 = specs->spec.io[ESWITCHMOD_IN_2].buf;
126 cbuf = specs->spec.io[ESWITCHMOD_CLOCK].buf;
127 ob = specs->spec.io[ESWITCHMOD_OUT].buf;
128
129 for (; count > 0;count-=8)
130 {
131 /*
132 * If the clock signal is greater than zero take the next sample from
133 * input buffer one, other wise input buffer two. When it changes we
134 * should interpret a sample, but that can be done later.
135 */
136 /* *ob++ = *ib1++ * *ib2++; */
137 if (*cbuf++ >= 0)
138 {
139 *ob++ = *ib1++; ib2++;
140 *ob++ = *ib1++; ib2++;
141 *ob++ = *ib1++; ib2++;
142 *ob++ = *ib1++; ib2++;
143 *ob++ = *ib1++; ib2++;
144 *ob++ = *ib1++; ib2++;
145 *ob++ = *ib1++; ib2++;
146 *ob++ = *ib1++; ib2++;
147 } else {
148 *ob++ = *ib2++; ib1++;
149 *ob++ = *ib2++; ib1++;
150 *ob++ = *ib2++; ib1++;
151 *ob++ = *ib2++; ib1++;
152 *ob++ = *ib2++; ib1++;
153 *ob++ = *ib2++; ib1++;
154 *ob++ = *ib2++; ib1++;
155 *ob++ = *ib2++; ib1++;
156 }
157 }
158 return(0);
159 }
160
161 /*
162 * Setup any variables in our OP structure, in our IO structures, and malloc
163 * any memory we need.
164 */
165 bristolOP *
eswitchinit(bristolOP ** operator,int index,int samplerate,int samplecount)166 eswitchinit(bristolOP **operator, int index, int samplerate, int samplecount)
167 {
168 bristolESWITCHMOD *specs;
169
170 #ifdef BRISTOL_DBG
171 printf("eswitchinit(%x(%x), %i, %i, %i)\n",
172 operator, *operator, index, samplerate, samplecount);
173 #endif
174
175 *operator = bristolOPinit(operator, index, samplecount);
176
177 /*
178 * Then the local parameters specific to this operator. These will be
179 * the same for each operator, but must be inited in the local code.
180 */
181 (*operator)->operate = operate;
182 (*operator)->destroy = destroy;
183 (*operator)->reset = reset;
184 (*operator)->param = param;
185
186 specs = (bristolESWITCHMOD *) bristolmalloc0(sizeof(bristolESWITCHMOD));
187 (*operator)->specs = (bristolOPSpec *) specs;
188 (*operator)->size = sizeof(bristolESWITCHMOD);
189
190 /*
191 * These are specific to this operator, and will need to be altered for
192 * each operator.
193 */
194 specs->spec.opname = OPNAME;
195 specs->spec.description = OPDESCRIPTION;
196 specs->spec.pcount = PCOUNT;
197 specs->spec.iocount = IOCOUNT;
198 specs->spec.localsize = sizeof(bristolESWITCHMODlocal);
199
200 /*
201 * Now fill in the dco IO specs.
202 */
203 specs->spec.io[0].ioname = "Input 1";
204 specs->spec.io[0].description = "Electromod Input 1 Signal";
205 specs->spec.io[0].samplerate = samplerate;
206 specs->spec.io[0].samplecount = samplecount;
207 specs->spec.io[0].flags = BRISTOL_AC|BRISTOL_OUTPUT;
208 specs->spec.io[1].ioname = "Input 2";
209 specs->spec.io[1].description = "Electromod Input 2 Signal";
210 specs->spec.io[1].samplerate = samplerate;
211 specs->spec.io[1].samplecount = samplecount;
212 specs->spec.io[1].flags = BRISTOL_AC|BRISTOL_OUTPUT;
213 specs->spec.io[2].ioname = "Clock Input";
214 specs->spec.io[2].description = "Electromod clock Signal";
215 specs->spec.io[2].samplerate = samplerate;
216 specs->spec.io[2].samplecount = samplecount;
217 specs->spec.io[2].flags = BRISTOL_AC|BRISTOL_OUTPUT;
218 specs->spec.io[3].ioname = "output";
219 specs->spec.io[3].description = "Electromod Output Signal";
220 specs->spec.io[3].samplerate = samplerate;
221 specs->spec.io[3].samplecount = samplecount;
222 specs->spec.io[3].flags = BRISTOL_AC|BRISTOL_OUTPUT;
223
224 return(*operator);
225 }
226
227