Audacity  3.2.0
Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes | List of all members
EffectDtmf Class Referencefinal

An effect that generates DTMF tones. More...

#include <DtmfGen.h>

Inheritance diagram for EffectDtmf:
[legend]
Collaboration diagram for EffectDtmf:
[legend]

Public Member Functions

 EffectDtmf ()
 
virtual ~EffectDtmf ()
 
ComponentInterfaceSymbol GetSymbol () override
 
TranslatableString GetDescription () override
 
ManualPageID ManualPage () override
 Name of a page in the Audacity alpha manual, default is empty. More...
 
EffectType GetType () override
 Type determines how it behaves. More...
 
bool GetAutomationParameters (CommandParameters &parms) override
 Save current settings into parms. More...
 
bool SetAutomationParameters (CommandParameters &parms) override
 Change settings to those stored in parms. More...
 
unsigned GetAudioOutCount () override
 
bool ProcessInitialize (sampleCount totalLen, ChannelNames chanMap=NULL) override
 Called for destructive, non-realtime effect computation. More...
 
size_t ProcessBlock (float **inBlock, float **outBlock, size_t blockLen) override
 Called for destructive, non-realtime effect computation. More...
 
bool DefineParams (ShuttleParams &S) override
 
bool Startup () override
 
bool Init () override
 
void PopulateOrExchange (ShuttleGui &S) override
 
bool TransferDataFromWindow () override
 
bool TransferDataToWindow () override
 
- Public Member Functions inherited from Effect
 Effect ()
 
virtual ~Effect ()
 
PluginPath GetPath () override
 
ComponentInterfaceSymbol GetSymbol () override
 
VendorSymbol GetVendor () override
 
wxString GetVersion () override
 
TranslatableString GetDescription () override
 
EffectType GetType () override
 Type determines how it behaves. More...
 
EffectFamilySymbol GetFamily () override
 Report identifier and user-visible name of the effect protocol. More...
 
bool IsInteractive () override
 Whether the effect needs a dialog for entry of settings. More...
 
bool IsDefault () override
 Whether the effect sorts "above the line" in the menus. More...
 
bool IsLegacy () override
 
bool SupportsRealtime () override
 Whether the effect supports realtime previewing (while audio is playing). More...
 
bool SupportsAutomation () override
 Whether the effect can be used without the UI, in a macro. More...
 
bool GetAutomationParameters (CommandParameters &parms) override
 Save current settings into parms. More...
 
bool SetAutomationParameters (CommandParameters &parms) override
 Change settings to those stored in parms. More...
 
bool LoadUserPreset (const RegistryPath &name) override
 Change settings to a user-named preset. More...
 
bool SaveUserPreset (const RegistryPath &name) override
 Save current settings as a user-named preset. More...
 
RegistryPaths GetFactoryPresets () override
 Report names of factory presets. More...
 
bool LoadFactoryPreset (int id) override
 Change settings to the preset whose name is GetFactoryPresets()[id] More...
 
bool LoadFactoryDefaults () override
 Change settings back to "factory default". More...
 
bool SetHost (EffectHostInterface *host) override
 
unsigned GetAudioInCount () override
 
unsigned GetAudioOutCount () override
 
int GetMidiInCount () override
 
int GetMidiOutCount () override
 
sampleCount GetLatency () override
 Called for destructive, non-realtime effect computation. More...
 
size_t GetTailSize () override
 
void SetSampleRate (double rate) override
 
size_t SetBlockSize (size_t maxBlockSize) override
 
size_t GetBlockSize () const override
 
bool ProcessInitialize (sampleCount totalLen, ChannelNames chanMap=NULL) override
 Called for destructive, non-realtime effect computation. More...
 
bool ProcessFinalize () override
 Called for destructive, non-realtime effect computation. More...
 
size_t ProcessBlock (float **inBlock, float **outBlock, size_t blockLen) override
 Called for destructive, non-realtime effect computation. More...
 
bool RealtimeInitialize () override
 
