/[svn]/gigedit/trunk/src/gigedit/paramedit.cpp
ViewVC logotype

Contents of /gigedit/trunk/src/gigedit/paramedit.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1359 - (show annotations) (download)
Sun Sep 30 18:30:52 2007 UTC (16 years, 6 months ago) by schoenebeck
File size: 9794 byte(s)
* fixed couple other parameters which were silently ignored by the sampler
  on a live-editing session with LS (parameter "Gain" and various velocity
  response parameters for attenuation, filter cutoff frequency and EG
  release time)

1 /*
2 * Copyright (C) 2006, 2007 Andreas Persson
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with program; see the file COPYING. If not, write to the Free
16 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17 * 02110-1301 USA.
18 */
19
20 #include "paramedit.h"
21
22 namespace {
23 const char* const controlChangeTexts[] = {
24 "none", "channelaftertouch", "velocity",
25 0,
26 "modwheel", // "Modulation Wheel or Lever",
27 "breath", // "Breath Controller",
28 0,
29 "foot", // "Foot Controller",
30 "portamentotime", // "Portamento Time",
31 0, 0, 0, 0, 0, 0,
32 "effect1", // "Effect Control 1",
33 "effect2", // "Effect Control 2",
34 0, 0,
35 "genpurpose1", // "General Purpose Controller 1",
36 "genpurpose2", // "General Purpose Controller 2",
37 "genpurpose3", // "General Purpose Controller 3",
38 "genpurpose4", // "General Purpose Controller 4",
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0,
42 "sustainpedal", // "Damper Pedal on/off (Sustain)",
43 "portamento", // "Portamento On/Off",
44 "sostenuto", // "Sustenuto On/Off",
45 "softpedal", // "Soft Pedal On/Off",
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47 "genpurpose5", // "General Purpose Controller 5",
48 "genpurpose6", // "General Purpose Controller 6",
49 "genpurpose7", // "General Purpose Controller 7",
50 "genpurpose8", // "General Purpose Controller 8",
51 0, 0, 0, 0, 0, 0, 0,
52 "effect1depth", // "Effects 1 Depth",
53 "effect2depth", // "Effects 2 Depth",
54 "effect3depth", // "Effects 3 Depth",
55 "effect4depth", // "Effects 4 Depth",
56 "effect5depth", // "Effects 5 Depth"
57 };
58 }
59
60 LabelWidget::LabelWidget(const char* labelText, Gtk::Widget& widget) :
61 label(Glib::ustring(labelText) + ":"),
62 widget(widget)
63 {
64 label.set_alignment(Gtk::ALIGN_LEFT);
65 }
66
67 void LabelWidget::set_sensitive(bool sensitive)
68 {
69 label.set_sensitive(sensitive);
70 widget.set_sensitive(sensitive);
71 }
72
73 NumEntry::NumEntry(const char* labelText, double lower, double upper,
74 int decimals) :
75 adjust(lower, lower, upper, 1, 10),
76 scale(adjust),
77 spinbutton(adjust),
78 LabelWidget(labelText, box)
79 {
80 spinbutton.set_digits(decimals);
81 scale.set_draw_value(false);
82 box.pack_start(spinbutton, Gtk::PACK_SHRINK);
83 box.add(scale);
84 }
85
86 NumEntryGain::NumEntryGain(const char* labelText,
87 double lower, double upper,
88 int decimals, double coeff) :
89 NumEntry(labelText, lower, upper, decimals),
90 coeff(coeff)
91 {
92 spinbutton.signal_value_changed().connect(
93 sigc::mem_fun(*this, &NumEntryGain::value_changed));
94 }
95
96 void NumEntryGain::value_changed()
97 {
98 const double f = pow(10, spinbutton.get_digits());
99 int new_value = round_to_int(spinbutton.get_value() * f);
100 if (ptr) {
101 if (new_value != round_to_int(*ptr / coeff * f))
102 {
103 sig_to_be_changed.emit();
104 *ptr = round_to_int(new_value / f * coeff);
105 sig_val_changed.emit(new_value);
106 sig_changed.emit();
107 }
108 } else {
109 sig_to_be_changed.emit();
110 sig_val_changed.emit(new_value);
111 sig_changed.emit();
112 }
113 }
114
115 void NumEntryGain::set_ptr(int32_t* ptr)
116 {
117 this->ptr = 0;
118 bool plus6 = *ptr < 0;
119 set_value(plus6 ? 0 : *ptr / coeff);
120 set_sensitive(!plus6);
121 this->ptr = ptr;
122 }
123
124
125 BoolEntryPlus6::BoolEntryPlus6(const char* labelText, NumEntryGain& eGain, int32_t plus6value) :
126 LabelWidget(labelText, checkbutton),
127 checkbutton(labelText),
128 eGain(eGain),
129 plus6value(plus6value)
130 {
131 checkbutton.signal_toggled().connect(
132 sigc::mem_fun(*this, &BoolEntryPlus6::value_changed));
133 }
134
135 void BoolEntryPlus6::value_changed()
136 {
137 if (ptr) {
138 bool plus6 = checkbutton.get_active();
139 if (plus6) {
140 eGain.set_value(0);
141 *ptr = plus6value;
142 sig_changed();
143 } else {
144 if (*ptr < 0) {
145 *ptr = 0;
146 sig_changed();
147 }
148 }
149 eGain.set_sensitive(!plus6);
150 }
151 }
152
153 void BoolEntryPlus6::set_ptr(int32_t* ptr)
154 {
155 this->ptr = 0;
156 checkbutton.set_active(*ptr < 0);
157 this->ptr = ptr;
158 }
159
160 NumEntryPermille::NumEntryPermille(const char* labelText,
161 double lower, double upper, int decimals) :
162 NumEntry(labelText, lower, upper, decimals)
163 {
164 spinbutton.signal_value_changed().connect(
165 sigc::mem_fun(*this, &NumEntryPermille::value_changed));
166 }
167
168 void NumEntryPermille::value_changed()
169 {
170 if (ptr) {
171 uint16_t new_value = uint16_t(spinbutton.get_value() * 10 + 0.5);
172 if (new_value != *ptr) {
173 *ptr = uint16_t(spinbutton.get_value() * 10 + 0.5);
174 sig_changed();
175 }
176 }
177 }
178
179 void NumEntryPermille::set_ptr(uint16_t* ptr)
180 {
181 this->ptr = 0;
182 set_value(*ptr / 10.0);
183 this->ptr = ptr;
184 }
185
186
187 NoteEntry::NoteEntry(const char* labelText) :
188 NumEntryTemp<uint8_t>(labelText)
189 {
190 spinbutton.signal_input().connect(
191 sigc::mem_fun(*this, &NoteEntry::on_input));
192 spinbutton.signal_output().connect(
193 sigc::mem_fun(*this, &NoteEntry::on_output));
194 }
195
196 const char* notes[] = {
197 "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
198 };
199
200
201 // Convert the Entry text to a number
202 int NoteEntry::on_input(double* new_value)
203 {
204 const char* str = spinbutton.get_text().c_str();
205
206 int i;
207 for (i = 11 ; i >= 0 ; i--) {
208 if (strncmp(str, notes[i], strlen(notes[i])) == 0) break;
209 }
210 if (i >= 0) {
211 char* endptr;
212 long x = strtol(str + strlen(notes[i]), &endptr, 10);
213 if (endptr != str + strlen(notes[i])) {
214 *new_value = i + (x + 1) * 12;
215 return true;
216 }
217 }
218 return Gtk::INPUT_ERROR;
219 }
220
221 // Convert the Adjustment position to text
222 bool NoteEntry::on_output()
223 {
224 int x = int(spinbutton.get_adjustment()->get_value() + 0.5);
225 char buf[10];
226 sprintf(buf, "%s%d", notes[x % 12], x / 12 - 1);
227 spinbutton.set_text(buf);
228 return true;
229 }
230
231 ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(const char* labelText) :
232 align(0, 0, 0, 0),
233 LabelWidget(labelText, align)
234 {
235 for (int i = 0 ; i < 99 ; i++) {
236 if (controlChangeTexts[i]) {
237 combobox.append_text(controlChangeTexts[i]);
238 }
239 }
240 combobox.signal_changed().connect(
241 sigc::mem_fun(*this, &ChoiceEntryLeverageCtrl::value_changed));
242 align.add(combobox);
243 }
244
245 void ChoiceEntryLeverageCtrl::value_changed()
246 {
247 if (ptr) {
248 int rowno = combobox.get_active_row_number();
249 switch (rowno)
250 {
251 case -1:
252 break;
253 case 0:
254 ptr->type = gig::leverage_ctrl_t::type_none;
255 break;
256 case 1:
257 ptr->type = gig::leverage_ctrl_t::type_channelaftertouch;
258 break;
259 case 2:
260 ptr->type = gig::leverage_ctrl_t::type_velocity;
261 break;
262 default:
263 ptr->type = gig::leverage_ctrl_t::type_controlchange;
264 int x = 3;
265 for (int cc = 0 ; cc < 96 ; cc++) {
266 if (controlChangeTexts[cc + 3]) {
267 if (rowno == x) {
268 ptr->controller_number = cc;
269 break;
270 }
271 x++;
272 }
273 }
274 break;
275 }
276 if (rowno >= 0) sig_changed();
277 }
278 }
279
280 void ChoiceEntryLeverageCtrl::set_ptr(gig::leverage_ctrl_t* ptr)
281 {
282 this->ptr = 0;
283 int x;
284 switch (ptr->type)
285 {
286 case gig::leverage_ctrl_t::type_none:
287 x = 0;
288 break;
289 case gig::leverage_ctrl_t::type_channelaftertouch:
290 x = 1;
291 break;
292 case gig::leverage_ctrl_t::type_velocity:
293 x = 2;
294 break;
295 case gig::leverage_ctrl_t::type_controlchange:
296 x = -1;
297 for (int cc = 0 ; cc < 96 ; cc++) {
298 if (controlChangeTexts[cc + 3]) {
299 x++;
300 if (ptr->controller_number == cc) {
301 x += 3;
302 break;
303 }
304 }
305 }
306 break;
307 default:
308 x = -1;
309 break;
310 }
311 combobox.set_active(x);
312 this->ptr = ptr;
313 }
314
315
316 BoolEntry::BoolEntry(const char* labelText) :
317 LabelWidget(labelText, checkbutton),
318 checkbutton(labelText),
319 ptr(0)
320 {
321 checkbutton.signal_toggled().connect(
322 sigc::mem_fun(*this, &BoolEntry::value_changed));
323 }
324
325 void BoolEntry::value_changed()
326 {
327 if (ptr) {
328 *ptr = checkbutton.get_active();
329 sig_changed();
330 }
331 }
332
333 void BoolEntry::set_ptr(bool* ptr)
334 {
335 this->ptr = 0;
336 checkbutton.set_active(*ptr);
337 this->ptr = ptr;
338 }
339
340
341 StringEntry::StringEntry(const char* labelText) :
342 LabelWidget(labelText, entry)
343 {
344 entry.signal_changed().connect(
345 sigc::mem_fun(*this, &StringEntry::value_changed));
346 }
347
348 void StringEntry::value_changed()
349 {
350 if (ptr) {
351 *ptr = entry.get_text();
352 sig_changed();
353 }
354 }
355
356 void StringEntry::set_ptr(gig::String* ptr)
357 {
358 this->ptr = 0;
359 entry.set_text(*ptr);
360 this->ptr = ptr;
361 }

  ViewVC Help
Powered by ViewVC