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 "RemasterActionDialogs.h"
22 
23 #include <istring>
24 
25 #include "CFOXIcons.h"
26 
27 #include "../backend/CActionSound.h"
28 #include "../backend/CActionParameters.h"
29 #include "../backend/CSound.h"
30 
31 #include "../backend/ActionParamMappers.h"
32 
33 
34 // --- balance ------------------------
35 
36 #include "../backend/Remaster/CBalanceAction.h"
37 static const double ret_balance(const double x) { return x/100.0; }
38 
39 CSimpleBalanceActionDialog::CSimpleBalanceActionDialog(FXWindow *mainWindow) :
40 	CActionParamDialog(mainWindow)
41 {
42 	void *p0=newVertPanel(NULL,true);
43 		void *p1=newHorzPanel(p0,false);
44 			void *p2=newVertPanel(p1,false);
45 				vector<string> items;
46 				addComboTextEntry(p2,
47 					N_("Channel A"),
48 					items,
49 					CActionParamDialog::cpvtAsInteger,
50 					""
51 				);
52 
53 				addComboTextEntry(p2,
54 					N_("Channel B"),
55 					items,
56 					CActionParamDialog::cpvtAsInteger,
57 					""
58 				);
59 
60 
61 			CActionParamMapper_linear_bipolar *m=new CActionParamMapper_linear_bipolar(0.0,100,100);
62 			m->setMultiplier(-1.0);
63 			addSlider(p1,
64 				N_("Balance"),
65 				"%",
66 				m,
67 				ret_balance,
68 				false
69 			);
70 
71 			vector<string> balanceTypes;
72 			balanceTypes.push_back(N_("Strict Balance"));
73 			balanceTypes.push_back(N_("1x Pan"));
74 			balanceTypes.push_back(N_("2x Pan"));
75 		addComboTextEntry(p0,
76 			N_("Balance Type"),
77 			balanceTypes,
78 			CActionParamDialog::cpvtAsInteger,
79 			CBalanceAction::getBalanceTypeExplanation()
80 		);
81 		/* not possible
82 			vector<FXIcon *> balanceTypeIcons;
83 			balanceTypeIcons.push_back(FOXIcons->Falling_Sawtooth_Wave___0_1_);
84 			balanceTypeIcons.push_back(FOXIcons->Falling_Sawtooth_Wave___0_1_);
85 			balanceTypeIcons.push_back(FOXIcons->Falling_Sawtooth_Wave___0_1_);
86 		getComboText("Balance Type")->setIcons(balanceTypeIcons);
87 		*/
88 }
89 
90 bool CSimpleBalanceActionDialog::show(CActionSound *actionSound,CActionParameters *actionParameters)
91 {
92 	// exact same implementation as CCurvedBalanceActionDialog::show()
93 
94 	if(actionSound->sound->getChannelCount()<2)
95 		return false;
96 	else
97 	{
98 		if(getComboText("Channel A")->getItems().size()!=actionSound->sound->getChannelCount()) // don't alter selected channels if they didn't change in number
99 		{
100 			vector<string> items;
101 			for(size_t t=0;t<actionSound->sound->getChannelCount();t++)
102 				items.push_back(_("Channel ")+istring(t));
103 
104 			// set the combo boxes according to actionSound
105 			getComboText("Channel A")->setItems(items);
106 			getComboText("Channel B")->setItems(items);
107 			getComboText("Channel A")->setCurrentItem(0);
108 			getComboText("Channel B")->setCurrentItem(1);
109 		}
110 
111 		return CActionParamDialog::show(actionSound,actionParameters);
112 	}
113 }
114 
115 
116 
117 CCurvedBalanceActionDialog::CCurvedBalanceActionDialog(FXWindow *mainWindow) :
118 	CActionParamDialog(mainWindow)
119 {
120 	void *p0=newVertPanel(NULL,true);
121 		void *p1=newHorzPanel(p0,false);
122 			void *p2=newVertPanel(p1,false);
123 				vector<string> items;
124 				addComboTextEntry(p2,
125 					N_("Channel A"),
126 					items,
127 					CActionParamDialog::cpvtAsInteger,
128 					""
129 				);
130 
131 				addComboTextEntry(p2,
132 					N_("Channel B"),
133 					items,
134 					CActionParamDialog::cpvtAsInteger,
135 					""
136 				);
137 
138 			CActionParamMapper_linear_bipolar *m=new CActionParamMapper_linear_bipolar(0.0,100,100);
139 			m->setMultiplier(-1.0);
140 			addGraphWithWaveform(p1,
141 				N_("Balance Curve"),
142 				N_("Balance"),
143 				"%",
144 				m,
145 				ret_balance
146 			);
147 
148 		vector<string> balanceTypes;
149 		balanceTypes.push_back(N_("Strict Balance"));
150 		balanceTypes.push_back(N_("1x Pan"));
151 		balanceTypes.push_back(N_("2x Pan"));
152 		addComboTextEntry(p0,
153 			N_("Balance Type"),
154 			balanceTypes,
155 			CActionParamDialog::cpvtAsInteger,
156 			CBalanceAction::getBalanceTypeExplanation()
157 		);
158 }
159 
160 bool CCurvedBalanceActionDialog::show(CActionSound *actionSound,CActionParameters *actionParameters)
161 {
162 	// exact same implementation as CSimpleBalanceActionDialog::show()
163 
164 	if(actionSound->sound->getChannelCount()<2)
165 		return false;
166 	else
167 	{
168 		if(getComboText("Channel A")->getItems().size()!=actionSound->sound->getChannelCount()) // don't alter selected channels if they didn't change in number
169 		{
170 			vector<string> items;
171 			for(size_t t=0;t<actionSound->sound->getChannelCount();t++)
172 				items.push_back(_("Channel ")+istring(t));
173 
174 			// set the combo boxes according to actionSound
description(&self) -> &str175 			getComboText("Channel A")->setItems(items);
176 			getComboText("Channel B")->setItems(items);
177 			getComboText("Channel A")->setCurrentItem(0);
178 			getComboText("Channel B")->setCurrentItem(1);
179 		}
180 
181 		return CActionParamDialog::show(actionSound,actionParameters);
glob(&self) -> Option<&str>182 	}
183 }
184 
185 
186 
187 
188 
189 // --- monoize -----------------------------
190 
191 static const double retconv_monoize(const double x) { return x/100.0 ; }
192 
description(&self) -> &str193 CMonoizeActionDialog::CMonoizeActionDialog(FXWindow *mainWindow) :
194 	CActionParamDialog(mainWindow,true,"",FXModalDialogBox::stShrinkWrap)
195 {
196 		void *p0=newVertPanel(NULL);
197 			void *p1=newHorzPanel(p0,false);
198 			for(unsigned t=0;t<MAX_CHANNELS;t++)
199 			{
200 				addSlider(p1,
201 					N_("Channel ")+istring(t),
202 					"%",
203 					new CActionParamMapper_linear(100.0,100),
204 					retconv_monoize,
205 					false
206 				);
207 			}
208 
209 			vector<string> options;
210 			options.push_back(N_("Remove All But One Channel"));
211 			options.push_back(N_("Make All Channels The Same"));
212 			addComboTextEntry(p0,
213 				N_("Method"),
214 				options,
215 				CActionParamDialog::cpvtAsInteger
216 			);
217 }
218 
219 bool CMonoizeActionDialog::show(CActionSound *actionSound,CActionParameters *actionParameters)
220 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result221 	if(actionSound->sound->getChannelCount()<1)
222 		return false;
223 	else
224 	{
225 		for(unsigned t=0;t<MAX_CHANNELS;t++)
226 			showControl(N_("Channel ")+istring(t), t<actionSound->sound->getChannelCount() );
227 
228 		return CActionParamDialog::show(actionSound,actionParameters);
229 	}
230 }
231 
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result232 
233 // --- noise gate --------------------------
234 
235 CNoiseGateDialog::CNoiseGateDialog(FXWindow *mainWindow) :
236 	CActionParamDialog(mainWindow)
237 {
238 	void *p=newHorzPanel(NULL);
239 		addSlider(p,
240 			N_("Window Time"),
241 			"ms",
242 			new CActionParamMapper_linear(35.0,30,5,1000),
243 			NULL,
244 			false
245 		);
246 
247 		addSlider(p,
248 			N_("Threshold"),
249 			"dBFS",
250 			new CActionParamMapper_dBFS(-30.0),
251 			NULL,
252 			false
253 		);
254 
255 		addSlider(p,
256 			N_("Gain Attack Time"),
257 			"ms",
258 			new CActionParamMapper_linear(10.0,30,5,1000),
259 			NULL,
260 			false
261 		);
262 
263 		addSlider(p,
264 			N_("Gain Release Time"),
265 			"ms",
266 			new CActionParamMapper_linear(10.0,30,5,1000),
267 			NULL,
268 			false
269 		);
270 }
271 
272 #include "../backend/Remaster/CNoiseGateAction.h"
273 const string CNoiseGateDialog::getExplanation() const
274 {
275 	return CNoiseGateAction::getExplanation();
276 }
277 
278 
279 
280 // --- compressor --------------------------
281 
282 CCompressorDialog::CCompressorDialog(FXWindow *mainWindow) :
283 	CActionParamDialog(mainWindow)
284 {
empty() -> GlobSet285 	void *p0=newVertPanel(NULL,true);
286 		void *p1=newHorzPanel(p0,false);
287 			addSlider(p1,
288 				N_("Window Time"),
289 				"ms",
290 				new CActionParamMapper_linear_range_scaled(35.0,.1,100,1,1,10),
is_empty(&self) -> bool291 				NULL,
292 				false
293 			);
294 
295 			addSlider(p1,
296 				N_("Threshold"),
len(&self) -> usize297 				"dBFS",
298 				new CActionParamMapper_dBFS(-12.0),
299 				NULL,
300 				false
301 			);
is_match<P: AsRef<Path>>(&self, path: P) -> bool302 
303 			addSlider(p1,
304 				N_("Ratio"),
305 				":1",
306 				new CActionParamMapper_linear_min_to_scalar(2.0,1,6,2,20),
307 				NULL,
308 				false
309 			);
is_match_candidate(&self, path: &Candidate<'_>) -> bool310 
311 			addSlider(p1,
312 				N_("Attack Time"),
313 				"ms",
314 				new CActionParamMapper_parabola_range(10.0,0.1,100.0),
315 				NULL,
316 				false
317 			);
318 
319 			addSlider(p1,
320 				N_("Release Time"),
321 				"ms",
322 				new CActionParamMapper_parabola_range(50.0,1.0,1000.0),
323 				NULL,
matches<P: AsRef<Path>>(&self, path: P) -> Vec<usize>324 				false
325 			);
326 
327 			addSlider(p1,
328 				N_("Input Gain"),
329 				"x",
330 				new CActionParamMapper_recipsym(1.0,10,0,0),
331 				NULL,
332 				true
matches_candidate(&self, path: &Candidate<'_>) -> Vec<usize>333 			);
334 
335 			addSlider(p1,
336 				N_("Output Gain"),
337 				"x",
338 				new CActionParamMapper_recipsym(1.0,10,0,0),
339 				NULL,
340 				true
341 			);
342 
343 		p1=newVertPanel(p0,false);
344 			addCheckBoxEntry(p1,
345 				N_("Lock Channels"),
346 				true,
347 				_("This Toggles That Compression Should be Applied to Both Channels when Either Channel Needs Compression")
matches_into<P: AsRef<Path>>( &self, path: P, into: &mut Vec<usize>, )348 			);
349 
350 			addCheckBoxEntry(p1,
351 				N_("Look Ahead For Level"),
352 				true,
353 				_("This Toggles That the Compressor Should Look Ahead (by Half the Window Time Amount) in the Input Signal When Calculating the Level of the Input Signal")
354 			);
355 }
356 
357 // ??? remove this before 1.0 and make sure it is up-to-standard as far as a compressor goes before 1.0
358 #include "../backend/Remaster/CCompressorAction.h"
359 const string CCompressorDialog::getExplanation() const
360 {
361 	return CCompressorAction::getExplanation();
362 }
363 
364 
matches_candidate_into( &self, path: &Candidate<'_>, into: &mut Vec<usize>, )365 // --- normalize ---------------------------
366 
367 CNormalizeDialog::CNormalizeDialog(FXWindow *mainWindow) :
368 	CActionParamDialog(mainWindow)
369 {
370 	void *p1=newVertPanel(NULL);
371 		void *p2=newHorzPanel(p1,false);
372 			addSlider(p2,
373 				N_("Normalization Level"),
374 				"dBFS",
375 				new CActionParamMapper_dBFS(-0.5),
376 				NULL,
377 				false
378 			);
379 
380 			CActionParamMapper_linear_range *m=new CActionParamMapper_linear_range(1.0,1.0,100.0);
381 			m->floorTheValue(true);
382 			addSlider(p2,
383 				N_("Region Count"),
384 				"",
385 				m,
386 				NULL,
387 				false
388 			);
389 
390 		p2=newVertPanel(p1,false);
391 			addCheckBoxEntry(p2,
392 				N_("Lock Channels"),
393 				true,
394 				_("Calculate Maximum Sample Value in a Region Across All Channels")
395 			);
396 }
397 
398 
399 // --- adaptive normalize ------------------
400 
401 CAdaptiveNormalizeDialog::CAdaptiveNormalizeDialog(FXWindow *mainWindow) :
402 	CActionParamDialog(mainWindow)
403 {
404 	void *p1=newVertPanel(NULL);
405 		void *p2=newHorzPanel(p1,false);
406 			addSlider(p2,
407 				N_("Normalization Level"),
408 				"dBFS",
409 				new CActionParamMapper_dBFS(-20.0),
410 				NULL,
411 				false
412 			);
413 
414 			addSlider(p2,
415 				N_("Window Time"),
416 				"ms",
417 				new CActionParamMapper_linear_range_scaled(2000.0,10,1000,1,1,100),
418 				NULL,
419 				false
420 			);
421 
422 			addSlider(p2,
423 				N_("Maximum Gain"),
424 				"dB",
425 				new CActionParamMapper_linear(60.0,100,1,200),
426 				NULL,
427 				true
428 			);
429 
430 		p2=newVertPanel(p1,false);
431 			addCheckBoxEntry(p2,
432 				N_("Lock Channels"),
433 				true,
434 				_("Calculate Signal Level Across All Channels Simultaneously")
435 			);
436 }
437 
438 #include "../backend/Remaster/CAdaptiveNormalizeAction.h"
439 const string CAdaptiveNormalizeDialog::getExplanation() const
440 {
441 	return CAdaptiveNormalizeAction::getExplanation();
442 }
443 
444 // --- mark quiet areas --------------------
445 
446 CMarkQuietAreasDialog::CMarkQuietAreasDialog(FXWindow *mainWindow) :
447 	CActionParamDialog(mainWindow)
448 {
449 	FXConstantParamValue *t;
450 	void *p1=newVertPanel(NULL);
default() -> Self451 		void *p2=newHorzPanel(p1,false);
452 			t=addSlider(p2,
453 				N_("Threshold for Quiet"),
454 				"dBFS",
455 				new CActionParamMapper_dBFS(-48.0),
456 				NULL,
457 				false
458 			);
459 			t->setTipText(_("An audio level below this threshold is considered to be quiet."));
460 
461 			t=addSlider(p2,
462 				N_("Must Remain Quiet for"),
463 				"ms",
464 				new CActionParamMapper_linear(500,1000,10,10000),
465 				NULL,
466 				false
new() -> GlobSetBuilder467 			);
468 			t->setTipText(_("The audio level must remain below the threshold for this long before a beginning cue will be added."));
469 
470 			t=addSlider(p2,
471 				N_("Must Remain Unquiet for"),
472 				"ms",
473 				new CActionParamMapper_linear(0,1000,10,10000),
build(&self) -> Result<GlobSet, Error>474 				NULL,
475 				false
476 			);
477 			t->setTipText(_("After the beginning of a quiet area has been detected the audio level must rise above the threshold for this long for an ending cue to be added."));
478 
add(&mut self, pat: Glob) -> &mut GlobSetBuilder479 			t=addSlider(p2,
480 				N_("Level Detector Window Time"),
481 				"ms",
482 				new CActionParamMapper_linear_range_scaled(35.0,.1,100,1,1,10),
483 				NULL,
484 				false
485 			);
486 			t->setTipText(_("This is the length of the window of audio to analyze for detecting the audio level."));
487 
488 		p2=newVertPanel(p1,false);
489 			addStringTextEntry(p2,
490 				N_("Quiet Begin Cue Name"),
491 				"[",
492 				_("What to Name a Cue That Marks Beginning of a Quiet Region")
493 			);
494 
495 			addStringTextEntry(p2,
496 				N_("Quiet End Cue Name"),
497 				"]",
498 				_("What to Name a Cue That Marks End of a Quiet Region")
499 			);
new<P: AsRef<Path> + ?Sized>(path: &'a P) -> Candidate<'a>500 }
501 
502 
503 // --- shorten quiet areas --------------------
504 
505 CShortenQuietAreasDialog::CShortenQuietAreasDialog(FXWindow *mainWindow) :
506 	CActionParamDialog(mainWindow)
507 {
508 	FXConstantParamValue *t;
509 	void *p1=newVertPanel(NULL);
510 		void *p2=newHorzPanel(p1,false);
511 			t=addSlider(p2,
512 				N_("Threshold for Quiet"),
513 				"dBFS",
514 				new CActionParamMapper_dBFS(-48.0),
515 				NULL,
516 				false
517 			);
518 			t->setTipText(_("An audio level below this threshold is considered to be quiet."));
519 
520 			t=addSlider(p2,
521 				N_("Must Remain Quiet for"),
522 				"ms",
523 				new CActionParamMapper_linear(500,1000,10,10000),
524 				NULL,
525 				false
526 			);
527 			t->setTipText(_("The audio level must remain below the threshold for this long before a beginning cue will be added."));
528 
529 			t=addSlider(p2,
530 				N_("Must Remain Unquiet for"),
531 				"ms",
532 				new CActionParamMapper_linear(0,1000,10,10000),
533 				NULL,
534 				false
535 			);
536 			t->setTipText(_("After the beginning of a quiet area has been detected the audio level must rise above the threshold for this long for an ending cue to be added."));
537 
538 			t=addSlider(p2,
539 				N_("Level Detector Window Time"),
540 				"ms",
541 				new CActionParamMapper_linear_range_scaled(35.0,.1,100,1,1,10),
542 				NULL,
543 				false
544 			);
545 			t->setTipText(_("This is the length of the window of audio to analyze for detecting the audio level."));
546 
547 			t=addSlider(p2,
548 				N_("Shorten Found Area To"),
549 				"x",
550 				new CActionParamMapper_linear(0.5,1,1,1),
551 				NULL,
552 				false
553 			);
554 			t->setTipText(_("When a quiet area is found it will be shorted to this much of its original length."));
555 }
556 
557 
558 // --- resample ----------------------------
559 
560 CResampleDialog::CResampleDialog(FXWindow *mainWindow) :
561 	CActionParamDialog(mainWindow,false)
562 {
563 	vector<string> items;
564 	items.push_back("4000");
565 	items.push_back("8000");
566 	items.push_back("11025");
567 	items.push_back("22050");
568 	items.push_back("44100");
569 	items.push_back("48000");
570 	items.push_back("88200");
new() -> LiteralStrategy571 	items.push_back("96000");
572 
573 	void *p0=newVertPanel(NULL);
574 		addComboTextEntry(p0,
add(&mut self, global_index: usize, lit: String)575 			N_("New Sample Rate"),
576 			items,
577 			CActionParamDialog::cpvtAsInteger,
578 			"",
579 			true
580 		);
581 			getComboText("New Sample Rate")->setIntegerValue(44100);
582 }
583 
matches_into( &self, candidate: &Candidate<'_>, matches: &mut Vec<usize>, )584 
585 // --- change pitch ------------------------
586 
587 CChangePitchDialog::CChangePitchDialog(FXWindow *mainWindow) :
588 	CActionParamDialog(mainWindow,false)
589 {
590 	FXPacker *p0=newVertPanel(NULL);
591 	FXPacker *p1=new FXTabBook(p0,NULL,0,TABBOOK_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_NONE, 0,0,0,0, 0,0,0,0);
592 
593 		new FXTabItem((FXTabBook *)p1,_("Pitch"),NULL,TAB_TOP_NORMAL);
594 		FXPacker *p2=newHorzPanel(p1,true,true);
595 			addSlider(
596 				p2,
597 				N_("Semitones"),
598 				_("semitones"),
599 				new CActionParamMapper_linear_bipolar(1,7,60),
600 				NULL,
601 				true);
602 
603 		FXConstantParamValue *s;
604 
605 		new FXTabItem((FXTabBook *)p1,_("Tweaking"),NULL,TAB_TOP_NORMAL);
606 		p2=newVertPanel(p1,true,true);
607 			new FXLabel(p2,_("CAUTION: Some of combinations of these parameters cause the SoundTouch library to generate assertion errors \n that kill the current process.  It is not difficult to cause ReZound to exit by adjusting these parameters.  \n Play with these parameters with some testing data, and then save presets that do not cause problems.  \n Hopefully this issue will be worked out in the future.\nSee the SoundTouch header file for more information about these parameters."));
608 			FXPacker *p3=newHorzPanel(p2,false,false);
609 				addCheckBoxEntry(p3,
610 					N_("Use Anti-alias Filter"),
611 					true,
612 					_("Enable/disable anti-alias filter in pitch transposer")
613 				);
614 
615 				CActionParamMapper_linear_range *aafl_m=new CActionParamMapper_linear_range(32,8,128);
616 				aafl_m->floorTheValue(true);
617 				addSlider(p3,
618 					N_("Anti-alias Filter Length"),
619 					"taps",
620 					aafl_m,
621 					NULL,
622 					false
623 				);
624 
625 				addCheckBoxEntry(p3,
626 					N_("Use Quick Seek"),
627 					false,
628 					_("Enable/disable quick seeking algorithm in tempo changer routine (enabling quick seeking lowers CPU utilization but causes a minor sound quality compromising)")
629 				);
630 
631 				CActionParamMapper_linear_range *sl_m=new CActionParamMapper_linear_range(82,1,500);
632 				sl_m->floorTheValue(true);
633 				s=addSlider(p3,
634 					N_("Sequence Length"),
635 					"ms",
636 					sl_m,
637 					NULL,
638 					false
639 				);
640 				s->setTipText(_("This is the default length of a single processing sequence, in milliseconds. Determines to how long sequences the original sound is chopped in time-stretch algorithm. The larger this value is, the lesser sequences are used in processing. In principle a bigger value sounds better when slowing down tempo, but worse when increasing tempo and vice versa."));
641 
642 				CActionParamMapper_linear_range *swl_m=new CActionParamMapper_linear_range(28,1,500);
643 				swl_m->floorTheValue(true);
644 				s=addSlider(p3,
645 					N_("Seek Window Length"),
646 					"ms",
647 					swl_m,
648 					NULL,
649 					false
650 				);
651 				s->setTipText(_("Seeking window default length in milliseconds for algorithm that seeks for the best possible overlapping location. This determines from how wide sample 'window' the algorithm can look for an optimal mixing location when the sound sequences are to be linked back together.  The bigger this window setting is, the higher the possibility to find a better mixing position becomes, but at the same time large values may cause a 'drifting' sound artifact because neighbouring sequences can be chosen at more uneven intervals. If there's a disturbing artifact that sounds as if a constant frequency was drifting around, try reducing this setting."));
652 
653 				CActionParamMapper_linear_range *ol_m=new CActionParamMapper_linear_range(28,1,500);
654 				ol_m->floorTheValue(true);
655 				s=addSlider(p3,
656 					N_("Overlap Length"),
657 					"ms",
658 					ol_m,
659 					NULL,
660 					false
661 				);
662 				s->setTipText(_("Overlap length in milliseconds. When the chopped sound sequences are mixed back together to form again a continuous sound stream, this parameter defines over how long period the two consecutive sequences are allowed to overlap each other.  This shouldn't be that critical of a parameter. If you reduce the 'Sequence Length' setting by a large amount, you might wish to try a smaller value on this."));
663 }
664 
665 
666 // --- change tempo ------------------------
667 
668 CChangeTempoDialog::CChangeTempoDialog(FXWindow *mainWindow) :
669 	CActionParamDialog(mainWindow,false)
670 {
is_match(&self, candidate: &Candidate<'_>) -> bool671 	FXPacker *p0=newVertPanel(NULL);
672 	FXPacker *p1=new FXTabBook(p0,NULL,0,TABBOOK_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_NONE, 0,0,0,0, 0,0,0,0);
673 
674 		new FXTabItem((FXTabBook *)p1,_("Pitch"),NULL,TAB_TOP_NORMAL);
675 		FXPacker *p2=newHorzPanel(p1,true,true);
676 
677 			addSlider(
678 				p2,
679 				N_("Tempo Change"),
680 				"x",
matches_into( &self, candidate: &Candidate<'_>, matches: &mut Vec<usize>, )681 				new CActionParamMapper_recipsym(0.9,2,1,10),
682 				NULL,
683 				true);
684 
685 		FXConstantParamValue *s;
686 
687 		new FXTabItem((FXTabBook *)p1,_("Tweaking"),NULL,TAB_TOP_NORMAL);
688 		p2=newVertPanel(p1,true,true);
689 			new FXLabel(p2,_("CAUTION: Some of combinations of these parameters cause the SoundTouch library to generate assertion errors \n that kill the current process.  It is not difficult to cause ReZound to exit by adjusting these parameters.  \n Play with these parameters with some testing data, and then save presets that do not cause problems.  \n Hopefully this issue will be worked out in the future.\nSee the SoundTouch header file for more information about these parameters."));
690 			FXPacker *p3=newHorzPanel(p2,false,false);
691 				addCheckBoxEntry(p3,
692 					N_("Use Anti-alias Filter"),
693 					true,
694 					_("Enable/disable anti-alias filter in pitch transposer")
695 				);
696 
697 				CActionParamMapper_linear_range *aafl_m=new CActionParamMapper_linear_range(32,8,128);
698 				aafl_m->floorTheValue(true);
699 				addSlider(p3,
700 					N_("Anti-alias Filter Length"),
701 					"taps",
702 					aafl_m,
is_match(&self, candidate: &Candidate<'_>) -> bool703 					NULL,
704 					false
705 				);
706 
707 				addCheckBoxEntry(p3,
708 					N_("Use Quick Seek"),
709 					false,
710 					_("Enable/disable quick seeking algorithm in tempo changer routine (enabling quick seeking lowers CPU utilization but causes a minor sound quality compromising)")
711 				);
712 
matches_into( &self, candidate: &Candidate<'_>, matches: &mut Vec<usize>, )713 				CActionParamMapper_linear_range *sl_m=new CActionParamMapper_linear_range(82,1,500);
714 				sl_m->floorTheValue(true);
715 				s=addSlider(p3,
716 					N_("Sequence Length"),
717 					"ms",
718 					sl_m,
719 					NULL,
720 					false
721 				);
722 				s->setTipText(_("This is the default length of a single processing sequence, in milliseconds. Determines to how long sequences the original sound is chopped in time-stretch algorithm. The larger this value is, the lesser sequences are used in processing. In principle a bigger value sounds better when slowing down tempo, but worse when increasing tempo and vice versa."));
723 
724 				CActionParamMapper_linear_range *swl_m=new CActionParamMapper_linear_range(28,1,500);
725 				swl_m->floorTheValue(true);
726 				s=addSlider(p3,
727 					N_("Seek Window Length"),
728 					"ms",
729 					swl_m,
730 					NULL,
is_match(&self, candidate: &Candidate<'_>) -> bool731 					false
732 				);
733 				s->setTipText(_("Seeking window default length in milliseconds for algorithm that seeks for the best possible overlapping location. This determines from how wide sample 'window' the algorithm can look for an optimal mixing location when the sound sequences are to be linked back together.  The bigger this window setting is, the higher the possibility to find a better mixing position becomes, but at the same time large values may cause a 'drifting' sound artifact because neighbouring sequences can be chosen at more uneven intervals. If there's a disturbing artifact that sounds as if a constant frequency was drifting around, try reducing this setting."));
734 
735 				CActionParamMapper_linear_range *ol_m=new CActionParamMapper_linear_range(28,1,500);
736 				ol_m->floorTheValue(true);
737 				s=addSlider(p3,
738 					N_("Overlap Length"),
739 					"ms",
740 					ol_m,
741 					NULL,
742 					false
743 				);
744 				s->setTipText(_("Overlap length in milliseconds. When the chopped sound sequences are mixed back together to form again a continuous sound stream, this parameter defines over how long period the two consecutive sequences are allowed to overlap each other.  This shouldn't be that critical of a parameter. If you reduce the 'Sequence Length' setting by a large amount, you might wish to try a smaller value on this."));
745 }
746 
747