bool RealtimeAddProcessor (unsigned numChannels, float sampleRate) override
 
bool RealtimeFinalize () override
 
bool RealtimeSuspend () override
 
bool RealtimeResume () noexcept override
 
bool RealtimeProcessStart () override
 
size_t RealtimeProcess (int group, float **inbuf, float **outbuf, size_t numSamples) override
 
bool RealtimeProcessEnd () noexcept override
 
int ShowClientInterface (wxWindow &parent, wxDialog &dialog, bool forceModal=false) override
 
bool PopulateUI (ShuttleGui &S) final
 Adds controls to a panel that is given as the parent window of S More...
 
bool IsGraphicalUI () override
 
bool ValidateUI () override
 
bool HideUI () override
 
bool CloseUI () override
 
bool CanExportPresets () override
 
void ExportPresets () override
 
void ImportPresets () override
 
bool HasOptions () override
 
void ShowOptions () override
 
EffectDefinitionInterfaceGetDefinition () override
 
double GetDuration () override
 
NumericFormatSymbol GetDurationFormat () override
 
virtual NumericFormatSymbol GetSelectionFormat ()
 
void SetDuration (double duration) override
 
RegistryPath GetUserPresetsGroup (const RegistryPath &name) override
 
RegistryPath GetCurrentSettingsGroup () override
 
RegistryPath GetFactoryDefaultsGroup () override
 
virtual wxString GetSavedStateGroup ()
 
int ShowHostInterface (wxWindow &parent, const EffectDialogFactory &factory, bool forceModal=false) override
 
unsigned TestUIFlags (unsigned mask)
 
void SetPresetParameters (const wxArrayString *Names, const wxArrayString *Values)
 
virtual bool Startup (EffectUIClientInterface *client)
 
virtual bool GetAutomationParametersAsString (wxString &parms)
 
virtual bool SetAutomationParametersFromString (const wxString &parms)
 
virtual bool IsBatchProcessing ()
 
virtual void SetBatchProcessing (bool start)
 
bool DoEffect (double projectRate, TrackList *list, WaveTrackFactory *factory, NotifyingSelectedRegion &selectedRegion, unsigned flags, wxWindow *pParent=nullptr, const EffectDialogFactory &dialogFactory={})
 
bool Delegate (Effect &delegate, wxWindow &parent, const EffectDialogFactory &factory)
 
