8000 3 Hz high-pass filter is causing severe generational loss · Issue #434 · xiph/opus · GitHub
[go: up one dir, main page]

Skip to content

3 Hz high-pass filter is causing severe generational loss #434

Open

Description

@Mr-Z-2697

dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);

First introduced in: 0869829

I know this is not a general use case, but maybe worth to take a look?

Activity

  1. jmvalin commented on Sep 15, 2025

    @jmvalin
    Member

    Care to elaborate a bit?

  2. Mr-Z-2697 commented on Sep 15, 2025

    @Mr-Z-2697
    Author

    The audio is recursively decoded and encoded without any other alteration, there's an unusual amount of artifacts.
    By restoring the code back to the pcm samples copying behavior, the artifacts are gone, or at least imperceptible.
    The samples are using 512 kbps VBR, yes, even the highest bitrate won't save it.
    sample.7z.gz

    Some additional discussion at:
    https://forum.doom9.org/showthread.php?t=186465&page=3

  3. Mr-Z-2697 commented on Sep 17, 2025

    @Mr-Z-2697
    Author

    May I ask what are the reasons of adding this DC rejection filter, other than to address the problem with DC offset?
    Not all audio have DC offset problem, in fact they should and will be actively corrected in mixing stage.
    While not all audio being encoded by libopus will have gone through mixing stage, it's still not worth risking all audios just for a few problematic ones, since we now know the damage it can do, rather than being inaudible.

    My suggestion is following the guidance of this philosophy:

    Does Opus have an echo canceller like Speex does?
    Echo cancellation is completely independent from codecs.
    You can use any echo canceller (including the one from libspeexdsp) along with Opus.

    DC rejection is completely independent from codecs.
    You can use any DC rejector (including the one from libopus???) along with Opus.

    Or at least make it adaptive.

  4. Mr-Z-2697 commented on Sep 30, 2025

    @Mr-Z-2697
    Author

    Hello, it's been 2 weeks, do we have any progress?

  5. jmvalin commented on Oct 7, 2025

    @jmvalin
    Member

    DC rejection is linked to how each Opus component works and (e.g.) is different for SILK and CELT. Due to the CELT design, DC can mess up the coding and produce LF noise (which is why it got added). Now there may be ways to improve it, but it is needed in some form.

  6. Mr-Z-2697 commented on Oct 7, 2025

    @Mr-Z-2697
    Author

    My point is that not all audio has DC offset, or do you mean any waveform that might at some point "dip" below 3 Hz is considered has DC offset?
    Some LF noise is probably better (or "less bad") than generational loss?

  7. Mr-Z-2697 commented on Oct 9, 2025

    @Mr-Z-2697
    Author

    Now there may be ways to improve it

    Making it optional is the first step to improve it.

  8. jmvalin commented on Oct 22, 2025

    @jmvalin
    Member

    Making it optional is an API change so we'd need to be sure to get it right. Also, the proposed patch would glitch when you change the setting mid-stream, which I'd like to avoid. There may be other side effect that I haven't thought about too. So before betting there I'd like to understand what real problem this is causing. Can you explain a bit more?

  9. Mr-Z-2697 commented on Oct 22, 2025

    @Mr-Z-2697
    Author

    Well, it may be hard to find someone that encode the audio stream dozens of times, so in reality the problem could be "nothing".
    But it's not hard to imagine, if there's severe generational loss, then maybe the very first pass already has some imperceptible problem.
    And yes, this is a lossy codec, but a loss caused by unnecessary filtering (for most streams) is better avoided, don't you think?

  10. jmvalin commented on Oct 23, 2025

    @jmvalin
    Member

    So you're seeing much better tandeming performance without the high-pass than with the high-pass. Is that only for synchronous tandeming (i.e. encode/decode always with the same alignment) or are you also seeing that with asynchronous tandeming (random alignment every time)? The latter tends to be much worse, so I'm curious if the filtering makes a difference in that case.

  11. Mr-Z-2697 commented on Oct 24, 2025

    @Mr-Z-2697
    Author

    To my surprise, the unalignment makes this generational loss almost gone, tested at 512 kbps to minimize side effects, but of course the other generational loss caused by unalignment is much, much worse when bitrate is lower.

  12. Mr-Z-2697 commented on Oct 25, 2025

    @Mr-Z-2697
    Author

    Is qext the intended fix for this, I mean among the other features it has, is this one of them?

  13. jmvalin commented on Oct 25, 2025

    @jmvalin
    Member

    qext is a totally different thing. See https://datatracker.ietf.org/doc/draft-ietf-mlcodec-opus-scalable-quality-extension/
    But in any case, it doesn't seem like the DC high-pass filter is hurting the general trandeming case.

  14. Mr-Z-2697 commented on Oct 26, 2025

    @Mr-Z-2697
    Author

    I mean qext effectively disables the dc rejection filter.

    opus/src/opus_encoder.c

    Lines 1927 to 1932 in 43efb99

    #ifdef ENABLE_QEXT
    /* FIXME: Avoid glitching when we switch qext on/off dynamically. */
    if (st->enable_qext) OPUS_COPY(&pcm_buf[total_buffer*st->channels], pcm, frame_size*st->channels);
    else
    #endif
    dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);

  15. Mr-Z-2697 commented on Nov 4, 2025

    @Mr-Z-2697
    Author

    it doesn't seem like the DC high-pass filter is hurting the general trandeming case.

    So, is this issue a "won't fix"?

  16. a5632645 commented on Dec 15, 2025

    @a5632645

    Why do you use an IIR high pass filter instead of simply taking the average of a block and then subtracting that value?

  17. jmvalin commented on Dec 15, 2025

    @jmvalin
    Member

    That would result in a cutoff frequency around 50 Hz (or more for smaller frame sizes), along with blocking artifacts.

  18. ValeZAA commented on Aug 12, 2026

    @ValeZAA

    You claim CELT coding tool is causing LF noise because of 3 Hz stuff.

    But generational loss overall is higher with this fix, so this means OVERALL quality is worse.

    I am guessing the fix is to slightly move the audio around if this lowpass filter is also causing audio to move around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0