lordmulder / LameXP

Audio Encoder Front-End
http://lordmulder.github.io/LameXP
Other
184 stars 18 forks source link

Unable to create .FLACs in latest 4.21 Final-1, Build 2382) #115

Open KevinHoSmith opened 8 months ago

KevinHoSmith commented 8 months ago

Prior to installation through the Windows application of the latest version (4.21 Final-1, Build 2382), I'm not sure what version I was running because I allowed automatic updates since installing LameXP_v4.17_Final-1_2018-11-10.Release-Static.Build-2188. Since allowing updating to the latest version, no files I throw at LameXP will be converted to .FLAC using the same setting I've been using for years without incident (max compression, I have tried using 32-bit .WAV files, 24-bit .WAV files, and .MP3 files. LameXP goes through "Filtering" and then abruptly stops with a "Failed" notification. In each case, I have confirmed using the same files on another Windows machine where I did not allow LameXP to update to 4.21 that there's nothing wrong with the files I'm feeding in and they all convert just fine. I have saved a few of the logs from my unsuccessful attempts, but want first to see if this is just a bug that is known and will be soon fixed. Thank you. I'm a complete newbie to GitHub but couldn't find another forum to ask about this.

lordmulder commented 7 months ago

Your CPU reports to support AVX, but not AVX2.

LameXP does not contain a specific FLAC binary for x64 with AVX (but no AVX2). Instead, LameXP contains a FLAC binary for x64 with SSE2, and also one for x64 with AVX2. Because your CPU does not support AVX2, LameXP will not select the AVX2 binary, but instead will fall back to the SSE2 one. From your LameXP log we already saw that this works correctly.

Now, the SSE2 binary is not allowed to contain any AVX, AVX2 or AVX512 instructions, obviously. Therefore it makes no sense that we saw it crash with vpermpd instruction on your CPU, because that is an AVX2 instruction. Makes even less sense that it didn't crash on my old laptop, which, for sure, doesn't support vpermpd instruction either...

KevinHoSmith commented 7 months ago

Ah! I think I get it now. You can't figure out WHY the SSE2 binary DOES contain an AVX2-specific instruction (by definition, "illegal"), right?

Right! When I build the 64-Bit "SSE2" binary, I configure the C++ Compiler to disable all extended instructions sets.

(You can't really disable SSE/SSE2 for 64-Bit binaries, as 64-Bit processors implicitly support SSE2)

In contrast, when I build the "AVX2" binary, I configure the C++ Compiler to enable the AVX and AVX2 instruction sets.

I could also build a dedicated "AVX" binary (with only AVX enabled), but I want to limit the number of variants...

Which binary does your old laptop get? The same one as I?

Yes. It uses the 64-Bit "SSE2" binary. Exactly that same one that LameXP selects on your CPU.

KevinHoSmith commented 7 months ago

So there's an illegal instruction buried in the SSE2 binary that only gets executed on a machine like mine and not like yours. So maybe the program is fooled somewhere earlier about the differing capabilities of our 2 machines even though it's not supposed to be executing AVX2 instructions anyway! Sounds like a problem I need to leave you alone to solve!!! Thanks again. I can always force the 32-bit executable as you've suggested as a workaround rather than reverting back to older versions of LameXP.

KevinHoSmith commented 7 months ago

For anyone monitoring this thread in the future, I've confirmed that the option --cpu-no-x64 to force it using the "x86-i686" (32-Bit) binary for creating .FLACs works just fine. If you "pin" the LameXP app to your taskbar, edit the Properties of THAT icon with the option above, you can use that icon to open LameXP when wanting to create .FLACs (then just drag in your .WAVs). But you can still use Right-Click Convert This File With LameXP on your music files for everything but creating FLACs and it will open normally in 64-bit mode. Hope this helps someone!

lordmulder commented 7 months ago

So there's an illegal instruction buried in the SSE2 binary that only gets executed on a machine like mine and not like yours. So maybe the program is fooled somewhere earlier about the differing capabilities of our 2 machines even though it's not supposed to be executing AVX2 instructions anyway!

Compiler optimizations are not that dynamic.

It is configured, at build time, which instruction set extensions the compiler is allowed to use, or not. That is the reason why I create separate binaries of the same encoder (e.g. FLAC) with different compiler settings. For example, I create two 32-Bit binaries, a "generic" one and an "SSE2" one, as well as two 64-Bit binaries, an "SSE2" one and an "AVX2" one.

All of those four binaries, each one with a "fixed" instruction set, are included with LameXP.

The LameXP "main" application decides, at runtime, which binary should be used, depending on your specific CPU. And, as we can see from your log, LameXP decided for the 64-bit "SSE2" binary on your system – which is correct!


So, as it seems, the 64-bit "SSE2" binary contains an AVX2 instructions, even though this should be impossible, as per the compiler settings that were used to create this specific binary. What makes things even more confusing is that the problem is triggered on your CPU, but not on the one in my old laptop (which certainly has no AVX/AVX2 support).

One possibility is that the "problematic" AVX2 instruction is lurking on some code path that was entered in your usage scenario, but not in the one that I tested. Maybe because of different types of inputs files, or whatever 🤔

KevinHoSmith commented 7 months ago

Thanks. Remember that I did get some kind of warning about my .WAV showing "Type 1" but having 2 bits per something (32-bits). BTW, your explanation is really appreciated, but please know it's way over my head! I've never compiled anything except a résume! :)

KevinHoSmith commented 7 months ago

I don't think you ever answered my question about whether either LameXP or the encoder executable used converts a 32-bit WAV into a 24-bit WAV before converting it (to FLAC in our case). If so, I was thinking I'd save some time by just feeding it the 24-bit WAV I create anyway in order to use WaveCorrectorPro which won't take 32-bit (I create the FLACs only as backups of the original Audacity "recording"). HOWEVER, I noticed that the resulting FLAC is LARGER when I feed a 24-bit of the same audio (exported by Audacity) than when I feed a 32-bit (native to Audacity). Any quick explanation of that?

lordmulder commented 7 months ago

I don't think you ever answered my question about whether either LameXP or the encoder executable used converts a 32-bit WAV into a 24-bit WAV before converting it (to FLAC in our case). If so, I was thinking I'd save some time by just feeding it the 24-bit WAV I create anyway in order to use WaveCorrectorPro which won't take 32-bit (I create the FLACs only as backups of the original Audacity "recording"). HOWEVER, I noticed that the resulting FLAC is LARGER when I feed a 24-bit of the same audio (exported by Audacity) than when I feed a 32-bit (native to Audacity). Any quick explanation of that?

FLAC only supports integer samples, up to and including 32-bit. But it does not support floating-point samples at all.

Now, when it comes to “ 32-Bit” WAV files, the floating-point (FP32) format is the most common, by far.

32-Bit integer is possible too and that would be supported by FLAC unchanged. It's just not very common in the wild.

But, if we try to feed the FLAC encoder with 32-Bit (or 64-Bit) floating-point WAV files, it will just error out! 😞

Therefore, LameXP uses SoX to convert “ 32-Bit” WAV files to 24-Bit integer before passing them to the FLAC encoder.


As for the size differences: You are sure that both FLAC files you are comparing are 24-Bit, with the same sampling rate and the same umber of channels? This can be checked easily with the help of MediaInfo.

Another possibility that comes to my mind: There are different quantization/dithering methods to convert 32-Bit floating-point to 24-Bit integer. The exact method that was used to do the conversion can have an impact on the compressed size. Simply put, when going from a higher bit-depth to a lower one, or from floating-point to integer, then dithering is good for audio quality. Meanwhile, dithering is detrimental to compression, because dither essentially is random noise that is added to "mask" the quantization error. And random noise is hard to compress, by definition.

KevinHoSmith commented 7 months ago

Perfect explanation! Thank you! It would seem, compression-wise, that LameXP  (via SoX) does a better job converting from 32-bit floating point .WAVs to 24-bit integer .WAVs than does Audacity. Perhaps Audacity is more focused on dithering and SoX more focused on compression. Thus the FLAC encoder is starting with a smaller file from SoX than when I feed it an Audacity-converted 24-bit WAV. On Wednesday, January 17, 2024 at 07:42:56 PM CST, LoRd_MuldeR @.***> wrote:

I don't think you ever answered my question about whether either LameXP or the encoder executable used converts a 32-bit WAV into a 24-bit WAV before converting it (to FLAC in our case). If so, I was thinking I'd save some time by just feeding it the 24-bit WAV I create anyway in order to use WaveCorrectorPro which won't take 32-bit (I create the FLACs only as backups of the original Audacity "recording"). HOWEVER, I noticed that the resulting FLAC is LARGER when I feed a 24-bit of the same audio (exported by Audacity) than when I feed a 32-bit (native to Audacity). Any quick explanation of that?

FLAC only supports integer samples, up to and including 32-bit. But it does not support floating-point samples at all.

Now, when it comes to “ 32-Bit” WAV files, the floating-point (FP32) format is the most common, by far.

32-Bit integer is possible too and that would be supported by FLAC unchanged. It's just not very common in the wild.

But, if we try to feed the FLAC encoder with 32-Bit (or 64-Bit) floating-point WAV files, it will just error out! 😞

Therefore, LameXP uses SoX to convert “ 32-Bit” WAV files to 24-Bit integer before passing them to the FLAC encoder.

As for the size differences: You are sure that both FLAC files you are comparing are 24-Bit, with the same sampling rate and the same umber of channels? This can be checked easily with the help of MediaInfo.

There are different quantization/dithering methods to convert 32-Bit *floating-point to 24-Bit integer. The exact method that was used to do the conversion can have an impact on the compressed size. Simply put, when going from a higher bit-depth to a lower one, or from floating-point to integer, dithering is good for audio quality. Meanwhile, dithering is detrimental for compression, because it's essentially random noise that is added to "mask" the quantization error. And random noise is hard to compress, by definition.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>