int MessageBox (const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
 
- Public Member Functions inherited from EffectUIClientInterface
virtual ~EffectUIClientInterface ()
 
- Public Member Functions inherited from EffectProcessor
virtual ~EffectProcessor ()
 
- Public Member Functions inherited from EffectDefinitionInterface
virtual ~EffectDefinitionInterface ()
 
virtual EffectType GetClassification ()
 Determines which menu it appears in; default same as GetType(). More...
 
virtual bool EnablesDebug ()
 Whether the effect dialog should have a Debug button; default, always false. More...
 
virtual FilePath HelpPage ()
 Fully qualified local help file name, default is empty. More...
 
virtual bool IsHiddenFromMenus ()
 Default is false. More...
 
- Public Member Functions inherited from ComponentInterface
virtual ~ComponentInterface ()
 
TranslatableString GetName ()
 
virtual bool DefineParams (ShuttleParams &WXUNUSED(S))
 
- Public Member Functions inherited from EffectUIHostInterface
virtual ~EffectUIHostInterface ()
 
- Public Member Functions inherited from EffectHostInterface
virtual ~EffectHostInterface ()
 

Static Public Attributes

static const ComponentInterfaceSymbol Symbol { XO("DTMF Tones") }
 
- Static Public Attributes inherited from Effect
static const wxString kUserPresetIdent = wxT("User Preset:")
 
static const wxString kFactoryPresetIdent = wxT("Factory Preset:")
 
static const wxString kCurrentSettingsIdent = wxT("<Current Settings>")
 
static const wxString kFactoryDefaultsIdent = wxT("<Factory Defaults>")
 

Private Member Functions

bool MakeDtmfTone (float *buffer, size_t len, float fs, wxChar tone, sampleCount last, sampleCount total, float amplitude)
 
void Recalculate ()
 
void UpdateUI ()
 
void OnSequence (wxCommandEvent &evt)
 
void OnAmplitude (wxCommandEvent &evt)
 
void OnDuration (wxCommandEvent &evt)
 
void OnDutyCycle (wxCommandEvent &evt)
 

Private Attributes

sampleCount numSamplesSequence
 
sampleCount numSamplesTone
 
sampleCount numSamplesSilence
 
sampleCount diff
 
sampleCount numRemaining
 
sampleCount curTonePos
 
bool isTone
 
int curSeqPos
 
wxString dtmfSequence
 
int dtmfNTones
 
double dtmfTone
 
double dtmfSilence
 
double dtmfDutyCycle
 
double dtmfAmplitude
 
wxTextCtrl * mDtmfSequenceT
 
wxTextCtrl * mDtmfAmplitudeT
 
wxSlider * mDtmfDutyCycleS
 
NumericTextCtrlmDtmfDurationT
 
wxStaticText * mDtmfToneT
 
wxStaticText * mDtmfSilenceT
 
wxStaticText * mDtmfDutyT
 

Additional Inherited Members

- Public Types inherited from Effect
enum  : long { DefaultMessageBoxStyle = wxOK | wxCENTRE }
 
- Static Public Member Functions inherited from Effect
static void IncEffectCounter ()
 
- Static Public Member Functions inherited from EffectDefinitionInterface
static Identifier GetSquashedName (const Identifier &ident)
 A utility that strips spaces and CamelCases a name. More...
 
- Protected Member Functions inherited from Effect
bool EnableApply (bool enable=true)
 
bool EnablePreview (bool enable=true)
 
virtual bool CheckWhetherSkipEffect ()
 
virtual bool Process ()
 
virtual bool ProcessPass ()
 
virtual bool InitPass1 ()
 
virtual bool InitPass2 ()
 
virtual void End ()
 
virtual double CalcPreviewInputLength (double previewLength)
 
virtual void Preview (bool dryOnly)
 
bool TotalProgress (double frac, const TranslatableString &={})
 
bool TrackProgress (int whichTrack, double frac, const TranslatableString &={})
 
bool TrackGroupProgress (int whichGroup, double frac, const TranslatableString &={})
 
int GetNumWaveTracks ()
 
int GetNumWaveGroups ()
 
void GetBounds (const WaveTrack &track, const WaveTrack *pRight, sampleCount *start, sampleCount *len)
 
void SetLinearEffectFlag (bool linearEffectFlag)
 
void SetPreviewFullSelectionFlag (bool previewDurationFlag)
 
bool IsPreviewing ()
 
void IncludeNotSelectedPreviewTracks (bool includeNotSelected)
 
void CopyInputTracks (bool allSyncLockSelected=false)
 
std::shared_ptr< AddedAnalysisTrackAddAnalysisTrack (const wxString &name=wxString())
 
ModifiedAnalysisTrack ModifyAnalysisTrack (const LabelTrack *pOrigTrack, const wxString &name=wxString())
 
void ReplaceProcessedTracks (const bool bGoodResult)
 
TrackAddToOutputTracks (const std::shared_ptr< Track > &t)
 
const TrackListinputTracks () const
 
const AudacityProjectFindProject () const
 
- Protected Attributes inherited from Effect
BasicUI::ProgressDialogmProgress = nullptr
 
double mProjectRate
 
double mSampleRate
 
WaveTrackFactorymFactory
 
std::shared_ptr< TrackListmOutputTracks
 
double mT0
 
double mT1
 
wxArrayString mPresetNames
 
wxArrayString mPresetValues
 
int mPass
 
wxWeakRef< wxDialog > mHostUIDialog
 This smart pointer tracks the lifetime of the dialog. More...
 
wxWeakRef< wxDialog > mUIDialog
 This weak pointer may be the same as the above, or null. More...
 
wxWindow * mUIParent
 
unsigned mUIFlags { 0 }
 
sampleCount mSampleCnt
 
- Static Protected Attributes inherited from Effect
static int nEffectsDone =0
 

Detailed Description

An effect that generates DTMF tones.

Definition at line 25 of file DtmfGen.h.

Constructor & Destructor Documentation

◆ EffectDtmf()

EffectDtmf::EffectDtmf ( )

Definition at line 88 of file DtmfGen.cpp.

89 {
90  dtmfDutyCycle = DEF_DutyCycle;
91  dtmfAmplitude = DEF_Amplitude;
92  dtmfSequence = DEF_Sequence;
93  dtmfTone = 0.0;
94  dtmfSilence = 0.0;
95 }

◆ ~EffectDtmf()

EffectDtmf::~EffectDtmf ( )
virtual

Definition at line 97 of file DtmfGen.cpp.

98 {
99 }

Member Function Documentation

◆ DefineParams()

bool EffectDtmf::DefineParams ( ShuttleParams S)
override

Definition at line 248 of file DtmfGen.cpp.

248  {
249  S.SHUTTLE_PARAM( dtmfSequence, Sequence );
250  S.SHUTTLE_PARAM( dtmfDutyCycle, DutyCycle );
251  S.SHUTTLE_PARAM( dtmfAmplitude, Amplitude );
252  return true;
253 }

References dtmfAmplitude, dtmfDutyCycle, dtmfSequence, and S.

◆ GetAudioOutCount()

unsigned EffectDtmf::GetAudioOutCount ( )
overridevirtual

Implements EffectProcessor.

Definition at line 127 of file DtmfGen.cpp.

128 {
129  return 1;
130 }

◆ GetAutomationParameters()

bool EffectDtmf::GetAutomationParameters ( CommandParameters parms)
overridevirtual

Save current settings into parms.

Implements EffectDefinitionInterface.

Definition at line 255 of file DtmfGen.cpp.

256 {
257  parms.Write(KEY_Sequence, dtmfSequence);
258  parms.Write(KEY_DutyCycle, dtmfDutyCycle);
259  parms.Write(KEY_Amplitude, dtmfAmplitude);
260 
261  return true;
262 }

References dtmfAmplitude, dtmfDutyCycle, and dtmfSequence.

◆ GetDescription()

TranslatableString EffectDtmf::GetDescription ( )
overridevirtual

Implements ComponentInterface.

Definition at line 108 of file DtmfGen.cpp.

109 {
110  return XO("Generates dual-tone multi-frequency (DTMF) tones like those produced by the keypad on telephones");
111 }

References XO.

◆ GetSymbol()

ComponentInterfaceSymbol EffectDtmf::GetSymbol ( )
overridevirtual

Implements ComponentInterface.

Definition at line 103 of file DtmfGen.cpp.

104 {
105  return Symbol;
106 }

References Symbol.

◆ GetType()

EffectType EffectDtmf::GetType ( )
overridevirtual

Type determines how it behaves.

Implements EffectDefinitionInterface.

Definition at line 120 of file DtmfGen.cpp.

121 {
122  return EffectTypeGenerate;
123 }

References EffectTypeGenerate.

◆ Init()

bool EffectDtmf::Init ( )
overridevirtual

Reimplemented from Effect.

Definition at line 321 of file DtmfGen.cpp.

322 {
323  Recalculate();
324 
325  return true;
326 }

References Recalculate().

Here is the call graph for this function:

◆ MakeDtmfTone()

bool EffectDtmf::MakeDtmfTone ( float *  buffer,
size_t  len,
float  fs,
wxChar  tone,
sampleCount  last,
sampleCount  total,
float  amplitude 
)
private

Definition at line 475 of file DtmfGen.cpp.

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 }

