MCPcopy Create free account
hub / github.com/audacity/audacity / NeedsDither

Method NeedsDither

libraries/lib-mixer/Mix.cpp:227–287  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

225Mixer::~Mixer() = default;
226
227std::pair<bool, sampleFormat>
228Mixer::NeedsDither(bool needsDither, double rate) const
229{
230 // This will accumulate the widest effective format of any input
231 // clip
232 auto widestEffectiveFormat = narrowestSampleFormat;
233
234 // needsDither may already be given as true.
235 // There are many other possible disqualifiers for the avoidance of dither.
236 if (std::any_of(mSources.begin(), mSources.end(),
237 std::mem_fn(&MixerSource::VariableRates))
238 )
239 // We will call MixVariableRates(), so we need nontrivial resampling
240 needsDither = true;
241
242 for (const auto &input : mSources) {
243 auto &sequence = input.GetSequence();
244
245 if (sequence.GetRate() != rate)
246 // Also leads to MixVariableRates(), needs nontrivial resampling
247 needsDither = true;
248 else if (mApplyVolume == ApplyVolume::Mixdown &&
249 !mHasMixerSpec &&
250 sequence.NChannels() > 1 && mNumChannels == 1)
251 {
252 needsDither = true;
253 }
254 else if (mApplyVolume != ApplyVolume::Discard) {
255 /// TODO: more-than-two-channels
256 for (auto c : {0, 1}) {
257 const auto volume = sequence.GetChannelVolume(c);
258 if (!(volume == 0.0 || volume == 1.0))
259 // Fractional volume may be applied even in MixSameRate
260 needsDither = true;
261 }
262 }
263 // Examine all tracks. (This ignores the time bounds for the mixer.
264 // If it did not, we might avoid dither in more cases. But if we fix
265 // that, remember that some mixers change their time bounds after
266 // construction, as when scrubbing.)
267 if (!sequence.HasTrivialEnvelope())
268 // Varying or non-unit volume may be applied even in MixSameRate
269 needsDither = true;
270 auto effectiveFormat = sequence.WidestEffectiveFormat();
271 if (effectiveFormat > mFormat)
272 // Real, not just nominal, precision loss would happen in at
273 // least one clip
274 needsDither = true;
275 widestEffectiveFormat =
276 std::max(widestEffectiveFormat, effectiveFormat);
277 }
278
279 if (needsDither)
280 // Results will be dithered to width mFormat
281 return { true, mFormat };
282 else {
283 // Results will not be dithered
284 assert(widestEffectiveFormat <= mFormat);

Callers 1

NeedsDitherPredFunction · 0.45

Calls 8

maxFunction · 0.85
beginMethod · 0.45
endMethod · 0.45
GetRateMethod · 0.45
NChannelsMethod · 0.45
GetChannelVolumeMethod · 0.45
HasTrivialEnvelopeMethod · 0.45
WidestEffectiveFormatMethod · 0.45

Tested by

no test coverage detected