2010-01-23 19:44:49 +00:00
/**********************************************************************
Audacity : A Digital Audio Editor
Repair . cpp
Dominic Mazzoni
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /**
\ class EffectRepair
\ brief Use the interpolation code to fill in damaged audio .
Damage can include pops , clicks , or clipping . As long as the
damaged section is short and surrounded by lots of good audio ,
it is usually quite successful .
This was formerly the PopClickRemoval effect , but it was
renamed and focused on the smaller subproblem of repairing
the audio , rather than actually finding the clicks .
*/ /*******************************************************************/
2021-05-09 15:16:56 +00:00
2018-11-10 19:47:12 +00:00
# include "Repair.h"
2010-01-23 19:44:49 +00:00
# include <math.h>
# include <wx/intl.h>
# include "../InterpolateAudio.h"
2015-04-17 03:53:42 +00:00
# include "../WaveTrack.h"
2019-05-20 18:27:11 +00:00
# include "../widgets/AudacityMessageBox.h"
2015-04-17 03:53:42 +00:00
2019-01-17 23:31:08 +00:00
# include "LoadEffects.h"
2019-01-17 22:33:49 +00:00
const ComponentInterfaceSymbol EffectRepair : : Symbol
{ XO ( " Repair " ) } ;
2019-01-17 23:31:08 +00:00
namespace { BuiltinEffectsModule : : Registration < EffectRepair > reg ; }
2010-01-23 19:44:49 +00:00
EffectRepair : : EffectRepair ( )
{
}
EffectRepair : : ~ EffectRepair ( )
{
}
2018-11-02 15:31:44 +00:00
// ComponentInterface implementation
2015-04-17 03:53:42 +00:00
2018-11-02 15:31:44 +00:00
ComponentInterfaceSymbol EffectRepair : : GetSymbol ( )
2015-04-17 03:53:42 +00:00
{
2019-01-17 22:33:49 +00:00
return Symbol ;
2015-04-17 03:53:42 +00:00
}
2019-12-08 18:53:48 +00:00
TranslatableString EffectRepair : : GetDescription ( )
2015-04-17 03:53:42 +00:00
{
2019-12-08 18:53:48 +00:00
return XO ( " Sets the peak amplitude of a one or more tracks " ) ;
2015-04-17 03:53:42 +00:00
}
Automation: AudacityCommand
This is a squash of 50 commits.
This merges the capabilities of BatchCommands and Effects using a new
AudacityCommand class. AudacityCommand provides one function to specify the
parameters, and then we leverage that one function in automation, whether by chains,
mod-script-pipe or (future) Nyquist.
- Now have AudacityCommand which is using the same mechanism as Effect
- Has configurable parameters
- Has data-entry GUI (built using shuttle GUI)
- Registers with PluginManager.
- Menu commands now provided in chains, and to python batch.
- Tested with Zoom Toggle.
- ShuttleParams now can set, get, set defaults, validate and specify
the parameters.
- Bugfix: Don't overwrite values with defaults first time out.
- Add DefineParams function for all built-in effects.
- Extend CommandContext to carry output channels for results.
We abuse EffectsManager. It handles both Effects and
AudacityCommands now. In time an Effect should become a special case of
AudacityCommand and we'll split and rename the EffectManager class.
- Don't use 'default' as a parameter name.
- Massive renaming for CommandDefinitionInterface
- EffectIdentInterface becomes EffectDefinitionInterface
- EffectAutomationParameters becomes CommandAutomationParameters
- PluginType is now a bit field.
This way we can search for related types at the same time.
- Most old batch commands made into AudacityCommands.
The ones that weren't are for a reason. They are used by mod-script-pipe
to carry commands and responses across from a non-GUI thread to the GUI
thread.
- Major tidy up of ScreenshotCommand
- Reworking of SelectCommand
- GetPreferenceCommand and SetPreferenceCommand
- GetTrackInfo and SetTrackInfo
- GetInfoCommand
- Help, Open, Save, Import and Export commands.
- Removed obsolete commands ExecMenu, GetProjectInfo and SetProjectInfo
which are now better handled by other commands.
- JSONify "GetInfo: Commands" output, i.e. commas in the right places.
- General work on better Doxygen.
- Lyrics -> LyricsPanel
- Meter -> MeterPanel
- Updated Linux makefile.
- Scripting commands added into Extra menu.
- Distinct names for previously duplicated find-clipping parameters.
- Fixed longstanding error with erroneous status field number which
previously caused an ASSERT in debug.
- Sensible formatting of numbers in Chains, 0.1 not 0.1000000000137
2018-01-14 18:51:41 +00:00
// EffectDefinitionInterface implementation
2015-04-17 03:53:42 +00:00
EffectType EffectRepair : : GetType ( )
2010-01-23 19:44:49 +00:00
{
2015-04-17 03:53:42 +00:00
return EffectTypeProcess ;
2010-01-23 19:44:49 +00:00
}
2015-04-17 03:53:42 +00:00
bool EffectRepair : : IsInteractive ( )
2014-06-03 20:30:19 +00:00
{
2015-04-17 03:53:42 +00:00
return false ;
2010-01-23 19:44:49 +00:00
}
2015-04-17 03:53:42 +00:00
// Effect implementation
2010-01-23 19:44:49 +00:00
bool EffectRepair : : Process ( )
{
//v This may be too much copying for EffectRepair. To support Cancel, may be able to copy much less.
// But for now, Cancel isn't supported without this.
this - > CopyInputTracks ( ) ; // Set up mOutputTracks. //v This may be too much copying for EffectRepair.
bool bGoodResult = true ;
int count = 0 ;
2018-09-11 17:07:32 +00:00
for ( auto track : mOutputTracks - > Selected < WaveTrack > ( ) ) {
2016-09-02 12:59:27 +00:00
const
2010-01-23 19:44:49 +00:00
double trackStart = track - > GetStartTime ( ) ;
2016-09-02 12:59:27 +00:00
const double repair_t0 = std : : max ( mT0 , trackStart ) ;
const
2010-01-23 19:44:49 +00:00
double trackEnd = track - > GetEndTime ( ) ;
2016-09-02 12:59:27 +00:00
const double repair_t1 = std : : min ( mT1 , trackEnd ) ;
const
double repair_deltat = repair_t1 - repair_t0 ;
if ( repair_deltat > 0 ) { // selection is within track audio
const auto repair0 = track - > TimeToLongSamples ( repair_t0 ) ;
const auto repair1 = track - > TimeToLongSamples ( repair_t1 ) ;
const auto repairLen = repair1 - repair0 ;
2013-01-12 22:17:41 +00:00
if ( repairLen > 128 ) {
2019-12-19 19:19:51 +00:00
: : Effect : : MessageBox (
XO (
" The Repair effect is intended to be used on very short sections of damaged audio (up to 128 samples). \n \n Zoom in and select a tiny fraction of a second to repair. " ) ) ;
2013-01-12 22:17:41 +00:00
bGoodResult = false ;
break ;
}
2014-06-03 20:30:19 +00:00
2016-09-02 12:59:27 +00:00
const double rate = track - > GetRate ( ) ;
const double spacing = std : : max ( repair_deltat * 2 , 128. / rate ) ;
const double t0 = std : : max ( repair_t0 - spacing , trackStart ) ;
const double t1 = std : : min ( repair_t1 + spacing , trackEnd ) ;
const auto s0 = track - > TimeToLongSamples ( t0 ) ;
const auto s1 = track - > TimeToLongSamples ( t1 ) ;
2016-08-31 04:49:22 +00:00
// The difference is at most 2 * 128:
const auto repairStart = ( repair0 - s0 ) . as_size_t ( ) ;
2016-09-02 12:59:27 +00:00
const auto len = s1 - s0 ;
2013-01-12 22:17:41 +00:00
if ( s0 = = repair0 & & s1 = = repair1 ) {
2019-12-19 19:19:51 +00:00
: : Effect : : MessageBox (
XO (
" Repair works by using audio data outside the selection region. \n \n Please select a region that has audio touching at least one side of it. \n \n The more surrounding audio, the better it performs. " ) ) ;
/// The Repair effect needs some data to go on.\n\nPlease select an area to repair with some audio on at least one side (the more the better).") );
2013-01-12 22:17:41 +00:00
bGoodResult = false ;
break ;
}
2014-06-03 20:30:19 +00:00
2016-08-31 04:49:22 +00:00
if ( ! ProcessOne ( count , track , s0 ,
// len is at most 5 * 128.
len . as_size_t ( ) ,
repairStart ,
// repairLen is at most 128.
repairLen . as_size_t ( ) ) ) {
2013-01-12 22:17:41 +00:00
bGoodResult = false ;
break ;
}
2010-01-23 19:44:49 +00:00
}
count + + ;
}
2014-06-03 20:30:19 +00:00
this - > ReplaceProcessedTracks ( bGoodResult ) ;
2010-01-23 19:44:49 +00:00
return bGoodResult ;
}
bool EffectRepair : : ProcessOne ( int count , WaveTrack * track ,
sampleCount start ,
2016-09-06 13:19:27 +00:00
size_t len ,
size_t repairStart , size_t repairLen )
2010-01-23 19:44:49 +00:00
{
2016-04-14 16:35:15 +00:00
Floats buffer { len } ;
2021-05-23 21:43:38 +00:00
track - > GetFloats ( buffer . get ( ) , start , len ) ;
2016-04-14 16:35:15 +00:00
InterpolateAudio ( buffer . get ( ) , len , repairStart , repairLen ) ;
2010-01-23 19:44:49 +00:00
track - > Set ( ( samplePtr ) & buffer [ repairStart ] , floatSample ,
start + repairStart , repairLen ) ;
return ! TrackProgress ( count , 1.0 ) ; // TrackProgress returns true on Cancel.
}