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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3449 - (hide annotations) (download)
Sun Dec 23 23:06:56 2018 UTC (5 years, 3 months ago) by schoenebeck
File size: 72072 byte(s)
* GIG SOUND FORMAT EXTENSION: Added combo box "Sustain Release Trigger"
  which can be used to optionally play release trigger samples on sustain
  pedal up.
* GIG SOUND FORMAT EXTENSION: Added check box "No note-off release trigger"
  which allows to disable release trigger samples on regular MIDI note-off.
* Bumped version (1.1.0.svn8).

1 schoenebeck 1225 /*
2 schoenebeck 3070 * Copyright (C) 2006-2017 Andreas Persson
3 schoenebeck 1225 *
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 persson 3202 #include "global.h"
21 schoenebeck 1225 #include "dimregionedit.h"
22    
23 persson 2169 #include "compat.h"
24 schoenebeck 1225
25 schoenebeck 3364 #if USE_GTKMM_GRID
26     # include <gtkmm/grid.h>
27     #else
28     # include <gtkmm/table.h>
29     #endif
30    
31 schoenebeck 3409 #include "Settings.h"
32    
33 persson 2392 VelocityCurve::VelocityCurve(double (gig::DimensionRegion::*getter)(uint8_t)) :
34     getter(getter), dimreg(0) {
35     set_size_request(80, 80);
36     }
37    
38     #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
39     bool VelocityCurve::on_expose_event(GdkEventExpose* e) {
40     const Cairo::RefPtr<Cairo::Context>& cr =
41     get_window()->create_cairo_context();
42     #if 0
43     }
44     #endif
45     #else
46     bool VelocityCurve::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) {
47     #endif
48     if (dimreg) {
49     int w = get_width();
50     int h = get_height();
51    
52     for (int pass = 0 ; pass < 2 ; pass++) {
53 persson 2397 for (double x = 0 ; x <= w ; x++) {
54     int vel = int(x * (127 - 1e-10) / w + 1);
55     double y = (1 - (dimreg->*getter)(vel)) * (h - 3) + 1.5;
56 persson 2392
57 persson 2397 if (x < 1e-10) {
58 persson 2392 cr->move_to(x, y);
59     } else {
60     cr->line_to(x, y);
61     }
62     }
63     if (pass == 0) {
64 persson 2397 cr->line_to(w, h);
65     cr->line_to(0, h);
66 persson 2430 cr->set_source_rgba(0.5, 0.44, 1.0, is_sensitive() ? 0.2 : 0.1);
67 persson 2392 cr->fill();
68     } else {
69     cr->set_line_width(3);
70 persson 2430 cr->set_source_rgba(0.5, 0.44, 1.0, is_sensitive() ? 1.0 : 0.3);
71 persson 2392 cr->stroke();
72     }
73     }
74     }
75     return true;
76     }
77    
78    
79     CrossfadeCurve::CrossfadeCurve() : dimreg(0) {
80     set_size_request(280, 80);
81     }
82    
83     #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
84     bool CrossfadeCurve::on_expose_event(GdkEventExpose* e) {
85     const Cairo::RefPtr<Cairo::Context>& cr =
86     get_window()->create_cairo_context();
87     #if 0
88     }
89     #endif
90     #else
91     bool CrossfadeCurve::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) {
92     #endif
93 persson 2430 if (dimreg) {
94 persson 2397 cr->translate(1.5, 0);
95 persson 2430
96     // first, draw curves for the other layers
97     gig::Region* region = dimreg->GetParent();
98     int dimregno;
99     for (dimregno = 0 ; dimregno < region->DimensionRegions ; dimregno++) {
100     if (region->pDimensionRegions[dimregno] == dimreg) {
101     break;
102     }
103     }
104     int bitcount = 0;
105     for (int dim = 0 ; dim < region->Dimensions ; dim++) {
106     if (region->pDimensionDefinitions[dim].dimension ==
107     gig::dimension_layer) {
108     int mask =
109     ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) <<
110     bitcount);
111     int c = dimregno & mask; // mask away the layer dimension
112    
113     for (int i = 0 ; i < region->pDimensionDefinitions[dim].zones ;
114     i++) {
115     gig::DimensionRegion* d =
116     region->pDimensionRegions[c + (i << bitcount)];
117     if (d != dimreg) {
118     draw_one_curve(cr, d, false);
119     }
120     }
121     break;
122     }
123     bitcount += region->pDimensionDefinitions[dim].bits;
124     }
125    
126     // then, draw the currently selected layer
127     draw_one_curve(cr, dimreg, is_sensitive());
128     }
129     return true;
130     }
131    
132     void CrossfadeCurve::draw_one_curve(const Cairo::RefPtr<Cairo::Context>& cr,
133     const gig::DimensionRegion* d,
134     bool sensitive) {
135     int w = get_width();
136     int h = get_height();
137    
138     if (d->Crossfade.out_end) {
139 persson 2392 for (int pass = 0 ; pass < 2 ; pass++) {
140 persson 2430 cr->move_to(d->Crossfade.in_start / 127.0 * (w - 3), h);
141     cr->line_to(d->Crossfade.in_end / 127.0 * (w - 3), 1.5);
142     cr->line_to(d->Crossfade.out_start / 127.0 * (w - 3), 1.5);
143     cr->line_to(d->Crossfade.out_end / 127.0 * (w - 3), h);
144 persson 2392
145     if (pass == 0) {
146 persson 2430 cr->set_source_rgba(0.5, 0.44, 1.0, sensitive ? 0.2 : 0.1);
147 persson 2392 cr->fill();
148     } else {
149     cr->set_line_width(3);
150 persson 2430 cr->set_source_rgba(0.5, 0.44, 1.0, sensitive ? 1.0 : 0.3);
151 persson 2392 cr->stroke();
152     }
153     }
154     }
155     }
156    
157    
158 schoenebeck 3329 EGStateOptions::EGStateOptions() : HBox(),
159     label(_("May be cancelled: ")),
160     checkBoxAttack(_("Attack")),
161     checkBoxAttackHold(_("Attack Hold")),
162     checkBoxDecay1(_("Decay 1")),
163     checkBoxDecay2(_("Decay 2")),
164     checkBoxRelease(_("Release"))
165     {
166     set_spacing(6);
167    
168     pack_start(label);
169     pack_start(checkBoxAttack, Gtk::PACK_SHRINK);
170     pack_start(checkBoxAttackHold, Gtk::PACK_SHRINK);
171     pack_start(checkBoxDecay1, Gtk::PACK_SHRINK);
172     pack_start(checkBoxDecay2, Gtk::PACK_SHRINK);
173     pack_start(checkBoxRelease, Gtk::PACK_SHRINK);
174    
175     checkBoxAttack.set_tooltip_text(_(
176     "If checked: a note-off aborts the 'attack' stage."
177     ));
178     checkBoxAttackHold.set_tooltip_text(_(
179     "If checked: a note-off aborts the 'attack hold' stage."
180     ));
181     checkBoxDecay1.set_tooltip_text(_(
182     "If checked: a note-off aborts the 'decay 1' stage."
183     ));
184     checkBoxDecay2.set_tooltip_text(_(
185     "If checked: a note-off aborts the 'decay 2' stage."
186     ));
187     checkBoxRelease.set_tooltip_text(_(
188     "If checked: a note-on reverts back from the 'release' stage."
189     ));
190     }
191    
192 schoenebeck 3409 void EGStateOptions::on_show_tooltips_changed() {
193     const bool b = Settings::singleton()->showTooltips;
194 schoenebeck 3329
195 schoenebeck 3409 checkBoxAttack.set_has_tooltip(b);
196     checkBoxAttackHold.set_has_tooltip(b);
197     checkBoxDecay1.set_has_tooltip(b);
198     checkBoxDecay2.set_has_tooltip(b);
199     checkBoxRelease.set_has_tooltip(b);
200     }
201    
202    
203 schoenebeck 1225 DimRegionEdit::DimRegionEdit() :
204 persson 2392 velocity_curve(&gig::DimensionRegion::GetVelocityAttenuation),
205     release_curve(&gig::DimensionRegion::GetVelocityRelease),
206     cutoff_curve(&gig::DimensionRegion::GetVelocityCutoff),
207 schoenebeck 2566 eEG1PreAttack(_("Pre-attack Level (%)"), 0, 100, 2),
208     eEG1Attack(_("Attack Time (seconds)"), 0, 60, 3),
209     eEG1Decay1(_("Decay 1 Time (seconds)"), 0.005, 60, 3),
210     eEG1Decay2(_("Decay 2 Time (seconds)"), 0, 60, 3),
211 persson 1831 eEG1InfiniteSustain(_("Infinite sustain")),
212 schoenebeck 2566 eEG1Sustain(_("Sustain Level (%)"), 0, 100, 2),
213     eEG1Release(_("Release Time (seconds)"), 0, 60, 3),
214     eEG1Hold(_("Hold Attack Stage until Loop End")),
215 persson 1831 eEG1Controller(_("Controller")),
216     eEG1ControllerInvert(_("Controller invert")),
217     eEG1ControllerAttackInfluence(_("Controller attack influence"), 0, 3),
218     eEG1ControllerDecayInfluence(_("Controller decay influence"), 0, 3),
219     eEG1ControllerReleaseInfluence(_("Controller release influence"), 0, 3),
220     eLFO1Frequency(_("Frequency"), 0.1, 10, 2),
221     eLFO1InternalDepth(_("Internal depth"), 0, 1200),
222     eLFO1ControlDepth(_("Control depth"), 0, 1200),
223     eLFO1Controller(_("Controller")),
224     eLFO1FlipPhase(_("Flip phase")),
225     eLFO1Sync(_("Sync")),
226 schoenebeck 2566 eEG2PreAttack(_("Pre-attack Level (%)"), 0, 100, 2),
227     eEG2Attack(_("Attack Time (seconds)"), 0, 60, 3),
228     eEG2Decay1(_("Decay 1 Time (seconds)"), 0.005, 60, 3),
229     eEG2Decay2(_("Decay 2 Time (seconds)"), 0, 60, 3),
230 persson 1831 eEG2InfiniteSustain(_("Infinite sustain")),
231 schoenebeck 2566 eEG2Sustain(_("Sustain Level (%)"), 0, 100, 2),
232     eEG2Release(_("Release Time (seconds)"), 0, 60, 3),
233 persson 1831 eEG2Controller(_("Controller")),
234     eEG2ControllerInvert(_("Controller invert")),
235     eEG2ControllerAttackInfluence(_("Controller attack influence"), 0, 3),
236     eEG2ControllerDecayInfluence(_("Controller decay influence"), 0, 3),
237     eEG2ControllerReleaseInfluence(_("Controller release influence"), 0, 3),
238     eLFO2Frequency(_("Frequency"), 0.1, 10, 2),
239     eLFO2InternalDepth(_("Internal depth"), 0, 1200),
240     eLFO2ControlDepth(_("Control depth"), 0, 1200),
241     eLFO2Controller(_("Controller")),
242     eLFO2FlipPhase(_("Flip phase")),
243     eLFO2Sync(_("Sync")),
244     eEG3Attack(_("Attack"), 0, 10, 3),
245     eEG3Depth(_("Depth"), -1200, 1200),
246     eLFO3Frequency(_("Frequency"), 0.1, 10, 2),
247     eLFO3InternalDepth(_("Internal depth"), 0, 1200),
248     eLFO3ControlDepth(_("Control depth"), 0, 1200),
249     eLFO3Controller(_("Controller")),
250     eLFO3Sync(_("Sync")),
251     eVCFEnabled(_("Enabled")),
252     eVCFType(_("Type")),
253     eVCFCutoffController(_("Cutoff controller")),
254     eVCFCutoffControllerInvert(_("Cutoff controller invert")),
255     eVCFCutoff(_("Cutoff")),
256     eVCFVelocityCurve(_("Velocity curve")),
257     eVCFVelocityScale(_("Velocity scale")),
258     eVCFVelocityDynamicRange(_("Velocity dynamic range"), 0, 4),
259     eVCFResonance(_("Resonance")),
260     eVCFResonanceDynamic(_("Resonance dynamic")),
261     eVCFResonanceController(_("Resonance controller")),
262     eVCFKeyboardTracking(_("Keyboard tracking")),
263     eVCFKeyboardTrackingBreakpoint(_("Keyboard tracking breakpoint")),
264     eVelocityResponseCurve(_("Velocity response curve")),
265     eVelocityResponseDepth(_("Velocity response depth"), 0, 4),
266     eVelocityResponseCurveScaling(_("Velocity response curve scaling")),
267     eReleaseVelocityResponseCurve(_("Release velocity response curve")),
268     eReleaseVelocityResponseDepth(_("Release velocity response depth"), 0, 4),
269     eReleaseTriggerDecay(_("Release trigger decay"), 0, 8),
270     eCrossfade_in_start(_("Crossfade-in start")),
271     eCrossfade_in_end(_("Crossfade-in end")),
272     eCrossfade_out_start(_("Crossfade-out start")),
273     eCrossfade_out_end(_("Crossfade-out end")),
274     ePitchTrack(_("Pitch track")),
275 schoenebeck 3449 eSustainReleaseTrigger(_("Sustain Release Trigger")),
276     eNoNoteOffReleaseTrigger(_("No note-off release trigger")),
277 persson 1831 eDimensionBypass(_("Dimension bypass")),
278     ePan(_("Pan"), -64, 63),
279 schoenebeck 2566 eSelfMask(_("Kill lower velocity voices (a.k.a \"Self mask\")")),
280 persson 1831 eAttenuationController(_("Attenuation controller")),
281     eInvertAttenuationController(_("Invert attenuation controller")),
282     eAttenuationControllerThreshold(_("Attenuation controller threshold")),
283     eChannelOffset(_("Channel offset"), 0, 9),
284 schoenebeck 2536 eSustainDefeat(_("Ignore Hold Pedal (a.k.a. \"Sustain defeat\")")),
285 schoenebeck 2566 eMSDecode(_("Decode Mid/Side Recordings")),
286 persson 1831 eSampleStartOffset(_("Sample start offset"), 0, 2000),
287     eUnityNote(_("Unity note")),
288 schoenebeck 2991 eSampleGroup(_("Sample Group")),
289 schoenebeck 2690 eSampleFormatInfo(_("Sample Format")),
290     eSampleID("Sample ID"),
291 schoenebeck 2991 eChecksum("Wave Data CRC-32"),
292 persson 1831 eFineTune(_("Fine tune"), -49, 50),
293     eGain(_("Gain"), -96, 0, 2, -655360),
294     eGainPlus6(_("Gain +6dB"), eGain, 6 * -655360),
295     eSampleLoopEnabled(_("Enabled")),
296 schoenebeck 3408 eSampleLoopStart(_("Loop start position")),
297 persson 1831 eSampleLoopLength(_("Loop size")),
298     eSampleLoopType(_("Loop type")),
299     eSampleLoopInfinite(_("Infinite loop")),
300     eSampleLoopPlayCount(_("Playback count"), 1),
301 schoenebeck 2692 buttonSelectSample(UNICODE_LEFT_ARROW + " " + _("Select Sample")),
302 persson 1460 update_model(0)
303 schoenebeck 1225 {
304 schoenebeck 2877 // make synthesis parameter page tabs scrollable
305     // (workaround for GTK3: default theme uses huge tabs which breaks layout)
306     set_scrollable();
307    
308 persson 1460 connect(eEG1PreAttack, &gig::DimensionRegion::EG1PreAttack);
309     connect(eEG1Attack, &gig::DimensionRegion::EG1Attack);
310     connect(eEG1Decay1, &gig::DimensionRegion::EG1Decay1);
311     connect(eEG1Decay2, &gig::DimensionRegion::EG1Decay2);
312     connect(eEG1InfiniteSustain, &gig::DimensionRegion::EG1InfiniteSustain);
313     connect(eEG1Sustain, &gig::DimensionRegion::EG1Sustain);
314     connect(eEG1Release, &gig::DimensionRegion::EG1Release);
315     connect(eEG1Hold, &gig::DimensionRegion::EG1Hold);
316     connect(eEG1Controller, &gig::DimensionRegion::EG1Controller);
317     connect(eEG1ControllerInvert, &gig::DimensionRegion::EG1ControllerInvert);
318     connect(eEG1ControllerAttackInfluence,
319     &gig::DimensionRegion::EG1ControllerAttackInfluence);
320     connect(eEG1ControllerDecayInfluence,
321     &gig::DimensionRegion::EG1ControllerDecayInfluence);
322     connect(eEG1ControllerReleaseInfluence,
323     &gig::DimensionRegion::EG1ControllerReleaseInfluence);
324 schoenebeck 3329 {
325     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG1Options.AttackCancel));
326     connect(eEG1StateOptions.checkBoxAttack, mp.pmember);
327     }
328     {
329     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG1Options.AttackHoldCancel));
330     connect(eEG1StateOptions.checkBoxAttackHold, mp.pmember);
331     }
332     {
333     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG1Options.Decay1Cancel));
334     connect(eEG1StateOptions.checkBoxDecay1, mp.pmember);
335     }
336     {
337     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG1Options.Decay2Cancel));
338     connect(eEG1StateOptions.checkBoxDecay2, mp.pmember);
339     }
340     {
341     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG1Options.ReleaseCancel));
342     connect(eEG1StateOptions.checkBoxRelease, mp.pmember);
343     }
344 persson 1460 connect(eLFO1Frequency, &gig::DimensionRegion::LFO1Frequency);
345     connect(eLFO1InternalDepth, &gig::DimensionRegion::LFO1InternalDepth);
346     connect(eLFO1ControlDepth, &gig::DimensionRegion::LFO1ControlDepth);
347     connect(eLFO1Controller, &gig::DimensionRegion::LFO1Controller);
348     connect(eLFO1FlipPhase, &gig::DimensionRegion::LFO1FlipPhase);
349     connect(eLFO1Sync, &gig::DimensionRegion::LFO1Sync);
350     connect(eEG2PreAttack, &gig::DimensionRegion::EG2PreAttack);
351     connect(eEG2Attack, &gig::DimensionRegion::EG2Attack);
352     connect(eEG2Decay1, &gig::DimensionRegion::EG2Decay1);
353     connect(eEG2Decay2, &gig::DimensionRegion::EG2Decay2);
354     connect(eEG2InfiniteSustain, &gig::DimensionRegion::EG2InfiniteSustain);
355     connect(eEG2Sustain, &gig::DimensionRegion::EG2Sustain);
356     connect(eEG2Release, &gig::DimensionRegion::EG2Release);
357     connect(eEG2Controller, &gig::DimensionRegion::EG2Controller);
358     connect(eEG2ControllerInvert, &gig::DimensionRegion::EG2ControllerInvert);
359     connect(eEG2ControllerAttackInfluence,
360     &gig::DimensionRegion::EG2ControllerAttackInfluence);
361     connect(eEG2ControllerDecayInfluence,
362     &gig::DimensionRegion::EG2ControllerDecayInfluence);
363     connect(eEG2ControllerReleaseInfluence,
364     &gig::DimensionRegion::EG2ControllerReleaseInfluence);
365 schoenebeck 3329 {
366     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG2Options.AttackCancel));
367     connect(eEG2StateOptions.checkBoxAttack, mp.pmember);
368     }
369     {
370     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG2Options.AttackHoldCancel));
371     connect(eEG2StateOptions.checkBoxAttackHold, mp.pmember);
372     }
373     {
374     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG2Options.Decay1Cancel));
375     connect(eEG2StateOptions.checkBoxDecay1, mp.pmember);
376     }
377     {
378     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG2Options.Decay2Cancel));
379     connect(eEG2StateOptions.checkBoxDecay2, mp.pmember);
380     }
381     {
382     ClassMemberPtr<gig::DimensionRegion, bool> mp(offsetof(gig::DimensionRegion, EG2Options.ReleaseCancel));
383     connect(eEG2StateOptions.checkBoxRelease, mp.pmember);
384     }
385 persson 1460 connect(eLFO2Frequency, &gig::DimensionRegion::LFO2Frequency);
386     connect(eLFO2InternalDepth, &gig::DimensionRegion::LFO2InternalDepth);
387     connect(eLFO2ControlDepth, &gig::DimensionRegion::LFO2ControlDepth);
388     connect(eLFO2Controller, &gig::DimensionRegion::LFO2Controller);
389     connect(eLFO2FlipPhase, &gig::DimensionRegion::LFO2FlipPhase);
390     connect(eLFO2Sync, &gig::DimensionRegion::LFO2Sync);
391     connect(eEG3Attack, &gig::DimensionRegion::EG3Attack);
392     connect(eEG3Depth, &gig::DimensionRegion::EG3Depth);
393     connect(eLFO3Frequency, &gig::DimensionRegion::LFO3Frequency);
394     connect(eLFO3InternalDepth, &gig::DimensionRegion::LFO3InternalDepth);
395     connect(eLFO3ControlDepth, &gig::DimensionRegion::LFO3ControlDepth);
396     connect(eLFO3Controller, &gig::DimensionRegion::LFO3Controller);
397     connect(eLFO3Sync, &gig::DimensionRegion::LFO3Sync);
398     connect(eVCFEnabled, &gig::DimensionRegion::VCFEnabled);
399     connect(eVCFType, &gig::DimensionRegion::VCFType);
400     connect(eVCFCutoffController,
401     &gig::DimensionRegion::SetVCFCutoffController);
402     connect(eVCFCutoffControllerInvert,
403     &gig::DimensionRegion::VCFCutoffControllerInvert);
404     connect(eVCFCutoff, &gig::DimensionRegion::VCFCutoff);
405     connect(eVCFVelocityCurve, &gig::DimensionRegion::SetVCFVelocityCurve);
406     connect(eVCFVelocityScale, &gig::DimensionRegion::SetVCFVelocityScale);
407     connect(eVCFVelocityDynamicRange,
408     &gig::DimensionRegion::SetVCFVelocityDynamicRange);
409     connect(eVCFResonance, &gig::DimensionRegion::VCFResonance);
410     connect(eVCFResonanceDynamic, &gig::DimensionRegion::VCFResonanceDynamic);
411     connect(eVCFResonanceController,
412     &gig::DimensionRegion::VCFResonanceController);
413     connect(eVCFKeyboardTracking, &gig::DimensionRegion::VCFKeyboardTracking);
414     connect(eVCFKeyboardTrackingBreakpoint,
415     &gig::DimensionRegion::VCFKeyboardTrackingBreakpoint);
416     connect(eVelocityResponseCurve,
417     &gig::DimensionRegion::SetVelocityResponseCurve);
418     connect(eVelocityResponseDepth,
419     &gig::DimensionRegion::SetVelocityResponseDepth);
420     connect(eVelocityResponseCurveScaling,
421     &gig::DimensionRegion::SetVelocityResponseCurveScaling);
422     connect(eReleaseVelocityResponseCurve,
423     &gig::DimensionRegion::SetReleaseVelocityResponseCurve);
424     connect(eReleaseVelocityResponseDepth,
425     &gig::DimensionRegion::SetReleaseVelocityResponseDepth);
426     connect(eReleaseTriggerDecay, &gig::DimensionRegion::ReleaseTriggerDecay);
427     connect(eCrossfade_in_start, &DimRegionEdit::set_Crossfade_in_start);
428     connect(eCrossfade_in_end, &DimRegionEdit::set_Crossfade_in_end);
429     connect(eCrossfade_out_start, &DimRegionEdit::set_Crossfade_out_start);
430     connect(eCrossfade_out_end, &DimRegionEdit::set_Crossfade_out_end);
431     connect(ePitchTrack, &gig::DimensionRegion::PitchTrack);
432 schoenebeck 3449 connect(eSustainReleaseTrigger, &gig::DimensionRegion::SustainReleaseTrigger);
433     connect(eNoNoteOffReleaseTrigger, &gig::DimensionRegion::NoNoteOffReleaseTrigger);
434 persson 1460 connect(eDimensionBypass, &gig::DimensionRegion::DimensionBypass);
435     connect(ePan, &gig::DimensionRegion::Pan);
436     connect(eSelfMask, &gig::DimensionRegion::SelfMask);
437     connect(eAttenuationController,
438     &gig::DimensionRegion::AttenuationController);
439     connect(eInvertAttenuationController,
440     &gig::DimensionRegion::InvertAttenuationController);
441     connect(eAttenuationControllerThreshold,
442     &gig::DimensionRegion::AttenuationControllerThreshold);
443     connect(eChannelOffset, &gig::DimensionRegion::ChannelOffset);
444     connect(eSustainDefeat, &gig::DimensionRegion::SustainDefeat);
445     connect(eMSDecode, &gig::DimensionRegion::MSDecode);
446     connect(eSampleStartOffset, &gig::DimensionRegion::SampleStartOffset);
447     connect(eUnityNote, &DimRegionEdit::set_UnityNote);
448     connect(eFineTune, &DimRegionEdit::set_FineTune);
449     connect(eGain, &DimRegionEdit::set_Gain);
450     connect(eGainPlus6, &DimRegionEdit::set_Gain);
451     connect(eSampleLoopEnabled, &DimRegionEdit::set_LoopEnabled);
452     connect(eSampleLoopType, &DimRegionEdit::set_LoopType);
453     connect(eSampleLoopStart, &DimRegionEdit::set_LoopStart);
454     connect(eSampleLoopLength, &DimRegionEdit::set_LoopLength);
455     connect(eSampleLoopInfinite, &DimRegionEdit::set_LoopInfinite);
456     connect(eSampleLoopPlayCount, &DimRegionEdit::set_LoopPlayCount);
457 schoenebeck 2691 buttonSelectSample.signal_clicked().connect(
458     sigc::mem_fun(*this, &DimRegionEdit::onButtonSelectSamplePressed)
459     );
460 persson 1460
461 schoenebeck 1225 for (int i = 0 ; i < 7 ; i++) {
462 schoenebeck 3364 #if USE_GTKMM_GRID
463     table[i] = new Gtk::Grid;
464     table[i]->set_column_spacing(7);
465     #else
466 schoenebeck 1225 table[i] = new Gtk::Table(3, 1);
467     table[i]->set_col_spacings(7);
468 schoenebeck 3364 #endif
469    
470 schoenebeck 3368 // on Gtk 3 there is absolutely no margin by default
471     #if GTKMM_MAJOR_VERSION >= 3
472     # if GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION < 12
473     table[i]->set_margin_left(12);
474     table[i]->set_margin_right(12);
475     # else
476     table[i]->set_margin_start(12);
477     table[i]->set_margin_end(12);
478     # endif
479     #endif
480 schoenebeck 1225 }
481    
482     // set tooltips
483     eUnityNote.set_tip(
484     _("Note this sample is associated with (a.k.a. 'root note')")
485     );
486 schoenebeck 2691 buttonSelectSample.set_tooltip_text(
487     _("Selects the sample of this dimension region on the left hand side's sample tree view.")
488     );
489 schoenebeck 1225 eSampleStartOffset.set_tip(_("Sample position at which playback should be started"));
490     ePan.set_tip(_("Stereo balance (left/right)"));
491     eChannelOffset.set_tip(
492     _("Output channel where the audio signal should be routed to (0 - 9)")
493     );
494     ePitchTrack.set_tip(
495     _("If true: sample will be pitched according to the key position "
496     "(this would be disabled for drums for example)")
497     );
498     eSampleLoopEnabled.set_tip(_("If enabled: repeats to playback the sample"));
499     eSampleLoopStart.set_tip(
500     _("Start position within the sample (in sample points) of the area to "
501     "be looped")
502     );
503     eSampleLoopLength.set_tip(
504     _("Duration (in sample points) of the area to be looped")
505     );
506     eSampleLoopType.set_tip(
507     _("Direction in which the loop area in the sample should be played back")
508     );
509     eSampleLoopInfinite.set_tip(
510     _("Whether the loop area should be played back forever\n"
511     "Caution: this setting is stored on Sample side, thus is shared "
512     "among all dimension regions that use this sample!")
513     );
514     eSampleLoopPlayCount.set_tip(
515     _("How many times the loop area should be played back\n"
516     "Caution: this setting is stored on Sample side, thus is shared "
517     "among all dimension regions that use this sample!")
518     );
519 schoenebeck 2566
520     eEG1PreAttack.set_tip(
521     "Very first level this EG starts with. It rises then in Attack Time "
522     "seconds from this initial level to 100%."
523     );
524     eEG1Attack.set_tip(
525     "Duration of the EG's Attack stage, which raises its level from "
526     "Pre-Attack Level to 100%."
527     );
528     eEG1Hold.set_tip(
529     "On looped sounds, enabling this will cause the Decay 1 stage not to "
530     "enter before the loop has been passed one time."
531     );
532     eAttenuationController.set_tip(_(
533     "If you are not using the 'Layer' dimension, then this controller "
534     "simply alters the volume. If you are using the 'Layer' dimension, "
535     "then this controller is controlling the crossfade between Layers in "
536     "real-time."
537     ));
538 schoenebeck 1225
539 schoenebeck 2566 eLFO1Sync.set_tip(
540     "If not checked, every voice will use its own LFO instance, which "
541     "causes voices triggered at different points in time to have different "
542     "LFO levels. By enabling 'Sync' here the voices will instead use and "
543     "share one single LFO, causing all voices to have the same LFO level, "
544     "no matter when the individual notes have been triggered."
545     );
546     eLFO2Sync.set_tip(
547     "If not checked, every voice will use its own LFO instance, which "
548     "causes voices triggered at different points in time to have different "
549     "LFO levels. By enabling 'Sync' here the voices will instead use and "
550     "share one single LFO, causing all voices to have the same LFO level, "
551     "no matter when the individual notes have been triggered."
552     );
553     eLFO3Sync.set_tip(
554     "If not checked, every voice will use its own LFO instance, which "
555     "causes voices triggered at different points in time to have different "
556     "LFO levels. By enabling 'Sync' here the voices will instead use and "
557     "share one single LFO, causing all voices to have the same LFO level, "
558     "no matter when the individual notes have been triggered."
559     );
560     eLFO1FlipPhase.set_tip(
561     "Inverts the LFO's generated wave vertically."
562     );
563     eLFO2FlipPhase.set_tip(
564     "Inverts the LFO's generated wave vertically."
565     );
566    
567 schoenebeck 1225 pageno = 0;
568     rowno = 0;
569     firstRowInBlock = 0;
570    
571     addHeader(_("Mandatory Settings"));
572 schoenebeck 2720 addString(_("Sample"), lSample, wSample, buttonNullSampleReference);
573     buttonNullSampleReference->set_label("X");
574     buttonNullSampleReference->set_tooltip_text(_("Remove current sample reference (NULL reference). This can be used to define a \"silent\" case where no sample shall be played."));
575     buttonNullSampleReference->signal_clicked().connect(
576     sigc::mem_fun(*this, &DimRegionEdit::nullOutSampleReference)
577     );
578 schoenebeck 1225 //TODO: the following would break drag&drop: wSample->property_editable().set_value(false); or this: wSample->set_editable(false);
579 persson 2151 #ifdef OLD_TOOLTIPS
580 schoenebeck 2536 tooltips.set_tip(*wSample, _("Drag & drop a sample here"));
581 persson 2151 #else
582 schoenebeck 2536 wSample->set_tooltip_text(_("Drag & drop a sample here"));
583 persson 2151 #endif
584 schoenebeck 1225 addProp(eUnityNote);
585 schoenebeck 2991 addProp(eSampleGroup);
586 schoenebeck 2690 addProp(eSampleFormatInfo);
587     addProp(eSampleID);
588 schoenebeck 2991 addProp(eChecksum);
589 schoenebeck 2691 addRightHandSide(buttonSelectSample);
590 schoenebeck 1225 addHeader(_("Optional Settings"));
591     addProp(eSampleStartOffset);
592     addProp(eChannelOffset);
593 persson 1831 addHeader(_("Loops"));
594 schoenebeck 1225 addProp(eSampleLoopEnabled);
595     addProp(eSampleLoopStart);
596     addProp(eSampleLoopLength);
597     {
598 persson 1831 const char* choices[] = { _("normal"), _("bidirectional"), _("backward"), 0 };
599 schoenebeck 1225 static const uint32_t values[] = {
600     gig::loop_type_normal,
601     gig::loop_type_bidirectional,
602     gig::loop_type_backward
603     };
604     eSampleLoopType.set_choices(choices, values);
605     }
606     addProp(eSampleLoopType);
607     addProp(eSampleLoopInfinite);
608     addProp(eSampleLoopPlayCount);
609    
610     nextPage();
611    
612     addHeader(_("General Amplitude Settings"));
613     addProp(eGain);
614     addProp(eGainPlus6);
615     addProp(ePan);
616     addHeader(_("Amplitude Envelope (EG1)"));
617     addProp(eEG1PreAttack);
618     addProp(eEG1Attack);
619 schoenebeck 2566 addProp(eEG1Hold);
620 schoenebeck 1225 addProp(eEG1Decay1);
621     addProp(eEG1Decay2);
622     addProp(eEG1InfiniteSustain);
623     addProp(eEG1Sustain);
624     addProp(eEG1Release);
625     addProp(eEG1Controller);
626     addProp(eEG1ControllerInvert);
627     addProp(eEG1ControllerAttackInfluence);
628     addProp(eEG1ControllerDecayInfluence);
629     addProp(eEG1ControllerReleaseInfluence);
630 schoenebeck 3329 addLine(eEG1StateOptions);
631 schoenebeck 1225
632     nextPage();
633    
634     addHeader(_("Amplitude Oscillator (LFO1)"));
635     addProp(eLFO1Frequency);
636     addProp(eLFO1InternalDepth);
637     addProp(eLFO1ControlDepth);
638     {
639 persson 1831 const char* choices[] = { _("internal"), _("modwheel"), _("breath"),
640     _("internal+modwheel"), _("internal+breath"), 0 };
641 schoenebeck 1225 static const gig::lfo1_ctrl_t values[] = {
642     gig::lfo1_ctrl_internal,
643     gig::lfo1_ctrl_modwheel,
644     gig::lfo1_ctrl_breath,
645     gig::lfo1_ctrl_internal_modwheel,
646     gig::lfo1_ctrl_internal_breath
647     };
648     eLFO1Controller.set_choices(choices, values);
649     }
650     addProp(eLFO1Controller);
651     addProp(eLFO1FlipPhase);
652     addProp(eLFO1Sync);
653 persson 1831 addHeader(_("Crossfade"));
654 schoenebeck 1225 addProp(eAttenuationController);
655     addProp(eInvertAttenuationController);
656     addProp(eAttenuationControllerThreshold);
657     addProp(eCrossfade_in_start);
658     addProp(eCrossfade_in_end);
659     addProp(eCrossfade_out_start);
660     addProp(eCrossfade_out_end);
661    
662 persson 2392 Gtk::Frame* frame = new Gtk::Frame;
663     frame->add(crossfade_curve);
664 schoenebeck 3368 // on Gtk 3 there is no margin at all by default
665     #if GTKMM_MAJOR_VERSION >= 3
666     frame->set_margin_top(12);
667     frame->set_margin_bottom(12);
668     #endif
669 schoenebeck 3364 #if USE_GTKMM_GRID
670     table[pageno]->attach(*frame, 1, rowno, 2);
671     #else
672 persson 2392 table[pageno]->attach(*frame, 1, 3, rowno, rowno + 1,
673     Gtk::SHRINK, Gtk::SHRINK);
674 schoenebeck 3364 #endif
675 persson 2392 rowno++;
676    
677     eCrossfade_in_start.signal_value_changed().connect(
678     sigc::mem_fun(crossfade_curve, &CrossfadeCurve::queue_draw));
679     eCrossfade_in_end.signal_value_changed().connect(
680     sigc::mem_fun(crossfade_curve, &CrossfadeCurve::queue_draw));
681     eCrossfade_out_start.signal_value_changed().connect(
682     sigc::mem_fun(crossfade_curve, &CrossfadeCurve::queue_draw));
683     eCrossfade_out_end.signal_value_changed().connect(
684     sigc::mem_fun(crossfade_curve, &CrossfadeCurve::queue_draw));
685    
686 schoenebeck 1225 nextPage();
687    
688     addHeader(_("General Filter Settings"));
689     addProp(eVCFEnabled);
690     {
691 persson 1831 const char* choices[] = { _("lowpass"), _("lowpassturbo"), _("bandpass"),
692     _("highpass"), _("bandreject"), 0 };
693 schoenebeck 1225 static const gig::vcf_type_t values[] = {
694     gig::vcf_type_lowpass,
695     gig::vcf_type_lowpassturbo,
696     gig::vcf_type_bandpass,
697     gig::vcf_type_highpass,
698     gig::vcf_type_bandreject
699     };
700     eVCFType.set_choices(choices, values);
701     }
702     addProp(eVCFType);
703     {
704 persson 1831 const char* choices[] = { _("none"), _("none2"), _("modwheel"), _("effect1"), _("effect2"),
705     _("breath"), _("foot"), _("sustainpedal"), _("softpedal"),
706     _("genpurpose7"), _("genpurpose8"), _("aftertouch"), 0 };
707 schoenebeck 1225 static const gig::vcf_cutoff_ctrl_t values[] = {
708     gig::vcf_cutoff_ctrl_none,
709     gig::vcf_cutoff_ctrl_none2,
710     gig::vcf_cutoff_ctrl_modwheel,
711     gig::vcf_cutoff_ctrl_effect1,
712     gig::vcf_cutoff_ctrl_effect2,
713     gig::vcf_cutoff_ctrl_breath,
714     gig::vcf_cutoff_ctrl_foot,
715     gig::vcf_cutoff_ctrl_sustainpedal,
716     gig::vcf_cutoff_ctrl_softpedal,
717     gig::vcf_cutoff_ctrl_genpurpose7,
718     gig::vcf_cutoff_ctrl_genpurpose8,
719     gig::vcf_cutoff_ctrl_aftertouch
720     };
721     eVCFCutoffController.set_choices(choices, values);
722     }
723     addProp(eVCFCutoffController);
724     addProp(eVCFCutoffControllerInvert);
725     addProp(eVCFCutoff);
726 persson 1831 const char* curve_type_texts[] = { _("nonlinear"), _("linear"), _("special"), 0 };
727 schoenebeck 1225 static const gig::curve_type_t curve_type_values[] = {
728     gig::curve_type_nonlinear,
729     gig::curve_type_linear,
730     gig::curve_type_special
731     };
732     eVCFVelocityCurve.set_choices(curve_type_texts, curve_type_values);
733     addProp(eVCFVelocityCurve);
734     addProp(eVCFVelocityScale);
735     addProp(eVCFVelocityDynamicRange);
736 persson 2392
737     eVCFCutoffController.signal_value_changed().connect(
738     sigc::mem_fun(cutoff_curve, &VelocityCurve::queue_draw));
739     eVCFVelocityCurve.signal_value_changed().connect(
740     sigc::mem_fun(cutoff_curve, &VelocityCurve::queue_draw));
741     eVCFVelocityScale.signal_value_changed().connect(
742     sigc::mem_fun(cutoff_curve, &VelocityCurve::queue_draw));
743     eVCFVelocityDynamicRange.signal_value_changed().connect(
744     sigc::mem_fun(cutoff_curve, &VelocityCurve::queue_draw));
745    
746     frame = new Gtk::Frame;
747     frame->add(cutoff_curve);
748 schoenebeck 3368 // on Gtk 3 there is no margin at all by default
749     #if GTKMM_MAJOR_VERSION >= 3
750     frame->set_margin_top(12);
751     frame->set_margin_bottom(12);
752     #endif
753 schoenebeck 3364 #if USE_GTKMM_GRID
754     table[pageno]->attach(*frame, 1, rowno, 2);
755     #else
756 persson 2392 table[pageno]->attach(*frame, 1, 3, rowno, rowno + 1,
757     Gtk::SHRINK, Gtk::SHRINK);
758 schoenebeck 3364 #endif
759 persson 2392 rowno++;
760    
761 schoenebeck 1225 addProp(eVCFResonance);
762     addProp(eVCFResonanceDynamic);
763     {
764 persson 1831 const char* choices[] = { _("none"), _("genpurpose3"), _("genpurpose4"),
765     _("genpurpose5"), _("genpurpose6"), 0 };
766 schoenebeck 1225 static const gig::vcf_res_ctrl_t values[] = {
767     gig::vcf_res_ctrl_none,
768     gig::vcf_res_ctrl_genpurpose3,
769     gig::vcf_res_ctrl_genpurpose4,
770     gig::vcf_res_ctrl_genpurpose5,
771     gig::vcf_res_ctrl_genpurpose6
772     };
773     eVCFResonanceController.set_choices(choices, values);
774     }
775     addProp(eVCFResonanceController);
776     addProp(eVCFKeyboardTracking);
777     addProp(eVCFKeyboardTrackingBreakpoint);
778    
779     nextPage();
780    
781 persson 1623 lEG2 = addHeader(_("Filter Cutoff Envelope (EG2)"));
782 schoenebeck 1225 addProp(eEG2PreAttack);
783     addProp(eEG2Attack);
784     addProp(eEG2Decay1);
785     addProp(eEG2Decay2);
786     addProp(eEG2InfiniteSustain);
787     addProp(eEG2Sustain);
788     addProp(eEG2Release);
789     addProp(eEG2Controller);
790     addProp(eEG2ControllerInvert);
791     addProp(eEG2ControllerAttackInfluence);
792     addProp(eEG2ControllerDecayInfluence);
793     addProp(eEG2ControllerReleaseInfluence);
794 schoenebeck 3329 addLine(eEG2StateOptions);
795 persson 1623 lLFO2 = addHeader(_("Filter Cutoff Oscillator (LFO2)"));
796 schoenebeck 1225 addProp(eLFO2Frequency);
797     addProp(eLFO2InternalDepth);
798     addProp(eLFO2ControlDepth);
799     {
800 persson 1831 const char* choices[] = { _("internal"), _("modwheel"), _("foot"),
801     _("internal+modwheel"), _("internal+foot"), 0 };
802 schoenebeck 1225 static const gig::lfo2_ctrl_t values[] = {
803     gig::lfo2_ctrl_internal,
804     gig::lfo2_ctrl_modwheel,
805     gig::lfo2_ctrl_foot,
806     gig::lfo2_ctrl_internal_modwheel,
807     gig::lfo2_ctrl_internal_foot
808     };
809     eLFO2Controller.set_choices(choices, values);
810     }
811     addProp(eLFO2Controller);
812     addProp(eLFO2FlipPhase);
813     addProp(eLFO2Sync);
814    
815     nextPage();
816    
817     addHeader(_("General Pitch Settings"));
818     addProp(eFineTune);
819     addProp(ePitchTrack);
820     addHeader(_("Pitch Envelope (EG3)"));
821     addProp(eEG3Attack);
822     addProp(eEG3Depth);
823     addHeader(_("Pitch Oscillator (LFO3)"));
824     addProp(eLFO3Frequency);
825     addProp(eLFO3InternalDepth);
826     addProp(eLFO3ControlDepth);
827     {
828 persson 1831 const char* choices[] = { _("internal"), _("modwheel"), _("aftertouch"),
829     _("internal+modwheel"), _("internal+aftertouch"), 0 };
830 schoenebeck 1225 static const gig::lfo3_ctrl_t values[] = {
831     gig::lfo3_ctrl_internal,
832     gig::lfo3_ctrl_modwheel,
833     gig::lfo3_ctrl_aftertouch,
834     gig::lfo3_ctrl_internal_modwheel,
835     gig::lfo3_ctrl_internal_aftertouch
836     };
837     eLFO3Controller.set_choices(choices, values);
838     }
839     addProp(eLFO3Controller);
840     addProp(eLFO3Sync);
841    
842     nextPage();
843    
844 schoenebeck 2539 addHeader(_("Velocity Response"));
845 schoenebeck 1225 eVelocityResponseCurve.set_choices(curve_type_texts, curve_type_values);
846     addProp(eVelocityResponseCurve);
847     addProp(eVelocityResponseDepth);
848     addProp(eVelocityResponseCurveScaling);
849 persson 2392
850     eVelocityResponseCurve.signal_value_changed().connect(
851     sigc::mem_fun(velocity_curve, &VelocityCurve::queue_draw));
852     eVelocityResponseDepth.signal_value_changed().connect(
853     sigc::mem_fun(velocity_curve, &VelocityCurve::queue_draw));
854     eVelocityResponseCurveScaling.signal_value_changed().connect(
855     sigc::mem_fun(velocity_curve, &VelocityCurve::queue_draw));
856    
857     frame = new Gtk::Frame;
858     frame->add(velocity_curve);
859 schoenebeck 3368 // on Gtk 3 there is no margin at all by default
860     #if GTKMM_MAJOR_VERSION >= 3
861     frame->set_margin_top(12);
862     frame->set_margin_bottom(12);
863     #endif
864 schoenebeck 3364 #if USE_GTKMM_GRID
865     table[pageno]->attach(*frame, 1, rowno, 2);
866     #else
867 persson 2392 table[pageno]->attach(*frame, 1, 3, rowno, rowno + 1,
868     Gtk::SHRINK, Gtk::SHRINK);
869 schoenebeck 3364 #endif
870 persson 2392 rowno++;
871    
872 schoenebeck 2539 addHeader(_("Release Velocity Response"));
873 schoenebeck 1225 eReleaseVelocityResponseCurve.set_choices(curve_type_texts,
874     curve_type_values);
875     addProp(eReleaseVelocityResponseCurve);
876     addProp(eReleaseVelocityResponseDepth);
877 persson 2392
878     eReleaseVelocityResponseCurve.signal_value_changed().connect(
879     sigc::mem_fun(release_curve, &VelocityCurve::queue_draw));
880     eReleaseVelocityResponseDepth.signal_value_changed().connect(
881     sigc::mem_fun(release_curve, &VelocityCurve::queue_draw));
882     frame = new Gtk::Frame;
883     frame->add(release_curve);
884 schoenebeck 3368 // on Gtk 3 there is no margin at all by default
885     #if GTKMM_MAJOR_VERSION >= 3
886     frame->set_margin_top(12);
887     frame->set_margin_bottom(12);
888     #endif
889 schoenebeck 3364 #if USE_GTKMM_GRID
890     table[pageno]->attach(*frame, 1, rowno, 2);
891     #else
892 persson 2392 table[pageno]->attach(*frame, 1, 3, rowno, rowno + 1,
893     Gtk::SHRINK, Gtk::SHRINK);
894 schoenebeck 3364 #endif
895 persson 2392 rowno++;
896    
897 schoenebeck 1225 addProp(eReleaseTriggerDecay);
898     {
899 schoenebeck 3449 const char* choices[] = { _("off"), _("on (max. velocity)"), _("on (key velocity)"), 0 };
900     static const gig::sust_rel_trg_t values[] = {
901     gig::sust_rel_trg_none,
902     gig::sust_rel_trg_maxvelocity,
903     gig::sust_rel_trg_keyvelocity
904     };
905     eSustainReleaseTrigger.set_choices(choices, values);
906     }
907     eSustainReleaseTrigger.set_tip(_(
908     "By default release trigger samples are played on note-off events only. "
909     "This option allows to play release trigger sample on sustain pedal up "
910     "events as well. NOTE: This is a format extension!"
911     ));
912     addProp(eSustainReleaseTrigger);
913     {
914 persson 1831 const char* choices[] = { _("none"), _("effect4depth"), _("effect5depth"), 0 };
915 schoenebeck 1225 static const gig::dim_bypass_ctrl_t values[] = {
916     gig::dim_bypass_ctrl_none,
917     gig::dim_bypass_ctrl_94,
918     gig::dim_bypass_ctrl_95
919     };
920     eDimensionBypass.set_choices(choices, values);
921     }
922 schoenebeck 3449 eNoNoteOffReleaseTrigger.set_tip(_(
923     "By default release trigger samples are played on note-off events only. "
924     "If this option is checked, then no release trigger sample is played "
925     "when releasing a note. NOTE: This is a format extension!"
926     ));
927     addProp(eNoNoteOffReleaseTrigger);
928 schoenebeck 1225 addProp(eDimensionBypass);
929 schoenebeck 2566 eSelfMask.widget.set_tooltip_text(_(
930     "If enabled: new notes with higher velocity value will stop older "
931     "notes with lower velocity values, that way you can save voices that "
932     "would barely be audible. This is also useful for certain drum sounds."
933     ));
934 schoenebeck 1225 addProp(eSelfMask);
935 schoenebeck 2566 eSustainDefeat.widget.set_tooltip_text(_(
936     "If enabled: sustain pedal will not hold a note. This way you can use "
937     "the sustain pedal for other purposes, for example to switch among "
938     "dimension regions."
939     ));
940 schoenebeck 1225 addProp(eSustainDefeat);
941 schoenebeck 2566 eMSDecode.widget.set_tooltip_text(_(
942     "Defines if Mid/Side Recordings should be decoded. Mid/Side Recordings "
943     "are an alternative way to record sounds in stereo. The sampler needs "
944     "to decode such samples to actually make use of them. Note: this "
945     "feature is currently not supported by LinuxSampler."
946     ));
947 schoenebeck 1225 addProp(eMSDecode);
948    
949     nextPage();
950    
951    
952 persson 1460 eEG1InfiniteSustain.signal_value_changed().connect(
953     sigc::mem_fun(*this, &DimRegionEdit::EG1InfiniteSustain_toggled));
954     eEG2InfiniteSustain.signal_value_changed().connect(
955     sigc::mem_fun(*this, &DimRegionEdit::EG2InfiniteSustain_toggled));
956     eEG1Controller.signal_value_changed().connect(
957     sigc::mem_fun(*this, &DimRegionEdit::EG1Controller_changed));
958     eEG2Controller.signal_value_changed().connect(
959     sigc::mem_fun(*this, &DimRegionEdit::EG2Controller_changed));
960     eLFO1Controller.signal_value_changed().connect(
961     sigc::mem_fun(*this, &DimRegionEdit::LFO1Controller_changed));
962     eLFO2Controller.signal_value_changed().connect(
963     sigc::mem_fun(*this, &DimRegionEdit::LFO2Controller_changed));
964     eLFO3Controller.signal_value_changed().connect(
965     sigc::mem_fun(*this, &DimRegionEdit::LFO3Controller_changed));
966     eAttenuationController.signal_value_changed().connect(
967     sigc::mem_fun(*this, &DimRegionEdit::AttenuationController_changed));
968     eVCFEnabled.signal_value_changed().connect(
969     sigc::mem_fun(*this, &DimRegionEdit::VCFEnabled_toggled));
970     eVCFCutoffController.signal_value_changed().connect(
971     sigc::mem_fun(*this, &DimRegionEdit::VCFCutoffController_changed));
972     eVCFResonanceController.signal_value_changed().connect(
973     sigc::mem_fun(*this, &DimRegionEdit::VCFResonanceController_changed));
974 schoenebeck 1225
975 persson 1460 eCrossfade_in_start.signal_value_changed().connect(
976 schoenebeck 1225 sigc::mem_fun(*this, &DimRegionEdit::crossfade1_changed));
977 persson 1460 eCrossfade_in_end.signal_value_changed().connect(
978 schoenebeck 1225 sigc::mem_fun(*this, &DimRegionEdit::crossfade2_changed));
979 persson 1460 eCrossfade_out_start.signal_value_changed().connect(
980 schoenebeck 1225 sigc::mem_fun(*this, &DimRegionEdit::crossfade3_changed));
981 persson 1460 eCrossfade_out_end.signal_value_changed().connect(
982 schoenebeck 1225 sigc::mem_fun(*this, &DimRegionEdit::crossfade4_changed));
983    
984 persson 1460 eSampleLoopEnabled.signal_value_changed().connect(
985     sigc::mem_fun(*this, &DimRegionEdit::update_loop_elements));
986     eSampleLoopStart.signal_value_changed().connect(
987     sigc::mem_fun(*this, &DimRegionEdit::loop_start_changed));
988     eSampleLoopLength.signal_value_changed().connect(
989     sigc::mem_fun(*this, &DimRegionEdit::loop_length_changed));
990     eSampleLoopInfinite.signal_value_changed().connect(
991 schoenebeck 1225 sigc::mem_fun(*this, &DimRegionEdit::loop_infinite_toggled));
992    
993 persson 1831 append_page(*table[0], _("Sample"));
994     append_page(*table[1], _("Amplitude (1)"));
995     append_page(*table[2], _("Amplitude (2)"));
996     append_page(*table[3], _("Filter (1)"));
997     append_page(*table[4], _("Filter (2)"));
998     append_page(*table[5], _("Pitch"));
999     append_page(*table[6], _("Misc"));
1000 schoenebeck 3409
1001     Settings::singleton()->showTooltips.get_proxy().signal_changed().connect(
1002     sigc::mem_fun(*this, &DimRegionEdit::on_show_tooltips_changed)
1003     );
1004    
1005     on_show_tooltips_changed();
1006 schoenebeck 1225 }
1007    
1008     DimRegionEdit::~DimRegionEdit()
1009     {
1010     }
1011    
1012     void DimRegionEdit::addString(const char* labelText, Gtk::Label*& label,
1013     Gtk::Entry*& widget)
1014     {
1015     label = new Gtk::Label(Glib::ustring(labelText) + ":");
1016 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
1017 persson 2169 label->set_alignment(Gtk::ALIGN_START);
1018 schoenebeck 3364 #else
1019     label->set_halign(Gtk::Align::START);
1020     #endif
1021 schoenebeck 1225
1022 schoenebeck 3364 #if USE_GTKMM_GRID
1023     table[pageno]->attach(*label, 1, rowno);
1024     #else
1025 schoenebeck 1225 table[pageno]->attach(*label, 1, 2, rowno, rowno + 1,
1026     Gtk::FILL, Gtk::SHRINK);
1027 schoenebeck 3364 #endif
1028 schoenebeck 1225
1029     widget = new Gtk::Entry();
1030    
1031 schoenebeck 3364 #if USE_GTKMM_GRID
1032     table[pageno]->attach(*widget, 2, rowno);
1033     #else
1034 schoenebeck 1225 table[pageno]->attach(*widget, 2, 3, rowno, rowno + 1,
1035     Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
1036 schoenebeck 3364 #endif
1037 schoenebeck 1225
1038     rowno++;
1039     }
1040    
1041 schoenebeck 2720 void DimRegionEdit::addString(const char* labelText, Gtk::Label*& label,
1042     Gtk::Entry*& widget, Gtk::Button*& button)
1043     {
1044     label = new Gtk::Label(Glib::ustring(labelText) + ":");
1045 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
1046 schoenebeck 2720 label->set_alignment(Gtk::ALIGN_START);
1047 schoenebeck 3364 #else
1048     label->set_halign(Gtk::Align::START);
1049     #endif
1050 schoenebeck 2720
1051 schoenebeck 3364 #if USE_GTKMM_GRID
1052     table[pageno]->attach(*label, 1, rowno);
1053     #else
1054 schoenebeck 2720 table[pageno]->attach(*label, 1, 2, rowno, rowno + 1,
1055     Gtk::FILL, Gtk::SHRINK);
1056 schoenebeck 3364 #endif
1057 schoenebeck 2720
1058     widget = new Gtk::Entry();
1059     button = new Gtk::Button();
1060    
1061 schoenebeck 3364 HBox* hbox = new HBox;
1062 schoenebeck 2720 hbox->pack_start(*widget);
1063     hbox->pack_start(*button, Gtk::PACK_SHRINK);
1064    
1065 schoenebeck 3364 #if USE_GTKMM_GRID
1066     table[pageno]->attach(*hbox, 2, rowno);
1067     #else
1068 schoenebeck 2720 table[pageno]->attach(*hbox, 2, 3, rowno, rowno + 1,
1069     Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
1070 schoenebeck 3364 #endif
1071 schoenebeck 2720
1072     rowno++;
1073     }
1074    
1075 persson 1623 Gtk::Label* DimRegionEdit::addHeader(const char* text)
1076 schoenebeck 1225 {
1077     if (firstRowInBlock < rowno - 1)
1078     {
1079     Gtk::Label* filler = new Gtk::Label(" ");
1080 schoenebeck 3364 #if USE_GTKMM_GRID
1081     table[pageno]->attach(*filler, 0, firstRowInBlock);
1082     #else
1083 schoenebeck 1225 table[pageno]->attach(*filler, 0, 1, firstRowInBlock, rowno,
1084     Gtk::FILL, Gtk::SHRINK);
1085 schoenebeck 3364 #endif
1086 schoenebeck 1225 }
1087     Glib::ustring str = "<b>";
1088     str += text;
1089     str += "</b>";
1090     Gtk::Label* label = new Gtk::Label(str);
1091     label->set_use_markup();
1092 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
1093 persson 2169 label->set_alignment(Gtk::ALIGN_START);
1094 schoenebeck 3364 #else
1095     label->set_halign(Gtk::Align::START);
1096     #endif
1097 schoenebeck 3368 // on GTKMM 3 there is absolutely no margin by default
1098     #if GTKMM_MAJOR_VERSION >= 3
1099     label->set_margin_top(18);
1100     label->set_margin_bottom(13);
1101     #endif
1102 schoenebeck 3364 #if USE_GTKMM_GRID
1103     table[pageno]->attach(*label, 0, rowno, 3);
1104     #else
1105 schoenebeck 1225 table[pageno]->attach(*label, 0, 3, rowno, rowno + 1,
1106     Gtk::FILL, Gtk::SHRINK);
1107 schoenebeck 3364 #endif
1108 schoenebeck 1225 rowno++;
1109     firstRowInBlock = rowno;
1110 persson 1623 return label;
1111 schoenebeck 1225 }
1112    
1113 schoenebeck 3409 void DimRegionEdit::on_show_tooltips_changed() {
1114     const bool b = Settings::singleton()->showTooltips;
1115    
1116     buttonSelectSample.set_has_tooltip(b);
1117     buttonNullSampleReference->set_has_tooltip(b);
1118     wSample->set_has_tooltip(b);
1119    
1120     eEG1StateOptions.on_show_tooltips_changed();
1121     eEG2StateOptions.on_show_tooltips_changed();
1122    
1123     set_has_tooltip(b);
1124     }
1125    
1126 schoenebeck 1225 void DimRegionEdit::nextPage()
1127     {
1128     if (firstRowInBlock < rowno - 1)
1129     {
1130     Gtk::Label* filler = new Gtk::Label(" ");
1131 schoenebeck 3364 #if USE_GTKMM_GRID
1132     table[pageno]->attach(*filler, 0, firstRowInBlock);
1133     #else
1134 schoenebeck 1225 table[pageno]->attach(*filler, 0, 1, firstRowInBlock, rowno,
1135     Gtk::FILL, Gtk::SHRINK);
1136 schoenebeck 3364 #endif
1137 schoenebeck 1225 }
1138     pageno++;
1139     rowno = 0;
1140     firstRowInBlock = 0;
1141     }
1142    
1143     void DimRegionEdit::addProp(BoolEntry& boolentry)
1144     {
1145 schoenebeck 3364 #if USE_GTKMM_GRID
1146     table[pageno]->attach(boolentry.widget, 1, rowno, 2);
1147     #else
1148 schoenebeck 1225 table[pageno]->attach(boolentry.widget, 1, 3, rowno, rowno + 1,
1149     Gtk::FILL, Gtk::SHRINK);
1150 schoenebeck 3364 #endif
1151 schoenebeck 1225 rowno++;
1152     }
1153    
1154 persson 1262 void DimRegionEdit::addProp(BoolEntryPlus6& boolentry)
1155     {
1156 schoenebeck 3364 #if USE_GTKMM_GRID
1157     table[pageno]->attach(boolentry.widget, 1, rowno, 2);
1158     #else
1159 persson 1262 table[pageno]->attach(boolentry.widget, 1, 3, rowno, rowno + 1,
1160     Gtk::FILL, Gtk::SHRINK);
1161 schoenebeck 3364 #endif
1162 persson 1262 rowno++;
1163     }
1164    
1165 schoenebeck 1225 void DimRegionEdit::addProp(LabelWidget& prop)
1166     {
1167 schoenebeck 3364 #if USE_GTKMM_GRID
1168     table[pageno]->attach(prop.label, 1, rowno);
1169     table[pageno]->attach(prop.widget, 2, rowno);
1170     #else
1171 schoenebeck 1225 table[pageno]->attach(prop.label, 1, 2, rowno, rowno + 1,
1172     Gtk::FILL, Gtk::SHRINK);
1173     table[pageno]->attach(prop.widget, 2, 3, rowno, rowno + 1,
1174     Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
1175 schoenebeck 3364 #endif
1176 schoenebeck 1225 rowno++;
1177     }
1178    
1179 schoenebeck 3364 void DimRegionEdit::addLine(HBox& line)
1180 schoenebeck 3329 {
1181 schoenebeck 3364 #if USE_GTKMM_GRID
1182     table[pageno]->attach(line, 1, rowno, 2);
1183     #else
1184 schoenebeck 3329 table[pageno]->attach(line, 1, 3, rowno, rowno + 1,
1185     Gtk::FILL, Gtk::SHRINK);
1186 schoenebeck 3364 #endif
1187 schoenebeck 3329 rowno++;
1188     }
1189    
1190 schoenebeck 2691 void DimRegionEdit::addRightHandSide(Gtk::Widget& widget)
1191     {
1192 schoenebeck 3364 #if USE_GTKMM_GRID
1193     table[pageno]->attach(widget, 2, rowno);
1194     #else
1195 schoenebeck 2691 table[pageno]->attach(widget, 2, 3, rowno, rowno + 1,
1196     Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
1197 schoenebeck 3364 #endif
1198 schoenebeck 2691 rowno++;
1199     }
1200 schoenebeck 1225
1201     void DimRegionEdit::set_dim_region(gig::DimensionRegion* d)
1202     {
1203     dimregion = d;
1204 persson 2392 velocity_curve.set_dim_region(d);
1205     release_curve.set_dim_region(d);
1206     cutoff_curve.set_dim_region(d);
1207     crossfade_curve.set_dim_region(d);
1208 schoenebeck 1225
1209     set_sensitive(d);
1210     if (!d) return;
1211    
1212 persson 1460 update_model++;
1213     eEG1PreAttack.set_value(d->EG1PreAttack);
1214     eEG1Attack.set_value(d->EG1Attack);
1215     eEG1Decay1.set_value(d->EG1Decay1);
1216     eEG1Decay2.set_value(d->EG1Decay2);
1217     eEG1InfiniteSustain.set_value(d->EG1InfiniteSustain);
1218     eEG1Sustain.set_value(d->EG1Sustain);
1219     eEG1Release.set_value(d->EG1Release);
1220     eEG1Hold.set_value(d->EG1Hold);
1221     eEG1Controller.set_value(d->EG1Controller);
1222     eEG1ControllerInvert.set_value(d->EG1ControllerInvert);
1223     eEG1ControllerAttackInfluence.set_value(d->EG1ControllerAttackInfluence);
1224     eEG1ControllerDecayInfluence.set_value(d->EG1ControllerDecayInfluence);
1225     eEG1ControllerReleaseInfluence.set_value(d->EG1ControllerReleaseInfluence);
1226 schoenebeck 3329 eEG1StateOptions.checkBoxAttack.set_value(d->EG1Options.AttackCancel);
1227     eEG1StateOptions.checkBoxAttackHold.set_value(d->EG1Options.AttackHoldCancel);
1228     eEG1StateOptions.checkBoxDecay1.set_value(d->EG1Options.Decay1Cancel);
1229     eEG1StateOptions.checkBoxDecay2.set_value(d->EG1Options.Decay2Cancel);
1230     eEG1StateOptions.checkBoxRelease.set_value(d->EG1Options.ReleaseCancel);
1231 persson 1460 eLFO1Frequency.set_value(d->LFO1Frequency);
1232     eLFO1InternalDepth.set_value(d->LFO1InternalDepth);
1233     eLFO1ControlDepth.set_value(d->LFO1ControlDepth);
1234     eLFO1Controller.set_value(d->LFO1Controller);
1235     eLFO1FlipPhase.set_value(d->LFO1FlipPhase);
1236     eLFO1Sync.set_value(d->LFO1Sync);
1237     eEG2PreAttack.set_value(d->EG2PreAttack);
1238     eEG2Attack.set_value(d->EG2Attack);
1239     eEG2Decay1.set_value(d->EG2Decay1);
1240     eEG2Decay2.set_value(d->EG2Decay2);
1241     eEG2InfiniteSustain.set_value(d->EG2InfiniteSustain);
1242     eEG2Sustain.set_value(d->EG2Sustain);
1243     eEG2Release.set_value(d->EG2Release);
1244     eEG2Controller.set_value(d->EG2Controller);
1245     eEG2ControllerInvert.set_value(d->EG2ControllerInvert);
1246     eEG2ControllerAttackInfluence.set_value(d->EG2ControllerAttackInfluence);
1247     eEG2ControllerDecayInfluence.set_value(d->EG2ControllerDecayInfluence);
1248     eEG2ControllerReleaseInfluence.set_value(d->EG2ControllerReleaseInfluence);
1249 schoenebeck 3329 eEG2StateOptions.checkBoxAttack.set_value(d->EG2Options.AttackCancel);
1250     eEG2StateOptions.checkBoxAttackHold.set_value(d->EG2Options.AttackHoldCancel);
1251     eEG2StateOptions.checkBoxDecay1.set_value(d->EG2Options.Decay1Cancel);
1252     eEG2StateOptions.checkBoxDecay2.set_value(d->EG2Options.Decay2Cancel);
1253     eEG2StateOptions.checkBoxRelease.set_value(d->EG2Options.ReleaseCancel);
1254 persson 1460 eLFO2Frequency.set_value(d->LFO2Frequency);
1255     eLFO2InternalDepth.set_value(d->LFO2InternalDepth);
1256     eLFO2ControlDepth.set_value(d->LFO2ControlDepth);
1257     eLFO2Controller.set_value(d->LFO2Controller);
1258     eLFO2FlipPhase.set_value(d->LFO2FlipPhase);
1259     eLFO2Sync.set_value(d->LFO2Sync);
1260     eEG3Attack.set_value(d->EG3Attack);
1261     eEG3Depth.set_value(d->EG3Depth);
1262     eLFO3Frequency.set_value(d->LFO3Frequency);
1263     eLFO3InternalDepth.set_value(d->LFO3InternalDepth);
1264     eLFO3ControlDepth.set_value(d->LFO3ControlDepth);
1265     eLFO3Controller.set_value(d->LFO3Controller);
1266     eLFO3Sync.set_value(d->LFO3Sync);
1267     eVCFEnabled.set_value(d->VCFEnabled);
1268     eVCFType.set_value(d->VCFType);
1269     eVCFCutoffController.set_value(d->VCFCutoffController);
1270     eVCFCutoffControllerInvert.set_value(d->VCFCutoffControllerInvert);
1271     eVCFCutoff.set_value(d->VCFCutoff);
1272     eVCFVelocityCurve.set_value(d->VCFVelocityCurve);
1273     eVCFVelocityScale.set_value(d->VCFVelocityScale);
1274     eVCFVelocityDynamicRange.set_value(d->VCFVelocityDynamicRange);
1275     eVCFResonance.set_value(d->VCFResonance);
1276     eVCFResonanceDynamic.set_value(d->VCFResonanceDynamic);
1277     eVCFResonanceController.set_value(d->VCFResonanceController);
1278     eVCFKeyboardTracking.set_value(d->VCFKeyboardTracking);
1279     eVCFKeyboardTrackingBreakpoint.set_value(d->VCFKeyboardTrackingBreakpoint);
1280     eVelocityResponseCurve.set_value(d->VelocityResponseCurve);
1281     eVelocityResponseDepth.set_value(d->VelocityResponseDepth);
1282     eVelocityResponseCurveScaling.set_value(d->VelocityResponseCurveScaling);
1283     eReleaseVelocityResponseCurve.set_value(d->ReleaseVelocityResponseCurve);
1284     eReleaseVelocityResponseDepth.set_value(d->ReleaseVelocityResponseDepth);
1285     eReleaseTriggerDecay.set_value(d->ReleaseTriggerDecay);
1286     eCrossfade_in_start.set_value(d->Crossfade.in_start);
1287     eCrossfade_in_end.set_value(d->Crossfade.in_end);
1288     eCrossfade_out_start.set_value(d->Crossfade.out_start);
1289     eCrossfade_out_end.set_value(d->Crossfade.out_end);
1290     ePitchTrack.set_value(d->PitchTrack);
1291 schoenebeck 3449 eSustainReleaseTrigger.set_value(d->SustainReleaseTrigger);
1292     eNoNoteOffReleaseTrigger.set_value(d->NoNoteOffReleaseTrigger);
1293 persson 1460 eDimensionBypass.set_value(d->DimensionBypass);
1294     ePan.set_value(d->Pan);
1295     eSelfMask.set_value(d->SelfMask);
1296     eAttenuationController.set_value(d->AttenuationController);
1297     eInvertAttenuationController.set_value(d->InvertAttenuationController);
1298     eAttenuationControllerThreshold.set_value(d->AttenuationControllerThreshold);
1299     eChannelOffset.set_value(d->ChannelOffset);
1300     eSustainDefeat.set_value(d->SustainDefeat);
1301     eMSDecode.set_value(d->MSDecode);
1302     eSampleStartOffset.set_value(d->SampleStartOffset);
1303     eUnityNote.set_value(d->UnityNote);
1304 schoenebeck 2991 // show sample group name
1305     {
1306     Glib::ustring s = "---";
1307     if (d->pSample && d->pSample->GetGroup())
1308     s = d->pSample->GetGroup()->Name;
1309     eSampleGroup.text.set_text(s);
1310     }
1311 schoenebeck 2690 // assemble sample format info string
1312     {
1313     Glib::ustring s;
1314     if (d->pSample) {
1315     switch (d->pSample->Channels) {
1316     case 1: s = _("Mono"); break;
1317     case 2: s = _("Stereo"); break;
1318     default:
1319     s = ToString(d->pSample->Channels) + _(" audio channels");
1320     break;
1321     }
1322     s += " " + ToString(d->pSample->BitDepth) + " Bits";
1323     s += " " + ToString(d->pSample->SamplesPerSecond/1000) + "."
1324     + ToString((d->pSample->SamplesPerSecond%1000)/100) + " kHz";
1325     } else {
1326     s = _("No sample assigned to this dimension region.");
1327     }
1328     eSampleFormatInfo.text.set_text(s);
1329     }
1330     // generate sample's memory address pointer string
1331     {
1332     Glib::ustring s;
1333     if (d->pSample) {
1334     char buf[64] = {};
1335     snprintf(buf, sizeof(buf), "%p", d->pSample);
1336     s = buf;
1337     } else {
1338     s = "---";
1339     }
1340     eSampleID.text.set_text(s);
1341     }
1342 schoenebeck 2991 // generate raw wave form data CRC-32 checksum string
1343     {
1344     Glib::ustring s = "---";
1345     if (d->pSample) {
1346     char buf[64] = {};
1347     snprintf(buf, sizeof(buf), "%x", d->pSample->GetWaveDataCRC32Checksum());
1348     s = buf;
1349     }
1350     eChecksum.text.set_text(s);
1351     }
1352 schoenebeck 2691 buttonSelectSample.set_sensitive(d && d->pSample);
1353 persson 1460 eFineTune.set_value(d->FineTune);
1354     eGain.set_value(d->Gain);
1355     eGainPlus6.set_value(d->Gain);
1356     eSampleLoopEnabled.set_value(d->SampleLoops);
1357     eSampleLoopType.set_value(
1358     d->SampleLoops ? d->pSampleLoops[0].LoopType : 0);
1359     eSampleLoopStart.set_value(
1360     d->SampleLoops ? d->pSampleLoops[0].LoopStart : 0);
1361     eSampleLoopLength.set_value(
1362     d->SampleLoops ? d->pSampleLoops[0].LoopLength : 0);
1363     eSampleLoopInfinite.set_value(
1364     d->pSample && d->pSample->LoopPlayCount == 0);
1365     eSampleLoopPlayCount.set_value(
1366     d->pSample ? d->pSample->LoopPlayCount : 0);
1367     update_model--;
1368 persson 1261
1369 persson 2446 wSample->set_text(d->pSample ? gig_to_utf8(d->pSample->pInfo->Name) :
1370     _("NULL"));
1371 schoenebeck 1225
1372 persson 1460 update_loop_elements();
1373 schoenebeck 1225 VCFEnabled_toggled();
1374     }
1375    
1376 persson 1460
1377 schoenebeck 1225 void DimRegionEdit::VCFEnabled_toggled()
1378     {
1379 persson 1460 bool sensitive = eVCFEnabled.get_value();
1380 schoenebeck 1225 eVCFType.set_sensitive(sensitive);
1381     eVCFCutoffController.set_sensitive(sensitive);
1382     eVCFVelocityCurve.set_sensitive(sensitive);
1383     eVCFVelocityScale.set_sensitive(sensitive);
1384     eVCFVelocityDynamicRange.set_sensitive(sensitive);
1385 persson 2430 cutoff_curve.set_sensitive(sensitive);
1386 schoenebeck 1225 eVCFResonance.set_sensitive(sensitive);
1387     eVCFResonanceController.set_sensitive(sensitive);
1388     eVCFKeyboardTracking.set_sensitive(sensitive);
1389     eVCFKeyboardTrackingBreakpoint.set_sensitive(sensitive);
1390 persson 1623 lEG2->set_sensitive(sensitive);
1391 schoenebeck 1225 eEG2PreAttack.set_sensitive(sensitive);
1392     eEG2Attack.set_sensitive(sensitive);
1393     eEG2Decay1.set_sensitive(sensitive);
1394     eEG2InfiniteSustain.set_sensitive(sensitive);
1395     eEG2Sustain.set_sensitive(sensitive);
1396     eEG2Release.set_sensitive(sensitive);
1397     eEG2Controller.set_sensitive(sensitive);
1398     eEG2ControllerAttackInfluence.set_sensitive(sensitive);
1399     eEG2ControllerDecayInfluence.set_sensitive(sensitive);
1400     eEG2ControllerReleaseInfluence.set_sensitive(sensitive);
1401 schoenebeck 3329 eEG2StateOptions.set_sensitive(sensitive);
1402 persson 1623 lLFO2->set_sensitive(sensitive);
1403 schoenebeck 1225 eLFO2Frequency.set_sensitive(sensitive);
1404     eLFO2InternalDepth.set_sensitive(sensitive);
1405     eLFO2ControlDepth.set_sensitive(sensitive);
1406     eLFO2Controller.set_sensitive(sensitive);
1407     eLFO2FlipPhase.set_sensitive(sensitive);
1408     eLFO2Sync.set_sensitive(sensitive);
1409     if (sensitive) {
1410     VCFCutoffController_changed();
1411     VCFResonanceController_changed();
1412     EG2InfiniteSustain_toggled();
1413     EG2Controller_changed();
1414     LFO2Controller_changed();
1415     } else {
1416     eVCFCutoffControllerInvert.set_sensitive(false);
1417     eVCFCutoff.set_sensitive(false);
1418     eVCFResonanceDynamic.set_sensitive(false);
1419     eVCFResonance.set_sensitive(false);
1420     eEG2Decay2.set_sensitive(false);
1421     eEG2ControllerInvert.set_sensitive(false);
1422     eLFO2InternalDepth.set_sensitive(false);
1423     eLFO2ControlDepth.set_sensitive(false);
1424     }
1425     }
1426    
1427     void DimRegionEdit::VCFCutoffController_changed()
1428     {
1429 persson 1460 gig::vcf_cutoff_ctrl_t ctrl = eVCFCutoffController.get_value();
1430     bool hasController = ctrl != gig::vcf_cutoff_ctrl_none && ctrl != gig::vcf_cutoff_ctrl_none2;
1431 schoenebeck 1225
1432     eVCFCutoffControllerInvert.set_sensitive(hasController);
1433     eVCFCutoff.set_sensitive(!hasController);
1434     eVCFResonanceDynamic.set_sensitive(!hasController);
1435 persson 1831 eVCFVelocityScale.label.set_text(hasController ? _("Minimum cutoff:") :
1436     _("Velocity scale:"));
1437 schoenebeck 1225 }
1438    
1439     void DimRegionEdit::VCFResonanceController_changed()
1440     {
1441 persson 1460 bool hasController = eVCFResonanceController.get_value() != gig::vcf_res_ctrl_none;
1442 schoenebeck 1225 eVCFResonance.set_sensitive(!hasController);
1443     }
1444    
1445     void DimRegionEdit::EG1InfiniteSustain_toggled()
1446     {
1447 persson 1460 bool infSus = eEG1InfiniteSustain.get_value();
1448 schoenebeck 1225 eEG1Decay2.set_sensitive(!infSus);
1449     }
1450    
1451     void DimRegionEdit::EG2InfiniteSustain_toggled()
1452     {
1453 persson 1460 bool infSus = eEG2InfiniteSustain.get_value();
1454 schoenebeck 1225 eEG2Decay2.set_sensitive(!infSus);
1455     }
1456    
1457     void DimRegionEdit::EG1Controller_changed()
1458     {
1459 persson 1460 bool hasController = eEG1Controller.get_value().type != gig::leverage_ctrl_t::type_none;
1460 schoenebeck 1225 eEG1ControllerInvert.set_sensitive(hasController);
1461     }
1462    
1463     void DimRegionEdit::EG2Controller_changed()
1464     {
1465 persson 1460 bool hasController = eEG2Controller.get_value().type != gig::leverage_ctrl_t::type_none;
1466 schoenebeck 1225 eEG2ControllerInvert.set_sensitive(hasController);
1467     }
1468    
1469     void DimRegionEdit::AttenuationController_changed()
1470     {
1471 persson 1460 bool hasController =
1472     eAttenuationController.get_value().type != gig::leverage_ctrl_t::type_none;
1473 schoenebeck 1225 eInvertAttenuationController.set_sensitive(hasController);
1474     eAttenuationControllerThreshold.set_sensitive(hasController);
1475     eCrossfade_in_start.set_sensitive(hasController);
1476     eCrossfade_in_end.set_sensitive(hasController);
1477     eCrossfade_out_start.set_sensitive(hasController);
1478     eCrossfade_out_end.set_sensitive(hasController);
1479 persson 2430 crossfade_curve.set_sensitive(hasController);
1480 schoenebeck 1225 }
1481    
1482     void DimRegionEdit::LFO1Controller_changed()
1483     {
1484 persson 1460 gig::lfo1_ctrl_t ctrl = eLFO1Controller.get_value();
1485     eLFO1ControlDepth.set_sensitive(ctrl != gig::lfo1_ctrl_internal);
1486     eLFO1InternalDepth.set_sensitive(ctrl != gig::lfo1_ctrl_modwheel &&
1487     ctrl != gig::lfo1_ctrl_breath);
1488 schoenebeck 1225 }
1489    
1490     void DimRegionEdit::LFO2Controller_changed()
1491     {
1492 persson 1460 gig::lfo2_ctrl_t ctrl = eLFO2Controller.get_value();
1493     eLFO2ControlDepth.set_sensitive(ctrl != gig::lfo2_ctrl_internal);
1494     eLFO2InternalDepth.set_sensitive(ctrl != gig::lfo2_ctrl_modwheel &&
1495     ctrl != gig::lfo2_ctrl_foot);
1496 schoenebeck 1225 }
1497    
1498     void DimRegionEdit::LFO3Controller_changed()
1499     {
1500 persson 1460 gig::lfo3_ctrl_t ctrl = eLFO3Controller.get_value();
1501     eLFO3ControlDepth.set_sensitive(ctrl != gig::lfo3_ctrl_internal);
1502     eLFO3InternalDepth.set_sensitive(ctrl != gig::lfo3_ctrl_modwheel &&
1503     ctrl != gig::lfo3_ctrl_aftertouch);
1504 schoenebeck 1225 }
1505    
1506     void DimRegionEdit::crossfade1_changed()
1507     {
1508 persson 1460 update_model++;
1509     eCrossfade_in_end.set_value(dimregion->Crossfade.in_end);
1510     eCrossfade_out_start.set_value(dimregion->Crossfade.out_start);
1511     eCrossfade_out_end.set_value(dimregion->Crossfade.out_end);
1512     update_model--;
1513 schoenebeck 1225 }
1514    
1515     void DimRegionEdit::crossfade2_changed()
1516     {
1517 persson 1460 update_model++;
1518     eCrossfade_in_start.set_value(dimregion->Crossfade.in_start);
1519     eCrossfade_out_start.set_value(dimregion->Crossfade.out_start);
1520     eCrossfade_out_end.set_value(dimregion->Crossfade.out_end);
1521     update_model--;
1522 schoenebeck 1225 }
1523    
1524     void DimRegionEdit::crossfade3_changed()
1525     {
1526 persson 1460 update_model++;
1527     eCrossfade_in_start.set_value(dimregion->Crossfade.in_start);
1528     eCrossfade_in_end.set_value(dimregion->Crossfade.in_end);
1529     eCrossfade_out_end.set_value(dimregion->Crossfade.out_end);
1530     update_model--;
1531 schoenebeck 1225 }
1532    
1533     void DimRegionEdit::crossfade4_changed()
1534     {
1535 persson 1460 update_model++;
1536     eCrossfade_in_start.set_value(dimregion->Crossfade.in_start);
1537     eCrossfade_in_end.set_value(dimregion->Crossfade.in_end);
1538     eCrossfade_out_start.set_value(dimregion->Crossfade.out_start);
1539     update_model--;
1540 schoenebeck 1225 }
1541    
1542 persson 1460 void DimRegionEdit::update_loop_elements()
1543 schoenebeck 1225 {
1544 persson 1460 update_model++;
1545     const bool active = eSampleLoopEnabled.get_value();
1546 schoenebeck 1225 eSampleLoopStart.set_sensitive(active);
1547     eSampleLoopLength.set_sensitive(active);
1548     eSampleLoopType.set_sensitive(active);
1549 persson 1303 eSampleLoopInfinite.set_sensitive(active && dimregion && dimregion->pSample);
1550 persson 1460 // sample loop shall never be longer than the actual sample size
1551     loop_start_changed();
1552     loop_length_changed();
1553     eSampleLoopStart.set_value(
1554     dimregion->SampleLoops ? dimregion->pSampleLoops[0].LoopStart : 0);
1555     eSampleLoopLength.set_value(
1556     dimregion->SampleLoops ? dimregion->pSampleLoops[0].LoopLength : 0);
1557 persson 1261
1558 persson 1460 eSampleLoopInfinite.set_value(
1559     dimregion->pSample && dimregion->pSample->LoopPlayCount == 0);
1560 persson 1261
1561 persson 1460 loop_infinite_toggled();
1562     update_model--;
1563     }
1564 persson 1261
1565 persson 1460 void DimRegionEdit::loop_start_changed() {
1566     if (dimregion && dimregion->SampleLoops) {
1567     eSampleLoopLength.set_upper(dimregion->pSample ?
1568     dimregion->pSample->SamplesTotal -
1569     dimregion->pSampleLoops[0].LoopStart : 0);
1570 schoenebeck 1225 }
1571     }
1572    
1573 persson 1460 void DimRegionEdit::loop_length_changed() {
1574     if (dimregion && dimregion->SampleLoops) {
1575     eSampleLoopStart.set_upper(dimregion->pSample ?
1576     dimregion->pSample->SamplesTotal -
1577     dimregion->pSampleLoops[0].LoopLength : 0);
1578     }
1579     }
1580    
1581 schoenebeck 1225 void DimRegionEdit::loop_infinite_toggled() {
1582     eSampleLoopPlayCount.set_sensitive(
1583 persson 1303 dimregion && dimregion->pSample &&
1584 persson 1460 !eSampleLoopInfinite.get_value() &&
1585     eSampleLoopEnabled.get_value()
1586 schoenebeck 1225 );
1587 persson 1460 update_model++;
1588     eSampleLoopPlayCount.set_value(
1589     dimregion->pSample ? dimregion->pSample->LoopPlayCount : 0);
1590     update_model--;
1591 schoenebeck 1225 }
1592 persson 1265
1593 schoenebeck 2464 bool DimRegionEdit::set_sample(gig::Sample* sample, bool copy_sample_unity, bool copy_sample_tune, bool copy_sample_loop)
1594 persson 1265 {
1595 schoenebeck 3070 bool result = false;
1596 schoenebeck 2925 for (std::set<gig::DimensionRegion*>::iterator itDimReg = dimregs.begin();
1597     itDimReg != dimregs.end(); ++itDimReg)
1598     {
1599 schoenebeck 3070 result |= set_sample(*itDimReg, sample, copy_sample_unity, copy_sample_tune, copy_sample_loop);
1600 schoenebeck 2925 }
1601 schoenebeck 3070 return result;
1602 schoenebeck 2925 }
1603    
1604     bool DimRegionEdit::set_sample(gig::DimensionRegion* dimreg, gig::Sample* sample, bool copy_sample_unity, bool copy_sample_tune, bool copy_sample_loop)
1605     {
1606 schoenebeck 2926 if (dimreg) {
1607 schoenebeck 1322 //TODO: we should better move the code from MainWindow::on_sample_label_drop_drag_data_received() here
1608    
1609     // currently commented because we're sending a similar signal in MainWindow::on_sample_label_drop_drag_data_received()
1610 schoenebeck 3177 //DimRegionChangeGuard(this, dimregion);
1611 schoenebeck 1322
1612 persson 1798 // make sure stereo samples always are the same in both
1613     // dimregs in the samplechannel dimension
1614     int nbDimregs = 1;
1615 schoenebeck 2926 gig::DimensionRegion* d[2] = { dimreg, 0 };
1616 persson 1798 if (sample->Channels == 2) {
1617 schoenebeck 2926 gig::Region* region = dimreg->GetParent();
1618 persson 1798
1619     int bitcount = 0;
1620     int stereo_bit = 0;
1621     for (int dim = 0 ; dim < region->Dimensions ; dim++) {
1622     if (region->pDimensionDefinitions[dim].dimension == gig::dimension_samplechannel) {
1623     stereo_bit = 1 << bitcount;
1624     break;
1625     }
1626     bitcount += region->pDimensionDefinitions[dim].bits;
1627     }
1628    
1629     if (stereo_bit) {
1630     int dimregno;
1631     for (dimregno = 0 ; dimregno < region->DimensionRegions ; dimregno++) {
1632 schoenebeck 2926 if (region->pDimensionRegions[dimregno] == dimreg) {
1633 persson 1798 break;
1634     }
1635     }
1636     d[0] = region->pDimensionRegions[dimregno & ~stereo_bit];
1637     d[1] = region->pDimensionRegions[dimregno | stereo_bit];
1638     nbDimregs = 2;
1639     }
1640     }
1641    
1642 schoenebeck 2926 gig::Sample* oldref = dimreg->pSample;
1643 persson 1265
1644 persson 1798 for (int i = 0 ; i < nbDimregs ; i++) {
1645     d[i]->pSample = sample;
1646 persson 1265
1647 persson 1798 // copy sample information from Sample to DimensionRegion
1648 schoenebeck 2464 if (copy_sample_unity)
1649     d[i]->UnityNote = sample->MIDIUnityNote;
1650     if (copy_sample_tune)
1651     d[i]->FineTune = sample->FineTune;
1652     if (copy_sample_loop) {
1653     int loops = sample->Loops ? 1 : 0;
1654     while (d[i]->SampleLoops > loops) {
1655     d[i]->DeleteSampleLoop(&d[i]->pSampleLoops[0]);
1656     }
1657     while (d[i]->SampleLoops < sample->Loops) {
1658     DLS::sample_loop_t loop;
1659     d[i]->AddSampleLoop(&loop);
1660     }
1661     if (loops) {
1662     d[i]->pSampleLoops[0].Size = sizeof(DLS::sample_loop_t);
1663     d[i]->pSampleLoops[0].LoopType = sample->LoopType;
1664     d[i]->pSampleLoops[0].LoopStart = sample->LoopStart;
1665     d[i]->pSampleLoops[0].LoopLength = sample->LoopEnd - sample->LoopStart + 1;
1666     }
1667 persson 1798 }
1668 persson 1265 }
1669    
1670     // update ui
1671 persson 1460 update_model++;
1672 schoenebeck 2926 wSample->set_text(gig_to_utf8(dimreg->pSample->pInfo->Name));
1673     eUnityNote.set_value(dimreg->UnityNote);
1674     eFineTune.set_value(dimreg->FineTune);
1675     eSampleLoopEnabled.set_value(dimreg->SampleLoops);
1676 persson 1460 update_loop_elements();
1677     update_model--;
1678 persson 1265
1679 schoenebeck 1322 sample_ref_changed_signal.emit(oldref, sample);
1680 persson 1265 return true;
1681     }
1682     return false;
1683     }
1684 schoenebeck 1322
1685 schoenebeck 1339 sigc::signal<void, gig::DimensionRegion*>& DimRegionEdit::signal_dimreg_to_be_changed() {
1686 schoenebeck 1322 return dimreg_to_be_changed_signal;
1687     }
1688    
1689 schoenebeck 1339 sigc::signal<void, gig::DimensionRegion*>& DimRegionEdit::signal_dimreg_changed() {
1690 schoenebeck 1322 return dimreg_changed_signal;
1691     }
1692    
1693 schoenebeck 1339 sigc::signal<void, gig::Sample*/*old*/, gig::Sample*/*new*/>& DimRegionEdit::signal_sample_ref_changed() {
1694 schoenebeck 1322 return sample_ref_changed_signal;
1695     }
1696 persson 1460
1697    
1698     void DimRegionEdit::set_UnityNote(gig::DimensionRegion* d, uint8_t value)
1699     {
1700     d->UnityNote = value;
1701     }
1702    
1703     void DimRegionEdit::set_FineTune(gig::DimensionRegion* d, int16_t value)
1704     {
1705     d->FineTune = value;
1706     }
1707    
1708     void DimRegionEdit::set_Crossfade_in_start(gig::DimensionRegion* d,
1709     uint8_t value)
1710     {
1711     d->Crossfade.in_start = value;
1712     if (d->Crossfade.in_end < value) set_Crossfade_in_end(d, value);
1713     }
1714    
1715     void DimRegionEdit::set_Crossfade_in_end(gig::DimensionRegion* d,
1716     uint8_t value)
1717     {
1718     d->Crossfade.in_end = value;
1719     if (value < d->Crossfade.in_start) set_Crossfade_in_start(d, value);
1720     if (value > d->Crossfade.out_start) set_Crossfade_out_start(d, value);
1721     }
1722    
1723     void DimRegionEdit::set_Crossfade_out_start(gig::DimensionRegion* d,
1724     uint8_t value)
1725     {
1726     d->Crossfade.out_start = value;
1727     if (value < d->Crossfade.in_end) set_Crossfade_in_end(d, value);
1728     if (value > d->Crossfade.out_end) set_Crossfade_out_end(d, value);
1729     }
1730    
1731     void DimRegionEdit::set_Crossfade_out_end(gig::DimensionRegion* d,
1732     uint8_t value)
1733     {
1734     d->Crossfade.out_end = value;
1735     if (value < d->Crossfade.out_start) set_Crossfade_out_start(d, value);
1736     }
1737    
1738     void DimRegionEdit::set_Gain(gig::DimensionRegion* d, int32_t value)
1739     {
1740     d->SetGain(value);
1741     }
1742    
1743     void DimRegionEdit::set_LoopEnabled(gig::DimensionRegion* d, bool value)
1744     {
1745     if (value) {
1746     // create a new sample loop in case there is none yet
1747     if (!d->SampleLoops) {
1748 schoenebeck 3177 DimRegionChangeGuard(this, d);
1749    
1750 persson 1460 DLS::sample_loop_t loop;
1751     loop.LoopType = gig::loop_type_normal;
1752     // loop the whole sample by default
1753     loop.LoopStart = 0;
1754     loop.LoopLength =
1755     (d->pSample) ? d->pSample->SamplesTotal : 0;
1756     d->AddSampleLoop(&loop);
1757     }
1758     } else {
1759     if (d->SampleLoops) {
1760 schoenebeck 3177 DimRegionChangeGuard(this, d);
1761    
1762 persson 1460 // delete ALL existing sample loops
1763     while (d->SampleLoops) {
1764     d->DeleteSampleLoop(&d->pSampleLoops[0]);
1765     }
1766     }
1767     }
1768     }
1769    
1770     void DimRegionEdit::set_LoopType(gig::DimensionRegion* d, uint32_t value)
1771     {
1772     if (d->SampleLoops) d->pSampleLoops[0].LoopType = value;
1773     }
1774    
1775     void DimRegionEdit::set_LoopStart(gig::DimensionRegion* d, uint32_t value)
1776     {
1777     if (d->SampleLoops) {
1778     d->pSampleLoops[0].LoopStart =
1779     d->pSample ?
1780     std::min(value, uint32_t(d->pSample->SamplesTotal -
1781     d->pSampleLoops[0].LoopLength)) :
1782     0;
1783     }
1784     }
1785    
1786     void DimRegionEdit::set_LoopLength(gig::DimensionRegion* d, uint32_t value)
1787     {
1788     if (d->SampleLoops) {
1789     d->pSampleLoops[0].LoopLength =
1790     d->pSample ?
1791     std::min(value, uint32_t(d->pSample->SamplesTotal -
1792     d->pSampleLoops[0].LoopStart)) :
1793     0;
1794     }
1795     }
1796    
1797     void DimRegionEdit::set_LoopInfinite(gig::DimensionRegion* d, bool value)
1798     {
1799     if (d->pSample) {
1800     if (value) d->pSample->LoopPlayCount = 0;
1801     else if (d->pSample->LoopPlayCount == 0) d->pSample->LoopPlayCount = 1;
1802     }
1803     }
1804    
1805     void DimRegionEdit::set_LoopPlayCount(gig::DimensionRegion* d, uint32_t value)
1806     {
1807     if (d->pSample) d->pSample->LoopPlayCount = value;
1808     }
1809 schoenebeck 2691
1810 schoenebeck 2720 void DimRegionEdit::nullOutSampleReference() {
1811     if (!dimregion) return;
1812     gig::Sample* oldref = dimregion->pSample;
1813     if (!oldref) return;
1814    
1815 schoenebeck 3177 DimRegionChangeGuard(this, dimregion);
1816 schoenebeck 2720
1817     // in case currently assigned sample is a stereo one, then remove both
1818     // references (expected to be due to a "stereo dimension")
1819     gig::DimensionRegion* d[2] = { dimregion, NULL };
1820     if (oldref->Channels == 2) {
1821     gig::Region* region = dimregion->GetParent();
1822     {
1823 persson 2841 int stereo_bit = 0;
1824 schoenebeck 2720 int bitcount = 0;
1825     for (int dim = 0 ; dim < region->Dimensions ; dim++) {
1826     if (region->pDimensionDefinitions[dim].dimension == gig::dimension_samplechannel) {
1827     stereo_bit = 1 << bitcount;
1828     break;
1829     }
1830     bitcount += region->pDimensionDefinitions[dim].bits;
1831     }
1832    
1833     if (stereo_bit) {
1834     int dimregno;
1835     for (dimregno = 0 ; dimregno < region->DimensionRegions ; dimregno++) {
1836     if (region->pDimensionRegions[dimregno] == dimregion) {
1837     break;
1838     }
1839     }
1840     d[0] = region->pDimensionRegions[dimregno & ~stereo_bit];
1841     d[1] = region->pDimensionRegions[dimregno | stereo_bit];
1842     }
1843     }
1844     }
1845    
1846     if (d[0]) d[0]->pSample = NULL;
1847     if (d[1]) d[1]->pSample = NULL;
1848    
1849     // update UI elements
1850     set_dim_region(dimregion);
1851    
1852     sample_ref_changed_signal.emit(oldref, NULL);
1853     }
1854    
1855 schoenebeck 2691 void DimRegionEdit::onButtonSelectSamplePressed() {
1856     if (!dimregion) return;
1857     if (!dimregion->pSample) return;
1858     select_sample_signal.emit(dimregion->pSample);
1859     }
1860    
1861     sigc::signal<void, gig::Sample*>& DimRegionEdit::signal_select_sample() {
1862     return select_sample_signal;
1863     }

  ViewVC Help
Powered by ViewVC