1 /*
2 * Copyright (C) 2002 - David W. Durham
3 *
4 * This file is part of ReZound, an audio editing application.
5 *
6 * ReZound is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2 of the License,
9 * or (at your option) any later version.
10 *
11 * ReZound is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include "FilterActionDialogs.h"
22
23 #include "CStatusComm.h"
24
25 #include "../backend/ActionParamMappers.h"
26 #include "../backend/unit_conv.h"
27
28 #include <vector>
29
30
31 // --- convolution -----------------------
32
33
34 static const double froo=log(80.0/(24.0+80.0))/log(0.5); // this is to make the middle come out 0.00dB
35 class CActionParamMapper_dB_gain : public AActionParamMapper
36 {
37 public:
CActionParamMapper_dB_gain(double defaultValue)38 CActionParamMapper_dB_gain(double defaultValue) :
39 AActionParamMapper(defaultValue)
40 {
41 }
42
~CActionParamMapper_dB_gain()43 virtual ~CActionParamMapper_dB_gain() {}
44
interpretValue(const double x)45 double interpretValue(const double x)
46 {
47 return unitRange_to_otherRange_linear(pow(x,froo),-80,24);
48 }
49
uninterpretValue(const double x)50 double uninterpretValue(const double x)
51 {
52 return pow(otherRange_to_unitRange_linear(x,-80,24),1.0/froo);
53 }
54 };
55
56
CConvolutionFilterDialog(FXWindow * mainWindow)57 CConvolutionFilterDialog::CConvolutionFilterDialog(FXWindow *mainWindow) :
58 CActionParamDialog(mainWindow)
59 {
60 // ??? still need predelay sliders
61 void *p0=newVertPanel(NULL,true);
62 void *p1=newHorzPanel(p0,false);
63 addSlider(p1,
64 N_("Wet/Dry Mix"),
65 "%",
66 new CActionParamMapper_linear_range(50,-100,100),
67 NULL,
68 true
69 );
70
71 addSlider(p1,
72 N_("Input Lowpass"),
73 "Hz",
74 new CActionParamMapper_linear(25000.0,25000,5,100000),
75 NULL,
76 false
77 );
78
79 addSlider(p1,
80 N_("Input Gain"),
81 "dB",
82 new CActionParamMapper_dB_gain(0.0),
83 dB_to_scalar,
84 false
85 );
86
87 addSlider(p1,
88 N_("Output Gain"),
89 "dB",
90 new CActionParamMapper_dB_gain(0.0),
91 dB_to_scalar,
92 false
93 );
94
95 addSlider(p1,
96 N_("Predelay"),
97 "ms",
98 new CActionParamMapper_linear(50.0,100,1,500),
99 NULL,
100 false
101 );
102
103
104 void *p2=newVertPanel(p1,false);
105 addDiskEntityEntry(p2,N_("Filter Kernel"),"$share/impulse_hall1.wav",FXDiskEntityParamValue::detAudioFilename,_("The Audio File to Use as the Filter Kernel"));
106
107 void *p3=newHorzPanel(p2,false);
108 addSlider(p3,
109 N_("FK Gain"),
110 "x",
111 new CActionParamMapper_recipsym(0.06667,30,1,50),
112 NULL,
113 true
114 );
115
116 addSlider(p3,
117 N_("FK Lowpass"),
118 "Hz",
119 new CActionParamMapper_linear(25000.0,25000,5,1000000),
120 NULL,
121 false
122 );
123
124 void *p4=newVertPanel(p3,false);
125 addSlider(p4,
126 N_("FK Rate"),
127 "x",
128 new CActionParamMapper_recipsym(1.0,2,2,10),
129 NULL,
130 true
131 );
132
133 addCheckBoxEntry(p4,N_("Reverse"),false);
134 p1=newHorzPanel(p0,false);
135 addCheckBoxEntry(p1,N_("Wrap Decay back to Beginning"),false);
136 }
137
138
139
140
141
142 // --- arbitrary FIR filter --------------
143
144 class CActionParamMapper_arbitraryFIRFilter_freq : public AActionParamMapper
145 {
146 public:
147 // is set dynamically at runtime in by CArbitraryFIRFilterDialog
148 unsigned baseFrequency;
149 unsigned numberOfOctaves;
150
CActionParamMapper_arbitraryFIRFilter_freq()151 CActionParamMapper_arbitraryFIRFilter_freq() :
152 AActionParamMapper(),
153 baseFrequency(20),
154 numberOfOctaves(11)
155 {
156 }
157
~CActionParamMapper_arbitraryFIRFilter_freq()158 virtual ~CActionParamMapper_arbitraryFIRFilter_freq() {}
159
interpretValue(const double x)160 double interpretValue(const double x)
161 {
162 return octave_to_freq(x*numberOfOctaves,baseFrequency);
163 }
164
uninterpretValue(const double x)165 double uninterpretValue(const double x)
166 {
167 return freq_to_octave(x,baseFrequency)/numberOfOctaves;
168 }
169 };
170
171 class CActionParamMapper_arbitraryFIRFilter_amp : public AActionParamMapper
172 {
173 public:
CActionParamMapper_arbitraryFIRFilter_amp(double defaultValue,int defaultScalar,int minScalar,int maxScalar)174 CActionParamMapper_arbitraryFIRFilter_amp(double defaultValue,int defaultScalar,int minScalar,int maxScalar) :
175 AActionParamMapper(defaultValue,defaultScalar,minScalar,maxScalar)
176 {
177 }
178
~CActionParamMapper_arbitraryFIRFilter_amp()179 virtual ~CActionParamMapper_arbitraryFIRFilter_amp() {}
180
181 // intention: 0dB change is always in the middle, and the range above/below the gets wider or narrower depending on s (but that s is really only a tenth of what it would normally be)
interpretValue(const double x)182 double interpretValue(const double x)
183 {
184 return scalar_to_dB(x*2)*(getScalar()/10.0);
185 }
186
uninterpretValue(const double x)187 double uninterpretValue(const double x)
188 {
189 return dB_to_scalar(x/(getScalar()/10.0))/2;
190 }
191 };
192
193 #include "../backend/DSP/Convolver.h"
194 class CActionParamMapper_arbitraryFIRFilter_kernelLength : public AActionParamMapper
195 {
196 public:
197 // is set dynamically at runtime in by CArbitraryFIRFilterDialog
198 unsigned baseFrequency;
199 unsigned numberOfOctaves;
200
CActionParamMapper_arbitraryFIRFilter_kernelLength(double defaultValue)201 CActionParamMapper_arbitraryFIRFilter_kernelLength(double defaultValue) :
202 AActionParamMapper(defaultValue)
203 {
204 }
205
~CActionParamMapper_arbitraryFIRFilter_kernelLength()206 virtual ~CActionParamMapper_arbitraryFIRFilter_kernelLength() {}
207
208 #ifdef HAVE_LIBFFTW
interpretValue(const double x)209 double interpretValue(const double x)
210 {
211 if(goodFilterKernelSizes.size()<=0) // first time
212 goodFilterKernelSizes=TFFTConvolverTimeDomainKernel<float,float>::getGoodFilterKernelSizes();
213
214 // use min and max to place reasonable limits on the kernel size
215 return min((size_t)(4*1024*1024),max((size_t)8,goodFilterKernelSizes[(size_t)ceil(x*(goodFilterKernelSizes.size()-2))])); // -2 cause I need padding in the actual convolver
216 }
217
uninterpretValue(const double x)218 double uninterpretValue(const double x)
219 {
220 if(goodFilterKernelSizes.size()<=0) // first time
221 goodFilterKernelSizes=TFFTConvolverTimeDomainKernel<float,float>::getGoodFilterKernelSizes();
222
223 for(size_t t=0;t<goodFilterKernelSizes.size();t++)
224 {
225 if(goodFilterKernelSizes[t]==x)
226 return ((double)t)/(goodFilterKernelSizes.size()-2); // -2 cause I need padding in the actual convolver
227 }
228 return 0;
229 }
230 #else
231 // just for show
interpretValue(const double x)232 double interpretValue(const double x) { return floor(x*1024.0); }
uninterpretValue(const double x)233 double uninterpretValue(const double x) { return x/1024.0; }
234 #endif
235
236 private:
237 vector<size_t> goodFilterKernelSizes;
238 };
239
240
241
242 FXDEFMAP(CArbitraryFIRFilterDialog) CArbitraryFIRFilterDialogMap[]=
243 {
244 //Message_Type ID Message_Handler
245
246 FXMAPFUNC(SEL_COMMAND, CArbitraryFIRFilterDialog::ID_BASE_FREQUENCY, CArbitraryFIRFilterDialog::onFrequencyRangeChange),
247 FXMAPFUNC(SEL_COMMAND, CArbitraryFIRFilterDialog::ID_NUMBER_OF_OCTAVES, CArbitraryFIRFilterDialog::onFrequencyRangeChange),
248 };
249
FXIMPLEMENT(CArbitraryFIRFilterDialog,CActionParamDialog,CArbitraryFIRFilterDialogMap,ARRAYNUMBER (CArbitraryFIRFilterDialogMap))250 FXIMPLEMENT(CArbitraryFIRFilterDialog,CActionParamDialog,CArbitraryFIRFilterDialogMap,ARRAYNUMBER(CArbitraryFIRFilterDialogMap))
251
252 CArbitraryFIRFilterDialog::CArbitraryFIRFilterDialog(FXWindow *mainWindow) :
253 CActionParamDialog(mainWindow)
254 {
255 FXPacker *p0=newHorzPanel(NULL);
256 addSlider(p0,
257 N_("Wet/Dry Mix"),
258 "%",
259 new CActionParamMapper_linear_range(100.0,-100,100),
260 NULL,
261 true
262 );
263
264 FXPacker *p1=newVertPanel(p0,false);
265 addGraph(p1,
266 N_("Frequency Response"),
267 N_("Frequency"),
268 "Hz",
269 freqMapper=new CActionParamMapper_arbitraryFIRFilter_freq,
270 N_("Change"),
271 "dB",
272 new CActionParamMapper_arbitraryFIRFilter_amp(0.0,20,-100,100),
273 dB_to_scalar
274 );
275
276 FXPacker *p2=newHorzPanel(p1,false);
277 FXTextParamValue *baseFreq=addNumericTextEntry(p2,
278 N_("Base Frequency"),
279 "Hz",
280 20,
281 10,
282 1000,
283 _("This Sets the Lowest Frequency Displayed on the Graph.\nThis is the Frequency of the First Octave.")
284 );
285 baseFreq->setTarget(this);
286 baseFreq->setSelector(ID_BASE_FREQUENCY);
287
288 FXTextParamValue *numberOfOctaves=addNumericTextEntry(p2,
289 N_("Number of Octaves"),
290 "",
291 11,
292 1,
293 15,
294 _("This Sets the Number of Octaves Displayed on the Graph.\nBut Note that no Frequency Higher than Half of the Sound's Sampling Rate can be Affected Since it Cannot Contain a Frequency Higher than That.")
295 );
296 numberOfOctaves->setTarget(this);
297 numberOfOctaves->setSelector(ID_NUMBER_OF_OCTAVES);
298
299 p1=newVertPanel(p0,false);
300 addSlider(p1,
301 N_("Kernel Length"),
302 "",
303 new CActionParamMapper_arbitraryFIRFilter_kernelLength(1024),
304 NULL,
305 false
306 );
307 setTipText("Kernel Length",_("This is the Size of the Filter Kernel Computed (in samples) From Your Curve to be Convolved with the Audio"));
308
309 addCheckBoxEntry(p1,
310 N_("Undelay"),
311 true,
312 _("This Counteracts the Delay Side-Effect of Custom FIR Filters")
313 );
314
315 onFrequencyRangeChange(NULL,0,NULL);
316 }
317
onFrequencyRangeChange(FXObject * sender,FXSelector sel,void * ptr)318 long CArbitraryFIRFilterDialog::onFrequencyRangeChange(FXObject *sender,FXSelector sel,void *ptr)
319 {
320 FXGraphParamValue *g=getGraphParam("Frequency Response");
321
322 FXTextParamValue *baseFrequency=getTextParam("Base Frequency");
323 FXTextParamValue *numberOfOctaves=getTextParam("Number of Octaves");
324
325 freqMapper->baseFrequency=(unsigned)baseFrequency->getValue();
326 freqMapper->numberOfOctaves=(unsigned)numberOfOctaves->getValue();
327
328 g->updateNumbers();
329
330 return 1;
331 }
332
333
334
335
336 // --- morphing arbitrary FIR filter --------------
337
338 FXDEFMAP(CMorphingArbitraryFIRFilterDialog) CMorphingArbitraryFIRFilterDialogMap[]=
339 {
340 //Message_Type ID Message_Handler
341
342 FXMAPFUNC(SEL_COMMAND, CMorphingArbitraryFIRFilterDialog::ID_BASE_FREQUENCY, CMorphingArbitraryFIRFilterDialog::onFrequencyRangeChange),
343 FXMAPFUNC(SEL_COMMAND, CMorphingArbitraryFIRFilterDialog::ID_NUMBER_OF_OCTAVES, CMorphingArbitraryFIRFilterDialog::onFrequencyRangeChange),
344 FXMAPFUNC(SEL_COMMAND, CMorphingArbitraryFIRFilterDialog::ID_USE_LFO_CHECKBOX, CMorphingArbitraryFIRFilterDialog::onUseLFOCheckBox),
345 FXMAPFUNC(SEL_COMMAND, CMorphingArbitraryFIRFilterDialog::ID_COPY_1_TO_2, CMorphingArbitraryFIRFilterDialog::on1To2Button),
346 FXMAPFUNC(SEL_COMMAND, CMorphingArbitraryFIRFilterDialog::ID_COPY_2_TO_1, CMorphingArbitraryFIRFilterDialog::on1To2Button),
347 FXMAPFUNC(SEL_COMMAND, CMorphingArbitraryFIRFilterDialog::ID_SWAP_1_AND_2, CMorphingArbitraryFIRFilterDialog::on1To2Button),
348 };
349
FXIMPLEMENT(CMorphingArbitraryFIRFilterDialog,CActionParamDialog,CMorphingArbitraryFIRFilterDialogMap,ARRAYNUMBER (CMorphingArbitraryFIRFilterDialogMap))350 FXIMPLEMENT(CMorphingArbitraryFIRFilterDialog,CActionParamDialog,CMorphingArbitraryFIRFilterDialogMap,ARRAYNUMBER(CMorphingArbitraryFIRFilterDialogMap))
351
352 CMorphingArbitraryFIRFilterDialog::CMorphingArbitraryFIRFilterDialog(FXWindow *mainWindow) :
353 CActionParamDialog(mainWindow)
354 {
355 FXPacker *p0,*p1,*p2,*p3;
356
357 p0=newVertPanel(NULL);
358 p1=newHorzPanel(p0,false);
359 FXGraphParamValue *g1=addGraph(p1,
360 N_("Frequency Response 1"),
361 N_("Frequency"),
362 "Hz",
363 freqMapper=new CActionParamMapper_arbitraryFIRFilter_freq,
364 N_("Change"),
365 "dB",
366 new CActionParamMapper_arbitraryFIRFilter_amp(0.0,20,-100,100),
367 dB_to_scalar
368 );
369 g1->setMinSize(450,280);
370
371 p2=new FXVerticalFrame(p1,LAYOUT_CENTER_Y, 0,0,0,0, 0,0,0,0, 0,0);
372 new FXButton(p2,FXString("->\t")+_("Copy Response 1 to Response 2"),NULL,this,ID_COPY_1_TO_2,BUTTON_NORMAL|LAYOUT_FILL_X);
373 new FXButton(p2,FXString("<>\t")+_("Swap Response 1 and Response 2"),NULL,this,ID_SWAP_1_AND_2,BUTTON_NORMAL|LAYOUT_FILL_X);
374 new FXButton(p2,FXString("<-\t")+_("Copy Response 2 to Response 1"),NULL,this,ID_COPY_2_TO_1,BUTTON_NORMAL|LAYOUT_FILL_X);
375
376 FXGraphParamValue *g2=addGraph(p1,
377 N_("Frequency Response 2"),
378 N_("Frequency"),
379 "Hz",
380 freqMapper,
381 N_("Change"),
382 "dB",
383 new CActionParamMapper_arbitraryFIRFilter_amp(0.0,20,-100,100),
384 dB_to_scalar
385 );
386 g2->setMinSize(450,280);
387
388 p1=newHorzPanel(p0,false);
389 p2=newHorzPanel(p1,false);
390 p2->setLayoutHints(p2->getLayoutHints()&(~LAYOUT_FILL_X));
391
392 FXConstantParamValue *wetdryMix=addSlider(p2,
393 N_("Wet/Dry Mix"),
394 "%",
395 new CActionParamMapper_linear_range(100.0,-100,100),
396 NULL,
397 true
398 );
399 wetdryMix->setMinSize(0,150);
400
401 p3=newVertPanel(p2,false);
402 FXCheckBoxParamValue *useLFOCheckBox=addCheckBoxEntry(p3,
403 N_("Use LFO"),
404 false
405 );
406 useLFOCheckBox->setTarget(this);
407 useLFOCheckBox->setSelector(ID_USE_LFO_CHECKBOX);
408
409 FXLFOParamValue *lfo=addLFO(p3,
410 N_("Sweep LFO"),
411 "ms",
412 "",
413 0,
414 "Hz",
415 20,
416 true
417 );
418 lfo->setMinSize(0,170);
419
420 p3=newVertPanel(p2,false);
421 FXConstantParamValue *kernelLength=addSlider(p3,
422 N_("Kernel Length"),
423 "",
424 new CActionParamMapper_arbitraryFIRFilter_kernelLength(1024),
425 NULL,
426 false
427 );
428 setTipText("Kernel Length",_("This is the Size of the Filter Kernel Computed (in samples) From Your Curve to be Convolved with the Audio"));
429 kernelLength->setMinSize(0,150);
430
431 addCheckBoxEntry(p3,
432 N_("Undelay"),
433 true,
434 _("This Counteracts the Delay Side-Effect of Custom FIR Filters")
435 );
436
437 p2=newVertPanel(p1,false);
438 p2->setLayoutHints(p2->getLayoutHints()&(~LAYOUT_FILL_Y));
439 p2->setLayoutHints(p2->getLayoutHints()&(~LAYOUT_FILL_X));
440 FXTextParamValue *baseFrequency=addNumericTextEntry(p2,
441 N_("Base Frequency"),
442 "Hz",
443 20,
444 10,
445 1000,
446 _("This Sets the Lowest Frequency Displayed on the Graph.\nThis is the Frequency of the First Octave.")
447 );
448 baseFrequency->setTarget(this);
449 baseFrequency->setSelector(ID_BASE_FREQUENCY);
450
451 FXTextParamValue *numberOfOctaves=addNumericTextEntry(p2,
452 N_("Number of Octaves"),
453 "",
454 11,
455 1,
456 15,
457 _("This Sets the Number of Octaves Displayed on the Graph.\nBut Note that no Frequency Higher than Half of the Sound's Sampling Rate can be Affected Since it Cannot Contain a Frequency Higher than That.")
458 );
459 numberOfOctaves->setTarget(this);
460 numberOfOctaves->setSelector(ID_NUMBER_OF_OCTAVES);
461
462
463 onFrequencyRangeChange(NULL,0,NULL);
464 onUseLFOCheckBox(useLFOCheckBox,0,NULL);
465 }
466
onFrequencyRangeChange(FXObject * sender,FXSelector sel,void * ptr)467 long CMorphingArbitraryFIRFilterDialog::onFrequencyRangeChange(FXObject *sender,FXSelector sel,void *ptr)
468 {
469 FXGraphParamValue *g1=getGraphParam("Frequency Response 1");
470 FXGraphParamValue *g2=getGraphParam("Frequency Response 2");
471
472 FXTextParamValue *baseFrequency=getTextParam("Base Frequency");
473 FXTextParamValue *numberOfOctaves=getTextParam("Number of Octaves");
474
475 freqMapper->baseFrequency=(unsigned)baseFrequency->getValue();
476 freqMapper->numberOfOctaves=(unsigned)numberOfOctaves->getValue();
477
478 g1->updateNumbers();
479 g2->updateNumbers();
480
481 return 1;
482 }
483
onUseLFOCheckBox(FXObject * sender,FXSelector sel,void * ptr)484 long CMorphingArbitraryFIRFilterDialog::onUseLFOCheckBox(FXObject *sender,FXSelector sel,void *ptr)
485 {
486 if(((FXCheckBoxParamValue *)sender)->getValue())
487 getLFOParam("Sweep LFO")->enable();
488 else
489 getLFOParam("Sweep LFO")->disable();
490 return 1;
491 }
492
on1To2Button(FXObject * sender,FXSelector sel,void * ptr)493 long CMorphingArbitraryFIRFilterDialog::on1To2Button(FXObject *sender,FXSelector sel,void *ptr)
494 {
495 switch(FXSELID(sel))
496 {
497 case ID_COPY_1_TO_2:
498 getGraphParam("Frequency Response 2")->copyFrom(getGraphParam("Frequency Response 1"));
499 break;
500 case ID_COPY_2_TO_1:
501 getGraphParam("Frequency Response 1")->copyFrom(getGraphParam("Frequency Response 2"));
502 break;
503 case ID_SWAP_1_AND_2:
504 getGraphParam("Frequency Response 1")->swapWith(getGraphParam("Frequency Response 2"));
505 break;
506 default:
507 throw runtime_error(string(__func__)+" -- unhandled selector");
508 }
509 return 0;
510 }
511
validateOnOkay()512 bool CMorphingArbitraryFIRFilterDialog::validateOnOkay()
513 {
514 if(getGraphParam("Frequency Response 1")->getNodes().size()!=getGraphParam("Frequency Response 2")->getNodes().size())
515 {
516 Error(_("Frequency Response 1 and Frequency Response 2 must contain the same number of nodes"));
517 return false;
518 }
519 return true;
520 }
521
522 #include "../backend/Filters/CMorphingArbitraryFIRFilter.h"
getExplanation() const523 const string CMorphingArbitraryFIRFilterDialog::getExplanation() const
524 {
525 return CMorphingArbitraryFIRFilter::getExplanation();
526 }
527
528
529
530
531
532
533
534
535
536 // --- single pole lowpass ---------------
537
CSinglePoleLowpassFilterDialog(FXWindow * mainWindow)538 CSinglePoleLowpassFilterDialog::CSinglePoleLowpassFilterDialog(FXWindow *mainWindow) :
539 CActionParamDialog(mainWindow)
540 {
541 void *p=newHorzPanel(NULL);
542 addSlider(p,
543 N_("Gain"),
544 "x",
545 new CActionParamMapper_recipsym(1.0,2,2,50),
546 NULL,
547 true
548 );
549
550 addSlider(p,
551 N_("Cutoff Frequency"),
552 "Hz",
553 new CActionParamMapper_linear(500.0,5000,5,100000),
554 NULL,
555 false
556 );
557 }
558
559 // --- single pole highpass --------------
560
CSinglePoleHighpassFilterDialog(FXWindow * mainWindow)561 CSinglePoleHighpassFilterDialog::CSinglePoleHighpassFilterDialog(FXWindow *mainWindow) :
562 CActionParamDialog(mainWindow)
563 {
564 void *p=newHorzPanel(NULL);
565 addSlider(p,
566 N_("Gain"),
567 "x",
568 new CActionParamMapper_recipsym(1.0,2,2,50),
569 NULL,
570 true
571 );
572
573 addSlider(p,
574 N_("Cutoff Frequency"),
575 "Hz",
576 new CActionParamMapper_linear(1000.0,10000,5,100000),
577 NULL,
578 false
579 );
580 }
581
582 // --- bandpass --------------------------
583
CBandpassFilterDialog(FXWindow * mainWindow)584 CBandpassFilterDialog::CBandpassFilterDialog(FXWindow *mainWindow) :
585 CActionParamDialog(mainWindow)
586 {
587 void *p=newHorzPanel(NULL);
588 addSlider(p,
589 N_("Gain"),
590 "x",
591 new CActionParamMapper_recipsym(1.0,2,2,50),
592 NULL,
593 true
594 );
595
596 addSlider(p,
597 N_("Center Frequency"),
598 "Hz",
599 new CActionParamMapper_linear(1000.0,10000,5,100000),
600 NULL,
601 false
602 );
603
604 addSlider(p,
605 N_("Band Width"),
606 "Hz",
607 new CActionParamMapper_linear(500.0,1000,5,100000),
608 NULL,
609 false
610 );
611 }
612
613 // --- notch -----------------------------
614
CNotchFilterDialog(FXWindow * mainWindow)615 CNotchFilterDialog::CNotchFilterDialog(FXWindow *mainWindow) :
616 CActionParamDialog(mainWindow)
617 {
618 void *p=newHorzPanel(NULL);
619 addSlider(p,
620 N_("Gain"),
621 "x",
622 new CActionParamMapper_recipsym(1.0,2,2,50),
623 NULL,
624 true
625 );
626
627 addSlider(p,
628 N_("Center Frequency"),
629 "Hz",
630 new CActionParamMapper_linear(1000.0,10000,5,100000),
631 NULL,
632 false
633 );
634
635 addSlider(p,
636 N_("Band Width"),
637 "Hz",
638 new CActionParamMapper_linear(500.0,1000,5,100000),
639 NULL,
640 false
641 );
642 }
643
644
645
646 // --- biquad resonant lowpass -----------
647
CBiquadResLowpassFilterDialog(FXWindow * mainWindow)648 CBiquadResLowpassFilterDialog::CBiquadResLowpassFilterDialog(FXWindow *mainWindow) :
649 CActionParamDialog(mainWindow)
650 {
651 void *p=newHorzPanel(NULL);
652 addSlider(p,
653 N_("Gain"),
654 "x",
655 new CActionParamMapper_recipsym(1.0,2,2,50),
656 NULL,
657 true
658 );
659
660 addSlider(p,
661 N_("Cutoff Frequency"),
662 "Hz",
663 new CActionParamMapper_linear(500.0,5000,5,100000),
664 NULL,
665 false
666 );
667
668 addSlider(p,
669 N_("Resonance"),
670 "x",
671 new CActionParamMapper_recipsym(2.0,2,1,20),
672 NULL,
673 true
674 );
675 }
676
677 // --- biquad resonant highpass ----------
678
CBiquadResHighpassFilterDialog(FXWindow * mainWindow)679 CBiquadResHighpassFilterDialog::CBiquadResHighpassFilterDialog(FXWindow *mainWindow) :
680 CActionParamDialog(mainWindow)
681 {
682 void *p=newHorzPanel(NULL);
683 addSlider(p,
684 N_("Gain"),
685 "x",
686 new CActionParamMapper_recipsym(1.0,2,2,50),
687 NULL,
688 true
689 );
690
691 addSlider(p,
692 N_("Cutoff Frequency"),
693 "Hz",
694 new CActionParamMapper_linear(500.0,5000,5,100000),
695 NULL,
696 false
697 );
698
699 addSlider(p,
700 N_("Resonance"),
701 "x",
702 new CActionParamMapper_recipsym(2.0,2,1,20),
703 NULL,
704 true
705 );
706 }
707
708 // --- biquad resonant bandpass ----------
709
CBiquadResBandpassFilterDialog(FXWindow * mainWindow)710 CBiquadResBandpassFilterDialog::CBiquadResBandpassFilterDialog(FXWindow *mainWindow) :
711 CActionParamDialog(mainWindow)
712 {
713 void *p=newHorzPanel(NULL);
714 addSlider(p,
715 N_("Gain"),
716 "x",
717 new CActionParamMapper_recipsym(1.0,2,2,50),
718 NULL,
719 true
720 );
721
722 addSlider(p,
723 N_("Center Frequency"),
724 "Hz",
725 new CActionParamMapper_linear(500.0,5000,5,100000),
726 NULL,
727 false
728 );
729
730 addSlider(p,
731 N_("Resonance"),
732 "x",
733 new CActionParamMapper_recipsym(2.0,2,1,20),
734 NULL,
735 true
736 );
737 }
738
739