Audacity 3.2.0
Repair.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 Repair.cpp
6
7 Dominic Mazzoni
8
9*******************************************************************//*******************************************************************/
22#include "Repair.h"
23
24#include <math.h>
25
26#include "AudacityMessageBox.h"
27#include "EffectOutputTracks.h"
28#include "InterpolateAudio.h"
29#include "LoadEffects.h"
30#include "WaveTrack.h"
31#include "TimeStretching.h"
32
34{ XO("Repair") };
35
37
39{
40}
41
43{
44}
45
46// ComponentInterface implementation
47
49{
50 return Symbol;
51}
52
54{
55 return XO("Sets the peak amplitude of a one or more tracks");
56}
57
58// EffectDefinitionInterface implementation
59
61{
62 return EffectTypeProcess;
63}
64
66{
67 return false;
68}
69
70// Effect implementation
71
73{
74 // This may be too much copying for EffectRepair. To support Cancel, may be
75 // able to copy much less.
76 // But for now, Cancel isn't supported without this.
77 // Repair doesn't make sense for stretched clips, so don't pass a stretch
78 // interval.
79 EffectOutputTracks outputs { *mTracks, GetType(), {} };
80 bool bGoodResult = true;
81
82 int count = 0;
83 for (auto track : outputs.Get().Selected<WaveTrack>()) {
84 const double trackStart = track->GetStartTime();
85 const double repair_t0 = std::max(mT0, trackStart);
86 const double trackEnd = track->GetEndTime();
87 const double repair_t1 = std::min(mT1, trackEnd);
88 const double repair_deltat = repair_t1 - repair_t0;
89 if (repair_deltat > 0) { // selection is within track audio
90 const auto repair0 = track->TimeToLongSamples(repair_t0);
91 const auto repair1 = track->TimeToLongSamples(repair_t1);
92 const auto repairLen = repair1 - repair0;
93 if (TimeStretching::HasPitchOrSpeed(*track, repair_t0, repair_t1)) {
95 XO(
96"The Repair effect cannot be applied within stretched or shrunk clips") );
97 bGoodResult = false;
98 break;
99 }
100 if (repairLen > 128) {
102 XO(
103"The Repair effect is intended to be used on very short sections of damaged audio (up to 128 samples).\n\nZoom in and select a tiny fraction of a second to repair.") );
104 bGoodResult = false;
105 break;
106 }
107
108 const double rate = track->GetRate();
109 const double spacing = std::max(repair_deltat * 2, 128. / rate);
110 const double t0 = std::max(repair_t0 - spacing, trackStart);
111 const double t1 = std::min(repair_t1 + spacing, trackEnd);
112
113 const auto s0 = track->TimeToLongSamples(t0);
114 const auto s1 = track->TimeToLongSamples(t1);
115 // The difference is at most 2 * 128:
116 const auto repairStart = (repair0 - s0).as_size_t();
117 const auto len = s1 - s0;
118
119 if (s0 == repair0 && s1 == repair1) {
121 XO(
122"Repair works by using audio data outside the selection region.\n\nPlease select a region that has audio touching at least one side of it.\n\nThe more surrounding audio, the better it performs.") );
124 bGoodResult = false;
125 break;
126 }
127
128 for (const auto pChannel : track->Channels())
129 if (!ProcessOne(count++, *pChannel, s0,
130 // len is at most 5 * 128.
131 len.as_size_t(),
132 repairStart,
133 // repairLen is at most 128.
134 repairLen.as_size_t())
135 ) {
136 bGoodResult = false;
137 goto done;
138 }
139 }
140 }
141done:
142
143 if (bGoodResult)
144 outputs.Commit();
145
146 return bGoodResult;
147}
148
150 sampleCount start, size_t len, size_t repairStart, size_t repairLen)
151{
152 Floats buffer{ len };
153 track.GetFloats(buffer.get(), start, len);
154 InterpolateAudio(buffer.get(), len, repairStart, repairLen);
155 if (!track.SetFloats(&buffer[repairStart],
156 start + repairStart, repairLen,
157 // little repairs shouldn't force dither on rendering:
159 ))
160 return false;
161 return !TrackProgress(count, 1.0); // TrackProgress returns true on Cancel.
162}
163
165{
166 return false;
167}
int min(int a, int b)
EffectType
@ EffectTypeProcess
XO("Cut/Copy/Paste")
void InterpolateAudio(float *buffer, const size_t len, size_t firstBad, size_t numBad)
@ narrowestSampleFormat
Two synonyms for previous values that might change if more values were added.
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
double mT1
Definition: EffectBase.h:114
std::shared_ptr< TrackList > mTracks
Definition: EffectBase.h:107
double mT0
Definition: EffectBase.h:113
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Definition: Effect.cpp:343
Performs effect computation.
Use this object to copy the input tracks to tentative outputTracks.
bool ProcessOne(int count, WaveChannel &track, sampleCount start, size_t len, size_t repairStart, size_t repairLen)
Definition: Repair.cpp:149
EffectType GetType() const override
Type determines how it behaves.
Definition: Repair.cpp:60
ComponentInterfaceSymbol GetSymbol() const override
Definition: Repair.cpp:48
bool IsInteractive() const override
Whether the effect needs a dialog for entry of settings.
Definition: Repair.cpp:65
bool Process(EffectInstance &instance, EffectSettings &settings) override
Definition: Repair.cpp:72
virtual ~EffectRepair()
Definition: Repair.cpp:42
EffectRepair()
Definition: Repair.cpp:38
TranslatableString GetDescription() const override
Definition: Repair.cpp:53
bool NeedsDither() const override
Definition: Repair.cpp:164
static const ComponentInterfaceSymbol Symbol
Definition: Repair.h:21
static int DoMessageBox(const EffectPlugin &plugin, const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
Holds a msgid for the translation catalog; may also bind format arguments.
bool SetFloats(const float *buffer, sampleCount start, size_t len, sampleFormat effectiveFormat=widestSampleFormat)
Random-access assignment of a range of samples.
Definition: WaveTrack.h:162
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
"narrow" overload fetches from the unique channel
Definition: WaveTrack.h:129
A Track that contains audio waveform data.
Definition: WaveTrack.h:203
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
WAVE_TRACK_API bool HasPitchOrSpeed(const WaveTrack &track, double t0, double t1)
BuiltinEffectsModule::Registration< EffectRepair > reg
Definition: Repair.cpp:36
Externalized state of a plug-in.