Browsed by
Category: Development

PAQCompress v0.3.47 has been released

PAQCompress v0.3.47 has been released

Hi everyone,

Today, I have released PAQCompress v0.3.47:

PAQCompress v0.3.47

This release fixes the following issues:

  • Fixes an issue where the software would not work if its location contained spaces and “Show Command Prompt” was checked.
  • Fixes Batch script generation if the software was placed on a location with spaces.

You can download this new version on GitHub by clicking here.


Opus GUI v1.16 released

Opus GUI v1.16 released

Hi everyone,

Today, I have released Opus GUI v1.16:

Opus GUI v1.16

This release adds a new text file called audioformats.txt. In this file, you can specify the file extensions that the GUI will process:

You can add new extensions as long as ffmpeg supports it, and they will be processed only if ffmpeg is present. Otherwise, only WAV files will be processed.

This version also has some bug fixes and improvements and updates the Google APIs to their latest version.

You can download this release on GitHub by clicking here.


Collaborating in the exhale project – Part 2

Collaborating in the exhale project – Part 2

Hi everyone,

Yesterday, I began working on my second collaboration for the exhale xHE-AAC USAC encoder. This time, I worked on adding an argument to print the software version on the console.


The above is the main software, printing its information as well as how to use it.

There was no option to print the version only. Ideally, I just wanted a way to print something like exhale version 1.0.3 that I can easily parse it as I do with other tools like Opusenc and Flac. Because of this, I began working on adding this functionality.

The code that performs this will check if there is just one argument (actually 2, since the first one is the executable filename). It also checks if the argument is either -v or -V. If this is true, we print the software information to the user:

This is the result:

A very simple and minimalistic output. Thanks to this, I can parse it and use on tools like my upcoming exchale GUI:

This Merge Request was approved and merged and is ready to use for everyone. As for the GUI, expect it in the next couple of days!

Click here to see the Merge Request on GitLab.

My first GitLab contribution: exhale encoder

My first GitLab contribution: exhale encoder

Hi everyone,

Yesterday, I collaborated on the exhale xHE-AAC Audio Encoder to add compatibility to compile the project on MinGW on Windows.

The exhale project is an Open-Source xHE-AAC USAC encoder. It allows you to encode wave (WAV) files to M4A using this specific codec.

Originally, compilation on Windows was done using Visual Studio, and this worked fine, but when compiling it on MSYS2/MinGW, it gave some issues, specifically:

H:/repos/media-autobuild_suite/build/exhale-git/src/app/../../src/app/exhaleApp.cpp: In function 'int main(int, char**)':
H:/repos/media-autobuild_suite/build/exhale-git/src/app/../../src/app/exhaleApp.cpp:246:85: error: '_SH_DENYWR' was not declared in this scope
  246 |     if (_sopen_s (&inFileHandle, inFileName, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY, _SH_DENYWR, _S_IREAD) != 0)
      |                                                                                     ^~~~~~~~~~
H:/repos/media-autobuild_suite/build/exhale-git/src/app/../../src/app/exhaleApp.cpp:320:100: error: '_SH_DENYRD' was not declared in this scope
  320 |     if (_sopen_s (&outFileHandle, outFileName, i | _O_SEQUENTIAL | _O_CREAT | _O_EXCL | _O_BINARY, _SH_DENYRD, _S_IWRITE) != 0)
      |                                                                                                    ^~~~~~~~~~
make[1]: *** [../makefile.base:112: ../../build/exhaleApp.d.o] Error 1
make[1]: Leaving directory '/build/exhale-git/src/app'
make: *** [makefile:18: all] Error 2

It also complained about fprintf_s, so some changes needed to be done on the code.

To solve the _SH_DENYRD not declared issue, we had to include the share.h header:

Next, to solve the fprintf_s issue, I surrounded this on an #if !defined block to check if we were compiling on MinGW. If we are, we simply skip this declaration:

After these changes were done, the software compiled successfully.

Next, I did some additional changes to the makefile.base file to allow the Media Autobuild Suite project to pass its CXXFLAGS and LDFLAGS variable to exhale:

These changes got merged into the project.

My inspiration to add this tool to the Media Autobuild Suite came as a user requested this tool to be added to it. So, I worked on it and submitted a Pull Request, where I refined it further to apply some recommendations.

The Pull Request was merged into the suite and is now available for everyone to build and use.


PAQ8PX ported to ARM processors

PAQ8PX ported to ARM processors

Hi everyone,

Over the past few days, I worked on porting the PAQ8PX compressor for ARM CPUs. Initially, it would not compile because it relied on some SSE instructions that are not available on ARM. This required porting some code to equivalent functions in this architecture. Once this was done, paq8px happily compiled and ran on the Snapdragon 845 and 865 CPU’s from my Samsung Galaxy S9+ and S20 Ultra smartphones:

paq8px_v186fix1 running on ARM

I tested it using the Termux app running Ubuntu from the AndroNix project.

The changes that were done to make it compile mostly involved adding some #elif directives. These were added below the initial #if directives that checked if we were compiling on i386 or x86_64 architectures. This #elif directive checks to see if the platform is ARM. The reason is that the header immintrin.h doesn’t exist on ARM. Instead, we need to include arm_neon.h and make the appropriate changes to convert the SSE/SSE2 instructions to NEON.

There were 2 main files that had SSE2/SSSE3 instructions that needed to be ported to NEON. In reality, these ports were not needed, as PAQ8PX contains code that doesn’t depends on the instruction set, but porting it makes the software take advantage of the CPU to its potential.

I started by doing the changed to the Mixer.hpp file, which had code for SSE2 and AVX2.

After porting the code, you can see 2 new functions along with some SSE2 to NEON helper functions were added:

SimdMixer.hpp and MixerFactory.cpp needed some additional else if and some additional conditions in order to support the NEON code:



The other file that contained SSSE3 instructions and needed to be ported to NEON was Bucket.hpp. I also did a mayor refactoring to let the code which SIMD to use according to the system spec or the user-specified SIMD to use:

Ported the SSSE3 code to AVX2:

The SSSE3 function is now called findSsse3:

And here we have the NEON code:

If no SIMD is specified or detected, the code will run findNone:

Finally, here’s the find function. It was extended to accept a second argument indicating which SIMD to use:

This change required adding this second argument to the corresponding lines of ContextMap.cpp and ContextMap2.cpp.


This file required adding some #ifdef defines:

Then, I’m returning the value 11 if we have compiled paq8px on an ARM processor:

Finally, the paq8px.cpp file was updated to accept the NEON argument when using the -simd parameter.

And those were the main changes done to paq8px.

Currently, the latest version v187, which completes porting the SSE2/SSSE3 code to NEON, and fixes some bugs from previous versions.

You can follow paq8px development on the forum by clicking here.