References A, kFadeInOut, and M_PI.

Referenced by ProcessBlock().

Here is the caller graph for this function:

◆ ManualPage()

ManualPageID EffectDtmf::ManualPage ( )
overridevirtual

Name of a page in the Audacity alpha manual, default is empty.

Reimplemented from EffectDefinitionInterface.

Definition at line 113 of file DtmfGen.cpp.

114 {
115  return L"DTMF_Tones";
116 }

◆ OnAmplitude()

void EffectDtmf::OnAmplitude ( wxCommandEvent &  evt)
private

Definition at line 620 of file DtmfGen.cpp.

621 {
622  if (!mDtmfAmplitudeT->GetValidator()->TransferFromWindow())
623  {
624  return;
625  }
626  Recalculate();
627  UpdateUI();
628 }

References mDtmfAmplitudeT, Recalculate(), and UpdateUI().

Here is the call graph for this function:

◆ OnDuration()

void EffectDtmf::OnDuration ( wxCommandEvent &  evt)
private

Definition at line 629 of file DtmfGen.cpp.

630 {
632  Recalculate();
633  UpdateUI();
634 }

References NumericConverter::GetValue(), mDtmfDurationT, Recalculate(), Effect::SetDuration(), and UpdateUI().

Here is the call graph for this function:

