How to compute the sine function, on a CPU with no FPU.

There exists a maxim in the publishing world, which is, ‘Publish or Perish.’ I guess it’s a good thing I’m not a publisher, then. In any case, it’s been a while since I posted anything, so I decided to share with the community some wisdom that existed in the early days of computing, and when I say that, it really means, ‘back in the early days’. This is something that might have been used on mini-computers, or, on the computers in certain special applications, before PCs as such existed.

A standard capability which should exist, is to compute a decently accurate sine function. And one of the most lame reasons could be, the fact that audio files have been encoded with an amplitude, but that a decoder, or speech synthesis chip, might only need to be able to play back a sine-wave, that has that encoded peak amplitude. However, it’s not always a given that any ‘CPU’ (“Central Processing Unit”) actually possesses an ‘FPU’ (a “Floating-Point Unit”). In such situations, programmers back-when devised a trick.

It’s already known, that a table of pre-computed sine functions could be made part of a program, numbering maybe 256, but that, if all a program did was, to look up sine values from such a table once, ridiculously poor accuracies would initially result. But it was also known that, as long as the interval of 1 sine-wave was from (zero) to (two-times-pi), the derivative of the sine function was the cosine function. So, the trick, really, was, to make not one lookup into the table, but at least two, one to fetch an approximate sine value, and the next, to fetch an approximate cosine value, the latter of which was supposedly the derivative of the sine value at the same point. What could be done was, that a fractional part of the parameter, between table entries, could be multiplied by this derivative, and the result also added to the sine value, thus yielding a closer approximation to the real sine value.

But, a question which readers might have about this next could be, ‘Why does Dirk not just look up two adjacent sine-values, subtract to get the delta, and then, multiply the fractional part by this delta?’ And the answer is, ‘Because one can not only apply the first derivative, but also the second derivative, by squaring the fractional part and halving it (:1), before multiplying the result from that, by the negative of the sine function!’ One obtains a section of a parabola, and results from a 256-element table, that are close to 16 bits accurate!

The source code can be found in my binaries folder, which is:

https://dirkmittler.homeip.net/binaries/

And, in that folder, the compressed files of interest would be, ‘IntSine.tar.gz’ and ‘IntSine.zip’. They are written in C. The variance that I get, from established values, in (16-bit) integer units squared, is “0.811416” “0.580644” (:2). Any variance lower than (1.0) should be considered ‘good’, since (±1) is actually the smallest-possible, per-result error.


(Updated 12/03/2020, 12h55… )

Continue reading How to compute the sine function, on a CPU with no FPU.

About testing a subwoofer with open-source software, and some inadequate skills in music.

One of the things which I will never be, is a Musician. However, I think I have some skills in Math and Technology. This allows me to play with open-source software such as the “Linux Multimedia Studio”, and also, to try testing a subwoofer which I bought back in 2019. However, my lack of skill in the field actually caused me to underrate the performance of the subwoofer considerably. Why? Let me explain.

I once had an acquaintance, who was a Musician, and who told me, that the musical scale had intentionally been detuned, or retuned, in a specific way. I had already heard that the note ‘A below Middle C’ was meant since olden times, to refer to a frequency of 440Hz. Yet, according to this Musician, in more recent times, that same note had been retuned to 441Hz. My own personal guess as to why would be, to force at least one note on the Chromatic Scale to have a rational relationship with the sample-rate of Audio CDs, which was 44.1kHz.

According to Western music several centuries ago, the Diatonic Scale had been invented, so that its notes had frequencies with rational relationships. But it was missing the so-called ‘black keys’. What the Chromatic Scale, which was invented later, did, was to detune the existing Diatonic notes, so that all the key-positions, including the black keys, became a sort of logarithm of frequency. According to modern realities, the exact relationships between two adjacent Chromatic notes, is the same over an entire octave, so that each octave again, represents an exact doubling or halving of frequencies. According to that, a maximum of one note, ‘A’, could have a rational frequency in Hertz, and all the other frequencies, in Hertz, end up being irrational.

