1 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
2  * Copyright (C) 2011-2016 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU Lesser General Public License as published by
6  *  the Free Software Foundation, either version 2.1 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <cstddef>
19 
20 #include "internals.h"
21 
22 #include "Partial.h"
23 #include "Part.h"
24 #include "Poly.h"
25 #include "Synth.h"
26 #include "Tables.h"
27 #include "TVA.h"
28 #include "TVF.h"
29 #include "TVP.h"
30 
31 namespace MT32Emu {
32 
33 static const Bit8u PAN_NUMERATOR_MASTER[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7};
34 static const Bit8u PAN_NUMERATOR_SLAVE[]  = {0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7};
35 
36 static const Bit32s PAN_FACTORS[] = {0, 18, 37, 55, 73, 91, 110, 128, 146, 165, 183, 201, 219, 238, 256};
37 
Partial(Synth * useSynth,int useDebugPartialNum)38 Partial::Partial(Synth *useSynth, int useDebugPartialNum) :
39 	synth(useSynth), debugPartialNum(useDebugPartialNum), sampleNum(0) {
40 	// Initialisation of tva, tvp and tvf uses 'this' pointer
41 	// and thus should not be in the initializer list to avoid a compiler warning
42 	tva = new TVA(this, &ampRamp);
43 	tvp = new TVP(this);
44 	tvf = new TVF(this, &cutoffModifierRamp);
45 	ownerPart = -1;
46 	poly = NULL;
47 	pair = NULL;
48 }
49 
~Partial()50 Partial::~Partial() {
51 	delete tva;
52 	delete tvp;
53 	delete tvf;
54 }
55 
56 // Only used for debugging purposes
debugGetPartialNum() const57 int Partial::debugGetPartialNum() const {
58 	return debugPartialNum;
59 }
60 
61 // Only used for debugging purposes
debugGetSampleNum() const62 Bit32u Partial::debugGetSampleNum() const {
63 	return sampleNum;
64 }
65 
getOwnerPart() const66 int Partial::getOwnerPart() const {
67 	return ownerPart;
68 }
69 
isActive() const70 bool Partial::isActive() const {
71 	return ownerPart > -1;
72 }
73 
getPoly() const74 const Poly *Partial::getPoly() const {
75 	return poly;
76 }
77 
activate(int part)78 void Partial::activate(int part) {
79 	// This just marks the partial as being assigned to a part
80 	ownerPart = part;
81 }
82 
deactivate()83 void Partial::deactivate() {
84 	if (!isActive()) {
85 		return;
86 	}
87 	ownerPart = -1;
88 	if (poly != NULL) {
89 		poly->partialDeactivated(this);
90 	}
91 #if MT32EMU_MONITOR_PARTIALS > 2
92 	synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, debugPartialNum);
93 	synth->printPartialUsage(sampleNum);
94 #endif
95 	if (isRingModulatingSlave()) {
96 		pair->la32Pair.deactivate(LA32PartialPair::SLAVE);
97 	} else {
98 		la32Pair.deactivate(LA32PartialPair::MASTER);
99 		if (hasRingModulatingSlave()) {
100 			pair->deactivate();
101 			pair = NULL;
102 		}
103 	}
104 	if (pair != NULL) {
105 		pair->pair = NULL;
106 	}
107 }
108 
startPartial(const Part * part,Poly * usePoly,const PatchCache * usePatchCache,const MemParams::RhythmTemp * rhythmTemp,Partial * pairPartial)109 void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *usePatchCache, const MemParams::RhythmTemp *rhythmTemp, Partial *pairPartial) {
110 	if (usePoly == NULL || usePatchCache == NULL) {
111 		synth->printDebug("[Partial %d] *** Error: Starting partial for owner %d, usePoly=%s, usePatchCache=%s", debugPartialNum, ownerPart, usePoly == NULL ? "*** NULL ***" : "OK", usePatchCache == NULL ? "*** NULL ***" : "OK");
112 		return;
113 	}
114 	patchCache = usePatchCache;
115 	poly = usePoly;
116 	mixType = patchCache->structureMix;
117 	structurePosition = patchCache->structurePosition;
118 
119 	Bit8u panSetting = rhythmTemp != NULL ? rhythmTemp->panpot : part->getPatchTemp()->panpot;
120 	if (mixType == 3) {
121 		if (structurePosition == 0) {
122 			panSetting = PAN_NUMERATOR_MASTER[panSetting] << 1;
123 		} else {
124 			panSetting = PAN_NUMERATOR_SLAVE[panSetting] << 1;
125 		}
126 		// Do a normal mix independent of any pair partial.
127 		mixType = 0;
128 		pairPartial = NULL;
129 	} else {
130 		// Mok wanted an option for smoother panning, and we love Mok.
131 #ifndef INACCURATE_SMOOTH_PAN
132 		// CONFIRMED by Mok: exactly bytes like this (right shifted?) are sent to the LA32.
133 		panSetting &= 0x0E;
134 #endif
135 	}
136 
137 	leftPanValue = synth->reversedStereoEnabled ? 14 - panSetting : panSetting;
138 	rightPanValue = 14 - leftPanValue;
139 
140 #if !MT32EMU_USE_FLOAT_SAMPLES
141 	leftPanValue = PAN_FACTORS[leftPanValue];
142 	rightPanValue = PAN_FACTORS[rightPanValue];
143 #endif
144 
145 	// SEMI-CONFIRMED: From sample analysis:
146 	// Found that timbres with 3 or 4 partials (i.e. one using two partial pairs) are mixed in two different ways.
147 	// Either partial pairs are added or subtracted, it depends on how the partial pairs are allocated.
148 	// It seems that partials are grouped into quarters and if the partial pairs are allocated in different quarters the subtraction happens.
149 	// Though, this matters little for the majority of timbres, it becomes crucial for timbres which contain several partials that sound very close.
150 	// In this case that timbre can sound totally different depending of the way it is mixed up.
151 	// Most easily this effect can be displayed with the help of a special timbre consisting of several identical square wave partials (3 or 4).
152 	// Say, it is 3-partial timbre. Just play any two notes simultaneously and the polys very probably are mixed differently.
153 	// Moreover, the partial allocator retains the last partial assignment it did and all the subsequent notes will sound the same as the last released one.
154 	// The situation is better with 4-partial timbres since then a whole quarter is assigned for each poly. However, if a 3-partial timbre broke the normal
155 	// whole-quarter assignment or after some partials got aborted, even 4-partial timbres can be found sounding differently.
156 	// This behaviour is also confirmed with two more special timbres: one with identical sawtooth partials, and one with PCM wave 02.
157 	// For my personal taste, this behaviour rather enriches the sounding and should be emulated.
158 	// Also, the current partial allocator model probably needs to be refined.
159 	if (debugPartialNum & 8) {
160 		leftPanValue = -leftPanValue;
161 		rightPanValue = -rightPanValue;
162 	}
163 
164 	if (patchCache->PCMPartial) {
165 		pcmNum = patchCache->pcm;
166 		if (synth->controlROMMap->pcmCount > 128) {
167 			// CM-32L, etc. support two "banks" of PCMs, selectable by waveform type parameter.
168 			if (patchCache->waveform > 1) {
169 				pcmNum += 128;
170 			}
171 		}
172 		pcmWave = &synth->pcmWaves[pcmNum];
173 	} else {
174 		pcmWave = NULL;
175 	}
176 
177 	// CONFIRMED: pulseWidthVal calculation is based on information from Mok
178 	pulseWidthVal = (poly->getVelocity() - 64) * (patchCache->srcPartial.wg.pulseWidthVeloSensitivity - 7) + Tables::getInstance().pulseWidth100To255[patchCache->srcPartial.wg.pulseWidth];
179 	if (pulseWidthVal < 0) {
180 		pulseWidthVal = 0;
181 	} else if (pulseWidthVal > 255) {
182 		pulseWidthVal = 255;
183 	}
184 
185 	pair = pairPartial;
186 	alreadyOutputed = false;
187 	tva->reset(part, patchCache->partialParam, rhythmTemp);
188 	tvp->reset(part, patchCache->partialParam);
189 	tvf->reset(patchCache->partialParam, tvp->getBasePitch());
190 
191 	LA32PartialPair::PairType pairType;
192 	LA32PartialPair *useLA32Pair;
193 	if (isRingModulatingSlave()) {
194 		pairType = LA32PartialPair::SLAVE;
195 		useLA32Pair = &pair->la32Pair;
196 	} else {
197 		pairType = LA32PartialPair::MASTER;
198 		la32Pair.init(hasRingModulatingSlave(), mixType == 1);
199 		useLA32Pair = &la32Pair;
200 	}
201 	if (isPCM()) {
202 		useLA32Pair->initPCM(pairType, &synth->pcmROMData[pcmWave->addr], pcmWave->len, pcmWave->loop);
203 	} else {
204 		useLA32Pair->initSynth(pairType, (patchCache->waveform & 1) != 0, pulseWidthVal, patchCache->srcPartial.tvf.resonance + 1);
205 	}
206 	if (!hasRingModulatingSlave()) {
207 		la32Pair.deactivate(LA32PartialPair::SLAVE);
208 	}
209 }
210 
getAmpValue()211 Bit32u Partial::getAmpValue() {
212 	// SEMI-CONFIRMED: From sample analysis:
213 	// (1) Tested with a single partial playing PCM wave 77 with pitchCoarse 36 and no keyfollow, velocity follow, etc.
214 	// This gives results within +/- 2 at the output (before any DAC bitshifting)
215 	// when sustaining at levels 156 - 255 with no modifiers.
216 	// (2) Tested with a special square wave partial (internal capture ID tva5) at TVA envelope levels 155-255.
217 	// This gives deltas between -1 and 0 compared to the real output. Note that this special partial only produces
218 	// positive amps, so negative still needs to be explored, as well as lower levels.
219 	//
220 	// Also still partially unconfirmed is the behaviour when ramping between levels, as well as the timing.
221 	// TODO: The tests above were performed using the float model, to be refined
222 	Bit32u ampRampVal = 67117056 - ampRamp.nextValue();
223 	if (ampRamp.checkInterrupt()) {
224 		tva->handleInterrupt();
225 	}
226 	return ampRampVal;
227 }
228 
getCutoffValue()229 Bit32u Partial::getCutoffValue() {
230 	if (isPCM()) {
231 		return 0;
232 	}
233 	Bit32u cutoffModifierRampVal = cutoffModifierRamp.nextValue();
234 	if (cutoffModifierRamp.checkInterrupt()) {
235 		tvf->handleInterrupt();
236 	}
237 	return (tvf->getBaseCutoff() << 18) + cutoffModifierRampVal;
238 }
239 
hasRingModulatingSlave() const240 bool Partial::hasRingModulatingSlave() const {
241 	return pair != NULL && structurePosition == 0 && (mixType == 1 || mixType == 2);
242 }
243 
isRingModulatingSlave() const244 bool Partial::isRingModulatingSlave() const {
245 	return pair != NULL && structurePosition == 1 && (mixType == 1 || mixType == 2);
246 }
247 
isPCM() const248 bool Partial::isPCM() const {
249 	return pcmWave != NULL;
250 }
251 
getControlROMPCMStruct() const252 const ControlROMPCMStruct *Partial::getControlROMPCMStruct() const {
253 	if (pcmWave != NULL) {
254 		return pcmWave->controlROMPCMStruct;
255 	}
256 	return NULL;
257 }
258 
getSynth() const259 Synth *Partial::getSynth() const {
260 	return synth;
261 }
262 
getTVA() const263 TVA *Partial::getTVA() const {
264 	return tva;
265 }
266 
backupCache(const PatchCache & cache)267 void Partial::backupCache(const PatchCache &cache) {
268 	if (patchCache == &cache) {
269 		cachebackup = cache;
270 		patchCache = &cachebackup;
271 	}
272 }
273 
produceOutput(Sample * leftBuf,Sample * rightBuf,Bit32u length)274 bool Partial::produceOutput(Sample *leftBuf, Sample *rightBuf, Bit32u length) {
275 	if (!isActive() || alreadyOutputed || isRingModulatingSlave()) {
276 		return false;
277 	}
278 	if (poly == NULL) {
279 		synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::produceOutput()!", debugPartialNum);
280 		return false;
281 	}
282 	alreadyOutputed = true;
283 
284 	for (sampleNum = 0; sampleNum < length; sampleNum++) {
285 		if (!tva->isPlaying() || !la32Pair.isActive(LA32PartialPair::MASTER)) {
286 			deactivate();
287 			break;
288 		}
289 		la32Pair.generateNextSample(LA32PartialPair::MASTER, getAmpValue(), tvp->nextPitch(), getCutoffValue());
290 		if (hasRingModulatingSlave()) {
291 			la32Pair.generateNextSample(LA32PartialPair::SLAVE, pair->getAmpValue(), pair->tvp->nextPitch(), pair->getCutoffValue());
292 			if (!pair->tva->isPlaying() || !la32Pair.isActive(LA32PartialPair::SLAVE)) {
293 				pair->deactivate();
294 				if (mixType == 2) {
295 					deactivate();
296 					break;
297 				}
298 			}
299 		}
300 
301 		// Although, LA32 applies panning itself, we assume here it is applied in the mixer, not within a pair.
302 		// Applying the pan value in the log-space looks like a waste of unlog resources. Though, it needs clarification.
303 		Sample sample = la32Pair.nextOutSample();
304 
305 		// FIXME: Sample analysis suggests that the use of panVal is linear, but there are some quirks that still need to be resolved.
306 #if MT32EMU_USE_FLOAT_SAMPLES
307 		Sample leftOut = (sample * (float)leftPanValue) / 14.0f;
308 		Sample rightOut = (sample * (float)rightPanValue) / 14.0f;
309 		*(leftBuf++) += leftOut;
310 		*(rightBuf++) += rightOut;
311 #else
312 		// FIXME: Dividing by 7 (or by 14 in a Mok-friendly way) looks of course pointless. Need clarification.
313 		// FIXME2: LA32 may produce distorted sound in case if the absolute value of maximal amplitude of the input exceeds 8191
314 		// when the panning value is non-zero. Most probably the distortion occurs in the same way it does with ring modulation,
315 		// and it seems to be caused by limited precision of the common multiplication circuit.
316 		// From analysis of this overflow, it is obvious that the right channel output is actually found
317 		// by subtraction of the left channel output from the input.
318 		// Though, it is unknown whether this overflow is exploited somewhere.
319 		Sample leftOut = Sample((sample * leftPanValue) >> 8);
320 		Sample rightOut = Sample((sample * rightPanValue) >> 8);
321 		*leftBuf = Synth::clipSampleEx((SampleEx)*leftBuf + (SampleEx)leftOut);
322 		*rightBuf = Synth::clipSampleEx((SampleEx)*rightBuf + (SampleEx)rightOut);
323 		leftBuf++;
324 		rightBuf++;
325 #endif
326 	}
327 	sampleNum = 0;
328 	return true;
329 }
330 
shouldReverb()331 bool Partial::shouldReverb() {
332 	if (!isActive()) {
333 		return false;
334 	}
335 	return patchCache->reverb;
336 }
337 
startAbort()338 void Partial::startAbort() {
339 	// This is called when the partial manager needs to terminate partials for re-use by a new Poly.
340 	tva->startAbort();
341 }
342 
startDecayAll()343 void Partial::startDecayAll() {
344 	tva->startDecay();
345 	tvp->startDecay();
346 	tvf->startDecay();
347 }
348 
349 } // namespace MT32Emu
350