◆ OnDutyCycle()

void EffectDtmf::OnDutyCycle ( wxCommandEvent &  evt)
private

Definition at line 636 of file DtmfGen.cpp.

637 {
638  dtmfDutyCycle = (double) evt.GetInt() / SCL_DutyCycle;
639  Recalculate();
640  UpdateUI();
641 }

References dtmfDutyCycle, Recalculate(), and UpdateUI().

Here is the call graph for this function:

◆ OnSequence()

void EffectDtmf::OnSequence ( wxCommandEvent &  evt)
private

Definition at line 613 of file DtmfGen.cpp.

614 {
615  dtmfSequence = mDtmfSequenceT->GetValue();
616  Recalculate();
617  UpdateUI();
618 }

References dtmfSequence, mDtmfSequenceT, Recalculate(), and UpdateUI().

Here is the call graph for this function:

◆ PopulateOrExchange()

void EffectDtmf::PopulateOrExchange ( ShuttleGui S)
overridevirtual

Reimplemented from Effect.

Definition at line 328 of file DtmfGen.cpp.

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:"));
356  NumericTextCtrl(S.GetParent(), ID_Duration,
359  GetDuration(),
360  mProjectRate,
362  .AutoPos(true));
363  S.Name(XO("Duration"))
364  .AddWindow(mDtmfDurationT);
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 }

References NumericTextCtrl::Options::AutoPos(), dtmfAmplitude, dtmfDutyCycle, dtmfSequence, dtmfSilence, dtmfTone, Effect::GetDuration(), Effect::GetDurationFormat(), ID_Amplitude, ID_Duration, ID_DutyCycle, ID_Sequence, kSymbols, mDtmfDurationT, mDtmfDutyCycleS, mDtmfDutyT, mDtmfSequenceT, mDtmfSilenceT, mDtmfToneT, Effect::mProjectRate, S, safenew, NumericConverter::TIME, XO, and XXO.

Here is the call graph for this function:

◆ ProcessBlock()

size_t EffectDtmf::ProcessBlock ( float **  inBlock,
float **  outBlock,
size_t  blockLen 
)
overridevirtual

Called for destructive, non-realtime effect computation.

Implements EffectProcessor.

Definition at line 182 of file DtmfGen.cpp.

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 }

References curSeqPos, curTonePos, diff, dtmfAmplitude, dtmfSequence, isTone, limitSampleBufferSize(), MakeDtmfTone(), Effect::mSampleRate, numRemaining, numSamplesSilence, numSamplesTone, and size.

Here is the call graph for this function:

◆ ProcessInitialize()

bool EffectDtmf::ProcessInitialize ( sampleCount  totalLen,
ChannelNames  chanMap = NULL 
)
overridevirtual

Called for destructive, non-realtime effect computation.

Implements EffectProcessor.

Definition at line 132 of file DtmfGen.cpp.

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 }

