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