MPEG Encode/Decode Support#499
Conversation
|
Yes, I have seen #493, it's what inspired to put this up, having sat on it for a while. I hope that this and #493 can be merged into one another. There are a few differences between this and the approach of #493. Firstly, as encoding and decoding use completely orthogonal libraries, encoding and decoding are split into separate files. The subformat types introduced differ. #493 introduces the subtypes SF_FORMAT_MP3_CBR and SF_FORMAT_MP3_VBR. #499 (this) introduces SF_FORMAT_MPEG_I through SF_FORMAT_MPEG_III. Otherwise, it is a measure of completeness in different areas comparing the two, and much of the code from two could be merged into one another (id3 support, xing tag support, normalization support.) |
|
My attempt has got bogged down in reading. I failed to get mpg123 to work and I was warned off the HIP part of lame. Currently I have been experimenting with a different library -- I seem to loose half the input but reading ints otherwise works (for some value of work...) If you have got further I am happy to withdraw. I will look at your PR |
|
I was hoping you would take this over from me :) I too got bogged down in this. MP3 as a file-format is under-specified. I looked at HIP from liblame too. No seek support, and questions about what it would do with non-vanilla files. What other library are you looking at? I looked at libmad too, but again, no seek support. mpg123 sometimes seems a bit heavy. |
|
I was reasonably happy with the writing of mp3 files using the lame library. With mpg123 it took me time to realise that it is frame oriented and I did not discover how to abstract beyond it.
The library I have been looking at recently is mpadec from a Russian I found on sourceforge which I then used in csound to allow reading of mp3 files (and encoding via pipes to lame). I revised the sources and did a few minor fixes. It is only used simply in csound with an opcode mp3in that reads stereo files from start to end in chunks. There is a drawback that it is written so at open time one selects the format of the output. I was planning to read 32bit and castthe result with range changes. At present I am just trying to read 32 bit integers mono or stereo. Looks feasible but it is a little known library.
What I got nowhere with was the GNU configuration tools. Never used them for anything I have written so I just hacked cmake scripts etc to build and test.
Do you have views on merging our two schemes? Happy to help if useful.
Sent from TypeApp
…On Nov 20, 2019, 18:59, at 18:59, Arthur Taylor ***@***.***> wrote:
I was hoping you would take this over from me :) I too got bogged down
in this. MP3 as a file-format is under-specified.
I looked at HIP from liblame too. No seek support, and questions about
what it would do with non-vanilla files.
What other library are you looking at? I looked at libmad too, but
again, no seek support. mpg123 sometimes seems a bit heavy.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#499 (comment)
|
|
First task is the rebase this against current master to remove the merge commits. Does this include tests? |
|
This version runs the mpeg_test code (simple edit from ogg_test) Will do some more tests but so far looks good. |
795e8ee to
d0de714
Compare
|
Thank you @jpffitch! I have included your test program, and thanks again for finding the float decoding bug. |
|
In this pull, the major format specifier is named (Only layer III is supported for writing. Nothing precludes using twolame for layer II writing support at some future point.) The more I think about it, I wonder if renaming the major format from So-called mp3 files aren't actually a thing, there is no specification, just conventions on headers and trailers added to a MPEG audio layer III stream shoved in a file. I still think the subformat types should model MPEG audio layers.
One case to look out for is |
|
Is this going to be merged? MP3 support would be great. |
|
Needs more work at this time sadly, and I need more time (or money, can contract, call me.) 'MP3 files' are an ad-hoc dirty standard, based on MPEG-1 and MPEG-2 sure, but there's a whole lot of fuzzy crap around the edges. Add to that the fact that the leading libraries for them, lame (lackluster API) and mpg123 (not threadsafe), and well, you have where we are now. |
Why, is libsndfile thread safe? And libmp3lame uses libmpg123 for decoding anyway. However. If its issues are listed anywhere, I may be able to help, not because i'm rich yet :) but I have some time and ability |
|
What do you mean by "needs more work"? |
Yes, it is mostly thread safe. The only exception is in error handling and reporting. |
According to #499 (comment) by the MP3 branch's current maintainer |
|
What kind of work, though? |
I'm trying to find that out. |
mpg123 has non-thread safe global init and cleanup functions. It's a problem that can be ignored for now, it's some table precalculation stuff, so threads could race at writing the same data, but it feels dirty, and who knows, maybe some future version of mpg123 will use the global functions for more. Yes, lame contains a mp3 decoder in it's API which is mpg123, but it is an old version which has been copied into the lame codebase, and while it doesn't contain the non-threadsafe parts, also is very much lacking. (Been there, tried it.) |
93ca6c0 to
0ffba2f
Compare
|
OK, I've run some tests on this and got help privately from arthurt, so I'm forwarding the salient parts of that in case they're userful to other testers (I know, I should have kept it on-list) Me: I'm trying to test the new code, but with all MP3 files, sf_open Is there something obvious I'm missing here? Arthur: To compile with MPEG support not only do you have to pass --enable-mpeg, you also have to pass --enable-experimental. Me: OK! It was saying anyway, so maybe that could be protected by some kind of && Single-threaded MP3 decoding seems to work flawlessly for me. I'm Results: The app has five threads doing essentially random seek-reads on five separate SNDFILE*'s open to the same file (one for the audio player and four for FFTs). It works fine on WAV files but, after a few seconds, on OGG files the seek fails and then it dumps core when ogg_sync_buffers() calls realloc() with an invalid pointer and with FLAC files, either the seeks start failing, or it segmentation faults or (apparently) the calls to sf_read() stop returning any data. With multiple threads, the mpeg code wins the prize though: Putting a lock()-unlock() pair around each call to sf_*() functions, to ensure that only one call is in flight at a time, cures all of these problems and everything works as it should. I can only conclude that libsndfile's WAV reader seems thread safe, but that the ogg- and flac-reading libraries. or the way libsndfile calls them, are not, even though libflac itself does claim to be so. One oddity: though the MP3 reader works on what "file" calls "MPEG ADTS, layer II, and layer III, v1 and v2", it says "Format not recognized" on what "file" calls "Audio file with ID3 version 2.2.0, contains:MPEG ADTS, layer III, v1". snd-file-play fails similarly but the mpg123 command plays it OK. The MP3 reading in arthurt's mpeg-support branch seems to be stable. I haven't tested its encoding side. |
Are you sharing and simultaneously using a SNDFILE* context between threads? That is very much not supported. libsndfile is a thread safe library, as in multiple threads can use the library within one process. SNDFILE contexts are not threadsafe, a context may only be used by one thread at a time.
That is probably an existing bug with very large ID3v2 headers in libsndfile (like such headers containing album art.) It's outstanding but not in the scope of this pull request. Check the output of |
I don't think so but will run further checks.
|
Yes, I'd missed one case; the audio player was using the last-opened audio file instead of its own handle. With that fixed, it works fine for WAV, OGG, FLAC and MP3 too, so libmpg123 (1.25.10) and mpeg-support appear to be thread safe. And libsndfile too of course - maybe that could be mentioned in the Features page. Re: the oddity, calling libmpg123 does decode it correctly, but libsndfile-mpeg-support doesn't recognise it. If you're interested in looking at that, the file is under martinwguy.net/test |
Thanks! Turns out it was because the file has a ID3v2.2 header, whereas libsndfile would only recognise ID3v2.3. Fixed now. |
I'm not sure: https://en.wikipedia.org/wiki/X_Window_System#Release_history. @SoapGentoo , what do you think? |
|
That's the entire "X Window System", which is not released monolithically anymore. |
* [mpg123] Upgrade to 1.26.3-1 Fix invalid MPG123_API_VERSION value in mpg123.h.in for Windows platform. It was equal to @API_VERSION@, now it is read from configure.ac and set to correct value. See also libsndfile/libsndfile#499. * [mpg123] Update 1.26.3-1 baseline version
|
I see odd and even stable minor versions: xorg-server-1.1.0.tar.bz2 |
|
To be honest, I'm completely confused with this XOrg versioning scheme. Our next minor prerelease version using the XOrg scheme is 1.0.99.1 or 1.0.900?
Is this correct? |
|
In that case, I'd consider |
|
semantic versioning should be really considered (https://semver.org/) |
|
FYI, Xorg versioning is perfectly in line with SemVer. |
|
So, to be precise, SemVer would be 1.1.0-beta.1, right? I'm following this as interested outsider. The extra dot irritates me a bit, but I recognize that it eases sorting. personally, I used the scheme 1.1.0-beta1 before and think that it also shouldn't be troublesome to do this without the dot between beta and 1 — as long as you don't do more than 9 rounds of beta/release candidate, which is sensible, IMHO. I also used 1.2.3-somepatch in the past to indicate an addition to the base version and relied on stuff parsing that as equivalent to 1.2.3 at least… but did not expect any automatism to decide that 1.2.3-foo is newer or older than 1.2.3. |
Correct.
SemVer supports prereleases only, so any 1.2.3-foo is older than 1.2.3. |
I'm pretty sure it is bug in our |
It is not, check here https://jubianchi.github.io/semver-check Funnily enough, such a number does not appear to be incorrect, but parsing into separate components fails. Check 1.1.0-beta.1 to see how it works. To begin with, SemVer does not use the fourth digit of the version at all. Something similar is 'prerelease': 1.1.0-1. New feature requires minor bump. XOrg's |
|
I am not saying that I am not ready to accept XOrg versioning. But this is not SemVer. And we can even say that this is not entirely semantic versioning in cases of prereleases. |
|
Honestly, just decide on something, I'm kinda tired of this debate. |
|
use 1.0.99.1 |
|
Sorry, sometimes I can be very boring. Remind me about it 😄 We choose the XOrg versioning scheme with the majority of votes. |
|
@SoapGentoo, it's your turn now. |
|
so |
If I understand correctly, you are asking about the ABI version? If so, it has its own versioning scheme. 1.0.31 -> 1.0.32. |
|
Would 1.1.0beta1 be the first official release with MP3 support? |
No, it is pre-release. Not all of the planned features of official 1.1.0 release have been implemented, but it is quite stable. |
|
@arthurt, is there an approximate date? |
|
Just to confirm: does the beta version https://github.com/libsndfile/libsndfile/releases/tag/1.1.0beta1 have MP3 read/write support? |
Yes. |
Thanks @evpobr! |
MPEG Encode/Decode Support
Uses libmpg123 for decode, liblame for encode. Encoding and decoding support is independent of each other and is split into separate files. MPEG support is generalized as subformats, SF_FORMAT_MPEG_LAYER(I,II,III) so that it might be used by other containers (MPEG1WAVEFORMAT for example), but also contains a major format SF_FORMAT_MP3 for 'mp3 files.'
Introduces the command SFC_GET_BITRATE_MODE/SFC_SET_BITRATE_MODE.
Encoding Status
Decoding Status
Decoding Todo
mpg123 global init racespecific error codesbetter decoder corruption handlingFuture Possible Todos