References curSeqPos, diff, dtmfNTones, dtmfSilence, dtmfTone, Effect::GetDuration(), isTone, Effect::MessageBox(), Effect::mSampleRate, Effect::mT0, numRemaining, numSamplesSequence, numSamplesSilence, numSamplesTone, and XO.

Here is the call graph for this function:

◆ Recalculate()

void EffectDtmf::Recalculate ( )
private

Definition at line 433 of file DtmfGen.cpp.

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 }

References dtmfDutyCycle, dtmfNTones, dtmfSequence, dtmfSilence, dtmfTone, Effect::GetDuration(), and Effect::SetDuration().

Referenced by Init(), OnAmplitude(), OnDuration(), OnDutyCycle(), OnSequence(), SetAutomationParameters(), TransferDataFromWindow(), and TransferDataToWindow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetAutomationParameters()

bool EffectDtmf::SetAutomationParameters ( CommandParameters parms)
overridevirtual

Change settings to those stored in parms.

Implements EffectDefinitionInterface.

Definition at line 264 of file DtmfGen.cpp.

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 }

References dtmfAmplitude, dtmfDutyCycle, dtmfSequence, kSymbols, ReadAndVerifyDouble, ReadAndVerifyString, and Recalculate().

Here is the call graph for this function:

◆ Startup()

bool EffectDtmf::Startup ( )
overridevirtual

Reimplemented from Effect.

Definition at line 292 of file DtmfGen.cpp.

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 }

References dtmfAmplitude, dtmfDutyCycle, dtmfSequence, FileConfig::Flush(), Effect::GetCurrentSettingsGroup(), gPrefs, Effect::SaveUserPreset(), and SHORT_APP_NAME.

Here is the call graph for this function:

◆ TransferDataFromWindow()

bool EffectDtmf::TransferDataFromWindow ( )
overridevirtual

Reimplemented from Effect.

Definition at line 414 of file DtmfGen.cpp.

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 }

References dtmfDutyCycle, NumericConverter::GetValue(), mDtmfDurationT, mDtmfDutyCycleS, Effect::mUIParent, Recalculate(), and Effect::SetDuration().

Here is the call graph for this function:

◆ TransferDataToWindow()

bool EffectDtmf::TransferDataToWindow ( )
overridevirtual

Reimplemented from Effect.

Definition at line 396 of file DtmfGen.cpp.

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 }

References dtmfDutyCycle, Effect::GetDuration(), mDtmfDurationT, mDtmfDutyCycleS, Effect::mUIParent, Recalculate(), NumericTextCtrl::SetValue(), and UpdateUI().

Here is the call graph for this function:

◆ UpdateUI()

void EffectDtmf::UpdateUI ( void  )
private

Definition at line 601 of file DtmfGen.cpp.

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 }

References _, dtmfDutyCycle, dtmfSilence, dtmfTone, mDtmfDutyT, mDtmfSilenceT, and mDtmfToneT.

Referenced by OnAmplitude(), OnDuration(), OnDutyCycle(), OnSequence(), and TransferDataToWindow().

Here is the caller graph for this function:

Member Data Documentation

◆ curSeqPos

int EffectDtmf::curSeqPos
private

Definition at line 83 of file DtmfGen.h.

Referenced by ProcessBlock(), and ProcessInitialize().

◆ curTonePos

sampleCount EffectDtmf::curTonePos
private

Definition at line 81 of file DtmfGen.h.

Referenced by ProcessBlock().

◆ diff

sampleCount EffectDtmf::diff
private

Definition at line 79 of file DtmfGen.h.

Referenced by ProcessBlock(), and ProcessInitialize().

◆ dtmfAmplitude

double EffectDtmf::dtmfAmplitude
private

◆ dtmfDutyCycle

double EffectDtmf::dtmfDutyCycle
private

◆ dtmfNTones

int EffectDtmf::dtmfNTones
private

Definition at line 86 of file DtmfGen.h.

Referenced by ProcessInitialize(), and Recalculate().

◆ dtmfSequence

