mackron / dr_libs

Audio decoding libraries for C/C++, each in a single source file.
Other
1.23k stars 204 forks source link

Add support for Ogg Vorbis and Ogg Opus #139

Open pseiler opened 4 years ago

pseiler commented 4 years ago

This project is awesome.

Is it possible to add ogg vorbis and opus support. Useful for podcasts and people who prefer ogg compared to mp3.

mackron commented 4 years ago

These are both planned, but a long way out unfortunately. I've started on Opus (https://github.com/mackron/dr_libs/blob/master/wip/dr_opus.h), but don't get excited - it doesn't do anything right now and won't for a long time.

pseiler commented 4 years ago

Thank you for the fast update. I'm interested because of this: https://github.com/HookedBehemoth/sys-tune

I mostly encoded my music in ogg vorbis. Unfortunately I'm not really experienced in c/cpp programming. Thank you very much

mackron commented 4 years ago

Let's leave this issue open and use it to track progress on this. Neither of these will be happening this year, that's for certain.

kcgen commented 4 years ago

Of the two: Opus vs Vorbis, the former has massive real-world adoption and makes up the vast majority of lossy-audio moving across the Internet at any given time. Youtube, Whatsapp (and other realtime voice apps), Playstation 4, Spotify, and on and on. All Opus.

"Opus replaces both Vorbis and Speex for new applications, and several blind listening tests have ranked it higher-quality than any other standard audio format at any given bitrate until transparency is reached, including MP3, AAC, and HE-AAC." (wikipedia)

Vorbis enjoyed decent use embeded in games (packaging their audio and music tarcks), but its timing put somewhat behind the curve in what HE-AAC offered plus it had MP3 to contend with as the incumbent. Vorbis simply didn't offer bitrate-shattering performance or millisend-level latency (both of which Opus offers) to make it standout above the rest.

So given the two, and the fact that only so many human-cycles are available, I would lean toward putting effort into Opus first. By that time, Vorbis might be retro project! (it practically already is :-)

mackron commented 4 years ago

Are there any open source Opus implementations that were built from the spec, and not based on the code in the reference implementation? The spec says that the code is the authoritative reference, but in order for a public domain implementation to work it needs to be built entirely from scratch from spec. That's my biggest concern for me with Opus.

Does anybody know the difference in decoding speed between Vorbis and Opus by the way?

kcgen commented 4 years ago

FFmpeg has their own open-source implementation: http://git.videolan.org/?p=ffmpeg.git;a=tree;f=libavcodec;hb=HEAD

Screenshot at 2020-05-26 19-02-09

I'm not sure how it came about though.

The spec says that the code is the authoritative reference, but in order for a public domain implementation to work it needs to be built entirely from scratch from spec

I know the Xiph foundation has tried extremely hard to make their codecs as open and free as possible, so this linkage of their code forming part of the specification sounds like an accidental catch-22 that now blocks the creation of public-domain implementations.

Legally, if Xiph says the specification is officially "A + B", and B happen to be some source code that they wrote; the spirit of the law would treat that simply as part of the specification. To be absolutely sure, I would reach out to Xiph and explain your conundrum.

Performance-wise, my measurements have put Opus at needing roughly 2x the CPU cycles to decode; and it's playable even on very low-end embedded devices. The file-format and packetization is much lower-latency than other codecs though, which is how Opus allows musicians across the internet to play together in realtime and still hold a beat :-).

mackron commented 4 years ago

My thinking is that the spec alone should be enough. It hasn't been a problem yet, but I haven't got to the technical stuff yet so who knows.

A 2x speed difference would be about what I'd expect.

kcgen commented 4 years ago

Cool; that bodes well! (I was worried they were just being lazy and were using their source as a crutch to allow them to only document high-level concepts, and defer the other 70% of details to their source).

DatCaptainHorse commented 4 years ago

If you are in hurry for getting your hands into opus you can use opusfile, which is the official library from xiph for decoding opus. There also exists a variant for vorbis called vorbisfile.

ell1e commented 4 years ago

I would definitely use this, mainly because I've had a bad experience with stb_vorbis. It's streaming API looks kind of bad (especially compared to drmp3), the code looks worse in general, and I've actually had it crash on a couple of files as well and seen a write-up that it'll happily allocate 2GB vorbis packets with no sane limits on untrusted files. So it'd be really cool to have a well-written alternative one day!

mackron commented 3 years ago

So I've put in leave for early October with the intention on working on a dr_vorbis. No promises or anything as to whether or not that actually happens, but hopefully I can get a good chunk of it done (only have four days allocated). I need this for miniaudio, so figured I'd better get this knocked out sooner than later. Opus will probably happen next year. Will keep this issue updated with progress.

@ell1e Yes, I've had my own problems with it in my other audio project, miniaudio, which is the primary motivation for me writing an alternative. Don't want to bash on it too hard here, but way too many issues that, in my opinion, have no place in a professional code base.

pseiler commented 3 years ago

@mackron can I donate you a few bucks for your effort? I didn't find any hints on your site. Vorbis support would be awesome!

mackron commented 3 years ago

@pseiler I actually just signed up for the GitHub Sponsors program just yesterday so maybe that'd be the best place? Thank you! But of course you don't have to do that.

pseiler commented 3 years ago

Unfortunately this is more like an abo so I just thought more about a one-time donation. Sorry :)

mackron commented 3 years ago

Yeah that's no worries, I understand. I don't have any other donation platforms set up right now, but I appreciate you reaching out.

mackron commented 3 years ago

I've started on some preliminary work on dr_vorbis. No actual audio decoding is implemented yet - mostly just boilerplate and a bit of infrastructure. It's in the "vorbis" branch. Code here: https://github.com/mackron/dr_libs/blob/vorbis/dr_vorbis.h

I'm imagining most of you are already using some other dr_ libraries at the moment, so I'd be particularly interested in your feedback at the top of drvorbis.h under the Notes section regarding some API changes I'm experimenting with. Eventually I want to get all dr libraries consistent with each other, so some feedback on that would be really useful. Also feel free to suggest things I haven't already mentioned.

MichealReed commented 3 years ago

Curious if these will be able to decode opus by the packet, or require full and properly sequenced files? Here is a great discussion around this topic for web audio and media sources: https://github.com/w3c/media-source/issues/190

mackron commented 3 years ago

I'm not sure yet. From my preliminary look it looks like I might be able to do it per-packet, but no guarantees or anything.

ell1e commented 2 years ago

@mackron some API feedback: personally, errno use makes me think "will that mess up things on some systems like BSD or Windows with possibly differing errno values"? Not sure if that is realistically a problem, but if it possibly is I'd suggest just using an enum of all custom error codes instead. I also thinkDR_VORBIS_NO_STDIO not declaring the I/O may have been better if it allowed injecting custom ones more easily (did it?). All the other changes sound nice to me.

MikuAuahDark commented 2 years ago

I'm not sure if you have checked RFC 6716 so I assume you haven't do so. For Opus, the spec is in RFC 6716, so that's probably sufficient?