Audacity 3.2.0
DtmfGen.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 DtmfGen.cpp
6
7 Salvo Ventura - Dec 2006
8
9*******************************************************************//*******************************************************************/
15
16
17#include "DtmfGen.h"
18#include "EffectEditor.h"
19#include "LoadEffects.h"
20
21#include <wx/slider.h>
22#include <wx/valgen.h>
23#include <wx/valtext.h>
24#include <wx/stattext.h>
25
26#include "ShuttleGui.h"
27#include "../widgets/NumericTextCtrl.h"
28#include "../widgets/valnum.h"
29
31
32// Event handler object
35{
36 Editor(const EffectUIServices &effect,
38 : EffectEditor{effect, access}
39 // Copy settings
41 {}
42 virtual ~Editor() = default;
43
44 bool ValidateUI() override;
45 bool UpdateUI() override;
46 void DoUpdateUI();
47
49 const EffectSettings &settings, double projectRate);
50 void OnSequence(wxCommandEvent & evt);
51 void OnDuration(wxCommandEvent & evt);
52 void OnDutyCycle(wxCommandEvent & evt);
53
54 // These settings exist for the lifetime of the validator
56
57 wxTextCtrl *mDtmfSequenceT;
58 wxSlider *mDtmfDutyCycleS;
60 wxStaticText *mDtmfToneT;
61 wxStaticText *mDtmfSilenceT;
62 wxStaticText *mDtmfDutyT;
63};
64
66 const EffectSettings &settings, double projectRate)
67{
68 // Reference to our copy of this effect's special settings
69 auto &dtmfSettings = mSettings;
70
71 // Do NOT hold a reference to EffectSettings, just use it to find initial
72 // duration values. (It came from EffectSettingsAccess so its stable address
73 // can't be relied on.)
74
75 // dialog will be passed values from effect
76 // Effect retrieves values from saved config
77 // Dialog will take care of using them to initialize controls
78 // If there is a selection, use that duration, otherwise use
79 // value from saved config: this is useful is user wants to
80 // replace selection with dtmf sequence
81
82 S.AddSpace(0, 5);
83 S.StartMultiColumn(2, wxCENTER);
84 {
86 S
87 .Validator([&dtmfSettings]{
88 wxTextValidator vldDtmf(
89 wxFILTER_INCLUDE_CHAR_LIST, &dtmfSettings.dtmfSequence);
90 wxArrayString symbols;
91 symbols.Alloc(DtmfBase::kSymbols.size());
92 for (auto c : DtmfBase::kSymbols)
93 symbols.Add(wxString::Format(wxT("%c"), c));
94 vldDtmf.SetIncludes(symbols);
95 return vldDtmf;
96 })
97 .AddTextBox(XXO("DTMF &sequence:"), wxT(""), 10);
99
100 // A control with no event handler but the validator causes updates
101 // when TransferData functions are called
102 S
103 .Validator<FloatingPointValidator<double>>(
104 3, &dtmfSettings.dtmfAmplitude, NumValidatorStyle::NO_TRAILING_ZEROES,
106 .AddTextBox(XXO("&Amplitude (0-1):"), wxT(""), 10);
107
108 S.AddPrompt(XXO("&Duration:"));
109 auto &extra = settings.extra;
112 S.GetParent(), wxID_ANY,
114 extra.GetDurationFormat(),
115 extra.GetDuration(),
117 .AutoPos(true));
118 S.Name(XO("Duration"))
119 .AddWindow(mDtmfDurationT);
121
122 S.AddFixedText(XO("&Tone/silence ratio:"), false);
124 S
125 .Style(wxSL_HORIZONTAL | wxEXPAND)
126 .MinSize( { -1, -1 } )
127 .AddSlider( {},
128 dtmfSettings.dtmfDutyCycle * DutyCycle.scale,
132 }
133 S.EndMultiColumn();
134
135 S.StartMultiColumn(2, wxCENTER);
136 {
137 S.AddFixedText(XO("Duty cycle:"), false);
138 mDtmfDutyT =
139 S.AddVariableText(XO("%.1f %%")
140 .Format( dtmfSettings.dtmfDutyCycle ), false);
141
142 S.AddFixedText(XO("Tone duration:"), false);
144 /* i18n-hint milliseconds */
145 S.AddVariableText(XO("%.0f ms")
146 .Format( dtmfSettings.dtmfTone * 1000.0 ), false);
147
148 S.AddFixedText(XO("Silence duration:"), false);
149 mDtmfToneT =
150 /* i18n-hint milliseconds */
151 S.AddVariableText(XO("%0.f ms")
152 .Format( dtmfSettings.dtmfSilence * 1000.0 ), false);
153 }
154 S.EndMultiColumn();
155}
156
157// Effect implementation
158
159std::unique_ptr<EffectEditor> EffectDtmf::MakeEditor(
161 const EffectOutputs *) const
162{
163 auto &settings = access.Get();
164 auto &dtmfSettings = GetSettings(settings);
165 auto result = std::make_unique<Editor>(*this, access, dtmfSettings);
166 result->PopulateOrExchange(S, settings, mProjectRate);
167 return result;
168}
169
171{
172 const auto &settings = mAccess.Get();
173 auto &dtmfSettings = mSettings;
174
175 // Copy into our settings
176 mSettings = GetSettings(settings);
177
178 mDtmfDutyCycleS->SetValue(dtmfSettings.dtmfDutyCycle * DutyCycle.scale);
179
180 mDtmfDurationT->SetValue(settings.extra.GetDuration());
181
182 DoUpdateUI();
183
184 return true;
185}
186
188{
189 mAccess.ModifySettings([this](EffectSettings &settings){
190 auto &dtmfSettings = mSettings;
191 dtmfSettings.dtmfDutyCycle =
192 (double) mDtmfDutyCycleS->GetValue() / DutyCycle.scale;
193 settings.extra.SetDuration(mDtmfDurationT->GetValue());
194
195 // recalculate to make sure all values are up-to-date. This is especially
196 // important if the user did not change any values in the dialog
197 dtmfSettings.Recalculate(settings);
198 return nullptr;
199 });
200
201 return true;
202}
203
205{
206 // Update some texts in response to controls
207 auto &dtmfSettings = mSettings;
208
209 mDtmfDutyT
210 ->SetLabel(wxString::Format(wxT("%.1f %%"), dtmfSettings.dtmfDutyCycle));
211 mDtmfDutyT->SetName(mDtmfDutyT->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
212
213 mDtmfSilenceT
214 ->SetLabel(wxString::Format(_("%.0f ms"), dtmfSettings.dtmfTone * 1000.0));
215 mDtmfSilenceT->SetName(mDtmfSilenceT->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
216
217 mDtmfToneT
218 ->SetLabel(wxString::Format(_("%.0f ms"), dtmfSettings.dtmfSilence * 1000.0));
219 mDtmfToneT->SetName(mDtmfToneT->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
220}
221
222void EffectDtmf::Editor::OnSequence(wxCommandEvent & WXUNUSED(evt))
223{
224 mAccess.ModifySettings([this](EffectSettings &settings){
225 auto &dtmfSettings = mSettings;
226 dtmfSettings.dtmfSequence = mDtmfSequenceT->GetValue();
227 dtmfSettings.Recalculate(settings);
228 return nullptr;
229 });
230 DoUpdateUI();
231}
232
233void EffectDtmf::Editor::OnDuration(wxCommandEvent & WXUNUSED(evt))
234{
235 mAccess.ModifySettings([this](EffectSettings &settings){
236 auto &dtmfSettings = mSettings;
237 settings.extra.SetDuration(mDtmfDurationT->GetValue());
238 dtmfSettings.Recalculate(settings);
239 return nullptr;
240 });
241 DoUpdateUI();
242}
243
244void EffectDtmf::Editor::OnDutyCycle(wxCommandEvent & evt)
245{
246 mAccess.ModifySettings([this, &evt](EffectSettings &settings){
247 auto &dtmfSettings = mSettings;
248 dtmfSettings.dtmfDutyCycle = (double) evt.GetInt() / DutyCycle.scale;
249 dtmfSettings.Recalculate(settings);
250 return nullptr;
251 });
252 DoUpdateUI();
253}
wxT("CloseDown"))
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define _(s)
Definition: Internat.h:73
#define safenew
Definition: MemoryX.h:10
const NumericConverterType & NumericConverterType_TIME()
#define S(N)
Definition: ToChars.cpp:64
static Settings & settings()
Definition: TrackInfo.cpp:51
static constexpr EffectParameter Amplitude
Definition: DtmfBase.h:117
static constexpr EffectParameter DutyCycle
Definition: DtmfBase.h:111
static constexpr std::array< char, 6 *7 > kSymbols
Definition: DtmfBase.h:34
double mProjectRate
Definition: EffectBase.h:119
std::unique_ptr< EffectEditor > MakeEditor(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) const override
Called only from PopulateUI, to add controls to effect panel.
Definition: DtmfGen.cpp:159
void BindTo(wxEvtHandler &src, const EventTag &eventType, void(Class::*pmf)(Event &))
Definition: EffectEditor.h:85
Performs effect computation.
Hold values to send to effect output meters.
virtual const EffectSettings & Get()=0
static DtmfSettings & GetSettings(EffectSettings &settings)
Assume settings originated from MakeSettings() and copies thereof.
Definition: Effect.h:166
Abstract base class used in importing a file.
static FormatterContext SampleRateContext(double sampleRate)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640
BuiltinEffectsModule::Registration< EffectDtmf > reg
Definition: DtmfGen.cpp:30
wxSlider * mDtmfDutyCycleS
Definition: DtmfGen.cpp:58
void OnDuration(wxCommandEvent &evt)
Definition: DtmfGen.cpp:233
wxStaticText * mDtmfDutyT
Definition: DtmfGen.cpp:62
void OnDutyCycle(wxCommandEvent &evt)
Definition: DtmfGen.cpp:244
Editor(const EffectUIServices &effect, EffectSettingsAccess &access, const DtmfSettings &settings)
Definition: DtmfGen.cpp:36
wxTextCtrl * mDtmfSequenceT
Definition: DtmfGen.cpp:57
void PopulateOrExchange(ShuttleGui &S, const EffectSettings &settings, double projectRate)
Definition: DtmfGen.cpp:65
bool ValidateUI() override
Get settings data from the panel; may make error dialogs and return false.
Definition: DtmfGen.cpp:187
NumericTextCtrl * mDtmfDurationT
Definition: DtmfGen.cpp:59
wxStaticText * mDtmfSilenceT
Definition: DtmfGen.cpp:61
wxStaticText * mDtmfToneT
Definition: DtmfGen.cpp:60
DtmfSettings mSettings
Definition: DtmfGen.cpp:55
virtual ~Editor()=default
bool UpdateUI() override
Update appearance of the panel for changes in settings.
Definition: DtmfGen.cpp:170
void OnSequence(wxCommandEvent &evt)
Definition: DtmfGen.cpp:222
const Type scale
Scaling factor, for slider control.
const Type min
Minimum value.
const Type max
Maximum value.
Externalized state of a plug-in.
Options & AutoPos(bool enable)