wxString EffectDtmf::dtmfSequence
private

◆ dtmfSilence

double EffectDtmf::dtmfSilence
private

Definition at line 88 of file DtmfGen.h.

Referenced by PopulateOrExchange(), ProcessInitialize(), Recalculate(), and UpdateUI().

◆ dtmfTone

double EffectDtmf::dtmfTone
private

Definition at line 87 of file DtmfGen.h.

Referenced by PopulateOrExchange(), ProcessInitialize(), Recalculate(), and UpdateUI().

◆ isTone

bool EffectDtmf::isTone
private

Definition at line 82 of file DtmfGen.h.

Referenced by ProcessBlock(), and ProcessInitialize().

◆ mDtmfAmplitudeT

wxTextCtrl* EffectDtmf::mDtmfAmplitudeT
private

Definition at line 93 of file DtmfGen.h.

Referenced by OnAmplitude().

◆ mDtmfDurationT

NumericTextCtrl* EffectDtmf::mDtmfDurationT
private

◆ mDtmfDutyCycleS

wxSlider* EffectDtmf::mDtmfDutyCycleS
private

Definition at line 94 of file DtmfGen.h.

Referenced by PopulateOrExchange(), TransferDataFromWindow(), and TransferDataToWindow().

◆ mDtmfDutyT

wxStaticText* EffectDtmf::mDtmfDutyT
private

Definition at line 98 of file DtmfGen.h.

Referenced by PopulateOrExchange(), and UpdateUI().

◆ mDtmfSequenceT

wxTextCtrl* EffectDtmf::mDtmfSequenceT
private

Definition at line 92 of file DtmfGen.h.

Referenced by OnSequence(), and PopulateOrExchange().

◆ mDtmfSilenceT

wxStaticText* EffectDtmf::mDtmfSilenceT
private

Definition at line 97 of file DtmfGen.h.

Referenced by PopulateOrExchange(), and UpdateUI().

◆ mDtmfToneT

wxStaticText* EffectDtmf::mDtmfToneT
private

Definition at line 96 of file DtmfGen.h.

Referenced by PopulateOrExchange(), and UpdateUI().

◆ numRemaining

sampleCount EffectDtmf::numRemaining
private

Definition at line 80 of file DtmfGen.h.

Referenced by ProcessBlock(), and ProcessInitialize().

◆ numSamplesSequence

sampleCount EffectDtmf::numSamplesSequence
private

Definition at line 76 of file DtmfGen.h.

Referenced by ProcessInitialize().

◆ numSamplesSilence

sampleCount EffectDtmf::numSamplesSilence
private

Definition at line 78 of file DtmfGen.h.

Referenced by ProcessBlock(), and ProcessInitialize().

◆ numSamplesTone

sampleCount EffectDtmf::numSamplesTone
private

Definition at line 77 of file DtmfGen.h.

Referenced by ProcessBlock(), and ProcessInitialize().

◆ Symbol

const ComponentInterfaceSymbol EffectDtmf::Symbol { XO("DTMF Tones") }
static

Definition at line 28 of file DtmfGen.h.

Referenced by GetSymbol().


