DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/mt32/Part.h
00001 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
00002  * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
00003  *
00004  *  This program is free software: you can redistribute it and/or modify
00005  *  it under the terms of the GNU Lesser General Public License as published by
00006  *  the Free Software Foundation, either version 2.1 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU Lesser General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Lesser General Public License
00015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #ifndef MT32EMU_PART_H
00019 #define MT32EMU_PART_H
00020 
00021 namespace MT32Emu {
00022 
00023 class PartialManager;
00024 class Synth;
00025 
00026 class PolyList {
00027 private:
00028 
00029 public:
00030         Poly *firstPoly;
00031         Poly *lastPoly;
00032         PolyList();
00033         bool isEmpty() const;
00034         Poly *getFirst() const;
00035         Poly *getLast() const;
00036         void prepend(Poly *poly);
00037         void append(Poly *poly);
00038         Poly *takeFirst();
00039         void remove(Poly * const poly);
00040 };
00041 
00042 class Part {
00043 private:
00044         // Direct pointer to sysex-addressable memory dedicated to this part (valid for parts 1-8, NULL for rhythm)
00045         TimbreParam *timbreTemp;
00046 
00047         // 0=Part 1, .. 7=Part 8, 8=Rhythm
00048         unsigned int partNum;
00049 
00050         bool holdpedal;
00051 
00052         unsigned int activePartialCount;
00053         PatchCache patchCache[4];
00054         PolyList freePolys;
00055         PolyList activePolys;
00056 
00057         void setPatch(const PatchParam *patch);
00058         unsigned int midiKeyToKey(unsigned int midiKey);
00059 
00060         void abortPoly(Poly *poly);
00061         bool abortFirstPoly(unsigned int key);
00062 
00063 protected:
00064         Synth *synth;
00065         // Direct pointer into sysex-addressable memory
00066         MemParams::PatchTemp *patchTemp;
00067         char name[8]; // "Part 1".."Part 8", "Rhythm"
00068         char currentInstr[11];
00069         Bit8u modulation;
00070         Bit8u expression;
00071         Bit32s pitchBend;
00072         bool nrpn;
00073         Bit16u rpn;
00074         Bit16u pitchBenderRange; // (patchTemp->patch.benderRange * 683) at the time of the last MIDI program change or MIDI data entry.
00075 
00076         void backupCacheToPartials(PatchCache cache[4]);
00077         void cacheTimbre(PatchCache cache[4], const TimbreParam *timbre);
00078         void playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity);
00079         void stopNote(unsigned int key);
00080         const char *getName() const;
00081 
00082 public:
00083         Part(Synth *synth, unsigned int usePartNum);
00084         virtual ~Part();
00085         void reset();
00086         void setDataEntryMSB(unsigned char midiDataEntryMSB);
00087         void setNRPN();
00088         void setRPNLSB(unsigned char midiRPNLSB);
00089         void setRPNMSB(unsigned char midiRPNMSB);
00090         void resetAllControllers();
00091         virtual void noteOn(unsigned int midiKey, unsigned int velocity);
00092         virtual void noteOff(unsigned int midiKey);
00093         void allNotesOff();
00094         void allSoundOff();
00095         Bit8u getVolume() const; // Internal volume, 0-100, exposed for use by ExternalInterface
00096         void setVolume(unsigned int midiVolume);
00097         Bit8u getModulation() const;
00098         void setModulation(unsigned int midiModulation);
00099         Bit8u getExpression() const;
00100         void setExpression(unsigned int midiExpression);
00101         virtual void setPan(unsigned int midiPan);
00102         Bit32s getPitchBend() const;
00103         void setBend(unsigned int midiBend);
00104         virtual void setProgram(unsigned int midiProgram);
00105         void setHoldPedal(bool pedalval);
00106         void stopPedalHold();
00107         void updatePitchBenderRange();
00108         virtual void refresh();
00109         virtual void refreshTimbre(unsigned int absTimbreNum);
00110         virtual void setTimbre(TimbreParam *timbre);
00111         virtual unsigned int getAbsTimbreNum() const;
00112         const char *getCurrentInstr() const;
00113         unsigned int getActivePartialCount() const;
00114         unsigned int getActiveNonReleasingPartialCount() const;
00115 
00116         const MemParams::PatchTemp *getPatchTemp() const;
00117 
00118         // This should only be called by Poly
00119         void partialDeactivated(Poly *poly);
00120 
00121         // These are rather specialised, and should probably only be used by PartialManager
00122         bool abortFirstPoly(PolyState polyState);
00123         // Abort the first poly in PolyState_HELD, or if none exists, the first active poly in any state.
00124         bool abortFirstPolyPreferHeld();
00125         bool abortFirstPoly();
00126 
00127         const Poly *getActivePoly(int num);
00128         int getActivePolyCount();
00129         const PatchCache *getPatchCache(int num);
00130 };
00131 
00132 class RhythmPart: public Part {
00133         // Pointer to the area of the MT-32's memory dedicated to rhythm
00134         const MemParams::RhythmTemp *rhythmTemp;
00135 
00136         // This caches the timbres/settings in use by the rhythm part
00137         PatchCache drumCache[85][4];
00138 public:
00139         RhythmPart(Synth *synth, unsigned int usePartNum);
00140         void refresh();
00141         void refreshTimbre(unsigned int timbreNum);
00142         void setTimbre(TimbreParam *timbre);
00143         void noteOn(unsigned int key, unsigned int velocity);
00144         void noteOff(unsigned int midiKey);
00145         unsigned int getAbsTimbreNum() const;
00146         void setPan(unsigned int midiPan);
00147         void setProgram(unsigned int patchNum);
00148 
00149         const PatchCache *getDrumCache(int num1, int num2);
00150 };
00151 
00152 }
00153 #endif