aboutsummaryrefslogtreecommitdiff
path: root/audio/softsynth/mt32/Partial.h
blob: e297710f78790eb2fa66c61f44f61a3e6e0021e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
 * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 2.1 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MT32EMU_PARTIAL_H
#define MT32EMU_PARTIAL_H

#include "globals.h"
#include "internals.h"
#include "Types.h"
#include "Structures.h"
#include "LA32Ramp.h"
#include "LA32WaveGenerator.h"
#include "LA32FloatWaveGenerator.h"

namespace MT32Emu {

class Part;
class Poly;
class Synth;
class TVA;
class TVF;
class TVP;
struct ControlROMPCMStruct;

// A partial represents one of up to four waveform generators currently playing within a poly.
class Partial {
private:
	Synth *synth;
	const int partialIndex; // Index of this Partial in the global partial table
	// Number of the sample currently being rendered by produceOutput(), or 0 if no run is in progress
	// This is only kept available for debugging purposes.
	Bit32u sampleNum;

	// Actually, this is a 4-bit register but we abuse this to emulate inverted mixing.
	// Also we double the value to enable INACCURATE_SMOOTH_PAN, with respect to MoK.
	Bit32s leftPanValue, rightPanValue;

	int ownerPart; // -1 if unassigned
	int mixType;
	int structurePosition; // 0 or 1 of a structure pair

	// Only used for PCM partials
	int pcmNum;
	// FIXME: Give this a better name (e.g. pcmWaveInfo)
	PCMWaveEntry *pcmWave;

	// Final pulse width value, with velfollow applied, matching what is sent to the LA32.
	// Range: 0-255
	int pulseWidthVal;

	Poly *poly;
	Partial *pair;

	TVA *tva;
	TVP *tvp;
	TVF *tvf;

	LA32Ramp ampRamp;
	LA32Ramp cutoffModifierRamp;

	// TODO: This should be owned by PartialPair
	LA32PartialPair *la32Pair;
	const bool floatMode;

	const PatchCache *patchCache;
	PatchCache cachebackup;

	Bit32u getAmpValue();
	Bit32u getCutoffValue();

	template <class Sample, class LA32PairImpl>
	bool doProduceOutput(Sample *leftBuf, Sample *rightBuf, Bit32u length, LA32PairImpl *la32PairImpl);
	bool canProduceOutput();
	template <class LA32PairImpl>
	bool generateNextSample(LA32PairImpl *la32PairImpl);
	void produceAndMixSample(IntSample *&leftBuf, IntSample *&rightBuf, LA32IntPartialPair *la32IntPair);
	void produceAndMixSample(FloatSample *&leftBuf, FloatSample *&rightBuf, LA32FloatPartialPair *la32FloatPair);

public:
	bool alreadyOutputed;

	Partial(Synth *synth, int debugPartialNum);
	~Partial();

	int debugGetPartialNum() const;
	Bit32u debugGetSampleNum() const;

	int getOwnerPart() const;
	const Poly *getPoly() const;
	bool isActive() const;
	void activate(int part);
	void deactivate(void);
	void startPartial(const Part *part, Poly *usePoly, const PatchCache *useCache, const MemParams::RhythmTemp *rhythmTemp, Partial *pairPartial);
	void startAbort();
	void startDecayAll();
	bool shouldReverb();
	bool isRingModulatingNoMix() const;
	bool hasRingModulatingSlave() const;
	bool isRingModulatingSlave() const;
	bool isPCM() const;
	const ControlROMPCMStruct *getControlROMPCMStruct() const;
	Synth *getSynth() const;
	TVA *getTVA() const;

	void backupCache(const PatchCache &cache);

	// Returns true only if data written to buffer
	// These functions produce processed stereo samples
	// made from combining this single partial with its pair, if it has one.
	bool produceOutput(IntSample *leftBuf, IntSample *rightBuf, Bit32u length);
	bool produceOutput(FloatSample *leftBuf, FloatSample *rightBuf, Bit32u length);
}; // class Partial

} // namespace MT32Emu

#endif // #ifndef MT32EMU_PARTIAL_H