But, that same note can have slightly greater clarity when sampled, if one sine-wave occupied exactly 100 samples. Thus, my presumed reason for retuning A-below-Middle-C to 441Hz. Theoretically, a sine-wave can be sampled, with an irrational frequency, in relationship to the sample rate. But, when that is done, the clarity with which it gets played back depends strongly on the quality of ‘the low-pass filter’, which is also known as the quality of ‘the interpolation’.

(Edit 10/28/2020, 8h20: )

Actually, playing back a frequency of 440Hz at that sample rate, differs from the rational situation by 1Hz. Because it’s factually untrue, that the period of time taken into account by the low-pass filter, would be as long as 1 second, what should result is non-participation by the low-pass filter, but possibly audibly, for people who have very fine hearing, some sort of ‘beating’ or ‘interference effect’, with its own frequency of 1Hz.

To make things worse, what the listener will seem to hear is, one frequency at 441Hz anyway, even though the scale might be tuned to place that note at 440Hz, but with that one note being modulated in some non-specific way.

(End of Edit 10/28/2020, 8h20. )

(Edit 10/28/2020, 19h00: )

In addition to that, a third frequency will physically be present, at ~439Hz, to account of this modulation. This would be similar to the concept of ‘amplitude modulation’.

(End of Edit 10/28/2020, 19h00. )

So, here is the mistake I made. I did not know that the note ‘C’ always begins a new octave. Thus, I was able to play the ‘A’ note which is below ‘Middle C’, as well as the ‘A’ note which is below ‘C1′. But, even when playing with this software, I had failed to notice that the numbering of ‘Middle C’ was ‘C5′, not, ‘C4‘. But, ‘A below Middle C’ was still ‘A4′.

Therefore, naively, I played ‘A below C1′. But I thought that I was sending a frequency of 55.125Hz to my newly purchased subwoofer, when in fact, I was sending it a frequency of 27.5625Hz. The subwoofer reproduced the lower of the two frequencies with excellence, causing my walls to shake, and, making it impossible for me to discern that it was in fact an ‘A’. But a person with musically trained ears would have noticed, that the musical tone of ‘A below C2′ is easy to discern, while this musical tone of ‘A below C1′ is almost impossible to discern.

So, the subwoofer performs much better, than I gave it credit for doing.

Screenshot_20201027_202511

Screenshot_20201027_202544

 

Dirk

 

ChromeOS Upgrade from Debian 9 to Debian 10 – aka Buster – Google Script crashed.

I have one of those Chromebooks, which allow a Linux subsystem to be installed, that subsystem being referred to in the Google world as “Crostini”. It takes the form of a Virtual Machine, which mounts a Container. That container provides the logical hard drive of the VM’s Guest System. What Google had done at some point in the past was, to install Debian 9 / Stretch as the Linux version, in a simplified, automated way. But, because Debian Stretch is being replaced by Debian 10 / Buster, the option also exists, to upgrade the Linux Guest System to Buster. Only, while the option to do so manually was always available to knowledgeable users, with the recent Update of ChromeOS, Google insists that the user perform the upgrade, and provides ‘an easy script’ to do so. The user is prompted to click on something in his ChromeOS settings panel.

What happened to me, and what may also happen to my readers is, that this script crashes, and leaves the user with a ChromeOS window, that has a big red symbol displayed, to indicate that the upgrade failed. I failed to take a screen-shot of what this looks like. The button to offer the upgrade again, is thankfully taken away at that point. But, if he or she reaches that point, the user will need to decide what to do next, out of essentially two options:

  • Delete the Linux Container, and set up a new one from scratch. In that case, everything that was installed to, or stored within Linux will be lost. Or,
  • Try to complete the upgrade in spite of the failed script.

