Browsed by
Category: Programming

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.


Installing Node.js 10.x on Ubuntu Focal (20.04) before the official release

Installing Node.js 10.x on Ubuntu Focal (20.04) before the official release

Hi everyone,

Today, I’ll guide you through the steps of installing Node.js 10.x on Ubuntu Focal (20.04) which is stated to be officially released on April 23, 2020.

Right now, installing Node.js using the NodeSource Node.js official repositories do not work because they do not support unreleased versions of Ubuntu.

You may think of using a previous Ubuntu repository in order to install Node.js, but this will actually not work. This is because Ubuntu 20.04 renamed the Python 2 packages from python to python2.

Trying to install Node.js using the NodeSource repositories

The easiest way to normally install Node.js 10.x is by using the official NodeSource repository. For this, we follow their steps.

curl -sL | sudo -E bash

The problem is that because the OS hasn’t been officially released, we get the following issue:

NodeJS script failing on Ubuntu Focal 20.04

No problem. Let’s move to the manual installation method:

  1. Add the NodeSource package signing key:
    curl -sSL | sudo apt-key add -
  2. Set the version to node_10.x:
  3. Let’s set the distro to eoan, the current stable Ubuntu version:
  4. Now, we need to add the repository to our Linux installation:
    echo "deb$VERSION $DISTRO main" | sudo tee /etc/apt/sources.list.d/nodesource.list
    echo "deb-src$VERSION $DISTRO main" | sudo tee -a /etc/apt/sources.list.d/nodesource.list
  5. The commands should like this in the terminal:
    NodeJS Manual installation commands
  6. We can now run sudo apt update to update the repository information:
    NodeJS manual installation apt update
  7. We will now attempt to install the nodejs package by running sudo apt install nodejs:
    NodeJS installing nodejs fails

As you can see above, following the manual installation steps fails as well because there is no python-minimal package in Ubuntu 20.04. To solve this, we will manually download the Node.js Debian package and modify it to have it refer to python2-minimal instead of python-minimal.

Manually downloading, modifying and installing Node.js 10.x

  1. We will manually navigate to the repository to download the file here:
    NodeJS HTTP repo
  2. From there, just copy the desired Node.js package link to the clipboard. Then, use wget to download it on the terminal. I recommend downloading it to a clean directory since we will run some commands to extract and perform some modifications to it:
    Downloading the NodeJS debian package
  3. Once the download finishes, we need to extract the downloaded debian package with the ar utility:
    ar x nodejs_10.19.0-1nodesource1_amd64.deb
    extracting the NodeJS debian package
  4. We need to extract the control.tar.gz file:
    tar -xzf control.tar.gz
    Extracting control.tar.gz
  5. Using nano or your favorite text editor, we will edit the control file. Look for python-minimal:
    nano control
    Editing the control file
  6. Change python-minimal to python2-minimal:
    Renaming python-minimal to python2-minimal
  7. Save the file. On nano, press CTRL + O, then exit pressing CTRL + X.
  8. We now need to recreate the control.tar.gz tar package to include the modified control file. To do this, we will run the following command:
    tar -czf control.tar.gz control md5sums postinst pr einst prerm
    Recreating the control.tar.gz file
  9. Finally, we will replace the control.tar.gz in the debian package file. We will run the following command to do so:
    ar -r nodejs_10.19.0-1nodesource1_amd64.deb control.tar.gz
    Replacing the control.tar.gz in the NodeJS debian package
  10. We can now install the package with dpkg. We’ll run the following:
    sudo dpkg -i nodejs_10.19.0-1nodesource1_amd64.deb
    Installing the modified NodeJS debian package

After following the above steps, we should have Node.js installed on our operating system. We can confirm this by running node -v and npm -v:

Checking NodeJS and npm versions

And that’s it! We have successfully installed Node.js on our Ubuntu Focal installation.

Opus GUI v1.10 released!

Opus GUI v1.10 released!

Hi everyone,

Today, I released Opus GUI v1.10:

Opus GUI v1.10
Opus GUI v1.10

This new version adds support for ffmpeg’s native Opus encoder. I also included the latest x64 release of opusenc.

As to what ffmpeg encoder to use, I recommend sticking to ffmpeg libopus, as my own tests revealed some artifact issues using ffmpeg opus. A difference between these 2 is that libopus encodes using variable bitrate while ffmpeg opus encodes only with a constant bitrate. Since libopus use variable bitrate, it can allocate more bits to those complex audio sections, hence having a better quality.

You can download this new version at the project’s GitHub release page by clicking here.

I also posted the latest opus-tools build:

opusenc 04-01-2019
opusenc 04-01-2019

You can download it here.


Announcing TIFF Recompressor

Announcing TIFF Recompressor

Hi everyone,

I’ve been working on a brand-new software called TIFF Recompressor:

TIFF Recompressor v0.1
TIFF Recompressor v0.1

This is a tool that allows you to recompress TIFF files by using different compression methods. It also allows you to store them uncompressed so that you can use another software to further compress the files.

The following compression methods can be used in the software:

  • CCITT3
  • CCITT4
  • LZW
  • RLE
  • Uncompressed

Try it out! You can download this new tool here:

More information about the software can be found at the software page by clicking here.


Opus GUI v1.9 released

Opus GUI v1.9 released

Hi everyone,

Today, I have released Opus GUI v1.9:

Opus GUI v1.9
Opus GUI v1.9

This new release allows you to click on the opusenc and ffmpeg version labels to copy the text to your clipboard. This allows you to create folders by pasting the version string from the clipboard to better organize your content if you want to maintain the encodes organized by encoder version. This could be also useful if you want to store the files in folders named with the encoder version to compare them against other versions.

Folders created by copying the encoder version shown in Opus GUI
Folders created by copying the encoder version shown in Opus GUI to the clipboard and pasting them in the folder name

The other change this version provides is that if ffmpeg does not exist in your system and you want to encode MP3 or M4A audio files, these will simply be skipped as opusenc cannot encode those file formats.


You can download this release at the Opus GUI project repo here:

I hope you enjoy this new release!

PAQCompress v0.3.7 released!

PAQCompress v0.3.7 released!

Hi everyone,

Today, I have released PAQCompress v0.3.7:

PAQCompress v0.3.7
PAQCompress v0.3.7

This new release adds support for the following PAQ versions:

  • paq8pxd v64
  • paq8pxv v6

You can download this new release at GitHub here:

The source code, as usual, is available at the PAQCompress project repository:

Technical notes:

paq8pxv v6 provided only one executable, and it was not labeled either with their usual “jit.exe” ending nor with “vm.exe”. Because of this, I had to write a new function that will check in the version folder whenever we have a version ending with “jit.exe” and/or “vm.exe”. If we have them, the software adds the respective entry to the “compiler” list box, and selects the option that the user has previously selected if it is available for the selected PAQ version.

If none of the versions exist, we simply disable the listbox and just use the paq filename as it is, without any of the above terminations:

PAQCompress v0.3.7 code
PAQCompress v0.3.7 new function code

We call this function whenever the version has changed (seen in the end of the above screenshot) or when the PAQ family/series has changed:

PAQCompress v0.3.7 code 2
PAQCompress v0.3.7 code 2

That’s what’s new in the code of this new release.

Hope you enjoy this new version!

Opus GUI v1.8 released

Opus GUI v1.8 released

Hi everyone,

Today, I have released Opus GUI v1.8:

Opus GUI v1.8
Opus GUI v1.8

This is an improvement release. It is now able to detect whenever opusenc and FFmpeg exists in your PC. It will also now show the FFmpeg version if it exists.

Also since I didn’t made a post regarding v1.7, here are the details of the past version:

  • You can now encode individual files by browsing for it or dragging and dropping it. The output should be a folder
  • If there is a file in the output folder with the same name as the input file, it will not be encoded.
  • Drag-and-drop is disabled when encoding is in progress. After the encode finish, drag-anddrop is enabled again.

You can download this new release at the GitHub project here:

The source code is also available here:

Hope you like this new release!

Installing Rust on Windows

Installing Rust on Windows

Hi everyone,

Today, I’ll show you how to install Rust on Windows. The steps are very easy!

1. First, navigate to

Rust Windows 1

2. Click the “rustup-init.exe” link and save the installer:

Rust windows 2

3. Click “Run”:

Rust Windows 3

4. You’ll be presented a Command-Line window. Type “1” and press enter:

Rust Windows 4

5. Installation will begin:

Rust Windows 5

6. If everything runs as it should, you should see the following:

Rust Windows 7

That’s it! Rust is installed!

Learning and Programming Days – DLNA Player

Learning and Programming Days – DLNA Player

Hi everyone,

I got my HiBy R3 music player some time ago and I’ve been enjoying it a lot, and I recently started playing the DLNA portion of it.

Using DLNA with Android is a piece of cake thanks to an app called BubbleUPnP, for which I purchased the app license as it allows me to stream my media files without limitations compared with the free version. However, it is when it comes to the PC where I had difficulties finding compatible DLNA-compatible software. All of which I tried were either buggy or were not able to playback the files to my HiBy R3. That’s when I started researching about the DLNA/UPnP protocol and found some examples. I then started developing software to fit my needs immediately.

DLNA is a protocol used to send media files to wireless players. It usually consists of a Server, Renderer, and a Controller:

  • Server: This is where the media files are stored. They are sent to the player by the controller or the player itself if it is able to browse the server
  • Renderer: This is the device that plays back the media file. The renderer can also be able to browse and play the media acting as a controller, but if the renderer is just a renderer, a controller is needed.
  • Controller: This is like a remote control. You choose the media file and the renderer device with this.

I found one great resource at CodeProject, which you can see here. It talked about how to communicate with DLNA devices and send media files to it, given you have a DLNA Server. It worked using my own HTTP server, but then I wanted to develop software that allows me to playback my media locally. That’s where the fun part began.

I then started researching how to implement HTTP servers in C#. I found some examples which I tried and they seemed to work, but were not able to handle partial requests, which seems are needed for media playback as my player was sending partial requests in the HTTP header. That’s when I also found this other great resource at CodeProject which implemented a simple DLNA server.

Since both codes are open source and their license allows its use in projects including modifying them to fit the needs of others, I used both of these as a base for my project.

Meet DLNA-Player:

DLNA Player
DLNA Player Screenshot

I adapted the above codes to work with a player I designed. It allows you to select a rendered device to playback your music files, build a queue, and control your device with its Play, Pause, Stop, Previous and Next buttons. It also allows you to seek the track by using the slider and shows the track progress in real-time! Clearly, this is my first app that deals with socket connections in particular, since this is all the software does. It’s all about sockets!

You simply need to specify your machine’s IP Address, choose a port and press the Apply button, then Scan for Media Renderers, select one, and then drag and drop your music files. Then press the Play button and enjoy your music!

When you playback a file, it is copied to your machine’s RAM which is then used to send the media file to the renderer as it requests it when it sends the HTTP request. This means the software has its own internal web server, so you don’t need a separate DLNA Server as this software does that, serving the files in the queue as it’s being played.

This project is available at GitHub here:

DLNA Player GitHub Repo

Tested with my Hiby R3 player, I can now enjoy true wireless music playback without the quality loss that happens during the Bluetooth transmission. This is all done via Wifi and the player does all the rendering using the original file. I’ve tested it with FLAC 16-bit/44.1Hz as well as MP3 files, which are working correctly.

I hope this tool is useful for others and this has been an incredible learning journey.