Audacity  3.0.3
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 "LoadEffects.h"
19 
20 #include <wx/intl.h>
21 #include <wx/slider.h>
22 #include <wx/valgen.h>
23 #include <wx/valtext.h>
24 #include <wx/stattext.h>
25 
26 #include "Prefs.h"
27 #include "../Shuttle.h"
28 #include "../ShuttleGui.h"
29 #include "../widgets/NumericTextCtrl.h"
30 #include "../widgets/valnum.h"
31 
32 
33 enum
34 {
39 };
40 
41 // DA: DTMF for Audacity uses a different string.
42 #ifdef EXPERIMENTAL_DA
43 #define SHORT_APP_NAME "darkaudacity"
44 #else
45 #define SHORT_APP_NAME "audacity"
46 #endif
47 
48 // Define keys, defaults, minimums, and maximums for the effect parameters
49 //
50 // Name Type Key Def Min Max Scale
51 Param( Sequence, wxString, wxT("Sequence"), wxT(SHORT_APP_NAME), wxT(""), wxT(""), wxT(""));
52 Param( DutyCycle, double, wxT("Duty Cycle"), 55.0, 0.0, 100.0, 10.0 );
53 Param( Amplitude, double, wxT("Amplitude"), 0.8, 0.001, 1.0, 1 );
54 
55 static const double kFadeInOut = 250.0; // used for fadein/out needed to remove clicking noise
56 
57 const static wxChar *kSymbols[] =
58 {
59  wxT("0"), wxT("1"), wxT("2"), wxT("3"),
60  wxT("4"), wxT("5"), wxT("6"), wxT("7"),
61  wxT("8"), wxT("9"), wxT("*"), wxT("#"),
62  wxT("A"), wxT("B"), wxT("C"), wxT("D"),
63  wxT("a"), wxT("b"), wxT("c"), wxT("d"),
64  wxT("e"), wxT("f"), wxT("g"), wxT("h"),
65  wxT("i"), wxT("j"), wxT("k"), wxT("l"),
66  wxT("m"), wxT("n"), wxT("o"), wxT("p"),
67  wxT("q"), wxT("r"), wxT("s"), wxT("t"),
68  wxT("u"), wxT("v"), wxT("w"), wxT("x"),
69  wxT("y"), wxT("z")
70 };
71 
72 //
73 // EffectDtmf
74 //
75 
77 { XO("DTMF Tones") };
78 
80 
81 BEGIN_EVENT_TABLE(EffectDtmf, wxEvtHandler)
87 
89 {
90  dtmfDutyCycle = DEF_DutyCycle;
91  dtmfAmplitude = DEF_Amplitude;
92  dtmfSequence = DEF_Sequence;
93  dtmfTone = 0.0;
94  dtmfSilence = 0.0;
95 }
96 
98 {
99 }
100 
101 // ComponentInterface implementation
102 
104 {
105  return Symbol;
106 }
107 
109 {
110  return XO("Generates dual-tone multi-frequency (DTMF) tones like those produced by the keypad on telephones");
111 }
112 
114 {
115  return L"DTMF_Tones";
116 }
117 
118 // EffectDefinitionInterface implementation
119 
121 {
122  return EffectTypeGenerate;
123 }
124 
125 // EffectClientInterface implementation
126 
128 {
129  return 1;
130 }
131 
132 bool EffectDtmf::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames WXUNUSED(chanMap))
133 {
134  if (dtmfNTones <= 0) { // Bail if no DTFM sequence.
136  XO("DTMF sequence empty.\nCheck ALL settings for this effect."),
137  wxICON_ERROR );
138 
139  return false;
140  }
141  double duration = GetDuration();
142 
143  // all dtmf sequence durations in samples from seconds
144  // MJS: Note that mDuration is in seconds but will have been quantised to the units of the TTC.
145  // If this was 'samples' and the project rate was lower than the track rate,
146  // extra samples may get created as mDuration may now be > mT1 - mT0;
147  // However we are making our best efforts at creating what was asked for.
148 
149  auto nT0 = (sampleCount)floor(mT0 * mSampleRate + 0.5);
150  auto nT1 = (sampleCount)floor((mT0 + duration) * mSampleRate + 0.5);
151  numSamplesSequence = nT1 - nT0; // needs to be exact number of samples selected
152 
153  //make under-estimates if anything, and then redistribute the few remaining samples
156 
157  // recalculate the sum, and spread the difference - due to approximations.
158  // Since diff should be in the order of "some" samples, a division (resulting in zero)
159  // is not sufficient, so we add the additional remaining samples in each tone/silence block,
160  // at least until available.
162  while (diff > 2*dtmfNTones - 1) { // more than one per thingToBeGenerated
163  // in this case, both numSamplesTone and numSamplesSilence would change, so it makes sense
164  // to recalculate diff here, otherwise just keep the value we already have
165 
166  // should always be the case that dtmfNTones>1, as if 0, we don't even start processing,
167  // and with 1 there is no difference to spread (no silence slot)...
168  wxASSERT(dtmfNTones > 1);
172  }
173  wxASSERT(diff >= 0); // should never be negative
174 
175  curSeqPos = -1; // pointer to string in dtmfSequence
176  isTone = false;
177  numRemaining = 0;
178 
179  return true;
180 }
181 
182 size_t EffectDtmf::ProcessBlock(float **WXUNUSED(inbuf), float **outbuf, size_t size)
183 {
184  float *buffer = outbuf[0];
185  decltype(size) processed = 0;
186 
187  // for the whole dtmf sequence, we will be generating either tone or silence
188  // according to a bool value, and this might be done in small chunks of size
189  // 'block', as a single tone might sometimes be larger than the block
190  // tone and silence generally have different duration, thus two generation blocks
191  //
192  // Note: to overcome a 'clicking' noise introduced by the abrupt transition from/to
193  // silence, I added a fade in/out of 1/250th of a second (4ms). This can still be
194  // tweaked but gives excellent results at 44.1kHz: I haven't tried other freqs.
195  // A problem might be if the tone duration is very short (<10ms)... (?)
196  //
197  // One more problem is to deal with the approximations done when calculating the duration
198  // of both tone and silence: in some cases the final sum might not be same as the initial
199  // duration. So, to overcome this, we had a redistribution block up, and now we will spread
200  // the remaining samples in every bin in order to achieve the full duration: test case was
201  // to generate an 11 tone DTMF sequence, in 4 seconds, and with DutyCycle=75%: after generation
202  // you ended up with 3.999s or in other units: 3 seconds and 44097 samples.
203  //
204  while (size)
205  {
206  if (numRemaining == 0)
207  {
208  isTone = !isTone;
209 
210  if (isTone)
211  {
212  curSeqPos++;
214  curTonePos = 0;
215  }
216  else
217  {
219  }
220 
221  // the statement takes care of extracting one sample from the diff bin and
222  // adding it into the current block until depletion
223  numRemaining += (diff-- > 0 ? 1 : 0);
224  }
225 
226  const auto len = limitSampleBufferSize( size, numRemaining );
227 
228  if (isTone)
229  {
230  // generate the tone and append
232  curTonePos += len;
233  }
234  else
235  {
236  memset(buffer, 0, sizeof(float) * len);
237  }
238 
239  numRemaining -= len;
240 
241  buffer += len;
242  size -= len;
243  processed += len;
244  }
245 
246  return processed;
247 }
249  S.SHUTTLE_PARAM( dtmfSequence, Sequence );
250  S.SHUTTLE_PARAM( dtmfDutyCycle, DutyCycle );
251  S.SHUTTLE_PARAM( dtmfAmplitude, Amplitude );
252  return true;
253 }
254 
256 {
257  parms.Write(KEY_Sequence, dtmfSequence);
258  parms.Write(KEY_DutyCycle, dtmfDutyCycle);
259  parms.Write(KEY_Amplitude, dtmfAmplitude);
260 
261  return true;
262 }
263 
265 {
266  ReadAndVerifyDouble(DutyCycle);
267  ReadAndVerifyDouble(Amplitude);
269 
270  wxString symbols;
271  for (unsigned int i = 0; i < WXSIZEOF(kSymbols); i++)
272  {
273  symbols += kSymbols[i];
274  }
275 
276  if (Sequence.find_first_not_of(symbols) != wxString::npos)
277  {
278  return false;
279  }
280 
281  dtmfDutyCycle = DutyCycle;
282  dtmfAmplitude = Amplitude;
284 
285  Recalculate();
286 
287  return true;
288 }
289 
290 // Effect implementation
291 
293 {
294  wxString base = wxT("/Effects/DtmfGen/");
295 
296  // Migrate settings from 2.1.0 or before
297 
298  // Already migrated, so bail
299  if (gPrefs->Exists(base + wxT("Migrated")))
300  {
301  return true;
302  }
303 
304  // Load the old "current" settings
305  if (gPrefs->Exists(base))
306  {
307  gPrefs->Read(base + wxT("String"), &dtmfSequence, wxT(SHORT_APP_NAME));
308  gPrefs->Read(base + wxT("DutyCycle"), &dtmfDutyCycle, 550L);
309  gPrefs->Read(base + wxT("Amplitude"), &dtmfAmplitude, 0.8f);
310 
312 
313  // Do not migrate again
314  gPrefs->Write(base + wxT("Migrated"), true);
315  gPrefs->Flush();
316  }
317 
318  return true;
319 }
320 
322 {
323  Recalculate();
324 
325  return true;
326 }
327 
329 {
330  // dialog will be passed values from effect
331  // Effect retrieves values from saved config
332  // Dialog will take care of using them to initialize controls
333  // If there is a selection, use that duration, otherwise use
334  // value from saved config: this is useful is user wants to
335  // replace selection with dtmf sequence
336 
337  S.AddSpace(0, 5);
338  S.StartMultiColumn(2, wxCENTER);
339  {
341  .Validator([this]{
342  wxTextValidator vldDtmf(wxFILTER_INCLUDE_CHAR_LIST, &dtmfSequence);
343  vldDtmf.SetIncludes(wxArrayString(WXSIZEOF(kSymbols), kSymbols));
344  return vldDtmf;
345  })
346  .AddTextBox(XXO("DTMF &sequence:"), wxT(""), 10);
347 
348  S.Id(ID_Amplitude)
349  .Validator<FloatingPointValidator<double>>(
350  3, &dtmfAmplitude, NumValidatorStyle::NO_TRAILING_ZEROES,
351  MIN_Amplitude, MAX_Amplitude)
352  .AddTextBox(XXO("&Amplitude (0-1):"), wxT(""), 10);
353 
354  S.AddPrompt(XXO("&Duration:"));
359  GetDuration(),
360  mProjectRate,
362  .AutoPos(true));
363  S.Name(XO("Duration"))
365 
366  S.AddFixedText(XO("&Tone/silence ratio:"), false);
368  .Style(wxSL_HORIZONTAL | wxEXPAND)
369  .MinSize( { -1, -1 } )
370  .AddSlider( {},
371  dtmfDutyCycle * SCL_DutyCycle,
372  MAX_DutyCycle * SCL_DutyCycle,
373  MIN_DutyCycle * SCL_DutyCycle);
374  }
375  S.EndMultiColumn();
376 
377  S.StartMultiColumn(2, wxCENTER);
378  {
379  S.AddFixedText(XO("Duty cycle:"), false);
380  mDtmfDutyT =
381  S.AddVariableText(XO("%.1f %%").Format( dtmfDutyCycle ), false);
382 
383  S.AddFixedText(XO("Tone duration:"), false);
384  mDtmfSilenceT =
385  /* i18n-hint milliseconds */
386  S.AddVariableText(XO("%.0f ms").Format( dtmfTone * 1000.0 ), false);
387 
388  S.AddFixedText(XO("Silence duration:"), false);
389  mDtmfToneT =
390  /* i18n-hint milliseconds */
391  S.AddVariableText(XO("%0.f ms").Format( dtmfSilence * 1000.0 ), false);
392  }
393  S.EndMultiColumn();
394 }
395 
397 {
398  Recalculate();
399 
400  if (!mUIParent->TransferDataToWindow())
401  {
402  return false;
403  }
404 
405  mDtmfDutyCycleS->SetValue(dtmfDutyCycle * SCL_DutyCycle);
406 
408 
409  UpdateUI();
410 
411  return true;
412 }
413 
415 {
416  if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
417  {
418  return false;
419  }
420 
421  dtmfDutyCycle = (double) mDtmfDutyCycleS->GetValue() / SCL_DutyCycle;
423 
424  // recalculate to make sure all values are up-to-date. This is especially
425  // important if the user did not change any values in the dialog
426  Recalculate();
427 
428  return true;
429 }
430 
431 // EffectDtmf implementation
432 
434 {
435  // remember that dtmfDutyCycle is in range (0.0-100.0)
436 
437  dtmfNTones = (int) dtmfSequence.length();
438 
439  if (dtmfNTones==0) {
440  // no tones, all zero: don't do anything
441  // this should take care of the case where user got an empty
442  // dtmf sequence into the generator: track won't be generated
443  SetDuration(0.0);
444  dtmfTone = 0;
445  dtmfSilence = 0;
446  } else {
447  if (dtmfNTones==1) {
448  // single tone, as long as the sequence
449  dtmfTone = GetDuration();
450  dtmfSilence = 0;
451  } else {
452  // Don't be fooled by the fact that you divide the sequence into dtmfNTones:
453  // the last slot will only contain a tone, not ending with silence.
454  // Given this, the right thing to do is to divide the sequence duration
455  // by dtmfNTones tones and (dtmfNTones-1) silences each sized according to the duty
456  // cycle: original division was:
457  // slot=mDuration / (dtmfNTones*(dtmfDutyCycle/MAX_DutyCycle)+(dtmfNTones-1)*(1.0-dtmfDutyCycle/MAX_DutyCycle))
458  // which can be simplified in the one below.
459  // Then just take the part that belongs to tone or silence.
460  //
461  double slot = GetDuration() / ((double)dtmfNTones + (dtmfDutyCycle / 100.0) - 1);
462  dtmfTone = slot * (dtmfDutyCycle / 100.0); // seconds
463  dtmfSilence = slot * (1.0 - (dtmfDutyCycle / 100.0)); // seconds
464 
465  // Note that in the extremes we have:
466  // - dutyCycle=100%, this means no silence, so each tone will measure mDuration/dtmfNTones
467  // - dutyCycle=0%, this means no tones, so each silence slot will measure mDuration/(NTones-1)
468  // But we always count:
469  // - dtmfNTones tones
470  // - dtmfNTones-1 silences
471  }
472  }
473 }
474 
475 bool EffectDtmf::MakeDtmfTone(float *buffer, size_t len, float fs, wxChar tone, sampleCount last, sampleCount total, float amplitude)
476 {
477 /*
478  --------------------------------------------
479  1209 Hz 1336 Hz 1477 Hz 1633 Hz
480 
481  ABC DEF
482  697 Hz 1 2 3 A
483 
484  GHI JKL MNO
485  770 Hz 4 5 6 B
486 
487  PQRS TUV WXYZ
488  852 Hz 7 8 9 C
489 
490  oper
491  941 Hz * 0 # D
492  --------------------------------------------
493  Essentially we need to generate two sin with
494  frequencies according to this table, and sum
495  them up.
496  sin wave is generated by:
497  s(n)=sin(2*pi*n*f/fs)
498 
499  We will precalculate:
500  A= 2*pi*f1/fs
501  B= 2*pi*f2/fs
502 
503  And use two switch statements to select the frequency
504 
505  Note: added support for letters, like those on the keypad
506  This support is only for lowercase letters: uppercase
507  are still considered to be the 'military'/carrier extra
508  tones.
509 */
510 
511  float f1, f2=0.0;
512  double A,B;
513 
514  // select low tone: left column
515  switch (tone) {
516  case '1': case '2': case '3': case 'A':
517  case 'a': case 'b': case 'c':
518  case 'd': case 'e': case 'f':
519  f1=697;
520  break;
521  case '4': case '5': case '6': case 'B':
522  case 'g': case 'h': case 'i':
523  case 'j': case 'k': case 'l':
524  case 'm': case 'n': case 'o':
525  f1=770;
526  break;
527  case '7': case '8': case '9': case 'C':
528  case 'p': case 'q': case 'r': case 's':
529  case 't': case 'u': case 'v':
530  case 'w': case 'x': case 'y': case 'z':
531  f1=852;
532  break;
533  case '*': case '0': case '#': case 'D':
534  f1=941;
535  break;
536  default:
537  f1=0;
538  }
539 
540  // select high tone: top row
541  switch (tone) {
542  case '1': case '4': case '7': case '*':
543  case 'g': case 'h': case 'i':
544  case 'p': case 'q': case 'r': case 's':
545  f2=1209;
546  break;
547  case '2': case '5': case '8': case '0':
548  case 'a': case 'b': case 'c':
549  case 'j': case 'k': case 'l':
550  case 't': case 'u': case 'v':
551  f2=1336;
552  break;
553  case '3': case '6': case '9': case '#':
554  case 'd': case 'e': case 'f':
555  case 'm': case 'n': case 'o':
556  case 'w': case 'x': case 'y': case 'z':
557  f2=1477;
558  break;
559  case 'A': case 'B': case 'C': case 'D':
560  f2=1633;
561  break;
562  default:
563  f2=0;
564  }
565 
566  // precalculations
567  A=B=2*M_PI/fs;
568  A*=f1;
569  B*=f2;
570 
571  // now generate the wave: 'last' is used to avoid phase errors
572  // when inside the inner for loop of the Process() function.
573  for(decltype(len) i = 0; i < len; i++) {
574  buffer[i] = amplitude * 0.5 *
575  (sin( A * (i + last).as_double() ) +
576  sin( B * (i + last).as_double() ));
577  }
578 
579  // generate a fade-in of duration 1/250th of second
580  if (last == 0) {
581  A = wxMin(len, (fs / kFadeInOut));
582  for(size_t i = 0; i < A; i++) {
583  buffer[i] *= i/A;
584  }
585  }
586 
587  // generate a fade-out of duration 1/250th of second
588  if (last >= total - len) {
589  // we are at the last buffer of 'len' size, so, offset is to
590  // backup 'A' samples, from 'len'
591  A = wxMin(len, (fs / kFadeInOut));
592  size_t offset = len - A;
593  wxASSERT(offset >= 0);
594  for(size_t i = 0; i < A; i++) {
595  buffer[i + offset] *= (1 - (i / A));
596  }
597  }
598  return true;
599 }
600 
602 {
603  mDtmfDutyT->SetLabel(wxString::Format(wxT("%.1f %%"), dtmfDutyCycle));
604  mDtmfDutyT->SetName(mDtmfDutyT->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
605 
606  mDtmfSilenceT->SetLabel(wxString::Format(_("%.0f ms"), dtmfTone * 1000.0));
607  mDtmfSilenceT->SetName(mDtmfSilenceT->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
608 
609  mDtmfToneT->SetLabel(wxString::Format(_("%.0f ms"), dtmfSilence * 1000.0));
610  mDtmfToneT->SetName(mDtmfToneT->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
611 }
612 
613 void EffectDtmf::OnSequence(wxCommandEvent & WXUNUSED(evt))
614 {
615  dtmfSequence = mDtmfSequenceT->GetValue();
616  Recalculate();
617  UpdateUI();
618 }
619 
620 void EffectDtmf::OnAmplitude(wxCommandEvent & WXUNUSED(evt))
621 {
622  if (!mDtmfAmplitudeT->GetValidator()->TransferFromWindow())
623  {
624  return;
625  }
626  Recalculate();
627  UpdateUI();
628 }
629 void EffectDtmf::OnDuration(wxCommandEvent & WXUNUSED(evt))
630 {
632  Recalculate();
633  UpdateUI();
634 }
635 
636 void EffectDtmf::OnDutyCycle(wxCommandEvent & evt)
637 {
638  dtmfDutyCycle = (double) evt.GetInt() / SCL_DutyCycle;
639  Recalculate();
640  UpdateUI();
641 }
EffectDtmf::mDtmfSilenceT
wxStaticText * mDtmfSilenceT
Definition: DtmfGen.h:97
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
EffectDtmf::Init
bool Init() override
Definition: DtmfGen.cpp:321
CommandParameters
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
Definition: EffectAutomationParameters.h:67
EffectDtmf::isTone
bool isTone
Definition: DtmfGen.h:82
Effect::GetDuration
double GetDuration() override
Definition: Effect.cpp:815
NumericTextCtrl::Options::AutoPos
Options & AutoPos(bool enable)
Definition: NumericTextCtrl.h:190
EffectDtmf::SetAutomationParameters
bool SetAutomationParameters(CommandParameters &parms) override
Definition: DtmfGen.cpp:264
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
Effect::MessageBox
int MessageBox(const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
Definition: Effect.cpp:2481
EffectTypeGenerate
@ EffectTypeGenerate
Definition: EffectInterface.h:58
kFadeInOut
static const double kFadeInOut
Definition: DtmfGen.cpp:55
EffectDtmf::dtmfNTones
int dtmfNTones
Definition: DtmfGen.h:86
EffectDtmf::Symbol
static const ComponentInterfaceSymbol Symbol
Definition: DtmfGen.h:28
Format
Abstract base class used in importing a file.
EffectDtmf::dtmfAmplitude
double dtmfAmplitude
Definition: DtmfGen.h:90
ID_Sequence
@ ID_Sequence
Definition: DtmfGen.cpp:35
ShuttleGui::AddSpace
wxSizerItem * AddSpace(int width, int height, int prop=0)
Definition: ShuttleGui.cpp:2447
ShuttleGui::MinSize
ShuttleGui & MinSize()
Definition: ShuttleGui.h:733
XO
#define XO(s)
Definition: Internat.h:31
EffectDtmf::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: DtmfGen.cpp:414
EffectDtmf::~EffectDtmf
virtual ~EffectDtmf()
Definition: DtmfGen.cpp:97
ShuttleParams
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:62
EffectDtmf::GetType
EffectType GetType() override
Definition: DtmfGen.cpp:120
ShuttleGuiBase::EndMultiColumn
void EndMultiColumn()
Definition: ShuttleGui.cpp:1238
EffectDtmf::numSamplesTone
sampleCount numSamplesTone
Definition: DtmfGen.h:77
EffectDtmf::mDtmfSequenceT
wxTextCtrl * mDtmfSequenceT
Definition: DtmfGen.h:92
Sequence
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
Definition: Sequence.h:61
Effect::SaveUserPreset
bool SaveUserPreset(const RegistryPath &name) override
Definition: Effect.cpp:569
NumericTextCtrl
Definition: NumericTextCtrl.h:172
NumericTextCtrl::SetValue
void SetValue(double newValue)
Definition: NumericTextCtrl.cpp:1472
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
EffectDtmf::mDtmfDurationT
NumericTextCtrl * mDtmfDurationT
Definition: DtmfGen.h:95
NumericTextCtrl::Options
Definition: NumericTextCtrl.h:178
ShuttleGui::Id
ShuttleGui & Id(int id)
Definition: ShuttleGui.cpp:2274
EffectDtmf::OnAmplitude
void OnAmplitude(wxCommandEvent &evt)
Definition: DtmfGen.cpp:620
EffectDtmf::dtmfSequence
wxString dtmfSequence
Definition: DtmfGen.h:85
EffectDtmf::curTonePos
sampleCount curTonePos
Definition: DtmfGen.h:81
ShuttleGui::Style
ShuttleGui & Style(long iStyle)
Definition: ShuttleGui.h:727
EffectDtmf::GetDescription
TranslatableString GetDescription() override
Definition: DtmfGen.cpp:108
Effect::mProjectRate
double mProjectRate
Definition: Effect.h:458
SHORT_APP_NAME
#define SHORT_APP_NAME
Definition: DtmfGen.cpp:45
ID_Duration
@ ID_Duration
Definition: DtmfGen.cpp:37
XXO
#define XXO(s)
Definition: Internat.h:44
Effect::mT0
double mT0
Definition: Effect.h:466
EffectDtmf::diff
sampleCount diff
Definition: DtmfGen.h:79
EffectDtmf::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: DtmfGen.cpp:103
EffectDtmf::dtmfSilence
double dtmfSilence
Definition: DtmfGen.h:88
EffectDtmf::mDtmfAmplitudeT
wxTextCtrl * mDtmfAmplitudeT
Definition: DtmfGen.h:93
ShuttleGuiBase::StartMultiColumn
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:1229
EffectDtmf::dtmfTone
double dtmfTone
Definition: DtmfGen.h:87
EffectDtmf::GetAutomationParameters
bool GetAutomationParameters(CommandParameters &parms) override
Definition: DtmfGen.cpp:255
Param
Param(Sequence, wxString, wxT("Sequence"), wxT(SHORT_APP_NAME), wxT(""), wxT(""), wxT(""))
ShuttleGuiBase::AddFixedText
void AddFixedText(const TranslatableString &Str, bool bCenter=false, int wrapWidth=0)
Definition: ShuttleGui.cpp:440
EffectDtmf::GetAudioOutCount
unsigned GetAudioOutCount() override
Definition: DtmfGen.cpp:127
EffectDtmf::Recalculate
void Recalculate()
Definition: DtmfGen.cpp:433
DtmfGen.h
NumericConverter::TIME
@ TIME
Definition: NumericTextCtrl.h:52
ShuttleGuiBase::GetParent
wxWindow * GetParent()
Definition: ShuttleGui.h:496
ShuttleGui::Validator
ShuttleGui & Validator(const Factory &f)
Definition: ShuttleGui.h:678
EffectDtmf::ProcessInitialize
bool ProcessInitialize(sampleCount totalLen, ChannelNames chanMap=NULL) override
Definition: DtmfGen.cpp:132
ShuttleGuiBase::AddWindow
wxWindow * AddWindow(wxWindow *pWindow, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:299
EffectDtmf::mDtmfDutyCycleS
wxSlider * mDtmfDutyCycleS
Definition: DtmfGen.h:94
ChannelNames
enum ChannelName * ChannelNames
ReadAndVerifyDouble
#define ReadAndVerifyDouble(name)
Definition: Effect.h:633
EffectDtmf::MakeDtmfTone
bool MakeDtmfTone(float *buffer, size_t len, float fs, wxChar tone, sampleCount last, sampleCount total, float amplitude)
Definition: DtmfGen.cpp:475
Effect::GetCurrentSettingsGroup
RegistryPath GetCurrentSettingsGroup() override
Definition: Effect.cpp:865
LoadEffects.h
kSymbols
static const wxChar * kSymbols[]
Definition: DtmfGen.cpp:57
Effect::SetDuration
void SetDuration(double duration) override
Definition: Effect.cpp:837
ShuttleGui::Name
ShuttleGui & Name(const TranslatableString &name)
Definition: ShuttleGui.h:663
EffectDtmf::TransferDataToWindow
bool TransferDataToWindow() override
Definition: DtmfGen.cpp:396
Effect::mSampleRate
double mSampleRate
Definition: Effect.h:460
EffectDtmf::numRemaining
sampleCount numRemaining
Definition: DtmfGen.h:80
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
BuiltinEffectsModule::Registration
Definition: LoadEffects.h:40
EffectDtmf::mDtmfToneT
wxStaticText * mDtmfToneT
Definition: DtmfGen.h:96
Effect::mUIParent
wxWindow * mUIParent
Definition: Effect.h:478
TaggedIdentifier< ManualPageIDTag >
ReadAndVerifyString
#define ReadAndVerifyString(name)
Definition: Effect.h:636
_
#define _(s)
Definition: Internat.h:75
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
EffectDtmf
An effect that generates DTMF tones.
Definition: DtmfGen.h:26
EffectDtmf::dtmfDutyCycle
double dtmfDutyCycle
Definition: DtmfGen.h:89
EffectDtmf::ProcessBlock
size_t ProcessBlock(float **inBlock, float **outBlock, size_t blockLen) override
Definition: DtmfGen.cpp:182
EffectDtmf::ManualPage
ManualPageID ManualPage() override
Definition: DtmfGen.cpp:113
EffectDtmf::curSeqPos
int curSeqPos
Definition: DtmfGen.h:83
EffectDtmf::OnDuration
void OnDuration(wxCommandEvent &evt)
Definition: DtmfGen.cpp:629
M_PI
#define M_PI
Definition: Distortion.cpp:29
Effect::GetDurationFormat
NumericFormatSymbol GetDurationFormat() override
Definition: Effect.cpp:825
Prefs.h
ShuttleGuiBase::AddPrompt
void AddPrompt(const TranslatableString &Prompt, int wrapWidth=0)
Right aligned text string.
Definition: ShuttleGui.cpp:238
EffectDtmf::DefineParams
bool DefineParams(ShuttleParams &S) override
Definition: DtmfGen.cpp:248
EffectDtmf::numSamplesSequence
sampleCount numSamplesSequence
Definition: DtmfGen.h:76
anonymous_namespace{DtmfGen.cpp}::reg
BuiltinEffectsModule::Registration< EffectDtmf > reg
Definition: DtmfGen.cpp:79
ShuttleGuiBase::AddVariableText
wxStaticText * AddVariableText(const TranslatableString &Str, bool bCenter=false, int PositionFlags=0, int wrapWidth=0)
Definition: ShuttleGui.cpp:463
EffectType
EffectType
Definition: EffectInterface.h:55
safenew
#define safenew
Definition: MemoryX.h:10
EffectDtmf::OnDutyCycle
void OnDutyCycle(wxCommandEvent &evt)
Definition: DtmfGen.cpp:636
limitSampleBufferSize
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:21
EffectDtmf::mDtmfDutyT
wxStaticText * mDtmfDutyT
Definition: DtmfGen.h:98
NumericConverter::GetValue
double GetValue()
Definition: NumericTextCtrl.cpp:1172
EffectDtmf::numSamplesSilence
sampleCount numSamplesSilence
Definition: DtmfGen.h:78
EffectDtmf::OnSequence
void OnSequence(wxCommandEvent &evt)
Definition: DtmfGen.cpp:613
END_EVENT_TABLE
END_EVENT_TABLE()
EffectDtmf::Startup
bool Startup() override
Definition: DtmfGen.cpp:292
ID_DutyCycle
@ ID_DutyCycle
Definition: DtmfGen.cpp:38
ID_Amplitude
@ ID_Amplitude
Definition: DtmfGen.cpp:36
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
EffectDtmf::UpdateUI
void UpdateUI()
Definition: DtmfGen.cpp:601
EffectDtmf::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S) override
Definition: DtmfGen.cpp:328