--- gigedit/trunk/src/gigedit/dimregionedit.cpp 2014/04/21 17:49:17 2536 +++ gigedit/trunk/src/gigedit/dimregionedit.cpp 2015/01/04 19:46:54 2691 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2014 Andreas Persson + * Copyright (C) 2006-2015 Andreas Persson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -151,14 +151,14 @@ velocity_curve(&gig::DimensionRegion::GetVelocityAttenuation), release_curve(&gig::DimensionRegion::GetVelocityRelease), cutoff_curve(&gig::DimensionRegion::GetVelocityCutoff), - eEG1PreAttack(_("Pre-attack"), 0, 100, 2), - eEG1Attack(_("Attack"), 0, 60, 3), - eEG1Decay1(_("Decay 1"), 0.005, 60, 3), - eEG1Decay2(_("Decay 2"), 0, 60, 3), + eEG1PreAttack(_("Pre-attack Level (%)"), 0, 100, 2), + eEG1Attack(_("Attack Time (seconds)"), 0, 60, 3), + eEG1Decay1(_("Decay 1 Time (seconds)"), 0.005, 60, 3), + eEG1Decay2(_("Decay 2 Time (seconds)"), 0, 60, 3), eEG1InfiniteSustain(_("Infinite sustain")), - eEG1Sustain(_("Sustain"), 0, 100, 2), - eEG1Release(_("Release"), 0, 60, 3), - eEG1Hold(_("Hold")), + eEG1Sustain(_("Sustain Level (%)"), 0, 100, 2), + eEG1Release(_("Release Time (seconds)"), 0, 60, 3), + eEG1Hold(_("Hold Attack Stage until Loop End")), eEG1Controller(_("Controller")), eEG1ControllerInvert(_("Controller invert")), eEG1ControllerAttackInfluence(_("Controller attack influence"), 0, 3), @@ -170,13 +170,13 @@ eLFO1Controller(_("Controller")), eLFO1FlipPhase(_("Flip phase")), eLFO1Sync(_("Sync")), - eEG2PreAttack(_("Pre-attack"), 0, 100, 2), - eEG2Attack(_("Attack"), 0, 60, 3), - eEG2Decay1(_("Decay 1"), 0.005, 60, 3), - eEG2Decay2(_("Decay 2"), 0, 60, 3), + eEG2PreAttack(_("Pre-attack Level (%)"), 0, 100, 2), + eEG2Attack(_("Attack Time (seconds)"), 0, 60, 3), + eEG2Decay1(_("Decay 1 Time (seconds)"), 0.005, 60, 3), + eEG2Decay2(_("Decay 2 Time (seconds)"), 0, 60, 3), eEG2InfiniteSustain(_("Infinite sustain")), - eEG2Sustain(_("Sustain"), 0, 100, 2), - eEG2Release(_("Release"), 0, 60, 3), + eEG2Sustain(_("Sustain Level (%)"), 0, 100, 2), + eEG2Release(_("Release Time (seconds)"), 0, 60, 3), eEG2Controller(_("Controller")), eEG2ControllerInvert(_("Controller invert")), eEG2ControllerAttackInfluence(_("Controller attack influence"), 0, 3), @@ -221,15 +221,17 @@ ePitchTrack(_("Pitch track")), eDimensionBypass(_("Dimension bypass")), ePan(_("Pan"), -64, 63), - eSelfMask(_("One note/voice per key (a.k.a \"Self mask\")")), + eSelfMask(_("Kill lower velocity voices (a.k.a \"Self mask\")")), eAttenuationController(_("Attenuation controller")), eInvertAttenuationController(_("Invert attenuation controller")), eAttenuationControllerThreshold(_("Attenuation controller threshold")), eChannelOffset(_("Channel offset"), 0, 9), eSustainDefeat(_("Ignore Hold Pedal (a.k.a. \"Sustain defeat\")")), - eMSDecode(_("MS decode")), + eMSDecode(_("Decode Mid/Side Recordings")), eSampleStartOffset(_("Sample start offset"), 0, 2000), eUnityNote(_("Unity note")), + eSampleFormatInfo(_("Sample Format")), + eSampleID("Sample ID"), eFineTune(_("Fine tune"), -49, 50), eGain(_("Gain"), -96, 0, 2, -655360), eGainPlus6(_("Gain +6dB"), eGain, 6 * -655360), @@ -239,6 +241,7 @@ eSampleLoopType(_("Loop type")), eSampleLoopInfinite(_("Infinite loop")), eSampleLoopPlayCount(_("Playback count"), 1), + buttonSelectSample(Glib::ustring("<- ") + _("Select Sample")), update_model(0) { connect(eEG1PreAttack, &gig::DimensionRegion::EG1PreAttack); @@ -348,6 +351,9 @@ connect(eSampleLoopLength, &DimRegionEdit::set_LoopLength); connect(eSampleLoopInfinite, &DimRegionEdit::set_LoopInfinite); connect(eSampleLoopPlayCount, &DimRegionEdit::set_LoopPlayCount); + buttonSelectSample.signal_clicked().connect( + sigc::mem_fun(*this, &DimRegionEdit::onButtonSelectSamplePressed) + ); for (int i = 0 ; i < 7 ; i++) { table[i] = new Gtk::Table(3, 1); @@ -358,6 +364,9 @@ eUnityNote.set_tip( _("Note this sample is associated with (a.k.a. 'root note')") ); + buttonSelectSample.set_tooltip_text( + _("Selects the sample of this dimension region on the left hand side's sample tree view.") + ); eSampleStartOffset.set_tip(_("Sample position at which playback should be started")); ePan.set_tip(_("Stereo balance (left/right)")); eChannelOffset.set_tip( @@ -388,6 +397,53 @@ "Caution: this setting is stored on Sample side, thus is shared " "among all dimension regions that use this sample!") ); + + eEG1PreAttack.set_tip( + "Very first level this EG starts with. It rises then in Attack Time " + "seconds from this initial level to 100%." + ); + eEG1Attack.set_tip( + "Duration of the EG's Attack stage, which raises its level from " + "Pre-Attack Level to 100%." + ); + eEG1Hold.set_tip( + "On looped sounds, enabling this will cause the Decay 1 stage not to " + "enter before the loop has been passed one time." + ); + eAttenuationController.set_tip(_( + "If you are not using the 'Layer' dimension, then this controller " + "simply alters the volume. If you are using the 'Layer' dimension, " + "then this controller is controlling the crossfade between Layers in " + "real-time." + )); + + eLFO1Sync.set_tip( + "If not checked, every voice will use its own LFO instance, which " + "causes voices triggered at different points in time to have different " + "LFO levels. By enabling 'Sync' here the voices will instead use and " + "share one single LFO, causing all voices to have the same LFO level, " + "no matter when the individual notes have been triggered." + ); + eLFO2Sync.set_tip( + "If not checked, every voice will use its own LFO instance, which " + "causes voices triggered at different points in time to have different " + "LFO levels. By enabling 'Sync' here the voices will instead use and " + "share one single LFO, causing all voices to have the same LFO level, " + "no matter when the individual notes have been triggered." + ); + eLFO3Sync.set_tip( + "If not checked, every voice will use its own LFO instance, which " + "causes voices triggered at different points in time to have different " + "LFO levels. By enabling 'Sync' here the voices will instead use and " + "share one single LFO, causing all voices to have the same LFO level, " + "no matter when the individual notes have been triggered." + ); + eLFO1FlipPhase.set_tip( + "Inverts the LFO's generated wave vertically." + ); + eLFO2FlipPhase.set_tip( + "Inverts the LFO's generated wave vertically." + ); pageno = 0; rowno = 0; @@ -402,6 +458,9 @@ wSample->set_tooltip_text(_("Drag & drop a sample here")); #endif addProp(eUnityNote); + addProp(eSampleFormatInfo); + addProp(eSampleID); + addRightHandSide(buttonSelectSample); addHeader(_("Optional Settings")); addProp(eSampleStartOffset); addProp(eChannelOffset); @@ -431,12 +490,12 @@ addHeader(_("Amplitude Envelope (EG1)")); addProp(eEG1PreAttack); addProp(eEG1Attack); + addProp(eEG1Hold); addProp(eEG1Decay1); addProp(eEG1Decay2); addProp(eEG1InfiniteSustain); addProp(eEG1Sustain); addProp(eEG1Release); - addProp(eEG1Hold); addProp(eEG1Controller); addProp(eEG1ControllerInvert); addProp(eEG1ControllerAttackInfluence); @@ -636,7 +695,7 @@ nextPage(); - addHeader(_("Velocity Reponse")); + addHeader(_("Velocity Response")); eVelocityResponseCurve.set_choices(curve_type_texts, curve_type_values); addProp(eVelocityResponseCurve); addProp(eVelocityResponseDepth); @@ -655,7 +714,7 @@ Gtk::SHRINK, Gtk::SHRINK); rowno++; - addHeader(_("Release Velocity Reponse")); + addHeader(_("Release Velocity Response")); eReleaseVelocityResponseCurve.set_choices(curve_type_texts, curve_type_values); addProp(eReleaseVelocityResponseCurve); @@ -682,11 +741,24 @@ eDimensionBypass.set_choices(choices, values); } addProp(eDimensionBypass); - eSelfMask.widget.set_tooltip_text(_("If enabled: high velocity notes will stop low velocity notes at the same note, that way you can save voices that wouldn't be audible anyway.")); + eSelfMask.widget.set_tooltip_text(_( + "If enabled: new notes with higher velocity value will stop older " + "notes with lower velocity values, that way you can save voices that " + "would barely be audible. This is also useful for certain drum sounds." + )); addProp(eSelfMask); - eSustainDefeat.widget.set_tooltip_text(_("If enabled: sustain pedal will not hold a note.")); + eSustainDefeat.widget.set_tooltip_text(_( + "If enabled: sustain pedal will not hold a note. This way you can use " + "the sustain pedal for other purposes, for example to switch among " + "dimension regions." + )); addProp(eSustainDefeat); - eMSDecode.widget.set_tooltip_text(_("Gigastudio specific flag: defines if Mid Side Recordings should be decoded.")); + eMSDecode.widget.set_tooltip_text(_( + "Defines if Mid/Side Recordings should be decoded. Mid/Side Recordings " + "are an alternative way to record sounds in stereo. The sampler needs " + "to decode such samples to actually make use of them. Note: this " + "feature is currently not supported by LinuxSampler." + )); addProp(eMSDecode); nextPage(); @@ -820,6 +892,12 @@ rowno++; } +void DimRegionEdit::addRightHandSide(Gtk::Widget& widget) +{ + table[pageno]->attach(widget, 2, 3, rowno, rowno + 1, + Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK); + rowno++; +} void DimRegionEdit::set_dim_region(gig::DimensionRegion* d) { @@ -912,6 +990,38 @@ eMSDecode.set_value(d->MSDecode); eSampleStartOffset.set_value(d->SampleStartOffset); eUnityNote.set_value(d->UnityNote); + // assemble sample format info string + { + Glib::ustring s; + if (d->pSample) { + switch (d->pSample->Channels) { + case 1: s = _("Mono"); break; + case 2: s = _("Stereo"); break; + default: + s = ToString(d->pSample->Channels) + _(" audio channels"); + break; + } + s += " " + ToString(d->pSample->BitDepth) + " Bits"; + s += " " + ToString(d->pSample->SamplesPerSecond/1000) + "." + + ToString((d->pSample->SamplesPerSecond%1000)/100) + " kHz"; + } else { + s = _("No sample assigned to this dimension region."); + } + eSampleFormatInfo.text.set_text(s); + } + // generate sample's memory address pointer string + { + Glib::ustring s; + if (d->pSample) { + char buf[64] = {}; + snprintf(buf, sizeof(buf), "%p", d->pSample); + s = buf; + } else { + s = "---"; + } + eSampleID.text.set_text(s); + } + buttonSelectSample.set_sensitive(d && d->pSample); eFineTune.set_value(d->FineTune); eGain.set_value(d->Gain); eGainPlus6.set_value(d->Gain); @@ -1358,3 +1468,13 @@ { if (d->pSample) d->pSample->LoopPlayCount = value; } + +void DimRegionEdit::onButtonSelectSamplePressed() { + if (!dimregion) return; + if (!dimregion->pSample) return; + select_sample_signal.emit(dimregion->pSample); +} + +sigc::signal& DimRegionEdit::signal_select_sample() { + return select_sample_signal; +}