I chose to do the latter. The Linux O/S has its own method of performing such an upgrade. I would estimate that the reason for which the script crashed on me, might have been Google’s Expectation that my Linux Guest System might have 200-300 packages installed, when in fact I have a much more complete Linux system, with over 1000 packages installed, including services and other packages that ask for configuration options. At some point, the Google Script hangs, because the Linux O/S is asking an unexpected question. Also, while the easy button has a check-mark checked by default, to back up the Guest System’s files before performing the upgrade, I intentionally unchecked that, simply over the knowledge that I do not have sufficient storage on the Chromebook, to back up the Guest System.

I proceeded on the assumption, that what the Google script did first was, to change the contents of the file ‘/etc/apt/sources.list’, as well as of the directory ‘/etc/apt/sources.list.d’, to specify the new software sources, associated with Debian Buster as opposed to Debian Stretch. At that point, the Google script should also have set up, whatever it is that makes Crostini different from stock Linux. Only, once in the middle of the upgrade that follows, the Google script hanged.

(Updated 10/25/2020, 22h55… )

Continue reading ChromeOS Upgrade from Debian 9 to Debian 10 – aka Buster – Google Script crashed.

Garmin fenix 5x auto-update stuck at 50%.

I just recently purchased a ‘Garmin fenix 5x’ smart-watch, with emphasis on sports features. And, to make the watch work as smoothly as possible, it was necessary to allow it to install its latest firmware version, which happens to be 20.0 at the time of this posting. But there was a problem. I was intending to use this watch mainly with the ‘Garmin Connect app’, available on Google Play, which communicates with the watch only via Bluetooth. (:1) Installing a firmware upgrade to an unknown, generic device, via Bluetooth, depends on how large a file-size the F/W upgrade is supposed to have. Bluetooth tends to be a slow interface, in the day and age where WiFi as fast as 802.11n is possible. And in this case, the update was apparently stuck at 50%, perhaps not even due to how slow the file transfer would have been, but rather, due to Garmin preferring we install the update via the ‘Garmin Express application’, of which there is a Windows as well as a macOS version.

Problem? I neither have a Windows, nor a macOS device. I depend on installing that update otherwise. But, as indicated below, I found a solution that seems to work for me…

The ‘fenix 5x’ allows the watch itself to be connected to a WiFi network. The possibility should exist, to restart the update process, but, using the watch’s WiFi link, not the Bluetooth upgrade that somehow got broken. In order to accomplish that, the first thing I needed to do was, to add my home WiFi network to the watch’s WiFi networks. Fortunately for me, because the actual Bluetooth pairing between the watch and Android app works 100%, I was able to set up WiFi for the watch, using the Android app.

My phone is a Samsung Galaxy S9, with its latest firmware, and my Garmin Connect app is up-to-date.

The next thing needed to be done manually, because the watch did not just abandon its discontinued Bluetooth upgrade in favour of a new, WiFi-based upgrade.

  • On the watch, Press the ‘Menu’ and the ‘Up’ button simultaneously,
  • Next, Scroll Down to the ‘Settings Entry’,
  • Press the ‘Activate’ button once,
  • Scroll Down to the ‘System Entry’,
  • Press the ‘Activate’ button once, again,
  • Scroll down to the (last) ‘Software Update Entry’,
  • Press the ‘Activate’ button once, again,
  • There should be an ‘Auto-Update Entry’ set to ‘On’, as well as an ‘Update Available Entry…’ Scroll to this last Entry, if there is one after the ‘Auto-Update Entry’.
  • Press the ‘Activate’ button again, once,
  • Press ‘Continue’ if so instructed,
  • Repeat until doing this no longer reveals an ‘Update Available Entry’. At that point, the last menu should only have the ‘Auto-Update (== On) Entry’.

Because the watch was set up to connect to my WiFi without problems, it was able to install a major and a minor update quickly and without issues. After its major update, it restarted.

 

(Update 10/12/2020, 16h05: )

Continue reading Garmin fenix 5x auto-update stuck at 50%.