Audacity  2.2.2
Reverb.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4  Audacity(R) is copyright (c) 1999-2013 Audacity Team.
5  License: GPL v2. See License.txt.
6 
7  Reverb.cpp
8  Rob Sykes, Vaughan Johnson
9 
10 ******************************************************************//*******************************************************************/
16 
17 #include "../Audacity.h"
18 #include "Reverb.h"
19 
20 #include <wx/arrstr.h>
21 #include <wx/intl.h>
22 
23 #include "../Audacity.h"
24 #include "../Prefs.h"
25 #include "../ShuttleGui.h"
26 #include "../widgets/valnum.h"
27 
28 #include "Reverb_libSoX.h"
29 
30 enum
31 {
32  ID_RoomSize = 10000,
42 };
43 
44 // Define keys, defaults, minimums, and maximums for the effect parameters
45 //
46 // Name Type Key Def Min Max Scale
47 Param( RoomSize, double, wxT("RoomSize"), 75, 0, 100, 1 );
48 Param( PreDelay, double, wxT("Delay"), 10, 0, 200, 1 );
49 Param( Reverberance, double, wxT("Reverberance"), 50, 0, 100, 1 );
50 Param( HfDamping, double, wxT("HfDamping"), 50, 0, 100, 1 );
51 Param( ToneLow, double, wxT("ToneLow"), 100, 0, 100, 1 );
52 Param( ToneHigh, double, wxT("ToneHigh"), 100, 0, 100, 1 );
53 Param( WetGain, double, wxT("WetGain"), -1, -20, 10, 1 );
54 Param( DryGain, double, wxT("DryGain"), -1, -20, 10, 1 );
55 Param( StereoWidth, double, wxT("StereoWidth"), 100, 0, 100, 1 );
56 Param( WetOnly, bool, wxT("WetOnly"), false, false, true, 1 );
57 
58 static const struct
59 {
60  const wxChar *name;
62 }
64 {
65  // Room Pre Hf Tone Tone Wet Dry Stereo Wet
66  // Name Size, Delay, Reverb, Damping, Low, High, Gain, Gain, Width, Only
67  { XO("Vocal I" ), { 70, 20, 40, 99, 100, 50, -12, 0, 70, false } },
68  { XO("Vocal II"), { 50, 0, 50, 99, 50, 100, -1, -1, 70, false } },
69  { XO("Bathroom"), { 16, 8, 80, 0, 0, 100, -6, 0, 100, false } },
70  { XO("Small Room Bright"), { 30, 10, 50, 50, 50, 100, -1, -1, 100, false } },
71  { XO("Small Room Dark"), { 30, 10, 50, 50, 100, 0, -1, -1, 100, false } },
72  { XO("Medium Room"), { 75, 10, 40, 50, 100, 70, -1, -1, 70, false } },
73  { XO("Large Room"), { 85, 10, 40, 50, 100, 80, 0, -6, 90, false } },
74  { XO("Church Hall"), { 90, 32, 60, 50, 100, 50, 0, -12, 100, false } },
75  { XO("Cathedral"), { 90, 16, 90, 50, 100, 0, 0, -20, 100, false } },
76 };
77 
79 {
81  float *dry;
82  float *wet[2];
83 };
84 
85 //
86 // EffectReverb
87 //
88 
89 BEGIN_EVENT_TABLE(EffectReverb, wxEvtHandler)
90 
91 #define SpinSliderEvent(n) \
92  EVT_SLIDER(ID_ ## n, EffectReverb::On ## n ## Slider) \
93  EVT_TEXT(ID_ ## n, EffectReverb::On ## n ## Text)
94 
95  SpinSliderEvent(RoomSize)
96  SpinSliderEvent(PreDelay)
97  SpinSliderEvent(Reverberance)
98  SpinSliderEvent(HfDamping)
99  SpinSliderEvent(ToneLow)
100  SpinSliderEvent(ToneHigh)
101  SpinSliderEvent(WetGain)
102  SpinSliderEvent(DryGain)
103  SpinSliderEvent(StereoWidth)
104 
105 #undef SpinSliderEvent
106 
108 
110 {
111  mParams.mRoomSize = DEF_RoomSize;
112  mParams.mPreDelay = DEF_PreDelay;
113  mParams.mReverberance = DEF_Reverberance;
114  mParams.mHfDamping = DEF_HfDamping;
115  mParams.mToneLow = DEF_ToneLow;
116  mParams.mToneHigh = DEF_ToneHigh;
117  mParams.mWetGain = DEF_WetGain;
118  mParams.mDryGain = DEF_DryGain;
119  mParams.mStereoWidth = DEF_StereoWidth;
120  mParams.mWetOnly = DEF_WetOnly;
121 
122  mProcessingEvent = false;
123 
124  SetLinearEffectFlag(true);
125 }
126 
128 {
129 }
130 
131 // IdentInterface implementation
132 
134 {
135  return REVERB_PLUGIN_SYMBOL;
136 }
137 
139 {
140  return _("Adds ambience or a \"hall effect\"");
141 }
142 
144 {
145  return wxT("Reverb");
146 }
147 
148 // EffectIdentInterface implementation
149 
151 {
152  return EffectTypeProcess;
153 }
154 
155 // EffectClientInterface implementation
156 
158 {
159  return mParams.mStereoWidth ? 2 : 1;
160 }
161 
163 {
164  return mParams.mStereoWidth ? 2 : 1;
165 }
166 
167 static size_t BLOCK = 16384;
168 
169 bool EffectReverb::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames chanMap)
170 {
171  bool isStereo = false;
172  mNumChans = 1;
173  if (chanMap && chanMap[0] != ChannelNameEOL && chanMap[1] == ChannelNameFrontRight)
174  {
175  isStereo = true;
176  mNumChans = 2;
177  }
178 
179  mP = (Reverb_priv_t *) calloc(sizeof(*mP), mNumChans);
180 
181  for (unsigned int i = 0; i < mNumChans; i++)
182  {
183  reverb_create(&mP[i].reverb,
184  mSampleRate,
190  mParams.mStereoWidth * (isStereo ? 1 : 0),
193  BLOCK,
194  mP[i].wet);
195  }
196 
197  return true;
198 }
199 
201 {
202  for (unsigned int i = 0; i < mNumChans; i++)
203  {
204  reverb_delete(&mP[i].reverb);
205  }
206 
207  free(mP);
208 
209  return true;
210 }
211 
212 size_t EffectReverb::ProcessBlock(float **inBlock, float **outBlock, size_t blockLen)
213 {
214  float *ichans[2] = {NULL, NULL};
215  float *ochans[2] = {NULL, NULL};
216 
217  for (unsigned int c = 0; c < mNumChans; c++)
218  {
219  ichans[c] = inBlock[c];
220  ochans[c] = outBlock[c];
221  }
222 
223  float const dryMult = mParams.mWetOnly ? 0 : dB_to_linear(mParams.mDryGain);
224 
225  auto remaining = blockLen;
226 
227  while (remaining)
228  {
229  auto len = std::min(remaining, decltype(remaining)(BLOCK));
230  for (unsigned int c = 0; c < mNumChans; c++)
231  {
232  // Write the input samples to the reverb fifo. Returned value is the address of the
233  // fifo buffer which contains a copy of the input samples.
234  mP[c].dry = (float *) fifo_write(&mP[c].reverb.input_fifo, len, ichans[c]);
235  reverb_process(&mP[c].reverb, len);
236  }
237 
238  if (mNumChans == 2)
239  {
240  for (decltype(len) i = 0; i < len; i++)
241  {
242  for (int w = 0; w < 2; w++)
243  {
244  ochans[w][i] = dryMult *
245  mP[w].dry[i] +
246  0.5 *
247  (mP[0].wet[w][i] + mP[1].wet[w][i]);
248  }
249  }
250  }
251  else
252  {
253  for (decltype(len) i = 0; i < len; i++)
254  {
255  ochans[0][i] = dryMult *
256  mP[0].dry[i] +
257  mP[0].wet[0][i];
258  }
259  }
260 
261  remaining -= len;
262 
263  for (unsigned int c = 0; c < mNumChans; c++)
264  {
265  ichans[c] += len;
266  ochans[c] += len;
267  }
268  }
269 
270  return blockLen;
271 }
272 
273 bool EffectReverb::GetAutomationParameters(EffectAutomationParameters & parms)
274 {
275  parms.Write(KEY_RoomSize, mParams.mRoomSize);
276  parms.Write(KEY_PreDelay, mParams.mPreDelay);
277  parms.Write(KEY_Reverberance, mParams.mReverberance);
278  parms.Write(KEY_HfDamping, mParams.mHfDamping);
279  parms.Write(KEY_ToneLow, mParams.mToneLow);
280  parms.Write(KEY_ToneHigh, mParams.mToneHigh);
281  parms.Write(KEY_WetGain, mParams.mWetGain);
282  parms.Write(KEY_DryGain, mParams.mDryGain);
283  parms.Write(KEY_StereoWidth, mParams.mStereoWidth);
284  parms.Write(KEY_WetOnly, mParams.mWetOnly);
285 
286  return true;
287 }
288 
289 bool EffectReverb::SetAutomationParameters(EffectAutomationParameters & parms)
290 {
291  ReadAndVerifyDouble(RoomSize);
292  ReadAndVerifyDouble(PreDelay);
293  ReadAndVerifyDouble(Reverberance);
294  ReadAndVerifyDouble(HfDamping);
295  ReadAndVerifyDouble(ToneLow);
296  ReadAndVerifyDouble(ToneHigh);
297  ReadAndVerifyDouble(WetGain);
298  ReadAndVerifyDouble(DryGain);
299  ReadAndVerifyDouble(StereoWidth);
300  ReadAndVerifyBool(WetOnly);
301 
302  mParams.mRoomSize = RoomSize;
303  mParams.mPreDelay = PreDelay;
304  mParams.mReverberance = Reverberance;
305  mParams.mHfDamping = HfDamping;
306  mParams.mToneLow = ToneLow;
307  mParams.mToneHigh = ToneHigh;
308  mParams.mWetGain = WetGain;
309  mParams.mDryGain = DryGain;
310  mParams.mStereoWidth = StereoWidth;
311  mParams.mWetOnly = WetOnly;
312 
313  return true;
314 }
315 
317 {
318  wxArrayString names;
319 
320  for (size_t i = 0; i < WXSIZEOF(FactoryPresets); i++)
321  {
322  names.Add(wxGetTranslation(FactoryPresets[i].name));
323  }
324 
325  return names;
326 }
327 
329 {
330  if (id < 0 || id >= (int) WXSIZEOF(FactoryPresets))
331  {
332  return false;
333  }
334 
335  mParams = FactoryPresets[id].params;
336 
337  if (mUIDialog)
338  {
340  }
341 
342  return true;
343 }
344 
345 // Effect implementation
346 
348 {
349  wxString base = wxT("/Effects/Reverb/");
350 
351  // Migrate settings from 2.1.0 or before
352 
353  // Already migrated, so bail
354  if (gPrefs->Exists(base + wxT("Migrated")))
355  {
356  return true;
357  }
358 
359  // Load the old "current" settings
360  if (gPrefs->Exists(base))
361  {
362  gPrefs->Read(base + wxT("RoomSize"), &mParams.mRoomSize, DEF_RoomSize);
363  gPrefs->Read(base + wxT("Delay"), &mParams.mPreDelay, DEF_PreDelay);
364  gPrefs->Read(base + wxT("Reverberance"), &mParams.mReverberance, DEF_Reverberance);
365  gPrefs->Read(base + wxT("HfDamping"), &mParams.mHfDamping, DEF_HfDamping);
366  gPrefs->Read(base + wxT("ToneLow"), &mParams.mToneLow, DEF_ToneLow);
367  gPrefs->Read(base + wxT("ToneHigh"), &mParams.mToneHigh, DEF_ToneHigh);
368  gPrefs->Read(base + wxT("WetGain"), &mParams.mWetGain, DEF_WetGain);
369  gPrefs->Read(base + wxT("DryGain"), &mParams.mDryGain, DEF_DryGain);
370  gPrefs->Read(base + wxT("StereoWidth"), &mParams.mStereoWidth, DEF_StereoWidth);
371  gPrefs->Read(base + wxT("WetOnly"), &mParams.mWetOnly, DEF_WetOnly);
372 
374 
375  // Do not migrate again
376  gPrefs->Write(base + wxT("Migrated"), true);
377  }
378 
379  // Load the previous user presets
380  for (int i = 0; i < 10; i++)
381  {
382  wxString path = base + wxString::Format(wxT("%d/"), i);
383  if (gPrefs->Exists(path))
384  {
385  Params save = mParams;
386  wxString name;
387 
388  gPrefs->Read(path + wxT("RoomSize"), &mParams.mRoomSize, DEF_RoomSize);
389  gPrefs->Read(path + wxT("Delay"), &mParams.mPreDelay, DEF_PreDelay);
390  gPrefs->Read(path + wxT("Reverberance"), &mParams.mReverberance, DEF_Reverberance);
391  gPrefs->Read(path + wxT("HfDamping"), &mParams.mHfDamping, DEF_HfDamping);
392  gPrefs->Read(path + wxT("ToneLow"), &mParams.mToneLow, DEF_ToneLow);
393  gPrefs->Read(path + wxT("ToneHigh"), &mParams.mToneHigh, DEF_ToneHigh);
394  gPrefs->Read(path + wxT("WetGain"), &mParams.mWetGain, DEF_WetGain);
395  gPrefs->Read(path + wxT("DryGain"), &mParams.mDryGain, DEF_DryGain);
396  gPrefs->Read(path + wxT("StereoWidth"), &mParams.mStereoWidth, DEF_StereoWidth);
397  gPrefs->Read(path + wxT("WetOnly"), &mParams.mWetOnly, DEF_WetOnly);
398  gPrefs->Read(path + wxT("name"), &name, wxEmptyString);
399 
400  if (!name.IsEmpty())
401  {
402  name.Prepend(wxT(" - "));
403  }
404  name.Prepend(wxString::Format(wxT("Settings%d"), i));
405 
407 
408  mParams = save;
409  }
410  }
411 
412  return true;
413 }
414 
416 {
417  S.AddSpace(0, 5);
418 
419  S.StartMultiColumn(3, wxEXPAND);
420  {
421  S.SetStretchyCol(2);
422 
423 #define SpinSlider(n, p) \
424  m ## n ## T = S.Id(ID_ ## n). \
425  AddSpinCtrl( p, DEF_ ## n, MAX_ ## n, MIN_ ## n); \
426  S.SetStyle(wxSL_HORIZONTAL); \
427  m ## n ## S = S.Id(ID_ ## n). \
428  AddSlider( {}, DEF_ ## n, MAX_ ## n, MIN_ ## n);
429 
430  SpinSlider(RoomSize, _("&Room Size (%):"))
431  SpinSlider(PreDelay, _("&Pre-delay (ms):"))
432  SpinSlider(Reverberance, _("Rever&berance (%):"))
433  SpinSlider(HfDamping, _("Da&mping (%):"))
434  SpinSlider(ToneLow, _("Tone &Low (%):"))
435  SpinSlider(ToneHigh, _("Tone &High (%):"))
436  SpinSlider(WetGain, _("Wet &Gain (dB):"))
437  SpinSlider(DryGain, _("Dr&y Gain (dB):"))
438  SpinSlider(StereoWidth, _("Stereo Wid&th (%):"))
439 
440 #undef SpinSlider
441 
442  }
443  S.EndMultiColumn();
444 
445  S.StartHorizontalLay(wxCENTER, false);
446  {
447  mWetOnlyC = S.Id(ID_WetOnly).
448  AddCheckBox(_("Wet O&nly"), DEF_WetOnly ? wxT("true") : wxT("false"));
449  }
450  S.EndHorizontalLay();
451 
452  return;
453 }
454 
456 {
457 #define SetSpinSlider(n) \
458  m ## n ## S->SetValue((int) mParams.m ## n); \
459  m ## n ## T->SetValue(wxString::Format(wxT("%d"), (int) mParams.m ## n));
460 
461  SetSpinSlider(RoomSize);
462  SetSpinSlider(PreDelay);
463  SetSpinSlider(Reverberance);
464  SetSpinSlider(HfDamping);
465  SetSpinSlider(ToneLow);
466  SetSpinSlider(ToneHigh);
467  SetSpinSlider(WetGain);
468  SetSpinSlider(DryGain);
469  SetSpinSlider(StereoWidth);
470 
471 #undef SetSpinSlider
472 
473  mWetOnlyC->SetValue((int) mParams.mWetOnly);
474 
475  return true;
476 }
477 
479 {
480  if (!mUIParent->Validate())
481  {
482  return false;
483  }
484 
485  mParams.mRoomSize = mRoomSizeS->GetValue();
486  mParams.mPreDelay = mPreDelayS->GetValue();
487  mParams.mReverberance = mReverberanceS->GetValue();
488  mParams.mHfDamping = mHfDampingS->GetValue();
489  mParams.mToneLow = mToneLowS->GetValue();
490  mParams.mToneHigh = mToneHighS->GetValue();
491  mParams.mWetGain = mWetGainS->GetValue();
492  mParams.mDryGain = mDryGainS->GetValue();
493  mParams.mStereoWidth = mStereoWidthS->GetValue();
494  mParams.mWetOnly = mWetOnlyC->GetValue();
495 
496  return true;
497 }
498 
499 #define SpinSliderHandlers(n) \
500  void EffectReverb::On ## n ## Slider(wxCommandEvent & evt) \
501  { \
502  if (mProcessingEvent) return; \
503  mProcessingEvent = true; \
504  m ## n ## T->SetValue(wxString::Format(wxT("%d"), evt.GetInt())); \
505  mProcessingEvent = false; \
506  } \
507  void EffectReverb::On ## n ## Text(wxCommandEvent & evt) \
508  { \
509  if (mProcessingEvent) return; \
510  mProcessingEvent = true; \
511  m ## n ## S->SetValue(TrapLong(evt.GetInt(), MIN_ ## n, MAX_ ## n)); \
512  mProcessingEvent = false; \
513  }
514 
516 SpinSliderHandlers(PreDelay)
517 SpinSliderHandlers(Reverberance)
518 SpinSliderHandlers(HfDamping)
519 SpinSliderHandlers(ToneLow)
520 SpinSliderHandlers(ToneHigh)
521 SpinSliderHandlers(WetGain)
522 SpinSliderHandlers(DryGain)
523 SpinSliderHandlers(StereoWidth)
524 
525 #undef SpinSliderHandlers
526 
527 void EffectReverb::SetTitle(const wxString & name)
528 {
529  wxString title(_("Reverb"));
530 
531  if (!name.IsEmpty())
532  {
533  title += wxT(": ") + name;
534  }
535 
536  mUIDialog->SetTitle(title);
537 }
wxString GetUserPresetsGroup(const wxString &name) override
Definition: Effect.cpp:813
float * dry
Definition: Reverb.cpp:81
static wxArrayString names()
Definition: Tags.cpp:697
bool SaveUserPreset(const wxString &name) override
Definition: Effect.cpp:625
wxArrayString GetFactoryPresets() override
Definition: Reverb.cpp:316
reverb_t reverb
Definition: Reverb.cpp:80
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:366
wxString GetCurrentSettingsGroup() override
Definition: Effect.cpp:824
A reverberation effect.
Definition: Reverb.h:29
bool TransferDataToWindow() override
Definition: Reverb.cpp:455
void EndMultiColumn()
wxString ManualPage() override
Definition: Reverb.cpp:143
wxString GetDescription() override
Definition: Reverb.cpp:138
#define XO(s)
Definition: Internat.h:30
void SetTitle(const wxString &name=wxT(""))
static void reverb_process(reverb_t *p, size_t length)
SpinSlider(RoomSize) SpinSlider(PreDelay) SpinSlider(Reverberance) SpinSlider(HfDamping) SpinSlider(ToneLow) SpinSlider(ToneHigh) SpinSlider(WetGain) SpinSlider(DryGain) SpinSlider(StereoWidth) wxCheckBox *mWetOnlyC
unsigned GetAudioOutCount() override
Definition: Reverb.cpp:162
static const struct @31 FactoryPresets[]
double mSampleRate
Definition: Effect.h:458
#define dB_to_linear(x)
Definition: Reverb_libSoX.h:27
void EndHorizontalLay()
Definition: ShuttleGui.cpp:975
static void reverb_delete(reverb_t *p)
unsigned GetAudioInCount() override
Definition: Reverb.cpp:157
size_t ProcessBlock(float **inBlock, float **outBlock, size_t blockLen) override
Definition: Reverb.cpp:212
wxFileConfig * gPrefs
Definition: Prefs.cpp:72
#define REVERB_PLUGIN_SYMBOL
Definition: Reverb.h:25
bool LoadFactoryPreset(int id) override
Definition: Reverb.cpp:328
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:966
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:998
ShuttleGui & Id(int id)
#define ReadAndVerifyDouble(name)
Definition: Effect.h:791
bool SetAutomationParameters(EffectAutomationParameters &parms) override
Definition: Reverb.cpp:289
int min(int a, int b)
double mStereoWidth
Definition: Reverb.h:45
double mReverberance
Definition: Reverb.h:39
#define SetSpinSlider(n)
#define SpinSliderEvent(n)
Definition: Reverb.cpp:91
#define SpinSliderHandlers(n)
Definition: Reverb.cpp:499
EffectType GetType() override
Definition: Reverb.cpp:150
bool GetAutomationParameters(EffectAutomationParameters &parms) override
Definition: Reverb.cpp:273
wxWindow * mUIParent
Definition: Effect.h:475
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
Params mParams
Definition: Reverb.h:103
double mPreDelay
Definition: Reverb.h:38
bool ProcessInitialize(sampleCount totalLen, ChannelNames chanMap=NULL) override
Definition: Reverb.cpp:169
double mHfDamping
Definition: Reverb.h:40
SpinSliderHandlers(RoomSize) SpinSliderHandlers(PreDelay) SpinSliderHandlers(Reverberance) SpinSliderHandlers(HfDamping) SpinSliderHandlers(ToneLow) SpinSliderHandlers(ToneHigh) SpinSliderHandlers(WetGain) SpinSliderHandlers(DryGain) SpinSliderHandlers(StereoWidth) private Reverb_priv_t * mP
Definition: Reverb.h:87
Param(RoomSize, double, wxT("RoomSize"), 75, 0, 100, 1)
void PopulateOrExchange(ShuttleGui &S)
Definition: Reverb.cpp:415
bool Startup()
Definition: Reverb.cpp:347
wxDialog * mUIDialog
Definition: Effect.h:474
double mToneHigh
Definition: Reverb.h:42
float * wet[2]
Definition: Reverb.cpp:82
bool ProcessFinalize() override
Definition: Reverb.cpp:200
wxString GetSymbol() override
Definition: Reverb.cpp:133
#define ReadAndVerifyBool(name)
Definition: Effect.h:793
EffectReverb::Params params
Definition: Reverb.cpp:61
virtual ~EffectReverb()
Definition: Reverb.cpp:127
static void reverb_create(reverb_t *p, double sample_rate_Hz, double wet_gain_dB, double room_scale, double reverberance, double hf_damping, double pre_delay_ms, double stereo_depth, double tone_low, double tone_high, size_t buffer_size, float **out)
END_EVENT_TABLE()
wxSizerItem * AddSpace(int width, int height)
bool TransferDataFromWindow() override
Definition: Reverb.cpp:478
const wxChar * name
Definition: Reverb.cpp:60
static void * fifo_write(fifo_t *f, FIFO_SIZE_T n, void const *data)
Definition: Reverb_libSoX.h:74
double mRoomSize
Definition: Reverb.h:37
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:192
static size_t BLOCK
Definition: Reverb.cpp:167