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  * Need to have basic template for an operator. Will consist of
24  *
25  *	arpdcoinit()
26  *	operate()
27  *	reset()
28  *	destroy()
29  *
30  *	destroy() is in the library.
31  *
32  * Operate will be called when all the inputs have been loaded, and the result
33  * will be an output buffer written to the next operator.
34  */
35 
36 #include <math.h>
37 
38 #include "bristol.h"
39 #include "bristolblo.h"
40 #include "arpdco.h"
41 
42 float note_diff, *zbuf;
43 
44 #define BRISTOL_SQR 4
45 
46 /*
47  * The name of this operator, IO count, and IO names. This is where possible
48  * identical to the Prophet DCO, but we need separated outputs. We could use
49  * it for the Prophet as well but that would incur the cost of extra mixing
50  * code.
51  */
52 #define OPNAME "DCO"
53 #define OPDESCRIPTION "ARP Digitally Controlled Oscillator"
54 #define PCOUNT 8
55 #define IOCOUNT 7
56 
57 #define DCO_IN_IND 0
58 #define DCO_MOD_IND 1
59 #define DCO_OUT_RAMP 2
60 #define DCO_SYNC_IND 3
61 #define DCO_OUT_SQUARE 4
62 #define DCO_OUT_SINE 5
63 #define DCO_OUT_TRIANGLE 6
64 
65 #define DCO_WAVE_COUNT 6
66 
67 static void fillWave();
68 
69 /*
70  * We should not be doing this however I need a quick resolution to some issues
71  * with sync of square waves and this is a scratch buffer for the edge detector
72  */
73 static float *sbuf = NULL;
74 
75 /*
76  * Reset any local memory information.
77  */
destroy(bristolOP * operator)78 static int destroy(bristolOP *operator)
79 {
80 #ifdef BRISTOL_DBG
81 	printf("destroy(%x)\n", operator);
82 #endif
83 
84 	/*
85 	 * Unmalloc anything we added to this structure
86 	 */
87 	bristolfree(((bristolARPDCO *) operator)->wave[0]);
88 	bristolfree(((bristolARPDCO *) operator)->wave[1]);
89 	bristolfree(((bristolARPDCO *) operator)->wave[2]);
90 	bristolfree(((bristolARPDCO *) operator)->wave[3]);
91 	bristolfree(((bristolARPDCO *) operator)->wave[4]);
92 	bristolfree(((bristolARPDCO *) operator)->wave[5]);
93 	bristolfree(((bristolARPDCO *) operator)->wave[6]);
94 	bristolfree(((bristolARPDCO *) operator)->wave[7]);
95 
96 	bristolfree(operator->specs);
97 
98 	/*
99 	 * Free any local memory. We should also free ourselves, since we did the
100 	 * initial allocation.
101 	 */
102 	cleanup(operator);
103 
104 	return(0);
105 }
106 
107 /*
108  * Reset any local memory information.
109  */
reset(bristolOP * operator,bristolOPParams * param)110 static int reset(bristolOP *operator, bristolOPParams *param)
111 {
112 #ifdef BRISTOL_DBG
113 	printf("arpreset(%x)\n", operator);
114 #endif
115 
116 	param->param[0].int_val = ARPDCO_WAVE_SZE / 2;
117 	if (param->param[0].mem != NULL) bristolfree(param->param[0].mem);
118 	param->param[0].mem = bristolmalloc0(sizeof(float) * ARPDCO_WAVE_SZE);
119 	if (param->param[1].mem != NULL) bristolfree(param->param[1].mem);
120 	param->param[1].mem = bristolmalloc0(sizeof(float) * ARPDCO_WAVE_SZE);
121 	param->param[1].float_val = 1.0;
122 	param->param[2].float_val = 1.0;
123 	param->param[3].float_val = 1.0;
124 	param->param[6].int_val = 1;
125 	param->param[7].int_val = 0;
126 	param->param[9].float_val = 1.0;
127 	param->param[10].float_val = 1.0;
128 	param->param[11].float_val = 1.0;
129 
130 	return(0);
131 }
132 
133 /*
134  * Alter an internal parameter of an operator.
135  */
param(bristolOP * operator,bristolOPParams * param,unsigned char index,float value)136 static int param(bristolOP *operator, bristolOPParams *param,
137 	unsigned char index, float value)
138 {
139 #ifdef BRISTOL_DBG
140 	printf("arpdcoparam(%i, %f/%f)\n",
141 		index, value, (int) (value*CONTROLLER_RANGE));
142 #endif
143 
144 	switch (index) {
145 		case 0: /* PW */
146 			param->param[index].float_val = value * ARPDCO_WAVE_SZE * 0.5;
147 			break;
148 		case 1:
149 			/*
150 			 * Transpose in octaves. 0 to 5, down 2 up 3.
151 			 */
152 			{
153 				int note = value * CONTROLLER_RANGE;
154 
155 				param->param[1].int_val = 0;
156 
157 				switch (note) {
158 					case 0:
159 						param->param[1].float_val = 0.25;
160 						break;
161 					case 1:
162 						param->param[1].float_val = 0.50;
163 						break;
164 					case 2:
165 						param->param[1].float_val = 1.0;
166 						break;
167 					case 3:
168 						param->param[1].float_val = 2.0;
169 						break;
170 					case 4:
171 						param->param[1].float_val = 4.0;
172 						break;
173 					case 5:
174 						param->param[1].float_val = 8.0;
175 						break;
176 					case 10:
177 						/* This should set values for LFO operation. */
178 						param->param[1].float_val = 0.125;
179 						param->param[1].int_val = 1;
180 						break;
181 				}
182 			}
183 			break;
184 		case 2: /* Tune in "small" amounts */
185 			{
186 				float tune, notes = 1.0;
187 				int i;
188 
189 				tune = (value - 0.5) * 2;
190 
191 				/*
192 				 * Up or down 7 notes.
193 				 */
194 				for (i = 0; i < 7;i++)
195 				{
196 					if (tune > 0)
197 						notes *= note_diff;
198 					else
199 						notes /= note_diff;
200 				}
201 
202 				if (tune > 0)
203 					param->param[index].float_val =
204 						1.0 + (notes - 1) * tune;
205 				else
206 					param->param[index].float_val =
207 						1.0 - (1 - notes) * -tune;
208 
209 				break;
210 			}
211 		case 3: /* gain */
212 			param->param[index].float_val = value;
213 			break;
214 		case 4: /* mix ramp */
215 		case 5: /* mix tri */
216 		case 8: /* mix sine */
217 		case 6: /* mix PWM square */
218 			/*
219 			 * These were dropped, we always mix all waveforms. Perhaps there
220 			 * will be an odyssey/2600 option where we produce either
221 			 * ramp/square or ramp/square/sine/triangle, but this can also
222 			 * be achieved with null pointers.
223 			 */
224 			break;
225 		case 7: /* sync flag */
226 			if (value == 0)
227 				param->param[index].int_val = 0;
228 			else
229 				param->param[index].int_val = 1;
230 			break;
231 		/* case 8: used for waveform mix. */
232 		case 9: /* semitone tuning. */
233 			/*
234 			 * Transpose in semitones upwards.
235 			 */
236 			{
237 				int semitone = value * CONTROLLER_RANGE;
238 
239 				param->param[index].float_val = 1.0;
240 
241 				while (semitone-- > 0) {
242 					param->param[index].float_val *= (note_diff);
243 				}
244 			}
245 			break;
246 		case 10: /* semitone fine tuning. */
247 			/*
248 			 * finetune by a semitones up/down.
249 			 */
250 			{
251 				float tune, notes = 1.0;
252 
253 				tune = (value - 0.5);
254 
255 				/*
256 				 * Up or down 7 notes.
257 				 */
258 				if (tune > 0)
259 					notes *= note_diff;
260 				else
261 					notes /= note_diff;
262 
263 				if (tune > 0)
264 					param->param[index].float_val =
265 						1.0 + (notes - 1) * tune;
266 				else param->param[index].float_val =
267 						1.0 - (1 - notes) * -tune;
268 
269 				break;
270 			}
271 		case 11: /* This will be used by the OBX pitch bend */
272 			{
273 				float tune, notes = 1.0;
274 				int i;
275 
276 				tune = (value - 0.5) * 2;
277 
278 				/*
279 				 * Up or down 12 notes.
280 				 */
281 				for (i = 0; i < 12;i++)
282 				{
283 					if (tune > 0)
284 						notes *= note_diff;
285 					else
286 						notes /= note_diff;
287 				}
288 
289 				if (tune > 0)
290 					param->param[index].float_val =
291 						1.0 + (notes - 1) * tune;
292 				else
293 					param->param[index].float_val =
294 						1.0 - (1 - notes) * -tune;
295 
296 				break;
297 			}
298 	}
299 
300 	return(0);
301 }
302 
303 static float
genSyncPoints(register float * sbuf,float * sb,register float lsv,register int count)304 genSyncPoints(register float *sbuf, float *sb, register float lsv,
305 register int count)
306 {
307 	/*
308 	 * Take the sync buffer and look for zero crossings. When they are found
309 	 * do a resample to find out where the crossing happened as sample level
310 	 * resolution results in distortion and shimmer
311 	 *
312 	 * Resampling, or rather interpolation to zero, means we have to look at
313 	 * the respective above and below zero values.
314 	 */
315 	for (; count > 0; count--, lsv = *sb++)
316 		*sbuf++ = ((lsv < 0) && (*sb >= 0))? lsv / (lsv - *sb) : 0;
317 
318 	return(lsv);
319 }
320 
321 #define S_DEC 0.999f
322 
323 /*
324  * As of the first write, 9/11/01, this takes nearly 20mips to operate a single
325  * oscillator. Will work on optimisation of the code, using non-referenced
326  * variables in register workspace.
327  *
328  *	output buffer pointer.
329  *	output buffer index.
330  *	input buffer index.
331  *	wavetable.
332  *	wavetable index.
333  *	count.
334  *	gain.
335  *
336  * With optimisations this is reduced to a nominal amount. Put most parameters
337  * in registers, and then stretched the for loop to multiples of 16 samples.
338  *
339  * I would prefer to have this turned into a linear input, rated at 1float per
340  * octave. This would require some considerable alterations to the oscillator
341  * sample step code, though. The basic operation is reasonably simple - we take
342  * a (midikey/12) and it gives us a step rate. We need to work in portamento and
343  * some more subtle oscillator driver changes.
344  */
operate(bristolOP * operator,bristolVoice * voice,bristolOPParams * param,void * lcl)345 static int operate(bristolOP *operator,
346 	bristolVoice *voice,
347 	bristolOPParams *param,
348 	void *lcl)
349 {
350 	bristolARPDCOlocal *local = lcl;
351 	int obp, count, dosquare;
352 	float *ramp, wtpSqr, gdelta, width, ssg;
353 	float *ib, *ob, *ob2, *mb, *sb, *wt, wtp, gain, transp, cpwm, lsv;
354 	float *obsin, *obtri, *sinwave, *triwave;
355 	bristolARPDCO *specs;
356 
357 	specs = (bristolARPDCO *) operator->specs;
358 
359 #ifdef BRISTOL_DBG
360 	printf("arpdco(%x, %x, %x)\n", operator, param, local);
361 #endif
362 
363 	count = specs->spec.io[DCO_OUT_RAMP].samplecount;
364 	ib = specs->spec.io[DCO_IN_IND].buf;
365 	mb = specs->spec.io[DCO_MOD_IND].buf;
366 	ob = specs->spec.io[DCO_OUT_RAMP].buf;
367 	ob2 = specs->spec.io[DCO_OUT_SQUARE].buf;
368 	if ((obsin = specs->spec.io[DCO_OUT_SINE].buf) == 0)
369 		obsin = zbuf;
370 	if ((obtri = specs->spec.io[DCO_OUT_TRIANGLE].buf) == 0)
371 		obtri = zbuf;
372 
373 	lsv = local->lsv;
374 
375 	/*
376 	 * Hm, this was not necessary - could just have taken a zero bufptr.
377 	 */
378 	if ((param->param[7].int_val)
379 		&& ((sb = specs->spec.io[DCO_SYNC_IND].buf) != 0))
380 			local->lsv = genSyncPoints(sbuf, sb, lsv, count);
381 	else
382 		sb = 0;
383 
384 	width = param->param[0].float_val; /* Pulse width */
385 	dosquare = param->param[6].int_val;
386 /*	wtp = local->wtp; */
387 	gain = param->param[3].float_val;
388 	ssg = local->ssg >= 0? gain:-gain;
389 
390 	/*
391 	 * We are going to add another tune parameter - number of semitones from
392 	 * zero - an addition to octave transpose and fine tune. We should add
393 	 * another fine tune for just +/- semitone
394 	 */
395 	transp = param->param[1].float_val * param->param[2].float_val
396 		* param->param[9].float_val * param->param[10].float_val
397 		* param->param[11].float_val;
398 	wtp = local->wtp;
399 	cpwm = local->cpwm;
400 
401 	sinwave = specs->wave[0];
402 	if (bristolBLOcheck(voice->dFreq*transp))
403 	{
404 		/* Need to restuff tri, ramp */
405 		memset(param->param[0].mem, 0, ARPDCO_WAVE_SZE * sizeof(float));
406 		memset(param->param[1].mem, 0, ARPDCO_WAVE_SZE * sizeof(float));
407 		ramp = param->param[0].mem;
408 		wt = ramp;
409 		triwave = param->param[1].mem;
410 		generateBLOwaveformF(voice->cFreq*transp, ramp, BLO_SAW);
411 		generateBLOwaveformF(voice->cFreq*transp, triwave, BLO_TRI);
412 	} else {
413 		wt = ramp = specs->wave[3];
414 		triwave = specs->wave[4];
415 	}
416 
417 	/*
418 	 * Go jumping through the wavetable, with each jump defined by the value
419 	 * given on our input line, making sure we fill one output buffer.
420 	 */
421 	for (obp = 0; obp < count;obp++)
422 	{
423 		/*
424 		 * Take a sample from the wavetable into the output buffer. This
425 		 * should also be scaled by gain parameter.
426 		 *
427 		 * We can seperate this into subroutine calls, or we can take our
428 		 * values and take each wave?
429 		 */
430 		gdelta = wtp - ((float) ((int) wtp));
431 
432 		if (wtp >= ARPDCO_WAVE_SZE_M) {
433 			ob[obp] += (wt[(int) wtp] + (wt[0] - wt[(int) wtp])
434 				* gdelta) * gain;
435 			obsin[obp] += (sinwave[(int) wtp]
436 				+ (sinwave[0] - sinwave[(int) wtp])
437 				* gdelta) * gain;
438 			obtri[obp] += (triwave[(int) wtp]
439 				+ (triwave[0] - triwave[(int) wtp])
440 				* gdelta) * gain;
441 		} else {
442 			ob[obp] += (wt[(int) wtp] + ((wt[(int) wtp + 1] - wt[(int) wtp])
443 				* gdelta)) * gain;
444 			obsin[obp] += (sinwave[(int) wtp]
445 				+ ((sinwave[(int) wtp + 1] - sinwave[(int) wtp])
446 				* gdelta)) * gain;
447 			obtri[obp] += (triwave[(int) wtp]
448 				+ ((triwave[(int) wtp + 1] - triwave[(int) wtp])
449 				* gdelta)) * gain;
450 		}
451 
452 		/*
453 		 * The square has to be computed real time as we are going to have
454 		 * pulse width modulation. Width is a faction of the wavetable size
455 		 * from zero to 50% (should be 5 to 50%?).
456 		 *
457 		 * This is a phased difference between two ramps.
458 		 *
459 		 * Fill in the ramp wave, then subtract the same waveform with a
460 		 * phase offset related to the width.
461 		 */
462 		if ((wtpSqr = width + *mb++) < ARPDCO_WAVE_PWMIN)
463 			wtpSqr = ARPDCO_WAVE_PWMIN;
464 		else if (wtpSqr > ARPDCO_WAVE_PWMAX)
465 			wtpSqr = ARPDCO_WAVE_PWMAX;
466 
467 		if ((wtpSqr = wtp + wtpSqr) > ARPDCO_WAVE_SZE_M)
468 			wtpSqr -= ARPDCO_WAVE_SZE;
469 
470 		if (wtp >= ARPDCO_WAVE_SZE_M)
471 			ob2[obp] += (ramp[(int) wtp] + (ramp[0] - ramp[(int) wtp])
472 				* gdelta) * ssg;
473 		else
474 			ob2[obp] +=
475 				(ramp[(int) wtp] + ((ramp[(int) wtp + 1] - ramp[(int) wtp])
476 				* gdelta)) * ssg;
477 
478 		gdelta = wtpSqr - ((float) ((int) wtpSqr));
479 
480 		if (wtpSqr == ARPDCO_WAVE_SZE_M)
481 			ob2[obp] -= (ramp[(int) wtpSqr] + (ramp[0] - ramp[(int) wtpSqr])
482 				* gdelta) * ssg;
483 		else
484 			ob2[obp] -=
485 				(ramp[(int) wtpSqr] + ((ramp[(int) wtpSqr + 1]
486 				- ramp[(int) wtpSqr]) * gdelta)) * ssg;
487 
488 		if (sb && (sbuf[obp] != 0))
489 		{
490 			/*
491 			 * These are positive edged zero crossings on the sync buffer. If
492 			 * we find them, wtp is moved to zero resampled from buffer.
493 			 */
494 			wtp = sbuf[obp];
495 			ssg = -ssg;
496 
497 			/* We may need to resample here */
498 
499 			continue;
500 		}
501 
502 		/*
503 		 * Move the wavetable pointer forward by amount indicated in input
504 		 * buffer for this sample.
505 		 */
506 		if ((wtp += ib[obp] * transp) >= ARPDCO_WAVE_SZE)
507 		{
508 			while (wtp >= ARPDCO_WAVE_SZE)
509 				wtp -= ARPDCO_WAVE_SZE;
510 		}
511 
512 		/*
513 		 * If we have gone negative, round back up. Allows us to run the
514 		 * oscillator backwards.
515 		 */
516 		while (wtp < 0)
517 			wtp += ARPDCO_WAVE_SZE;
518 	}
519 
520 	local->wtp = wtp;
521 	local->cpwm = cpwm;
522 	local->ssg = ssg;
523 
524 	return(0);
525 }
526 
527 /*
528  * Setup any variables in our OP structure, in our IO structures, and malloc
529  * any memory we need.
530  */
531 bristolOP *
arpdcoinit(bristolOP ** operator,int index,int samplerate,int samplecount)532 arpdcoinit(bristolOP **operator, int index, int samplerate, int samplecount)
533 {
534 	bristolARPDCO *specs;
535 
536 	*operator = bristolOPinit(operator, index, samplecount);
537 
538 #ifdef BRISTOL_DBG
539 	printf("arpdcoinit(%x(%x), %i, %i, %i)\n",
540 		operator, *operator, index, samplerate, samplecount);
541 #endif
542 
543 	note_diff = pow(2, ((double) 1)/12);
544 
545 	if (sbuf == NULL)
546 		sbuf = bristolmalloc(sizeof(float) * samplecount);
547 
548 	/*
549 	 * Then the local parameters specific to this operator. These will be
550 	 * the same for each operator, but must be inited in the local code.
551 	 */
552 	(*operator)->operate = operate;
553 	(*operator)->destroy = destroy;
554 	(*operator)->reset = reset;
555 	(*operator)->param= param;
556 
557 	specs = (bristolARPDCO *) bristolmalloc0(sizeof(bristolARPDCO));
558 	(*operator)->specs = (bristolOPSpec *) specs;
559 	(*operator)->size = sizeof(bristolARPDCO);
560 
561 	/*
562 	 * These are specific to this operator, and will need to be altered for
563 	 * each operator.
564 	 */
565 	specs->spec.opname = OPNAME;
566 	specs->spec.description = OPDESCRIPTION;
567 	specs->spec.pcount = PCOUNT;
568 	specs->spec.iocount = IOCOUNT;
569 	specs->spec.localsize = sizeof(bristolARPDCOlocal);
570 
571 	/*
572 	 * We are going to assign multiple waves to this oscillator.
573 	 * sine, ramp, square, triangle?
574 	 */
575 	specs->wave[0] =
576 		(float *) bristolmalloc(ARPDCO_WAVE_SZE * sizeof(float));
577 	specs->wave[1] =
578 		(float *) bristolmalloc(ARPDCO_WAVE_SZE * sizeof(float));
579 	specs->wave[2] =
580 		(float *) bristolmalloc(ARPDCO_WAVE_SZE * sizeof(float));
581 	specs->wave[3] =
582 		(float *) bristolmalloc(ARPDCO_WAVE_SZE * sizeof(float));
583 	specs->wave[4] =
584 		(float *) bristolmalloc(ARPDCO_WAVE_SZE * sizeof(float));
585 	specs->wave[5] =
586 		(float *) bristolmalloc(ARPDCO_WAVE_SZE * sizeof(float));
587 	specs->wave[6] =
588 		(float *) bristolmalloc(ARPDCO_WAVE_SZE * sizeof(float));
589 	specs->wave[7] =
590 		(float *) bristolmalloc(ARPDCO_WAVE_SZE * sizeof(float));
591 	zbuf = (float *) bristolmalloc(ARPDCO_WAVE_SZE * sizeof(float));
592 
593 	/*
594 	 * FillWave is something that should be called as a parameter change, but
595 	 * for testing will load it here.
596 	 */
597 	fillWave(specs->wave[0], ARPDCO_WAVE_SZE, 0);
598 	fillWave(specs->wave[1], ARPDCO_WAVE_SZE, 1);
599 	fillWave(specs->wave[2], ARPDCO_WAVE_SZE, 2);
600 	fillWave(specs->wave[3], ARPDCO_WAVE_SZE, 3);
601 	fillWave(specs->wave[4], ARPDCO_WAVE_SZE, 4);
602 	fillWave(specs->wave[5], ARPDCO_WAVE_SZE, 5);
603 	fillWave(specs->wave[6], ARPDCO_WAVE_SZE, 6);
604 	fillWave(specs->wave[7], ARPDCO_WAVE_SZE, 7);
605 
606 	/*
607 	 * Now fill in the dco specs for this operator. These are specific to an
608 	 * oscillator.
609 	 */
610 	specs->spec.param[0].pname = "Pulse";
611 	specs->spec.param[0].description = "Pulse width";
612 	specs->spec.param[0].type = BRISTOL_FLOAT;
613 	specs->spec.param[0].low = 0;
614 	specs->spec.param[0].high = 1;
615 	specs->spec.param[0].flags = BRISTOL_ROTARY|BRISTOL_SLIDER;
616 
617 	specs->spec.param[1].pname = "Transpose";
618 	specs->spec.param[1].description = "Octave transposition";
619 	specs->spec.param[1].type = BRISTOL_INT;
620 	specs->spec.param[1].low = 0;
621 	specs->spec.param[1].high = 12;
622 	specs->spec.param[1].flags = BRISTOL_ROTARY|BRISTOL_SLIDER;
623 
624 	specs->spec.param[2].pname = "Tune";
625 	specs->spec.param[2].description = "fine tuning of frequency";
626 	specs->spec.param[2].type = BRISTOL_FLOAT;
627 	specs->spec.param[2].low = 0;
628 	specs->spec.param[2].high = 1;
629 	specs->spec.param[2].flags = BRISTOL_ROTARY|BRISTOL_SLIDER;
630 
631 	specs->spec.param[3].pname = "gain";
632 	specs->spec.param[3].description = "output gain on signal";
633 	specs->spec.param[3].type = BRISTOL_FLOAT;
634 	specs->spec.param[3].low = 0;
635 	specs->spec.param[3].high = 2;
636 	specs->spec.param[3].flags = BRISTOL_ROTARY|BRISTOL_SLIDER|BRISTOL_HIDE;
637 
638 	specs->spec.param[4].pname = "Ramp";
639 	specs->spec.param[4].description = "harmonic inclusion of ramp wave";
640 	specs->spec.param[4].type = BRISTOL_INT;
641 	specs->spec.param[4].low = 0;
642 	specs->spec.param[4].high = 1;
643 	specs->spec.param[4].flags = BRISTOL_BUTTON;
644 
645 	specs->spec.param[5].pname = "Triangle";
646 	specs->spec.param[5].description = "harmonic inclusion of triagular wave";
647 	specs->spec.param[5].type = BRISTOL_INT;
648 	specs->spec.param[5].low = 0;
649 	specs->spec.param[5].high = 1;
650 	specs->spec.param[5].flags = BRISTOL_BUTTON;
651 
652 	specs->spec.param[6].pname = "PWM";
653 	specs->spec.param[6].description = "harmonic inclusion of square/pwm wave";
654 	specs->spec.param[6].type = BRISTOL_INT;
655 	specs->spec.param[6].low = 0;
656 	specs->spec.param[6].high = 1;
657 	specs->spec.param[6].flags = BRISTOL_BUTTON;
658 
659 	specs->spec.param[7].pname = "Square";
660 	specs->spec.param[7].description = "harmonic inclusion of square wave";
661 	specs->spec.param[7].type = BRISTOL_INT;
662 	specs->spec.param[7].low = 0;
663 	specs->spec.param[7].high = 1;
664 	specs->spec.param[7].flags = BRISTOL_BUTTON;
665 
666 	specs->spec.param[8].pname = "Sine";
667 	specs->spec.param[8].description = "harmonic inclusion of sine wave";
668 	specs->spec.param[8].type = BRISTOL_INT;
669 	specs->spec.param[8].low = 0;
670 	specs->spec.param[8].high = 1;
671 	specs->spec.param[8].flags = BRISTOL_BUTTON;
672 
673 	/*
674 	 * Now fill in the dco IO specs.
675 	 */
676 	specs->spec.io[0].ioname = "input";
677 	specs->spec.io[0].description = "input rate modulation signal";
678 	specs->spec.io[0].samplerate = samplerate;
679 	specs->spec.io[0].samplecount = samplecount;
680 	specs->spec.io[0].flags = BRISTOL_DC|BRISTOL_INPUT;
681 
682 	specs->spec.io[1].ioname = "mod";
683 	specs->spec.io[1].description = "pulse width modulation";
684 	specs->spec.io[1].samplerate = samplerate;
685 	specs->spec.io[1].samplecount = samplecount;
686 	specs->spec.io[1].flags = BRISTOL_DC|BRISTOL_INPUT;
687 
688 	specs->spec.io[2].ioname = "ramp output";
689 	specs->spec.io[2].description = "oscillator ramp output signal";
690 	specs->spec.io[2].samplerate = samplerate;
691 	specs->spec.io[2].samplecount = samplecount;
692 	specs->spec.io[2].flags = BRISTOL_AC|BRISTOL_OUTPUT;
693 
694 	specs->spec.io[3].ioname = "sync";
695 	specs->spec.io[3].description = "synchronisation signal";
696 	specs->spec.io[3].samplerate = samplerate;
697 	specs->spec.io[3].samplecount = samplecount;
698 	specs->spec.io[3].flags = BRISTOL_DC|BRISTOL_INPUT;
699 
700 	specs->spec.io[4].ioname = "square output";
701 	specs->spec.io[4].description = "oscillator pulse/square output signal";
702 	specs->spec.io[4].samplerate = samplerate;
703 	specs->spec.io[4].samplecount = samplecount;
704 	specs->spec.io[4].flags = BRISTOL_AC|BRISTOL_OUTPUT;
705 
706 	specs->spec.io[5].ioname = "sine output";
707 	specs->spec.io[5].description = "oscillator sine output signal";
708 	specs->spec.io[5].samplerate = samplerate;
709 	specs->spec.io[5].samplecount = samplecount;
710 	specs->spec.io[5].flags = BRISTOL_AC|BRISTOL_OUTPUT;
711 
712 	specs->spec.io[6].ioname = "triangle output";
713 	specs->spec.io[6].description = "oscillator triangle output signal";
714 	specs->spec.io[6].samplerate = samplerate;
715 	specs->spec.io[6].samplecount = samplecount;
716 	specs->spec.io[6].flags = BRISTOL_AC|BRISTOL_OUTPUT;
717 
718 	return(*operator);
719 }
720 
721 static void
fillPDsine(float * mem,int count,int compress)722 fillPDsine(float *mem, int count, int compress)
723 {
724 	float j = 0, i, inc1, inc2;
725 
726 	/*
727 	 * Resample the sine wave with a phase distortion algorithm.
728 	 *
729 	 * We have to get to M_PI/2 in compress steps, hence
730 	 *
731 	 *	 inc1 = M_PI/(2 * compress)
732 	 *
733 	 * Then we have to scan M_PI in (count - 2 * compress), hence:
734 	 *
735 	 *	 inc2 = M_PI/(count - 2 * compress)
736 	 */
737 	inc1 = ((float) M_PI) / (((float) 2) * ((float) compress));
738 	inc2 = ((float) M_PI) / ((float) (count - 2 * compress));
739 
740 	for (i = 0;i < count; i++)
741 	{
742 		*mem++ = sinf(j) * BRISTOL_VPO;
743 
744 		if (i < compress)
745 			j += inc1;
746 		else if (i > (count - 2 * compress))
747 			j += inc1;
748 		else
749 			j += inc2;
750 	}
751 }
752 
753 /*
754  * Waves have a range of 24, which is basically two octaves. For larger
755  * differences will have to apply apms.
756  */
757 static void
fillWave(float * mem,int count,int type)758 fillWave(float *mem, int count, int type)
759 {
760 	int i;
761 
762 #ifdef BRISTOL_DBG
763 	printf("fillWave(%x, %i, %i)\n", mem, count, type);
764 #endif
765 
766 	switch (type) {
767 		case 0:
768 			/*
769 			 * This will be a sine wave. We have count samples, and
770 			 * 2PI radians in a full sine wave. Thus we take
771 			 * 		(2PI * i / count) * 2048.
772 			 */
773 			for (i = 0;i < count; i++)
774 				mem[i] = sin(2 * M_PI * ((double) i) / count) * BRISTOL_VPO;
775 			return;
776 		case 1:
777 		default:
778 		{
779 			float value = BRISTOL_SQR;
780 			/*
781 			 * This is a square wave, with decaying plateaus.
782 			 */
783 			if (blo.flags & BRISTOL_BLO)
784 			{
785 				for (i = 0;i < count; i++)
786 					mem[i] = blosquare[i];
787 					return;
788 			}
789 			for (i = 0;i < count / 2; i++)
790 				mem[i] = (value * S_DEC);
791 			value = -BRISTOL_SQR;
792 			for (;i < count; i++)
793 				mem[i] = (value * S_DEC);
794 			return;
795 		}
796 		case 2:
797 			/*
798 			 * This is a pulse wave - the arp dco does pwm.
799 			 */
800 			for (i = 0;i < count / 5; i++)
801 				mem[i] = BRISTOL_VPO * 2 / 3;
802 			for (;i < count; i++)
803 				mem[i] = -BRISTOL_VPO * 2 / 3;
804 			return;
805 		case 3:
806 			/*
807 			 * This is a ramp wave. We scale the index from -.5 to .5, and
808 			 * multiply by the range. We go from rear to front to table to make
809 			 * the ramp wave have a positive leading edge.
810 			for (i = 0; i < count / 2; i++)
811 				mem[i] = ((float) i / count) * BRISTOL_VPO * 2.0;
812 			for (; i < count; i++)
813 				mem[i] = ((float) i / count) * BRISTOL_VPO * 2.0 -
814 					BRISTOL_VPO * 2;
815 			for (i = count - 1;i >= 0; i--)
816 				mem[i] = (((float) i / count) - 0.5) * BRISTOL_VPO * 2.0;
817 			mem[0] = 0;
818 			mem[count - 1] = mem[1]
819 				= BRISTOL_VPO;
820 			 */
821 			if (blo.flags & BRISTOL_BLO)
822 			{
823 				for (i = 0;i < count; i++)
824 					mem[i] = bloramp[i];
825 					return;
826 			}
827 			fillPDsine(mem, count, 5);
828 			return;
829 		case 4:
830 			/*
831 			 * Triangular wave. From MIN point, ramp up at twice the rate of
832 			 * the ramp wave, then ramp down at same rate.
833 			 */
834 			if (blo.flags & BRISTOL_BLO)
835 			{
836 				for (i = 0;i < count; i++)
837 					mem[i] = blotriangle[i];
838 					return;
839 			}
840 			for (i = 0;i < count / 2; i++)
841 				mem[i] = -BRISTOL_VPO
842 					+ ((float) i / (count / 2)) * BRISTOL_VPO * 2;
843 			for (;i < count; i++)
844 				mem[i] = BRISTOL_VPO -
845 					(((float) (i - count / 2) * 2) / (count / 2)) * BRISTOL_VPO;
846 			return;
847 		case 5:
848 			/*
849 			 * Would like to put in a jagged edged ramp wave. Should make some
850 			 * interesting strings sounds.
851 			 */
852 			{
853 				float accum = -BRISTOL_VPO;
854 
855 				for (i = 0; i < count / 2; i++)
856 				{
857 					mem[i] = accum +
858 						(0.5 - (((float) i) / count)) * BRISTOL_VPO * 4;
859 					if (i == count / 8)
860 						accum = -BRISTOL_VPO * 3 / 4;
861 					if (i == count / 4)
862 						accum = -BRISTOL_VPO / 2;
863 					if (i == count * 3 / 8)
864 						accum = -BRISTOL_VPO / 4;
865 				}
866 				for (; i < count; i++)
867 					mem[i] = -mem[count - i];
868 			}
869 			return;
870 		case 6:
871 			/*
872 			 * Tangiential wave. We limit some of the values, since they do get
873 			 * excessive. This is only half a tan as well, to maintain the
874 			 * base frequency.
875 			 */
876 			for (i = 0;i < count; i++)
877 			{
878 				if ((mem[i] =
879 					tan(M_PI * ((double) i) / count) * BRISTOL_VPO / 16)
880 					> BRISTOL_VPO * 8)
881 					mem[i] = BRISTOL_VPO * 6;
882 				if (mem[i] < -(BRISTOL_VPO * 6))
883 					mem[i] = -BRISTOL_VPO * 6;
884 			}
885 			return;
886 		case 7:
887 			/*
888 			 * Sine wave - added as a part of the OBX extensions.
889 			 */
890 			for (i = 0;i < count; i++)
891 				mem[i] = sin(2 * M_PI * ((double) i) / count) * BRISTOL_VPO;
892 			return;
893 	}
894 }
895 
896