Another codec tip: if you're encoding with opus, especially with libopus, at low-mid bitrates (96k or so, the default), use --no-phase-inv (apply_phase_inv=0 in ffmpeg libopusenc).
-
-
The experimental ffmpeg opus encoder is a bit more conservative about using this feature, so it's not as bad, but still not good enough. Unfortunately, it doesn't have a flag to disable it at this time, so you're probably better off using libopus for now.
Show this thread -
The official "fix" for this is to tell the *decoder* to ignore the feature, and that software should tell the decoder when the output is going to be downmixed. Obviously, nobody does this, it is impossible to do in many frameworks, and it can't account for external downmixing.
Show this thread -
This whole thing was such a mess that the Opus guys had to add *alternate* official decodings to the official spec, because now there are two valid ways of decoding an Opus bitstream: ignoring phase inversion, or not. Which is pretty insane when you think about it.
Show this thread -
I hope they tweak the encoder to use this less aggressively, so it doesn't become a big gotcha for people who aren't aware that Opus kills mono compatibility by default. But now that you know, you can just turn it off yourself.
Show this thread -
Storytime: I noticed this 2 years ago. I had set up an awesome low-latency network stream for
@euskalencounter, using WebRTC and Opus. 70ms end to end latency. It sounded great when I set it up, but later during another event... I noticed really bad audio quality.Show this thread -
It wasn't the mono that I noticed (the audio was coming from some YouTube video on the feed end, it could've just been mono), but rather the artifacts. I thought the source video was bad, but then the next one also sounded bad... and I realized it was my stream.
Show this thread -
I thought Opus was broken until someone on IRC pointed me at this feature. Turns out I had not configured the channel count in my RTP descriptor, and some Chrome update had changed behavior: now it downmixed to mono if not explicitly told the stream was stereo in the descriptor.
Show this thread -
Anyway, I fixed the descriptor, but I also didn't want anyone with a mono path to end up getting crappy audio. At the time gstreamer did not support setting the no phase inversion flag, so I had to patch libopus to turn it off unconditionally.
Show this thread -
Addendum: after a bit of further investigation, this is *particularly* horrible at 2.5ms frame sizes (which I use for the stream to keep latency down) with libopus. This might be a bug, as the RFC makes no mention of frame size affecting the intensity coding threshold.
Show this thread -
So libopus computes one bitrate-equivalent parameter, at 128kbps, as: 20ms: 127600 10ms: 26800 5ms: -7100 2.5ms: -33050 ... I'm pretty sure that's a bug.
Show this thread -
Turns out ((opus_int32)nbCompressedBytes*8*50 >> (3-LM)) should've been ((opus_int32)nbCompressedBytes*8*50 << (3-LM)) Whoops. And this means even at 192kbps or beyond, mono downmixes still sound like crap with 2.5ms frame sizes. After the fix they sound fine.
Show this thread -
Now at 128kbps the downmixes still sound way better without phase inversion enabled, but that's at least intended behavior given the way the math was intended to work, and they sound about half as bad as before. This problem was definitely not supposed to exist at 192k though :-)
Show this thread -
Show this thread
-
Update: that fix has been merged into libopus, and an option to disable the phase inversion in ffmpeg's opus encoder has also been merged into ffmpeg.
Show this thread
End of conversation
New conversation -
Loading seems to be taking a while.
Twitter may be over capacity or experiencing a momentary hiccup. Try again or visit Twitter Status for more information.