1 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
2  * Copyright (C) 2011-2021 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 #ifndef MT32EMU_PART_H
19 #define MT32EMU_PART_H
20 
21 #include "globals.h"
22 #include "internals.h"
23 #include "Types.h"
24 #include "Structures.h"
25 
26 namespace MT32Emu {
27 
28 class Poly;
29 class Synth;
30 
31 class PolyList {
32 private:
33 	Poly *firstPoly;
34 	Poly *lastPoly;
35 
36 public:
37 	PolyList();
38 	bool isEmpty() const;
39 	Poly *getFirst() const;
40 	Poly *getLast() const;
41 	void prepend(Poly *poly);
42 	void append(Poly *poly);
43 	Poly *takeFirst();
44 	void remove(Poly * const poly);
45 };
46 
47 class Part {
48 private:
49 	// Direct pointer to sysex-addressable memory dedicated to this part (valid for parts 1-8, NULL for rhythm)
50 	TimbreParam *timbreTemp;
51 
52 	// 0=Part 1, .. 7=Part 8, 8=Rhythm
53 	unsigned int partNum;
54 
55 	bool holdpedal;
56 
57 	unsigned int activePartialCount;
58 	PatchCache patchCache[4];
59 	PolyList activePolys;
60 
61 	void setPatch(const PatchParam *patch);
62 	unsigned int midiKeyToKey(unsigned int midiKey);
63 
64 	bool abortFirstPoly(unsigned int key);
65 
66 protected:
67 	Synth *synth;
68 	// Direct pointer into sysex-addressable memory
69 	MemParams::PatchTemp *patchTemp;
70 	char name[8]; // "Part 1".."Part 8", "Rhythm"
71 	char currentInstr[11];
72 	Bit8u modulation;
73 	Bit8u expression;
74 	Bit32s pitchBend;
75 	bool nrpn;
76 	Bit16u rpn;
77 	Bit16u pitchBenderRange; // (patchTemp->patch.benderRange * 683) at the time of the last MIDI program change or MIDI data entry.
78 
79 	void backupCacheToPartials(PatchCache cache[4]);
80 	void cacheTimbre(PatchCache cache[4], const TimbreParam *timbre);
81 	void playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity);
82 	void stopNote(unsigned int key);
83 	const char *getName() const;
84 
85 public:
86 	Part(Synth *synth, unsigned int usePartNum);
87 	virtual ~Part();
88 	void reset();
89 	void setDataEntryMSB(unsigned char midiDataEntryMSB);
90 	void setNRPN();
91 	void setRPNLSB(unsigned char midiRPNLSB);
92 	void setRPNMSB(unsigned char midiRPNMSB);
93 	void resetAllControllers();
94 	virtual void noteOn(unsigned int midiKey, unsigned int velocity);
95 	virtual void noteOff(unsigned int midiKey);
96 	void allNotesOff();
97 	void allSoundOff();
98 	Bit8u getVolume() const; // Internal volume, 0-100, exposed for use by ExternalInterface
99 	void setVolume(unsigned int midiVolume);
100 	Bit8u getModulation() const;
101 	void setModulation(unsigned int midiModulation);
102 	Bit8u getExpression() const;
103 	void setExpression(unsigned int midiExpression);
104 	virtual void setPan(unsigned int midiPan);
105 	Bit32s getPitchBend() const;
106 	void setBend(unsigned int midiBend);
107 	virtual void setProgram(unsigned int midiProgram);
108 	void setHoldPedal(bool pedalval);
109 	void stopPedalHold();
110 	void updatePitchBenderRange();
111 	virtual void refresh();
112 	virtual void refreshTimbre(unsigned int absTimbreNum);
113 	virtual void setTimbre(TimbreParam *timbre);
114 	virtual unsigned int getAbsTimbreNum() const;
115 	const char *getCurrentInstr() const;
116 	const Poly *getFirstActivePoly() const;
117 	unsigned int getActivePartialCount() const;
118 	unsigned int getActiveNonReleasingPartialCount() const;
119 	Synth *getSynth() const;
120 
121 	const MemParams::PatchTemp *getPatchTemp() const;
122 
123 	// This should only be called by Poly
124 	void partialDeactivated(Poly *poly);
125 
126 	// These are rather specialised, and should probably only be used by PartialManager
127 	bool abortFirstPoly(PolyState polyState);
128 	// Abort the first poly in PolyState_HELD, or if none exists, the first active poly in any state.
129 	bool abortFirstPolyPreferHeld();
130 	bool abortFirstPoly();
131 }; // class Part
132 
133 class RhythmPart: public Part {
134 	// Pointer to the area of the MT-32's memory dedicated to rhythm
135 	const MemParams::RhythmTemp *rhythmTemp;
136 
137 	// This caches the timbres/settings in use by the rhythm part
138 	PatchCache drumCache[85][4];
139 public:
140 	RhythmPart(Synth *synth, unsigned int usePartNum);
141 	void refresh();
142 	void refreshTimbre(unsigned int timbreNum);
143 	void setTimbre(TimbreParam *timbre);
144 	void noteOn(unsigned int key, unsigned int velocity);
145 	void noteOff(unsigned int midiKey);
146 	unsigned int getAbsTimbreNum() const;
147 	void setPan(unsigned int midiPan);
148 	void setProgram(unsigned int patchNum);
149 };
150 
151 } // namespace MT32Emu
152 
153 #endif // #ifndef MT32EMU_PART_H
154