1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2 
3 #ifndef SPECTMORPH_MIDI_SYNTH_HH
4 #define SPECTMORPH_MIDI_SYNTH_HH
5 
6 #include "smmorphplansynth.hh"
7 #include "sminsteditsynth.hh"
8 
9 namespace SpectMorph {
10 
11 class MidiSynth
12 {
13   class Voice
14   {
15   public:
16     enum State {
17       STATE_IDLE,
18       STATE_ON,
19       STATE_RELEASE
20     };
21     enum class MonoType {
22       POLY,
23       MONO,
24       SHADOW
25     };
26     MorphPlanVoice *mp_voice;
27 
28     State        state;
29     MonoType     mono_type;
30     bool         pedal;
31     int          midi_note;
32     int          channel;
33     double       gain;
34     double       freq;
35     double       pitch_bend_freq;
36     double       pitch_bend_factor;
37     int          pitch_bend_steps;
38     int          note_id;
39 
Voice()40     Voice() :
41       mp_voice (NULL),
42       state (STATE_IDLE),
43       pedal (false)
44     {
45     }
~Voice()46     ~Voice()
47     {
48       mp_voice = NULL;
49     }
50   };
51 
52   MorphPlanSynth        morph_plan_synth;
53   InstEditSynth         m_inst_edit_synth;
54 
55   std::vector<Voice>    voices;
56   std::vector<Voice *>  idle_voices;
57   std::vector<Voice *>  active_voices;
58   double                m_mix_freq;
59   double                m_gain = 1;
60   double                m_tempo = 120;
61   double                m_ppq_pos = 0;
62   bool                  pedal_down;
63   uint64                audio_time_stamp;
64   bool                  mono_enabled;
65   float                 portamento_glide;
66   int                   portamento_note_id;
67   int                   next_note_id;
68   bool                  inst_edit = false;
69   bool                  m_control_by_cc = false;
70 
71   std::vector<float>    control = std::vector<float> (MorphPlan::N_CONTROL_INPUTS);
72 
73   Voice  *alloc_voice();
74   void    free_unused_voices();
75   bool    update_mono_voice();
76   float   freq_from_note (float note);
77 
78   void set_mono_enabled (bool new_value);
79   void process_audio (const TimeInfo& block_time, float *output, size_t n_values);
80   void process_note_on (const TimeInfo& block_time, int channel, int midi_note, int midi_velocity);
81   void process_note_off (int midi_note);
82   void process_midi_controller (int controller, int value);
83   void process_pitch_bend (int channel, double semi_tones);
84   void start_pitch_bend (Voice *voice, double dest_freq, double time_ms);
85   void kill_all_active_voices();
86 
87   struct MidiEvent
88   {
89     unsigned int  offset;
90     char          midi_data[3];
91 
92     bool is_note_on() const;
93     bool is_note_off() const;
94     bool is_controller() const;
95     bool is_pitch_bend() const;
96     int  channel() const;
97   };
98   std::vector<MidiEvent>  midi_events;
99 
100 public:
101   MidiSynth (double mix_freq, size_t n_voices);
102 
103   void add_midi_event (size_t offset, const unsigned char *midi_data);
104   void process (float *output, size_t n_values);
105 
106   void set_control_input (int i, float value);
107   void set_tempo (double tempo);
108   void set_ppq_pos (double ppq_pos);
109   void update_plan (MorphPlanPtr new_plan);
110   double mix_freq() const;
111 
112   size_t active_voice_count() const;
113 
114   void set_inst_edit (bool inst_edit);
115   void set_gain (double gain);
116   void set_control_by_cc (bool control_by_cc);
117   InstEditSynth *inst_edit_synth();
118 };
119 
120 class SynthNotifyEvent
121 {
122 public:
123   virtual
~SynthNotifyEvent()124   ~SynthNotifyEvent()
125   {
126   }
127   static SynthNotifyEvent *
128   create (const std::string& str);
129 };
130 
131 struct InstEditVoice : public SynthNotifyEvent
132 {
133   std::vector<int>   note;
134   std::vector<int>   layer;
135   std::vector<float> current_pos;
136   std::vector<float> fundamental_note;
137 };
138 
139 }
140 
141 #endif /* SPECTMORPH_MIDI_SYNTH_HH */
142