The documentation for this class was generated from the following files:
size
size_t size
Definition: ffmpeg-2.3.6-single-header.h:412
EffectDtmf::mDtmfSilenceT
wxStaticText * mDtmfSilenceT
Definition: DtmfGen.h:97
EffectDtmf::isTone
bool isTone
Definition: DtmfGen.h:82
Effect::GetDuration
double GetDuration() override
Definition: Effect.cpp:769
S
#define S(N)
Definition: ToChars.cpp:64
NumericTextCtrl::Options::AutoPos
Options & AutoPos(bool enable)
Definition: NumericTextCtrl.h:190
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:71
Effect::MessageBox
int MessageBox(const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
Definition: Effect.cpp:2238
EffectTypeGenerate
@ EffectTypeGenerate
Definition: EffectInterface.h:55
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
XO
#define XO(s)
Definition: Internat.h:31
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
Save current settings as a user-named preset.
Definition: Effect.cpp:547
NumericTextCtrl
Definition: NumericTextCtrl.h:172
NumericTextCtrl::SetValue
void SetValue(double newValue)
Definition: NumericTextCtrl.cpp:1474
EffectDtmf::mDtmfDurationT
NumericTextCtrl * mDtmfDurationT
Definition: DtmfGen.h:95
NumericTextCtrl::Options
Definition: NumericTextCtrl.h:178
EffectDtmf::dtmfSequence
wxString dtmfSequence
Definition: DtmfGen.h:85
EffectDtmf::curTonePos
sampleCount curTonePos
Definition: DtmfGen.h:81
Effect::mProjectRate
double mProjectRate
Definition: Effect.h:416
SHORT_APP_NAME
#define SHORT_APP_NAME
Definition: DtmfGen.cpp:45
ID_Duration
@ ID_Duration
Definition: DtmfGen.cpp:37
A
#define A(N)
Definition: ToChars.cpp:62
XXO
#define XXO(s)
Definition: Internat.h:44
Effect::mT0
double mT0
Definition: Effect.h:423
EffectDtmf::diff
sampleCount diff
Definition: DtmfGen.h:79
EffectDtmf::dtmfSilence
double dtmfSilence
Definition: DtmfGen.h:88
EffectDtmf::mDtmfAmplitudeT
wxTextCtrl * mDtmfAmplitudeT
Definition: DtmfGen.h:93
EffectDtmf::dtmfTone
double dtmfTone
Definition: DtmfGen.h:87
EffectDtmf::Recalculate
void Recalculate()
Definition: DtmfGen.cpp:433
NumericConverter::TIME
@ TIME
Definition: NumericTextCtrl.h:52
EffectDtmf::mDtmfDutyCycleS
wxSlider * mDtmfDutyCycleS
Definition: DtmfGen.h:94
ReadAndVerifyDouble
#define ReadAndVerifyDouble(name)
Definition: Effect.h:592
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:820
kSymbols
static const wxChar * kSymbols[]
Definition: DtmfGen.cpp:57
Effect::SetDuration
void SetDuration(double duration) override
Definition: Effect.cpp:791
Effect::mSampleRate
double mSampleRate
Definition: Effect.h:418
EffectDtmf::numRemaining
sampleCount numRemaining
Definition: DtmfGen.h:80
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
EffectDtmf::mDtmfToneT
wxStaticText * mDtmfToneT
Definition: DtmfGen.h:96
Effect::mUIParent
wxWindow * mUIParent
Definition: Effect.h:438
ReadAndVerifyString
#define ReadAndVerifyString(name)
Definition: Effect.h:595
_
#define _(s)
Definition: Internat.h:75
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
EffectDtmf::dtmfDutyCycle
double dtmfDutyCycle
Definition: DtmfGen.h:89
EffectDtmf::curSeqPos
int curSeqPos
Definition: DtmfGen.h:83
M_PI
#define M_PI
Definition: Distortion.cpp:29
Effect::GetDurationFormat
NumericFormatSymbol GetDurationFormat() override
Definition: Effect.cpp:779
EffectDtmf::numSamplesSequence
sampleCount numSamplesSequence
Definition: DtmfGen.h:76
safenew
#define safenew
Definition: MemoryX.h:10
limitSampleBufferSize
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:23
EffectDtmf::mDtmfDutyT
wxStaticText * mDtmfDutyT
Definition: DtmfGen.h:98
NumericConverter::GetValue
double GetValue()
Definition: NumericTextCtrl.cpp:1174
EffectDtmf::numSamplesSilence
sampleCount numSamplesSilence
Definition: DtmfGen.h:78
ID_DutyCycle
@ ID_DutyCycle
Definition: DtmfGen.cpp:38
ID_Amplitude
@ ID_Amplitude
Definition: DtmfGen.cpp:36
EffectDtmf::UpdateUI
void UpdateUI()
Definition: DtmfGen.cpp:601