1 // synthv1_controls.h
2 //
3 /****************************************************************************
4    Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved.
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public License
8    as published by the Free Software Foundation; either version 2
9    of the License, or (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License along
17    with this program; if not, write to the Free Software Foundation, Inc.,
18    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 
20 *****************************************************************************/
21 
22 #ifndef __synthv1_controls_h
23 #define __synthv1_controls_h
24 
25 #include "synthv1_param.h"
26 #include "synthv1_sched.h"
27 
28 #include <QMap>
29 
30 
31 //-------------------------------------------------------------------------
32 // synthv1_controls - Controller processs class.
33 //
34 
35 class synthv1_controls
36 {
37 public:
38 
39 	// ctor.
40 	synthv1_controls(synthv1 *pSynth);
41 
42 	// dtor.
43 	~synthv1_controls();
44 
45 	// operational mode flags.
enabled(bool on)46 	void enabled(bool on)
47 		{ m_enabled = on; }
enabled()48 	bool enabled() const
49 		{ return m_enabled; }
50 
51 	// controller types,
52 	enum Type { None = 0, CC = 0x100, RPN = 0x200, NRPN = 0x300, CC14 = 0x400 };
53 
54 	// controller hash key.
55 	struct Key
56 	{
KeyKey57 		Key () : status(0), param(0) {}
KeyKey58 		Key (const Key& key)
59 			: status(key.status), param(key.param) {}
60 
typeKey61 		Type type() const
62 			{ return Type(status & 0xf00); }
channelKey63 		unsigned short channel() const
64 			{ return (status & 0x1f); }
65 
66 		// hash key comparator.
67 		bool operator< (const Key& key) const
68 		{
69 			if (status != key.status)
70 				return (status < key.status);
71 			else
72 				return (param < key.param);
73 		}
74 
75 		// copy assignment operator.
76 		Key& operator= (const Key& key)
77 		{
78 			if (this != &key) {
79 				status = key.status;
80 				param  = key.param;
81 			}
82 			return *this;
83 		}
84 
85 		unsigned short status;
86 		unsigned short param;
87 	};
88 
89 	// controller flags,
90 	enum Flag { Logarithmic = 1, Invert = 2, Hook = 4 };
91 
92 	// controller data.
93 	struct Data
94 	{
DataData95 		Data () : index(-1), flags(0), val(0.0f), sync(false) {}
96 
97 		int index;
98 		int flags;
99 		float val;
100 		bool sync;
101 	};
102 
103 	typedef QMap<Key, Data> Map;
104 
105 	// controller events.
106 	struct Event
107 	{
108 		Key key;
109 		unsigned short value;
110 	};
111 
112 	// controller map methods.
map()113 	const Map& map() const { return m_map; }
114 
find_control(const Key & key)115 	int find_control(const Key& key) const
116 		{ return m_map.value(key).index; }
add_control(const Key & key,const Data & data)117 	void add_control(const Key& key, const Data& data)
118 		{ m_map.insert(key, data); }
remove_control(const Key & key)119 	void remove_control(const Key& key)
120 		{ m_map.remove(key); }
121 
clear()122 	void clear() { m_map.clear(); }
123 
124 	// reset all controllers.
125 	void reset();
126 
127 	// controller queue methods.
128 	void process_enqueue(
129 		unsigned short channel,
130 		unsigned short param,
131 		unsigned short value);
132 
133 	void process_dequeue();
134 
135 	// process timer counter.
136 	void process(unsigned int nframes);
137 
138 	// text utilities.
139 	static Type typeFromText(const QString& sText);
140 	static QString textFromType(Type ctype);
141 
142 	// current/last controller accessor.
143 	const Key& current_key() const;
144 
145 protected:
146 
147 	// controller action.
148 	void process_event(const Event& event);
149 
150 	// input controller scheduled events (learn)
151 	class SchedIn : public synthv1_sched
152 	{
153 	public:
154 
155 		// ctor.
SchedIn(synthv1 * pSynth)156 		SchedIn (synthv1 *pSynth)
157 			: synthv1_sched(pSynth, Controller) {}
158 
schedule_key(const Key & key)159 		void schedule_key(const Key& key)
160 			{ m_key = key; schedule(); }
161 
162 		// process (virtual stub).
process(int)163 		void process(int) {}
164 
165 		// current controller accessor.
current_key()166 		const Key& current_key() const
167 			{ return m_key; }
168 
169 	private:
170 
171 		// instance variables,.
172 		Key m_key;
173 	};
174 
175 	// output controller scheduled events (assignments)
176 	class SchedOut : public synthv1_sched
177 	{
178 	public:
179 
180 		// ctor.
SchedOut(synthv1 * pSynth)181 		SchedOut (synthv1 *pSynth)
182 			: synthv1_sched(pSynth, Controls), m_value(0.0f) {}
183 
schedule_event(synthv1::ParamIndex index,float value)184 		void schedule_event(synthv1::ParamIndex index, float value)
185 		{
186 			if (qAbs(value - m_value) > 0.001f) {
187 				m_value = value;
188 				schedule(int(index));
189 			}
190 		}
191 
192 		// process (virtual stub).
process(int sid)193 		void process(int sid)
194 		{
195 			synthv1 *pSynth = instance();
196 			synthv1::ParamIndex index = synthv1::ParamIndex(sid);
197 			pSynth->setParamValue(index, m_value);
198 			pSynth->updateParam(index);
199 		}
200 
201 	private:
202 
203 		// instance variables
204 		float m_value;
205 	};
206 
207 private:
208 
209 	// instance variables.
210 	class Impl;
211 
212 	Impl *m_pImpl;
213 
214 	// operational mode flags.
215 	bool m_enabled;
216 
217 	// controller schedulers.
218 	SchedIn  m_sched_in;
219 	SchedOut m_sched_out;
220 
221 	// controllers map.
222 	Map m_map;
223 
224 	// frame timers.
225 	unsigned int m_timeout;
226 	unsigned int m_timein;
227 };
228 
229 
230 #endif	// __synthv1_controls_h
231 
232 // end of synthv1_controls.h
233