Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AAC output is not the same as the QAAC command line (with the same settings and qaac.exe). #53

Closed
wellivea1 opened this issue Apr 12, 2017 · 4 comments

Comments

@wellivea1
Copy link

wellivea1 commented Apr 12, 2017

Feeding both lamexp and the qaac CLI a 16 bit/44.1 Khz FLAC file (both set to TVBR 127) does not output a file with an identical file hash. I thought maybe it had to do with how lamexp handled the container, so I decoded both files to .wav with the same program, and they were still different. Here's the files I used:
https://dl.dropboxusercontent.com/s/nrz24wkux2l48h3/AudioExample.zip
Also the QAAC command: "qaac Asterisk.flac --tvbr 127"
The files are the exact same size and bitrate, but I can't think of a good reason why they wouldn't decode exactly the same. Is lamexp performing resampling on a 16 bit file? Is there some parameter that lamexp is using that results in a different/better output (I doubt that)?

@wellivea1 wellivea1 changed the title AAC output is not the same as the QAAC command line (with the same settings). AAC output is not the same as the QAAC command line (with the same settings and qaac.exe). Apr 12, 2017
@lordmulder
Copy link
Owner

lordmulder commented Apr 12, 2017

Hello.

First of all, audio/video compression standards, such as AAC, only defined the bitstream format and how a "compliant" decoder must decode a valid bitstream. The compression standard does not define – not at all! – how a particular original (uncompressed) audio or video is "compressed" into a valid bitstream. It is totally up to the Encoder developers to figure out how to generate a valid compressed bitstream from an original (uncompressed) audio or video! And, of course, you do not want just some valid bitstream. You want a bistream that, after being decoded by a "compliant" decoder, resembles the original audio/video as closely as possible. Again, it is totally up to the Encoder developers to figure out how to achieve that 😮

Once you have understood this basic idea, it becomes very clear that there is not just one "correct" AAC stream that can result from a particular source audio file (and all others are somehow "wrong"). Instead, there is like an infinite number of possible AAC streams that could result from the very same original audio file – some of which more closely resemble the original audio (after being decoded by a "compliant" decoder) and some of which less closely resemble to original audio. But it is impossible to decide which compressed AAC stream is the "best" compressed representation of the original audio – at a particular target bitrate.

For this reason any AAC encoder (Nero AAC, QAAC, FAAC, etc. pp.) will generate a different AAC stream from the very same original (uncompressed) audio. Yet, none of them created the "correct" or the "wrong" output! So, differences are to be expected, they are perfectly normal. Which encoder – in general – generates the more "favorable" result may only be decided by careful listening test. And even then results may differ between different people or between different genres of music. Last but not least, even the same encoding software may generate different results when different settings are used. For example, many encoders have options for "fast" (quick and dirty) and "high quality" (slow) encoding – which of course result in different output. Needless to say that different target bitrates will, of course, also result in very different outputs.

Regards,
MuldeR

@wellivea1
Copy link
Author

wellivea1 commented Apr 13, 2017

They were encoded by the exact same encoder though, It's just that one was handled by lamexp. Is there some kind of randomness to Apple's AAC encoding (I highly doubt that)? If you pass the exact same FLAC file and encode it to the exact same bitrate, with the same encoder (and the same executable), shouldn't the AAC bitstream be the same? Unless lamexp resamples the audio if it's in a format that it doesn't accept, which does not apply here.

@wellivea1
Copy link
Author

wellivea1 commented Apr 13, 2017

I used QAAC to produce both files, I am aware that different encoders will give different results. But lamexp did not produce the same result with the same encoder, and with the same settings (both at TVBR 127).

@lordmulder
Copy link
Owner

lordmulder commented Apr 13, 2017

Well, some points to consider:

  1. AAC encoders (and encoders in general) are not guaranteed to be "deterministic". Which means that you can not expect – in general – that you always get a bit-identical output, if you encode the same input multiple times. Indeterminism can be caused by a "(pseudo-)random" component, yes. But it can also be a simple result of race conditions. Note that, in multi-threaded software, you easily get race conditions all over the place – and they are quite costly (in terms of performance overhead) to eradicate. That's because, in order to avoid race conditions in multi-threaded software, you will have to synchronize your "worker" threads quite a lot, which naturally slows things down drastically, as it kills the parallelism. So, quite often, we just accept some indeterminism in favor of speed. Did you actually assess that QAAC is deterministic, when you invoke it directly? If not, that is the first thing to check!

  2. QAAC actually has many options. The rate-control mode (e.g. TVBR) is not the only option that matters. So, when you invoke QAAC manually, did you make sure that you are using exactly the same command-line that LameXP is using when invoking QAAC? If not, then you certainly can not expect to get bit-identical output – even under the assumption that QAAC works perfectly deterministic.

  3. When you invoke QAAC manually, are you using the exactly same version of QAAC as LameXP does? Needless to say that different QAAC version may easily result in different outputs.

  4. Did you make sure that all audio effects are turn off in LameXP? If any effects are applied to the source prior to encoding, you will not get the same result as when encoding straight from the original.

  5. When you invoke QAAC manually, how do you decode the FLAC file? Or do you pass the FLAC file directly into QAAC? Even though FLAC is supposed to be "100% lossless", it is worth checking that the decompressed PCM data actually matches "100%" before it is sent to the encoding stage.

  6. Meta data! When you compute a hash over an AAC/MP4 file, it will of course hash the complete file, including any "meta tags" that may (or may not) be included in the file – not just the pure AAC audio data. So, the differences may very well be in the "meta tags" rather than in the actual audio data. And even if you compute the hash of an "uncompressed" WAV file there can still be differences in the WAV/RIFF structure! WAV files are not just "raw" PCM audio data, they contain a lot more information.

    To compute hash of only the actual audio data (PCM), I suggest:

    ffmpeg.exe -i INPUT_FILE -f s16le -c:a pcm_s16le - | rhash.exe --sha3-512 -
    

    Download:

That's all for now, I think 😀

Regards,
MuldeR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants