04 Apr 2022

feedPlanet Maemo

Computing replaygain for your Music library

TLDR; command at the end of post

If you want a equal loudness for your Music library the go to solution and the de-facto standard is ReplayGain.
If you are using a music streaming service, the provider is typically taking care of that for you - but maybe you want to migrate towards your own streaming solution.

ReplayGain analyses your audio files and stores their deviation from the baseline loudness as a tag. A compatible audio player can then read the tag and correct the playback volume so all you tracks have the same loudness.

Of course things get messy once you look at details like what the baseline loudness should be and how to determine loudness in the first place. Therefore we set the baseline once and for all as 89db and consider even tracks of the same album individually. If you disagree, feel free to branch off reading up the details now.

The next issue is that ReplayGain was born in a time where mp3 was synonymous to digital music, hence the algorithm was first implemented as the mp3gain CLI tool. Nowadays you also need aacgain and vorbisgain to cover all your formats, which is cumbersome to automate.

The larger issue with ReplayGain is that it defines loudness of a track by its peak volume. While a sane choice in theory, in practice the music and advertising industries raced to increase the perceived loudness without raising the peak volume. As broadcasters also used peak volume normalization, one could blow your eardrum with that very special advertisement.
Therefore the EBU R 128 was proposed which at its core is RMS based, meaning it is considering the average volume of the track.

Remember that ReplayGain merely adds a correction value to the tracks? This allows us to compute that correction value based on the R128 algorithm for a better normalization, which is exactly what the r128gain tool does.
Being written in modern day, r128gain also processes all possible audio files by hooking into ffmpeg as a filter.

So, without further ado, this is the command to normalize your Music library:

# pip3 install r128gain
r128gain -p -r Music/

This will preserve "-p" the file timestamps and recursively "-r" process all files in the given directory.

Trouble shooting

Note that if you previously used mp3gain, your files might contain non-standard lower-case replaygain_* tags, while r128gain will only write REPLAYGAIN_* tags.
To avoid confusing players with different values, you should remove the non-standard tags. This can be automated with eyeD3

eyeD3 -Q --remove-frame RGAD --preserve-file-times --user-text-frame=replaygain_track_gain: --user-text-frame=replaygain_track_peak: --user-text-frame=replaygain_album_gain: --user-text-frame=replaygain_album_peak: Music/

Refer to its documentation for the meaning of the parameters.

Header Image: "volume" by christina rutz (CC-BY-2.0)

0 Add to favourites0 Bury

04 Apr 2022 4:13pm GMT

18 Feb 2022

feedPlanet Maemo

Can Std Be Cured At Home

If you've been exposed to an std or are experiencing symptoms of an std you should see a doctor about std testing. 12.01.2022 · you can choose to test for a single sti or std, or do a full panel. Start treatment discreetly with medication provided at no additional charge. Same labs as physicians & hospitals. They work better the sooner you take them.

12.01.2022 · you can choose to test for a single sti or std, or do a full panel. Chhapaar Mela, Ludhiana Punjab India 2020 Dates, Festival Chhapaar Mela, Ludhiana Punjab India 2020 Dates, Festival from www.travelwhistle.com Echinacea tea also helps to treat tonsils with white spots on the throat along with boosting your … 22.07.2021 · chlamydia can be easily cured with antibiotics. Our providers can review the results of urine or blood tests that are ordered and collected by an outside lab to determine if you have an std, and provide a treatment recommendation, which may include a prescription. Majority of these are found in china with a few of them prevalent in asia and the mediterranean region. Emphasizing again on the fact that tonsillitis can be cured with simple home remedies if the bacterial infection has not caused a serious effect or else antibiotics will be prescribed by your doctor.salt water gargle can be the easiest way to treat an inflamed tonsil. 16.08.2021 · syphilis can be cured with antibiotics. They work better the sooner you take them. Cdc recommends a single dose of 500 mg of intramuscular ceftriaxone.

Sometimes there are no symptoms at all.

05.07.2017 · epimedium belongs to the flowering plants of the family berberidaceae. 12.02.2020 · get std testing and treatment online. Echinacea tea also helps to treat tonsils with white spots on the throat along with boosting your … Alternative regimens are available when ceftriaxone cannot be used to treat urogenital or rectal gonorrhea. They work better the sooner you take them. Once your results come back the doctor will. Majority of these are found in china with a few of them prevalent in asia and the mediterranean region. Start treatment discreetly with medication provided at no additional charge. This can be done online through plushcare. 12.01.2022 · you can choose to test for a single sti or std, or do a full panel. Cdc recommends a single dose of 500 mg of intramuscular ceftriaxone. Gonorrhea can be cured with the right treatment. 16.08.2021 · syphilis can be cured with antibiotics.

Once your results come back the doctor will. Although medication will stop the infection, it will not repair any permanent damage done by the disease. 12.02.2020 · get std testing and treatment online. They work better the sooner you take them. Our top doctors are able to write std testing orders and will refer you to your local lab for testing.

22.07.2021 · chlamydia can be easily cured with antibiotics. Stone Columns | Mountain Home Architects, Timber Frame Stone Columns | Mountain Home Architects, Timber Frame from www.homearchitects.com We now have very effective treatments for hiv. Sometimes there are no symptoms at all. 12.02.2020 · get std testing and treatment online. 12.01.2022 · you can choose to test for a single sti or std, or do a full panel. Cdc recommends a single dose of 500 mg of intramuscular ceftriaxone. Medication sent to you, at no extra cost. Confidential results in 2 to 5 days. Emphasizing again on the fact that tonsillitis can be cured with simple home remedies if the bacterial infection has not caused a serious effect or else antibiotics will be prescribed by your doctor.salt water gargle can be the easiest way to treat an inflamed tonsil.

Emphasizing again on the fact that tonsillitis can be cured with simple home remedies if the bacterial infection has not caused a serious effect or else antibiotics will be prescribed by your doctor.salt water gargle can be the easiest way to treat an inflamed tonsil.

Same labs as physicians & hospitals. This can be done online through plushcare. 22.07.2021 · chlamydia can be easily cured with antibiotics. 12.02.2020 · get std testing and treatment online. Echinacea tea also helps to treat tonsils with white spots on the throat along with boosting your … Our top doctors are able to write std testing orders and will refer you to your local lab for testing. We now have very effective treatments for hiv. Emphasizing again on the fact that tonsillitis can be cured with simple home remedies if the bacterial infection has not caused a serious effect or else antibiotics will be prescribed by your doctor.salt water gargle can be the easiest way to treat an inflamed tonsil. If you've been exposed to an std or are experiencing symptoms of an std you should see a doctor about std testing. 12.01.2022 · you can choose to test for a single sti or std, or do a full panel. 16.08.2021 · syphilis can be cured with antibiotics. Confidential results in 2 to 5 days. Medication sent to you, at no extra cost.

Medication sent to you, at no extra cost. Cdc recommends a single dose of 500 mg of intramuscular ceftriaxone. They work better the sooner you take them. Although medication will stop the infection, it will not repair any permanent damage done by the disease. 16.08.2021 · syphilis can be cured with antibiotics.

Sometimes there are no symptoms at all. Stone Columns | Mountain Home Architects, Timber Frame Stone Columns | Mountain Home Architects, Timber Frame from www.homearchitects.com Medication sent to you, at no extra cost. 09.09.2021 · it is the only way you can know for sure if you have hiv or an std. Start treatment discreetly with medication provided at no additional charge. Same labs as physicians & hospitals. Alternative regimens are available when ceftriaxone cannot be used to treat urogenital or rectal gonorrhea. Emphasizing again on the fact that tonsillitis can be cured with simple home remedies if the bacterial infection has not caused a serious effect or else antibiotics will be prescribed by your doctor.salt water gargle can be the easiest way to treat an inflamed tonsil. If it's difficult to access a doctor or other healthcare professional, fully … Gonorrhea can be cured with the right treatment.

Sometimes there are no symptoms at all.

09.09.2021 · it is the only way you can know for sure if you have hiv or an std. If you've been exposed to an std or are experiencing symptoms of an std you should see a doctor about std testing. This can be done online through plushcare. Echinacea tea also helps to treat tonsils with white spots on the throat along with boosting your … Although medication will stop the infection, it will not repair any permanent damage done by the disease. We now have very effective treatments for hiv. They work better the sooner you take them. If it's difficult to access a doctor or other healthcare professional, fully … Emphasizing again on the fact that tonsillitis can be cured with simple home remedies if the bacterial infection has not caused a serious effect or else antibiotics will be prescribed by your doctor.salt water gargle can be the easiest way to treat an inflamed tonsil. Gonorrhea can be cured with the right treatment. Start treatment discreetly with medication provided at no additional charge. Our top doctors are able to write std testing orders and will refer you to your local lab for testing. Majority of these are found in china with a few of them prevalent in asia and the mediterranean region.

Can Std Be Cured At Home. These medications are available to everyone who needs them in king county, wa. Emphasizing again on the fact that tonsillitis can be cured with simple home remedies if the bacterial infection has not caused a serious effect or else antibiotics will be prescribed by your doctor.salt water gargle can be the easiest way to treat an inflamed tonsil. Gonorrhea can be cured with the right treatment. 09.09.2021 · it is the only way you can know for sure if you have hiv or an std. This can be done online through plushcare.

Echinacea tea also helps to treat tonsils with white spots on the throat along with boosting your … Ayusya Home Health Care Pvt Ltd-Bangalore-Chennai-Madurai Source: www.ayusyahomehealthcare.com

Alternative regimens are available when ceftriaxone cannot be used to treat urogenital or rectal gonorrhea. Although medication will stop the infection, it will not repair any permanent damage done by the disease. Confidential results in 2 to 5 days. Our top doctors are able to write std testing orders and will refer you to your local lab for testing. Majority of these are found in china with a few of them prevalent in asia and the mediterranean region.

Untreated stds are leading causes of infertility (inability to make a baby) for both men and women. 10 New Fixtures to Illuminate the Outdoors | Architectural Source: cdnassets.hw.net

Start treatment discreetly with medication provided at no additional charge. Although medication will stop the infection, it will not repair any permanent damage done by the disease. 09.09.2021 · it is the only way you can know for sure if you have hiv or an std. 12.01.2022 · you can choose to test for a single sti or std, or do a full panel. Same labs as physicians & hospitals.

Confidential results in 2 to 5 days. Making Easy and Fun Food Molds with Silicone Putty Source: www.smooth-on.com

16.08.2021 · syphilis can be cured with antibiotics. We now have very effective treatments for hiv. This can be done online through plushcare. Echinacea tea also helps to treat tonsils with white spots on the throat along with boosting your … 22.07.2021 · chlamydia can be easily cured with antibiotics.

Same labs as physicians & hospitals. Pachmarhi hill station Source: welcomenri.com

22.07.2021 · chlamydia can be easily cured with antibiotics. Our top doctors are able to write std testing orders and will refer you to your local lab for testing. This can be done online through plushcare. 16.08.2021 · syphilis can be cured with antibiotics. 05.07.2017 · epimedium belongs to the flowering plants of the family berberidaceae.

Although medication will stop the infection, it will not repair any permanent damage done by the disease. Sexually Transmitted Disease Surveillance, 2019 Source: www.cdc.gov

Emphasizing again on the fact that tonsillitis can be cured with simple home remedies if the bacterial infection has not caused a serious effect or else antibiotics will be prescribed by your doctor.salt water gargle can be the easiest way to treat an inflamed tonsil. Cdc recommends a single dose of 500 mg of intramuscular ceftriaxone. Gonorrhea can be cured with the right treatment. If it's difficult to access a doctor or other healthcare professional, fully … 05.07.2017 · epimedium belongs to the flowering plants of the family berberidaceae.

Sometimes there are no symptoms at all. Chhapaar Mela, Ludhiana Punjab India 2020 Dates, Festival Source: www.travelwhistle.com

Medication sent to you, at no extra cost. If you've been exposed to an std or are experiencing symptoms of an std you should see a doctor about std testing. Although medication will stop the infection, it will not repair any permanent damage done by the disease. Emphasizing again on the fact that tonsillitis can be cured with simple home remedies if the bacterial infection has not caused a serious effect or else antibiotics will be prescribed by your doctor.salt water gargle can be the easiest way to treat an inflamed tonsil. We now have very effective treatments for hiv.

09.09.2021 · it is the only way you can know for sure if you have hiv or an std. Stone Columns | Mountain Home Architects, Timber Frame Source: www.homearchitects.com

Start treatment discreetly with medication provided at no additional charge. 16.08.2021 · syphilis can be cured with antibiotics. Same labs as physicians & hospitals. If it's difficult to access a doctor or other healthcare professional, fully … Medication sent to you, at no extra cost.

These medications are available to everyone who needs them in king county, wa. Commercial & Residential Construction - DWL Construction Source: www.dwlconstruction.com

Our providers can review the results of urine or blood tests that are ordered and collected by an outside lab to determine if you have an std, and provide a treatment recommendation, which may include a prescription. 12.01.2022 · you can choose to test for a single sti or std, or do a full panel. If it's difficult to access a doctor or other healthcare professional, fully … They work better the sooner you take them. If you've been exposed to an std or are experiencing symptoms of an std you should see a doctor about std testing.

0 Add to favourites2 Bury

18 Feb 2022 12:28pm GMT

17 Feb 2022

feedPlanet Maemo

Maemo Community e.V. - Invitation to the General Assembly 2022

Maemo Community e.V. - Invitation to the General Assembly 2022

Dear Member,

The meeting will be held on Thursday, March 17th 2022 at 20:00 CET on irc.libera.chat channel #maemo-meeting.

Unless any further issues are raised, the agenda includes the following topics:
1. Welcome by the Chairman of the Board
2. Determination of the proper convocation and the quorum of the General Assembly
3. Election of the Board Directors
6. Any other business

Requests for additions to the agenda must be submitted to the Board in writing one week prior to the meeting (§ 9.2 of the Statutes).

On Behalf of the Maemo Council, Jussi Ohenoja

0 Add to favourites0 Bury

17 Feb 2022 8:00am GMT

14 Feb 2022

feedPlanet Maemo

Honquest Funeral Home Loves Park Il

Stanislaus church, 201 buckbee, rockford, il 61104. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st.

Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Obituary | Jason Hunt of Lubbock, Texas | Hillcrest Obituary | Jason Hunt of Lubbock, Texas | Hillcrest from www.hillcrestfuneralhomelittlefield.com Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Stanislaus church, 201 buckbee, rockford, il 61104.

Stanislaus church, 201 buckbee, rockford, il 61104.

Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Stanislaus church, 201 buckbee, rockford, il 61104. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm.

Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st.

Stanislaus church, 201 buckbee, rockford, il 61104. Shelly Kanneberg Obituary - Machesney Park, IL Shelly Kanneberg Obituary - Machesney Park, IL from dux7id0k7hacn.cloudfront.net Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Stanislaus church, 201 buckbee, rockford, il 61104.

Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st.

Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm.

Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st.

Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Obituary for Kathleen Ann James | Honquest Family Funeral Obituary for Kathleen Ann James | Honquest Family Funeral from s3.amazonaws.com Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm.

Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st.

Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Stanislaus church, 201 buckbee, rockford, il 61104. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm.

Honquest Funeral Home Loves Park Il. Stanislaus church, 201 buckbee, rockford, il 61104. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st.

Stanislaus church, 201 buckbee, rockford, il 61104. Mulford Facility | Honquest Family Funeral Homes Source: s3.amazonaws.com

Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm.

Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Shelly Kanneberg Obituary - Machesney Park, IL Source: dux7id0k7hacn.cloudfront.net

Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm.

Stanislaus church, 201 buckbee, rockford, il 61104. Obituary for Robert E. Mueller | Honquest Family Funeral Homes Source: s3.amazonaws.com

Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Stanislaus church, 201 buckbee, rockford, il 61104. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm.

Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Obituary | MaryLou Reeser | Unger-Horner Funeral Home Source: www.ungerhorner.com

Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Stanislaus church, 201 buckbee, rockford, il 61104.

Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Find Richard Lewis at Legacy.com Source: cache.legacy.net

Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st.

Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Obituary | Jason Hunt of Lubbock, Texas | Hillcrest Source: www.hillcrestfuneralhomelittlefield.com

Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st.

Stanislaus church, 201 buckbee, rockford, il 61104. Obituary for Carol Ann McKnight-Foster | Honquest Family Source: s3.amazonaws.com

Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm. Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st.

Stanislaus church, 201 buckbee, rockford, il 61104. Obituary for Terri Lynn Hemphill | Honquest Family Funeral Source: s3.amazonaws.com

Stanislaus church, 201 buckbee, rockford, il 61104. Mass of christian burial will be held at 10:00am on friday, january 28, 2022 in st. Mulford rd., loves park, il 61111 on thursday january 27, 2022 from 4:00 to 6:30pm.

0 Add to favourites1 Bury

14 Feb 2022 12:41pm GMT

25 Dec 2021

feedPlanet Maemo

Debugging the “Factory mode” of BQ devices in Ubuntu Touch

As you know, I'm trying to get the FM radio to work in Ubuntu Touch, and I basically have it working on the Redmi Note 7 Pro. But then I remembered that the BQ Aquaris E4.5 (which is the first commercial device officially supporting Ubuntu Touch) also comes with an FM radio, so I decided to put some effort in getting that to work, too. You might think it's a waste of time, but as a matter of fact this device is built on a Mediatek SoC, and FM radio support is exposed to userspace in a very similar way across all Mediatek devices - so this work should be covering other devices as well.

It was relatively easy to get the FM radio to work on this phone: I can now tune to a frequency and see that the RDS data is received, but I cannot get any sound out of the speakers or headphones, which makes the whole radio experience a bit, uhm… suboptimal, let's say.

The problem is not new: back in the days when Ubuntu Touch was still supported by Canonical, sturmflut was trying to get the FM radio to work, and he met the same issues (see this and this messages in the mailing list). He also spent some time investigating how the Factory mode works (the FM radio is indeed one of the features that can be tested via the Factory mode, and it does work) and he mentioned that he could get gdb to attach to the factory mode program and could see the various ioctls being executed. Yesterday I tried to follow the same steps, but I failed quite soon: I simply could not connect with adb shell while the device was in factory mode, so no chances of debugging for me. ☹

Out of dispair, I tried just to manually run the program /system/bin/factory inside a Lomiri session and, to my surprise, it overlayed its yellow "Factory Mode" title on the screen - just to immediately quit afterwards. I tried running it with strace, and noticed these lines:

open("/sys/class/BOOT/BOOT/boot/boot_mode", O_RDWR|O_LARGEFILE) = 15
read(15, "0\n", 4)                      = 2
close(15)                               = 0
writev(5, [{"\3", 1}, {"FTM\0", 4}, {"[FTM UTILS] Unsupported factory "..., 39}], 3) = 44
writev(5, [{"\6", 1}, {"NVRAM\0", 6}, {"[MAIN] Unsupported Factory mode\n"..., 33}], 3) = 40

Of course, the /sys/class/BOOT/BOOT/boot/boot_mode file is read-only, so I couldn't just write 1 into it, but could a bind-mount work? Indeed it did! And after a few attempts, I verified that writing a value of 4 in the boot_mode file made the factory program happy. It was still unusable because it was acting as if the volume down button was being constantly pressed, so the cursor was always moving downwards, but killing the Lomiri session did the trick. In short, these are the steps you need to follow in order to run the Factory Mode from an ordinary boot session:

sudo -i  # become root
echo 4 > /tmp/trick
mount -o bind /tmp/trick /sys/class/BOOT/BOOT/boot/boot_mode
service lightdm stop  # wait a few seconds until this returns
unset LD_PRELOAD
/system/bin/factory

What is more surprising, is that the FM radio test is working even in this environment, and you can actually hear the sounds (for some reason, the FM radio item takes about 40 seconds to initialize when run under these conditions, but it eventually works). At this point, not only I could run gdb (which I didn't), but I could even run the factory program under strace and collect the logs.

At the moment of writing this post, I haven't yet examined the logs, so I'm not at all sure that they'll be enough to make audio work (I suspect that the factory mode binary might be playing some tricks that are somehow not replicable in a proper Linux system with Pulseaudio and lots of other services running), but I do have enough information to make at least a few attempts.

Stay tuned, and have a Merry Christmas!

0 Add to favourites0 Bury

25 Dec 2021 7:13am GMT

19 Dec 2021

feedPlanet Maemo

Improving Qt

We are a few years further. A few years in which we all tried to make a difference.

I'm incredibly proud of my achievement of QTBUG-61928. At the time I thought I could never convince the Qt development team of changing their APIs. They did and today in Qt6 it's all very much part of the package.

I want to thank Thiago and others. But I also think it's a team effort. It might not be because of just me. But I still feel a little bit proud of having pushed this team just enough to make the changes.

I am now at a new Qt bug report. This time it's about int64_t. I think that QModelIndex should be completely supporting it. Again, I think a lot. And I have a lot of opinions. But I anyway filed QTBUG-99312 for this.

0 Add to favourites0 Bury

19 Dec 2021 5:49pm GMT

07 Dec 2021

feedPlanet Maemo

Enabling the FM radio in Ubuntu Touch

I recently realized that my Xiaomi Redmi Note 7 Pro, on which I installed Ubuntu Touch not so long ago, has a working FM radio. One of the many psychological bugs of mine is the irrational urge I feel of having my hardware, no matter whether I use it or not, supported by Linux. So, the fact that I never listen to the radio is unfortunately not a reason to dissuade me from wasting time on getting the FM radio working in Ubuntu Touch.

This post is a quick summary of my investigation, which should serve as a note keeper for when I'll actually get to implement the feature.

The Android story

It was a bit surprising to find out that Android does not offer an API to use the FM radio, meaning that we cannot simply expose an API via libhybris. Every manufacturer is therefore choosing their own API, and Android applications are most often developed for a specific chipset family, or need to carry the code to support all the various devices.

For example, I found the RFM Radio Android application which supports a few Qualcomm Snapdragon processors, for which the FM radio functionality is exposed by a kernel driver via the V4L API. This means that the FM radio is probably working out of the box with QtMultimedia's QRadioTuner. Unfortunately the Note 7 Pro uses a newer Snapdragon, and even after some days of investigations I couldn't find out how the radio driver communicates to the userspace; but more on this below. Other chipsets offer other APIs, and I was glad to find that someone already wrote a Ubuntu Touch FM radio application for the Volla phone, which has a Mediatek board.

Anyway, the lack of a unified FM radio API is probably the reason why most of the so-called "FM radio" applications on Android are not really using the FM radio but rather streaming audio from the internet.

The FM radio in the Note 7 Pro

Before I start talking about a phone that no one cares about, let me say that what I'm going to write applies to several other Snapdragon chipsets and could be relevant to other phones. For one, the Redmi Note 9 Pro uses the very same bluetooth chipset as the Note 7 Pro (and in case you are wondering why I mentioned bluetooth, it's because the FM radio functionality is delivered by the same BT chip), so all what I'm going to write here is also relevant for that phone.

In order to figure out how the radio worked on this device, I took the drastic decision to reflash the stock Android (well, MIUI), started the preinstalled FM radio application, and meanwhile looked at the logcat messages (I'm not sure if this is needed, but before doing so I went to the "Developer options" in the system settings and set the debugging level to the maximum). Among a lot of noise, this showed me lines like these:

I android_hardware_fm: Opened fm_helium.so shared object library successfully
I android_hardware_fm: Obtaining handle: 'FM_HELIUM_LIB_INTERFACE' to the shared object library...
D FmReceiverJNI: init native called
D android_hardware_fm: BT soc is cherokee
I android_hardware_fm: Init native called
I android_hardware_fm: Initializing the FM HAL module & registering the JNI callback functions...
D radio_helium: ++hal_init
D fm_hci  : ++fm_hci_init
I fm_hci  : hci_initialize

Well, even without knowing nothing about all what these lines meant, I had something I could search the internet for. So I found the Qualcomm FM code in CodeAurora, and search for the code relative to my Snapdragon 675 (aka sm6150). I quickly gave up on trying to make some sense out of the git tag naming in that repository, and just tried to search for a tag which could be referring to my device. I found one, and started browsing its source tree.

It turns out that Qualcomm provides a Java package which applications can use, and which internally dlopen()s the fm_helium.so library, which in turn depends on the libfm_hci.so library. I had a quick look at the source code of these libraries, which are also present in the repository, but decided that I would have had more chances of success if I just tried to follow the JNI code, and in particular the android_hardware_fm.cpp file. I'm not sure why this code is not using the C structure types defined in the headers provided by the helium library, and instead redefines all the constants and accesses the character buffers by offsets - it might be just for historical reasons - but in any case I decided to follow along.

The fm-bridge program

Since we have a rather net separation between the Ubuntu Touch and the Android worlds (the Android services are running inside an LXC container, with all their Android libs and dependencies), one should not attempt to write an Ubuntu process that loads the Android libraries, because the libc used in Android is different, so things are likely not to work. But we can have Ubuntu and Android processes communicate over a socket or other kind of IPC; so, what I decided to go for, is writing a small C program that will live in the Android side, it will talk to the FM radio (via helium_fm), and accept commands / give replies via its stdin / stdout.

I unimaginatively called it "fm-bridge", and you can look at its horrible code here. Really, I just said it was terrible, so why did you look at it? I definitely need to rewrite it from scratch, possibly using the helium headers, but as a proof of concept this also works. Then I carefully examined the logcat output while using the MIUI FM radio application in Android, and figured out what was the command sequence I had to input into fm-bridge's standard input in order to have it tune onto a given frequency. I'm publishing the commands here too, should I ever lose my notes:

enableSlimbus 1
setControl 0x8000004 1
enableSoftMute 1
setControl 0x8000029 0
setControl 0x800000c 1
setControl 0x800000d 1
setControl 0x800000e 1
setControl 0x800002b 0
setControl 0x8000007 4
setControl 0x8000006 0x40
setControl 0x8000006 0x40
setControl 0x8000011 0
setControl 0x800000f 1
getControl 0x8000010
setControl 0x8000010 0xef
setControl 0x800000f 1
setControl 0x800001b 1
setControl 0x8000012 0
setFreq 89300
setMonoStereo 1

I'm sure that not all of them are needed, but I'll figure out the optimal sequence later. In order to use this program on Ubuntu Touch, I had to alter the vendor partition to add this program, but also the fm_helium.so and libfm_hci.so libraries (more on that below).

When feeding the above commands to the fm-bridge in Ubuntu, I saw that I was getting a logcat output similar to the one from Android, which was mildly comforting. No sound was comint out of the speaker or out of the earplugs, but I was hardly expecting it all to work at the first try. And I got convinced that the FM tuner was indeed working, because typing the command "startSearch 1" made a new frequency appear in the logs, proving that the tuner had found another station and tuned onto it.

Getting the sound out

This was actually the easiest of the steps, thanks to the Ubuntu Touch FM radio application we have for the Volla: its source code mentions a few pulseaudio commands that worked perfectly in the Note 7 Pro too, despite the fact that the underlying chipset is totally different. This should not be as surprising as it might sound like, given that Android has a common audio API.

Just for my future reference, the commands are these:

pacmd set-source-port 1 input-fm_tuner
pactl load-module module-loopback source=1 sink=0

Ta-daaa! The radio was now playing from the phone loudspeakers! It was indeed quite loud, and the volume buttons did not seem to have any effect on it, but the volume can be controlled with pulseaudio:

pactl set-source-volume 1 50%

Of course, if we ever manage to make this into an Ubuntu Touch feature, we'll have to find a way to make the volume respond to the volume buttons.

Addind the needed files to the vendor partition

The simplest approach (and the one I took initially) is that of downloading the vendor.img into your PC, loop-mounting it, adding the fm_helium.so, libfm_hci.so and fm-bridge files to it and then umount the partition and reflash it (remembering to converting it from/to a sparse image before downloading/uploading it). This approach works flawlessly, but I'm wondering if one might incur into issues if the version of the NDK used to compile fm-bridge is different from the one that was used to compile the other vendor binaries, so I decided to give it a try to build the whole vendor partition myself.

This turned out to be a non trivial process, because I was using the Halium tree to build the vendor image, and not the LineageOS which was used to build the vendor image for my device: I could make an image, but it took some time before I figured out which were the needed packages that somehow got lost because of the Halium changes and that had to be added to the Makefile.

To help my weak memory, I expanded the README file in the violet port with the steps needed in order to build the vendor image.

A system service for the FM radio

While it could be possible for Ubuntu Touch applications to directly access the FM radio device in the same way that Android applications do, this is suboptimal for a few reasons. Even if we provided a shared library to deal with the various radio chipset implementations, the application would either need to be unconfined, or we'd had to provide an ever-changing AppArmor profile that peeks new holes every time that a new device implementation is added (and what if this implemenation uses a generic kernel device, which could be used for other goals too?) and in any case we'd have to make this policy restricted, since the RDS data provided by the radio stations would reveal the user location (well, the city at least) to the application. Not to talk about concurrent access to the radio device if two applications attempt to use it.

Therefore, my proposition (and what I'll implement, if I'll live long enough or if someone doesn't beat me to it) is to have a system service deal with the various hardware differences and expose a D-Bus API that will be hooked up as a QRadioTunerControl plugin, so that Qt applications will be able to just use the QtMultimedia APIs to access the radio.

The service would also need to talk to the trust-store, to let the user decide whether the application should really be granted access to the FM receiver (and when using the turst-store, this decision is remembered, and revocable from the System Settings's Security panel). Of course we'll also need to add a fm-radio AppArmor policy to let applications use this service.

0 Add to favourites0 Bury

07 Dec 2021 4:41pm GMT

03 Nov 2021

feedPlanet Maemo

Breaking free of Google

This post will be for those of you that care about privacy - i.e. if you want that information about you is exclusively under your control.
In that context not only Google is to blame, but actually most of the cloud services we know and use today.

Still Google will serve us as a nice placeholder as it is the market-leader when it comes to providing free services in exchange for your user-profile that Google in turn uses to sell target advertising. Even if you are fine with that, Google is also infamous for killing services - which might hit the one you rely on eventually.

As the world is moving mobile-first, a prerequisite for replacing a service is that we can easily integrate the replacement with an Android device.
Some might wonder why I chose Android here, given that it is made by Google. See, the problem is not who makes a service/ device, but who controls it. And with Android the main leverage for Google is bundling its services. If you take them away, the device itself is fully under your control - in contrast to Apple/ iOS.

Now, that we set the stage, lets start with:

Nextcloud

At the heart of our efforts will be Nextcloud. This started as an open-source alternative to Dropbox/ Google Drive, but is nowadays grown into a platform for a plethora of different services.
The main selling-point is that you can just install Nextcloud on your own machine - ensuring that your data stays private. The software being Open-Source also means that it is not under control of a single corporation - in fact Nextcloud was forked from its predecessor Owncloud after a corporation tried to put the screws on its users.

Note, that if you are serious about this, you will need to invest around 500€ to get a machine for hosting that is decently fail-safe. If you rather want to be cheap, you can also just use a RaspberryPi to get away with less than half of that amount. For inspiration, you can take a look on the built I use or on the list of commercial nextcloud device providers.

Files & Photos

By using the Nextcloud Android App, you can directly replace Google Drive/ Dropbox as this is the core functionality of Nextcloud.

Additionally, the App allows you to automatically back-up your Photos/ Videos and free the local storage so you can stop using Google Photos too.

Contacts & Calendar

Nextcloud also supports Contacts and Calendar out of the box. To integrate them with into your Android Device there is the DAVx5 app. This app will function as an additional data provider, so you can just continue using the stock Google Contacts and Calendar apps. Those will, however, stop sending any data to Google.

This is especially useful, if you run a small-business and must ensure that your customer data is private according to the CCPA/ GDPR.

Nextcloud News

An often overlooked part of your privacy is Google News (also part of Google Now). Each time you view an article there, Google can mine your interests and political views - similar to what Facebook does. And by now you should know where these things can lead.

Another drawback here is that the Google Algorithm will create a bubble for you by only showing content coherent with your current world-view.
I still prefer to manually choose the news sources - to create that bubble myself.

To do that, one usual subscribes some Web-feeds using a Feed aggregator like the Feedly service - similar to what Google Reader used to offer, before being killed by Google.

The go-to app here is Nextcloud News combined with the Android App for a pleasant mobile usage.

Music

Most of you are probably just stream music via Spotify/ Youtube Music, but keep in mind that these services merely rent the songs and as such they can arbitrarily disappear from your library.

Therefore, I like to have my own copy of the song. Unfortunately it is very inconvenient to juggle mp3s around for getting the music to various devices.

Google Play Music used to offer best of both worlds for me, where you could upload your own music files and manage your playlists in one place. Additionally, you could make the music available offline by pinning individual playlists on your device.
Unfortunately, that concept did not allow Google to arbitrarily inject ads into my music stream and therefore the service got killed as well.

Nextcloud Music to the rescue! This app picks up your music library via Nextcloud files and allows to stream that via the Browser or the Subsonic API.
This is where the DSub Android Player takes over. As with Play Music, you can either stream the library or pin individual songs/ playlists for offline use. Note: untick the "Authorization Basic headers" box when setting-up Nextcloud Music.

Other

If you clicked on the links above, you probably noticed the F-Droid alternative app store for Android.
Getting your apps there ensures that you are using verified packages and open-source software. You can easily use it alongside with the Play Store. If that is too inconvenient for you, all of the above apps are also available via the Play Store.

Finally, there is the web-browser. If you do not log in with your Google Account, using Chrome is mostly safe. However, I suggest switching to Firefox. See the my original article on that topic for details. In short; the main reason is the availability of extensions. Those allow you to block ads on the mobile web too and use Youtube in the backround.

Header Image: Digital Chains by stanjourdan (CC-BY-SA-2.0)

0 Add to favourites0 Bury

03 Nov 2021 8:34pm GMT

10 Oct 2021

feedPlanet Maemo

QHtmlParser: writing an HTML parser with your brain switched off

While developing MiTubo I've recently felt the need of parsing HTML pages: the first problem I wanted to solve was implementing proper RSS feed detection when the user entered a website URL into MiTubo's search box, so that MiTubo would parse the site's HTML, look for <link rel="alternate"...> URLs in the HEAD section, and let the user subscribe to any video feeds found there.

A quick search in the internet did not provide a clear answer: I found a Qt HTML parser in (stalled) development, and a few other C++ or C parsers (among the latters, lexbor is the most inspiring), but all of them seem to take the approach of parsing the HTML file into a DOM tree, while I was hoping to find a lightweight SAX-like parser. Pretty much like Python's html.parser.

Anyway, I don't remember how it happened, but at a certain point I found myself looking at html.parser source code, and I was surprised to see how compact it was (apart, of course, for the long list of character references for the HTML entities!). Upon a closer look, it also appeared that the code was not making much use of Python's dynamic typing, so, I thought, maybe I could give it a try to rewrite that into a Qt class. And a few hours later QHtmlParser was born.

As this post's title suggests, the process of rewriting html.parser with Qt was quite straightforward, and the nice thing about it is that I didn't have to spend any time reading the HTML standard or trying to figure out how to implement the parser: I just had to translate Python code into C++ code, and thanks to the nice API of QString (which in many ways resembles Python's - or vice versa) this was not too hard. I even left most of the original code comments untouched, and reused quite a few tests from the test suite.

It was time well spent. :-)

If you think you might need an HTML parser for your Qt application, you are welcome to give it a try. It's not a library, just a set of files that you can import into your project; for the time being I only have a build file for QBS, but I'll happily accept contributions to make it easier to use QHtmlParser with projects built using other build systems. You can see here the changes I made in MiTubo to start using it and detect RSS feed in a webpage's HEAD.

That's all for now. And in case you missed the link before, you can find QHtmlParser here.

0 Add to favourites0 Bury

10 Oct 2021 7:57pm GMT

07 Aug 2021

feedPlanet Maemo

Beyond Google Bookmarks

I was a happy user of Del.icio.us for many years until the service closed. Then I moved my links to Google Bookmarks, which offered basically the same functionality (at least for my needs): link storage with title, tags and comments. I've carefully tagged and filed more than 2500 links since I started, and I've learnt to appreciate the usefulness of searching by tag to find again some precious information that was valuable to me in the past.

Google Bookmarks is a very old and simple service that "just works". Sometimes it looked as if Google had just forgotten about it and let it run for years without anybody noticing… until now. It's closing on September 2021.

I didn't want to lose all my links, still need a link database searchable by tags and don't want to be locked-in again in a similar service that might close in some years, so I wrote my own super-simple alternative to it. It's called bs, sort of bookmark search.

The usage can't be simpler, just add the tag you want to look for and it will print a list of links that have that tag:

$ bs webassembly
  title = Canvas filled three ways: JS, WebAssembly and WebGL | Compile
    url = https://compile.fi/canvas-filled-three-ways-js-webassembly-and-webgl/
   tags = canvas,graphics,html5,wasm,webassembly,webgl
   date = 2020-02-18 16:48:56
comment =  

  title = Compiling to WebAssembly: It's Happening! ★ Mozilla Hacks - the Web developer blog
    url = https://hacks.mozilla.org/2015/12/compiling-to-webassembly-its-happening/
   tags = asm.js,asmjs,emscripten,llvm,toolchain,web,webassembly
   date = 2015-12-18 09:14:35
comment = 

If you call the tools without parameters, it will prompt data to insert a new link or edit it if the entered url matches a preexisting one:

$ bs
url: https://compile.fi/canvas-filled-three-ways-js-webassembly-and-webgl/
title: Canvas filled three ways: JS, WebAssembly and WebGL | Compile
tags: canvas,graphics,html5,wasm,webassembly,webgl
comment:

The data is stored in an sqlite database and I've written some JavaScript snippets to import the Delicious exported bookmarks file and the Google Bookmarks exported bookmarks file. Those snippets are meant to be copypasted in the JavaScript console of your browser while you have the exported bookmarks html file open on it. They'll generate SQL sentences that will populate the database for the first time with your preexisting data.

By now the tool doesn't allow to delete bookmarks (I haven't had the need yet) and I still need to find a way to simplify its usage through the browser with a bookmarklet to ease adding new bookmarks automatically. But that's a task for other day. By now I have enough just by knowing that my bookmarks are now safe.

Enjoy!

[UPDATE: 2020-09-08]

I've now coded an alternate variant of the database client that can be hosted on any web server with PHP and SQLite3. The bookmarks can now be managed from a browser in a centralized way, in a similar fashion as you could before with Google Bookmarks and Delicious. As you can see in the screenshot, the style resembles Google Bookmarks in some way.

You can easily create a quick search / search engine link in Firefox and Chrome (I use "d" as keyword, a tradition from the Delicious days, so that if I type "d debug" in the browser search bar it will look for that tag in the bookmark search page). Also, the <span>0 <a href=Add to favourites0 Bury

07 Aug 2021 12:29pm GMT

01 Jul 2021

feedPlanet Maemo

Loonies 8192 now for Maemo 4 (N800) and MeeGo 1.2 Harmattan (N9)

As part of a summer clean-up of the desk drawers, I pulled out the N800 and N9 and ported my game Loonies 8192 to these devices. Since those are "proper" Linux devices, one can compile things directly on-device (just install gcc from the SDK repos), and with SSH, it's easy to type on a real keyboard.

Anyway, you can install the game via the landing pages:

For the N800, make sure "maemo Extras" is enabled so it will find libsdl1.2 if it's not already installed. Head over to https://loonies.thp.io/n800/ on the device and download the deb, it will be installed by Application manager.

For the N9, make sure you have n9repomirror installed (again, so libsdl1.2 can be installed if necessary). Enable third party applications in Settings, Applications, Installations. Then head over to https://loonies.thp.io/n9/ on the device and download the deb, selecting after the download is finished will ask you to install it.

The N9 version is also available on openrepos.net.

And don't forget that the game is also available for DOS, various consoles and handheld consoles as well as on Windows. All of the builds are available on itch.io.

0 Add to favourites0 Bury

01 Jul 2021 10:05am GMT

25 May 2021

feedPlanet Maemo

GStreamer WebKit debugging by using external tools (2/2)

This is the last post of the series showing interesting debugging tools, I hope you have found it useful. Don't miss the custom scripts at the bottom to process GStreamer logs, help you highlight the interesting parts and find the root cause of difficult bugs. Here are also the previous posts of the series:

How to debug pkgconfig

When pkg-config finds the PKG_CONFIG_DEBUG_SPEW env var, it explains all the steps used to resolve the packages:

PKG_CONFIG_DEBUG_SPEW=1 /usr/bin/pkg-config --libs x11

This is useful to know why a particular package isn't found and what are the default values for PKG_CONFIG_PATH when it's not defined. For example:

Adding directory '/usr/local/lib/x86_64-linux-gnu/pkgconfig' from PKG_CONFIG_PATH
Adding directory '/usr/local/lib/pkgconfig' from PKG_CONFIG_PATH
Adding directory '/usr/local/share/pkgconfig' from PKG_CONFIG_PATH
Adding directory '/usr/lib/x86_64-linux-gnu/pkgconfig' from PKG_CONFIG_PATH
Adding directory '/usr/lib/pkgconfig' from PKG_CONFIG_PATH
Adding directory '/usr/share/pkgconfig' from PKG_CONFIG_PATH

If we have tuned PKG_CONFIG_PATH, maybe we also want to add the default paths. For example:

SYSROOT=~/sysroot-x86-64
export PKG_CONFIG_PATH=${SYSROOT}/usr/local/lib/pkgconfig:${SYSROOT}/usr/lib/pkgconfig
# Add also the standard pkg-config paths to find libraries in the system
export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/usr/local/lib/x86_64-linux-gnu/pkgconfig:\
/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:\
/usr/lib/pkgconfig:/usr/share/pkgconfig
# This tells pkg-config where the "system" pkg-config dir is. This is useful when cross-compiling for other
# architecture, to avoid pkg-config using the system .pc files and mixing host and target libraries
export PKG_CONFIG_LIBDIR=${SYSROOT}/usr/lib
# This could have been used for cross compiling:
#export PKG_CONFIG_SYSROOT_DIR=${SYSROOT}

Man in the middle proxy for WebKit

Sometimes it's useful to use our own modified/unminified files with a 3rd party service we don't control. Mitmproxy can be used as a man-in-the-middle proxy, but I haven't tried it personally yet. What I have tried (with WPE) is this:

  1. Add an /etc/hosts entry to point the host serving the files we want to change to an IP address controlled by us.
  2. Configure a web server to provide the files in the expected path.
  3. Modify the ResourceRequestBase constructor to change the HTTPS requests to HTTP when the hostname matches the target:
ResourceRequestBase(const URL& url, ResourceRequestCachePolicy policy)
    : m_url(url)
    , m_timeoutInterval(s_defaultTimeoutInterval)
    ...
    , m_isAppBound(false)
{
    if (m_url.host().toStringWithoutCopying().containsIgnoringASCIICase(String("out-of-control-service.com"))
        && m_url.protocol().containsIgnoringASCIICase(String("https"))) {
        printf("### %s: URL %s detected, changing from https to http\n",
            __PRETTY_FUNCTION__, m_url.string().utf8().data());
        fflush(stdout);
        m_url.setProtocol(String("http"));
    }
}

:bulb: Pro tip: If you have to debug minified/obfuscated JavaScript code and don't have a deobfuscated version to use in a man-in-the-middle fashion, use http://www.jsnice.org/ to deobfuscate it and get meaningful variable names.

Bandwidth control for a dependent device

If your computer has a "shared internet connection" enabled in Network Manager and provides access to a dependent device , you can control the bandwidth offered to that device. This is useful to trigger quality changes on adaptive streaming videos from services out of your control.

This can be done using tc, the Traffic Control tool from the Linux kernel. You can use this script to automate the process (edit it to suit to your needs).

Useful scripts to process GStreamer logs

I use these scripts in my daily job to look for strange patterns in GStreamer logs that help me to find the cause of the bugs I'm debugging:

0 Add to favourites0 Bury

25 May 2021 6:00am GMT

18 May 2021

feedPlanet Maemo

GStreamer WebKit debugging by using external tools (1/2)

In this new post series, I'll show you how both existing and ad-hoc tools can be helpful to find the root cause of some problems. Here are also the older posts of this series in case you find them useful:

Use strace to know which config/library files are used by a program

If you're becoming crazy supposing that the program should use some config and it seems to ignore it, just use strace to check what config files, libraries or other kind of files is the program actually using. Use the grep rules you need to refine the search:

$ strace -f -e trace=%file nano 2> >(grep 'nanorc')
access("/etc/nanorc", R_OK)             = 0
access("/usr/share/nano/javascript.nanorc", R_OK) = 0
access("/usr/share/nano/gentoo.nanorc", R_OK) = 0
...

Know which process is killing another one

First, try to strace -e trace=signal -p 1234 the killed process.

If that doesn't work (eg: because it's being killed with the uncatchable SIGKILL signal), then you can resort to modifying the kernel source code (signal.c) to log the calls to kill():

SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
{
    struct task_struct *tsk_p;
    ...
    /* Log SIGKILL */
    if (sig & 0x1F == 9) {
        tsk_p = find_task_by_vpid(pid);

        if (tsk_p) {
            printk(KERN_DEBUG "Sig: %d from pid: %d (%s) to pid: %d (%s)\n",
                sig, current->pid, current->comm, pid, tsk_p->comm);
        } else {
            printk(KERN_DEBUG "Sig: %d from pid: %d (%s) to pid: %d\n",
                sig, current->pid, current->comm, pid);
        }
    }
    ...
}

Wrap gcc/ld/make to tweak build parameters

If you ever find yourself with little time in front of a stubborn build system and, no matter what you try, you can't get the right flags to the compiler, think about putting something (a wrapper) between the build system and the compiler. Example for g++:

#!/bin/bash
main() {
    # Build up arg[] array with all options to be passed
    # to subcommand.
    i=0
    for opt in "$@"; do
        case "$opt" in
        -O2) ;; # Removes this option
        *)
            arg[i]="$opt" # Keeps the others
            i=$((i+1))
            ;;
        esac
    done
    EXTRA_FLAGS="-O0" # Adds extra option
    echo "g++ ${EXTRA_FLAGS} ${arg[@]}" # >> /tmp/build.log # Logs the command
    /usr/bin/ccache g++ ${EXTRA_FLAGS} "${arg[@]}" # Runs the command
}
main "$@"

Make sure that the wrappers appear earlier than the real commands in your PATH.

The make wrapper can also call remake instead. Remake is fully compatible with make but has features to help debugging compilation and makefile errors.

Analyze the structure of MP4 data

The ISOBMFF Box Structure Viewer online tool allows you to upload an MP4 file and explore its structure.

0 Add to favourites0 Bury

18 May 2021 6:00am GMT

13 May 2021

feedPlanet Maemo

Mould King 13106 Forklift Review

I got myself the MouldKing 13106 Forklift, which is based on the MOC 3681 by KevinMoo and wanted to share my impressions with you.

First of all, MouldKing actually improved the set by exclusively using back technic pins instead of the blue ones like in the MOC. Also they are officially cooperating with the MOC designer - so he is likely getting some share of the sales.

The set comes with "New PowerModule 4.0″, which means it supports proportional output. If you use the new joystick controller (like I do in the video) or use the app, you can have smooth controls of the motors and not just binary 0% or 100% throttle as with the standard remote.

YouTube Video

As you can see, I actually put on some of the stickers. Some purists never do anything like this, because they argue that after some time the stickers start peeling off and look used. This is certainly a good point if you are building a sports-car - with a Forklift however, I would argue broken stickers add to the looks.

Compared to the original MOC, Mould King removed the lights, but added a pallet similar to the one found in the Lego 42079 Forklift.

Interested in getting the set? Support this Site by using the following affiliate Link:

Get this model on Amazon

Manual errata & comments

Generally, I prefer the Mould King manual to the original by Kevin Moo as I like renderings more than photographs. However, its nice to have the original at hand if something looks fishy. While building, I noticed the following:

Step 34: Cable-management is almost completely skipped in the manual. I laid all cables through the opening behind the threads. This keeps them out of the way later. The fiddle through the cables of the motors, that you add at steps 52 & 55.

Step 100: The battery-box position is wrong. It will collide with the bar you added at step 96. To make it fit, just rotate the battery-box by 180°.

Also, the direction of motor A has to be reversed. Press and hold left-shoulder, up and down for 3 seconds for this.

Step 111: The arms that you added in steps 89/ 90 should be oriented upwards to hold the footstep.

Step 143: Use a black bush instead of the 2-pin-axle beam, so things look symmetrical. This is a leftover from the original MOC, which squashed the IR receiver in there.

Step 156: Attach the levers to the front console at step 173 instead of attaching them to the seat here. After all they are supposed to control the fork and not the backrest.

Step 214: I suggest using gray 2-axles at step 230 instead of the suggested whites. This way the front facing axes will be all gray. For this just use white 2-axles here. Those wont be visible at all anyway.

Step 277: When adding the fork to the lift-arm, make sure that it has as much play as possible. Otherwise the fork will get stuck when moved all the way up.

Interior with fixes at step 143 & step 156

Step 278: Do not fix the threads yet. Wait until the end so you can correctly measure the lowest position of the fork (which gives you the length of the threads).

Step 286: Make sure that the 3-pin pops out towards the 8-axle. This will make joining things at step 288 much easier.

0 Add to favourites0 Bury

13 May 2021 5:11pm GMT

11 May 2021

feedPlanet Maemo

GStreamer WebKit debugging by instrumenting source code (3/3)

This is the last post on the instrumenting source code series. I hope you to find the tricks below as useful as the previous ones.

In this post I show some more useful debugging tricks. Don't forget to have a look at the other posts of the series:

Finding memory leaks in a RefCounted subclass

The source code shown below must be placed in the .h where the class to be debugged is defined. It's written in a way that doesn't need to rebuild RefCounted.h, so it saves a lot of build time. It logs all refs, unrefs and adoptPtrs, so that any anomaly in the refcounting can be traced and investigated later. To use it, just make your class inherit from LoggedRefCounted instead of RefCounted.

Example output:

void WTF::adopted(WTF::LoggedRefCounted<T>*) [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1
void WTF::adopted(WTF::LoggedRefCounted<T>*) [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1
^^^ Two adopts, this is not good.
void WTF::LoggedRefCounted<T>::ref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1 --> ...
void WTF::LoggedRefCounted<T>::ref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount ... --> 2
void WTF::LoggedRefCounted<T>::deref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 2 --> ...
void WTF::LoggedRefCounted<T>::deref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount ... --> 1
void WTF::adopted(WTF::LoggedRefCounted<T>*) [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1
void WTF::LoggedRefCounted<T>::deref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1 --> ...
void WTF::LoggedRefCounted<T>::deref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1 --> ...
^^^ Two recursive derefs, not good either.
#include "Logging.h"

namespace WTF {

template<typename T> class LoggedRefCounted : public WTF::RefCounted<T> {
    WTF_MAKE_NONCOPYABLE(LoggedRefCounted); WTF_MAKE_FAST_ALLOCATED;
public:
    void ref() {
        printf("%s: this=%p, refCount %d --> ...\n", __PRETTY_FUNCTION__, this, WTF::RefCounted<T>::refCount()); fflush(stdout);
        WTF::RefCounted<T>::ref();
        printf("%s: this=%p, refCount ... --> %d\n", __PRETTY_FUNCTION__, this, WTF::RefCounted<T>::refCount()); fflush(stdout);
    }

    void deref() {
        printf("%s: this=%p, refCount %d --> ...\n", __PRETTY_FUNCTION__, this, WTF::RefCounted<T>::refCount()); fflush(stdout);
        WTF::RefCounted<T>::deref();
        printf("%s: this=%p, refCount ... --> %d\n", __PRETTY_FUNCTION__, this, WTF::RefCounted<T>::refCount()); fflush(stdout);
    }

protected:
    LoggedRefCounted() { }
    ~LoggedRefCounted() { }
};

template<typename T> inline void adopted(WTF::LoggedRefCounted<T>* object)
{
    printf("%s: this=%p, refCount %d\n", __PRETTY_FUNCTION__, object, (object)?object->refCount():0); fflush(stdout);
    adopted(static_cast<RefCountedBase*>(object));
}

} // Namespace WTF

Pause WebProcess on launch

WebProcessMainGtk and WebProcessMainWPE will sleep for 30 seconds if a special environment variable is defined:

export WEBKIT2_PAUSE_WEB_PROCESS_ON_LAUNCH=1

It only works #if ENABLE(DEVELOPER_MODE), so you might want to remove those ifdefs if you're building in Release mode.

Log tracers

In big pipelines (e.g. playbin) it can be very hard to find what element is replying to a query or handling an event. Even using gdb can be extremely tedious due to the very high level of recursion. My coworker Alicia commented that using log tracers is more helpful in this case.

GST_TRACERS=log enables additional GST_TRACE() calls all accross GStreamer. The following example logs entries and exits into the query function.

GST_TRACERS=log GST_DEBUG='query:TRACE'

The names of the logging categories are somewhat inconsistent:

The log tracer code is in subprojects/gstreamer/plugins/tracers/gstlog.c.

0 Add to favourites0 Bury

11 May 2021 6:00am GMT

07 May 2021

feedPlanet Maemo

Comparing water filters

Lets say, you want to reduce the water carbonate hardness because you got a shiny coffee machine and descaling that is a time-consuming mess.

If you dont happen to run a coffee-shop, using a water-jug is totally sufficient for this. Unfortunately, while the jug itself is quite cheap, the filters you need will cost you an arm and a leg - similar to how the printer-ink business works.

The setup

Here, we want to look at the different filter options and compare their performance. The contenders are

Name Pricing
Brita Classic ~15.19 €
PearlCo Classic 12.90 €
PearlCo Protect+ 15.90 €

As said initially, the primary goal of using these filters is to reduce the water carbonate - any other changes, like pH mythology, will not be considered.

To measure the performance in this regard, I am using a digital total dissolved solid meter - just like the one used in the Wikipedia article. To make the measurement robust against environmental variations, I am not only measuring the PPM in the filtered water, but also in the tap water before filtering. The main indicator is then the reduction factor.

Also, you are not using the filter only once, so I repeat the measuring over the course of 37 days. Why 37? Well, most filters are specified for 30 days of usage - but I want to see how much cushion we got there.

So - without further ado - the results:

Results

Name Ø PPM reduction Ø absolute PPM
Brita Classic 31% 206
PearlCo Classic 24% 218
PearlCo Protect+ 32% 191

As motivated above, the difference in absolute PPM can be explained by environmental variation - after all the measurements took place over the course of more than 3 months.

However, we see that the pricing difference is indeed reflected by filtering performance. By paying ~20% more, you get a ~30% higher PPM reduction.

The only thing missing, is the time-series to see beyond 30 days:

As you can see, the filtering performance is continuously declining after a peak at about 10-15 days of use.

And for completeness, the absolute PPM values:

0 Add to favourites0 Bury

07 May 2021 6:08pm GMT