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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1359 - (hide 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 schoenebeck 1225 /*
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 schoenebeck 1359 const double f = pow(10, spinbutton.get_digits());
99     int new_value = round_to_int(spinbutton.get_value() * f);
100 persson 1261 if (ptr) {
101     if (new_value != round_to_int(*ptr / coeff * f))
102     {
103 schoenebeck 1359 sig_to_be_changed.emit();
104 persson 1261 *ptr = round_to_int(new_value / f * coeff);
105 schoenebeck 1359 sig_val_changed.emit(new_value);
106     sig_changed.emit();
107 persson 1261 }
108 schoenebeck 1359 } else {
109     sig_to_be_changed.emit();
110     sig_val_changed.emit(new_value);
111     sig_changed.emit();
112 schoenebeck 1225 }
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 persson 1262 checkbutton(labelText),
128 schoenebeck 1225 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 persson 1261 if (ptr) {
138 schoenebeck 1225 bool plus6 = checkbutton.get_active();
139     if (plus6) {
140     eGain.set_value(0);
141     *ptr = plus6value;
142 persson 1261 sig_changed();
143 schoenebeck 1225 } else {
144     if (*ptr < 0) {
145     *ptr = 0;
146 persson 1261 sig_changed();
147 schoenebeck 1225 }
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 persson 1261 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 schoenebeck 1225 }
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 persson 1261 int x = int(spinbutton.get_adjustment()->get_value() + 0.5);
225 schoenebeck 1225 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 persson 1261 if (ptr) {
248 schoenebeck 1225 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 persson 1261 if (rowno >= 0) sig_changed();
277 schoenebeck 1225 }
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 persson 1261 if (ptr) {
328 schoenebeck 1225 *ptr = checkbutton.get_active();
329 persson 1261 sig_changed();
330 schoenebeck 1225 }
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 persson 1261 if (ptr) {
351 schoenebeck 1225 *ptr = entry.get_text();
352 persson 1261 sig_changed();
353 schoenebeck 1225 }
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