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