123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- /*
- * OPL2 FM synth
- *
- * Copyright (c) 2013 Raine M. Ekman <raine/at/iki/fi>
- *
- * This file is part of LMMS - https://lmms.io
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program (see COPYING); if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- */
- #ifndef _OPL2_H
- #define _OPL2_H
- #include "Instrument.h"
- #include "InstrumentView.h"
- #include "opl.h"
- #include "LcdSpinBox.h"
- #include "Knob.h"
- #include "PixmapButton.h"
- // This one is a flag, MIDI notes take 7 low bits
- #define OPL2_VOICE_FREE 128
- #define OPL2_NO_VOICE 255
- #define OPL2_VOICES 9
- // The "normal" range for LMMS pitchbends
- #define DEFAULT_BEND_CENTS 100
- class opl2instrument : public Instrument
- {
- Q_OBJECT
- public:
- opl2instrument( InstrumentTrack * _instrument_track );
- virtual ~opl2instrument();
- virtual QString nodeName() const;
- virtual PluginView * instantiateView( QWidget * _parent );
- virtual Flags flags() const
- {
- return IsSingleStreamed | IsMidiBased;
- }
- virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset = 0 );
- virtual void play( sampleFrame * _working_buffer );
- void saveSettings( QDomDocument & _doc, QDomElement & _this );
- void loadSettings( const QDomElement & _this );
- void loadPatch(const unsigned char inst[14]);
- void tuneEqual(int center, float Hz);
- virtual void loadFile( const QString& file );
- IntModel m_patchModel;
- FloatModel op1_a_mdl;
- FloatModel op1_d_mdl;
- FloatModel op1_s_mdl;
- FloatModel op1_r_mdl;
- FloatModel op1_lvl_mdl;
- FloatModel op1_scale_mdl;
- FloatModel op1_mul_mdl;
- FloatModel feedback_mdl;
- BoolModel op1_ksr_mdl;
- BoolModel op1_perc_mdl;
- BoolModel op1_trem_mdl;
- BoolModel op1_vib_mdl;
- BoolModel op1_w0_mdl;
- BoolModel op1_w1_mdl;
- BoolModel op1_w2_mdl;
- BoolModel op1_w3_mdl;
- IntModel op1_waveform_mdl;
- FloatModel op2_a_mdl;
- FloatModel op2_d_mdl;
- FloatModel op2_s_mdl;
- FloatModel op2_r_mdl;
- FloatModel op2_lvl_mdl;
- FloatModel op2_scale_mdl;
- FloatModel op2_mul_mdl;
- BoolModel op2_ksr_mdl;
- BoolModel op2_perc_mdl;
- BoolModel op2_trem_mdl;
- BoolModel op2_vib_mdl;
- BoolModel op2_w0_mdl;
- BoolModel op2_w1_mdl;
- BoolModel op2_w2_mdl;
- BoolModel op2_w3_mdl;
- IntModel op2_waveform_mdl;
- BoolModel fm_mdl;
- BoolModel vib_depth_mdl;
- BoolModel trem_depth_mdl;
- private slots:
- void updatePatch();
- void reloadEmulator();
- void loadGMPatch();
- private:
- Copl *theEmulator;
- QString storedname;
- fpp_t frameCount;
- short *renderbuffer;
- int voiceNote[OPL2_VOICES];
- // Least recently used voices
- int voiceLRU[OPL2_VOICES];
- // 0 - no note, >0 - note on velocity
- int velocities[128];
- // These include both octave and Fnumber
- int fnums[128];
- // in cents, range defaults to +/-100 cents (should this be changeable?)
- int pitchbend;
- int pitchBendRange;
- int popVoice();
- int pushVoice(int v);
- int Hz2fnum(float Hz);
- static QMutex emulatorMutex;
- void setVoiceVelocity(int voice, int vel);
- // Pitch bend range comes through RPNs.
- int RPNcoarse, RPNfine;
- };
- class opl2instrumentView : public InstrumentView
- {
- Q_OBJECT
- public:
- opl2instrumentView( Instrument * _instrument, QWidget * _parent );
- virtual ~opl2instrumentView();
- LcdSpinBox *m_patch;
- void modelChanged();
- Knob *op1_a_kn;
- Knob *op1_d_kn;
- Knob *op1_s_kn;
- Knob *op1_r_kn;
- Knob *op1_lvl_kn;
- Knob *op1_scale_kn;
- Knob *op1_mul_kn;
- Knob *feedback_kn;
- PixmapButton *op1_ksr_btn;
- PixmapButton *op1_perc_btn;
- PixmapButton *op1_trem_btn;
- PixmapButton *op1_vib_btn;
- PixmapButton *op1_w0_btn;
- PixmapButton *op1_w1_btn;
- PixmapButton *op1_w2_btn;
- PixmapButton *op1_w3_btn;
- automatableButtonGroup *op1_waveform;
- Knob *op2_a_kn;
- Knob *op2_d_kn;
- Knob *op2_s_kn;
- Knob *op2_r_kn;
- Knob *op2_lvl_kn;
- Knob *op2_scale_kn;
- Knob *op2_mul_kn;
- PixmapButton *op2_ksr_btn;
- PixmapButton *op2_perc_btn;
- PixmapButton *op2_trem_btn;
- PixmapButton *op2_vib_btn;
- PixmapButton *op2_w0_btn;
- PixmapButton *op2_w1_btn;
- PixmapButton *op2_w2_btn;
- PixmapButton *op2_w3_btn;
- automatableButtonGroup *op2_waveform;
- PixmapButton *fm_btn;
- PixmapButton *vib_depth_btn;
- PixmapButton *trem_depth_btn;
- private slots:
- void updateKnobHints();
- private:
- QString knobHintHelper(float n);
- };
- #endif
|