PodcastsEducationHacker Public Radio

Hacker Public Radio

Hacker Public Radio
Hacker Public Radio
Latest episode

272 episodes

  • Hacker Public Radio

    HPR4652: simon says

    2026/06/02
    This show has been flagged as Clean by the host.



    From https://en.wikipedia.org/wiki/Simon_(game)




    Simon is an electronic game of short-term memory skill invented by Ralph H. Baer and Howard J. Morrison, working for toy design firm Marvin Glass and Associates, with software programming by Lenny Cope. The device creates a series of tones and lights and requires a user to repeat the sequence. If the user succeeds, the series becomes progressively longer and more complex. Once the user fails or the time limit runs out, the game is over. The original version was manufactured and distributed by Milton Bradley and later by Hasbro after it took over Milton Bradley. Much of the assembly language code was written by Charles Kapps, who taught computer science at Temple University and also wrote one of the first books on the theory of computer programming. Simon was launched in 1978 at Studio 54 in New York City and was an immediate success, becoming a pop culture symbol of the 1970s and 1980s












































    Provide feedback on this episode.
  • Hacker Public Radio

    HPR4651: HPR Community News for May 2026

    2026/06/01
    This show has been flagged as Explicit by the host.

    New hosts
    There were no new hosts this month.
    Last Month's Shows
    Id Day Date Title Host 4630 Fri 2026-05-01 Playing Civilization V, Part 11 Ahuka 4631 Mon 2026-05-04 HPR Community News for April 2026 HPR Volunteers 4632 Tue 2026-05-05 Hackerpublic Radio New Years Eve Show 2026 Episode 6 Honkeymagoo 4633 Wed 2026-05-06 Ham Radio Licence Lee 4634 Thu 2026-05-07 Upgrade Failsause operat0r 4635 Fri 2026-05-08 What did I do at work today? Part 3 Section 1 Lee 4636 Mon 2026-05-11 7 seconds memory Antoine 4637 Tue 2026-05-12 UNIX Curio #6 - at and batch Vance 4638 Wed 2026-05-13 Simple Podcasting - Episode 3 - Analyzing and Filtering Whiskeyjack 4639 Thu 2026-05-14 NLUUG Spring Conference 2026 Ken Fallon 4640 Fri 2026-05-15 Robert A. Heinlein Ahuka 4641 Mon 2026-05-18 Technical Dutch Open Source Event (T-DOSE) Ken Fallon 4642 Tue 2026-05-19 Hackerpublic Radio New Years Eve Show 2026 Episode 7 Honkeymagoo 4643 Wed 2026-05-20 HPR Beer Garden 13 - Triple IPA Kevie 4644 Thu 2026-05-21 Response to comments on HPR4424: Newsboat... Archer72 4645 Fri 2026-05-22 ZERO HOUR: FRIDAY AFTERNOON APK HACKING operat0r 4646 Mon 2026-05-25 Mobile Gaming Elsbeth 4647 Tue 2026-05-26 UNIX Curio #7 - Compression Vance 4648 Wed 2026-05-27 Simple Podcasting - Episode 4 - Audio Analysis Fun Whiskeyjack 4649 Thu 2026-05-28 What did I do at work today? Part 3 Section 2 Lee 4650 Fri 2026-05-29 Playing Civilization V, Part 12 Ahuka Comments this month
    Past shows
    hpr4424 (2025-07-17) "How I use Newsboat for Podcasts and Reddit" by Archer72.

    أحمد المحمودي said: "How did I find HPR" (2026-05-12 17:16:07)

    candycanearter07 said: "Re: How did I find HPR" (2026-05-12 19:36:04)

    hpr4502 (2025-11-04) "Cheap Yellow Display Project Part 3: Reverse beacon network " by Trey.

    Archer72 said: "Morse code" (2026-05-19 15:00:39)

    hpr4567 (2026-02-03) "Movie Recommendations for Hackers" by Deltaray.

    Antoine said: "Some watched!" (2026-05-27 03:33:12)

    hpr4587 (2026-03-03) "UNIX Curio #1 - Shell Archives" by Vance.

    Dave Morriss said: "Great reminder! I had forgotten shar" (2026-05-07 18:18:05)

    Vance said: "Color printing" (2026-05-08 22:02:23)

    hpr4607 (2026-03-31) "UNIX Curio #3 - basename and dirname" by Vance.

    Vance said: "Correction" (2026-05-12 01:03:12)

    hpr4618 (2026-04-15) "Simple Podcasting - Episode 2 - Basic Filtering" by Whiskeyjack.

    Henrik Hemrin said: "Generating sine wave" (2026-05-14 19:59:46)

    Whiskeyjack said: "Reply to Henrik Hemrin on Sine Waves in HPR4618" (2026-05-15 15:22:16)

    hpr4627 (2026-04-28) "UNIX Curio #5 - Faster, Pussycat! Kill! Kill!" by Vance.

    Steve Barnes said: "Thanks for the context!" (2026-05-21 05:28:05)

    hpr4628 (2026-04-29) "Nuclear Power Technology Follow Up" by Whiskeyjack.

    Antoine said: "o/" (2026-05-17 00:24:23)

    Whiskeyjack said: "Reply to Antoine on HPR4628" (2026-05-17 18:08:18)

    This month's shows
    hpr4631 (2026-05-04) "HPR Community News for April 2026" by HPR Volunteers.

    Whiskeyjack said: "Response to Ken Fallon in HPR4631 Community News" (2026-05-04 05:13:02)

    candycanearter07 said: "new episodes" (2026-05-04 18:47:39)

    Ken Fallon said: "new candycanearter07 episodes" (2026-05-05 09:00:00)

    أحمد المحمودي said: "Thanks for the encouragement" (2026-05-12 17:18:20)

    hpr4634 (2026-05-07) "Upgrade Failsause" by operat0r.

    YourName said: "Why is the audio so bad OMG sorry" (2026-05-06 20:05:43)

    Ken Fallon said: "Already reported and fixed" (2026-05-06 20:35:49)

    hpr4637 (2026-05-12) "UNIX Curio #6 - at and batch" by Vance.

    candycanearter07 said: "still useful!" (2026-05-13 03:43:37)

    norrist said: "at for scheduled reboots" (2026-05-16 19:41:04)

    Vance said: "Good points" (2026-05-17 03:03:47)

    Whiskeyjack said: "At and batch in HPR4637" (2026-05-17 18:35:11)

    hpr4640 (2026-05-15) "Robert A. Heinlein" by Ahuka.

    Antoine said: "Nice tips" (2026-05-17 00:22:01)

    Kevin O'Brien said: "I enjoyed doing it" (2026-05-17 19:14:19)

    hpr4646 (2026-05-25) "Mobile Gaming" by Elsbeth.

    candycanearter07 said: "my opinion of mobile gaming" (2026-05-27 00:24:58)

    hpr4647 (2026-05-26) "UNIX Curio #7 - Compression" by Vance.

    xmanmonk said: "Great Series" (2026-05-27 00:29:32)

    candycanearter07 said: "thoughts" (2026-05-27 13:20:13)

    Mailing List discussions
    Policy decisions surrounding HPR are taken by the community as a whole. This discussion takes place on the Mailing List which is open to all HPR listeners and contributors. The discussions are open and available on the HPR server under Mailman.
    The threaded discussions this month can be found here:
    https://lists.hackerpublicradio.com/pipermail/hpr/2026-May/thread.html Events Calendar
    With the kind permission of LWN.net we are linking to The LWN.net Community Calendar.
    Quoting the site:
    This is the LWN.net community event calendar, where we track events of interest to people using and developing Linux and free software. Clicking on individual events will take you to the appropriate web page. Provide feedback on this episode.
  • Hacker Public Radio

    HPR4650: Playing Civilization V, Part 12

    2026/05/29
    This show has been flagged as Clean by the host.

    In our sample game we look at playing as Austria and aiming for a Diplomatic Victory. And our focus is on puppeting Citty-States, but be I misunderstood and instead of making a Diplomatic Victory easier, it makes it harder. I still managed to get my Diplomatic Victory, but a Science or Domination Victory would definitely have been easier in this scenario.

    Playing Civilization V, Part 12

    A Diplomatic Victory Strategy

    Civilization V introduced a new Victory type and I thought it might be fun to try this strategy for a sample game to see broadly how this would work. I decided I would play as Austria on Prince level, which means that all players are equal and no one is favored. For my map I chose Fractal, Map Size = Standard, Game speed = Standard. My only Advanced Option was Quick Combat, because I didn’t need to see that drawn out, particularly since I plan to avoid combat as much as necessary. My leader is Maria Theresa, and her Austria has a unique ability called Diplomatic Marriage. This allows us to either Annex or Puppet any city-state that has been allied to us for 5 turns with the proper expenditure of Gold. My plan was to use this to Puppet the city-states to control their votes for the Diplomatic Victory, but that was a misunderstanding. I actually implemented one of the hardest ways to win a Diplomatic Victory. But that is what I did. Now to get them to ally with me the most effective way to do this is with cash and lots of it, and of course even more cash to actually effect to Puppeting of them. So my overriding objective in this game is to amass a large Treasury. But of course I cannot ignore my military either, since a weak military invites attacks form greedy neighbors. And I may need to “liberate” the occasional city-state if another player conquers them. Austria also has a Unique Unit, the Hussar, which replaces the Cavalry unit. It can move after attacking, has a flanking bonus, and has one extra movement. And the Unique Building is the Coffee House, which increases the generation of Great People in the city by 25%. So you can expect me to build these in every city as well.

    With that in mind, I started the game and settled in place, I had Mountains nearby, but also Sheep and Silver within my city, so some useful resources. I immediately started to produce a Scout as my first unit, and sent my Warrior out to explore. In the very early stage I focus on exploring the surrounding area and finding any Goody Huts, i.e. Ruins. My initial city site is not exactly ideal, as it is all hilly with Jungle nearby. After building my two Scouts, my next priority was to build a Worker unit to increase the productivity of my city. And for my first social policy I unlocked Tradition. When I got my second policy I picked Oligarchy, and plan to complete all of the Tradition tree. I cleared out a Barbarian encampment, and then discovered my first City-state, Vilnius. Then I needed to clear out another Barbarian encampment that was blocking me from finishing my exploration. Meanwhile I am focusing on getting techs for sailing the ocean blue, because that is how I plan to get trade routes, discover City-states I can puppet, and so on.

    Because money is key to my strategy I made a beeline for Currency in the my Science research. And while headed there I completed the Tradition tree. When I can get there I will work on the Commerce tree to maximize my cash, but until then the Patronage tree will let me improve my City-state relations, which is important for improving my relationships with City-states. After all, you need to be allies with them for 5 turns before you can puppet them. I now have three cities, and can probably squeeze out a few more, which should be sufficient to my needs.

    At Turn 141 I have 6 cities, which is all I will build in this game. I now have the technology to build Workshops, which are the first productivity boosters available, so I set all my cities to building them. For Research my immediate object was to get to Compass so I could build the Galleass, which would let me do more ocean exploration. But to go into deep Ocean I will need to go further to get Astronomy, which will let me build the Caravel which can enter deep ocean. Once I got that I switched to Banking, not just for the money, but as a prerequisite to building the Forbidden Palace, which grants two additional delegates in the World Congress/United Nations. When I get Banking I’ll go back to Astronomy, and then Navigation, to advance my seagoing capabilities.

    By Turn 216 I had gotten Banking and started on the Forbidden Palace. And by luck, just as I got started I got a Great Engineer. I am holding him in reserve in case I need to hurry production, since Great Engineers are the only way to do that in Civ 5. I also picked up Astronomy, which will let me build Caravels to explore the whole ocean. My next research priority will be Gunpowder since it is time to beef up my defenses.

    At Turn 240 my Caravels started to come out, and I found several new City-States. And since my Treasury is healthy (I started with 6,000 gold, and I’m bringing in 100 each turn), I began the process of puppeting the City-states.

    Puppeting City-states as Austria

    Let’s look at this in detail since it is important. The requirements are 2 things:

    Be allied with the City-state for 5 consecutive turns

    Have the cash needed. This amount is not too much early on, but it rises over time.

    So, how do you become allies with a City-state? There are a number of things you can do to improve your relationship. You can take on a quest that a City-state has published, which can be things like “Find another Natural Wonder” or “Create a Great Admiral”. These quests pop up continuously throughout the game, and you are free to ignore them, but fulfilling one will improve your relationship. Trade will also improve your relationship, so in this game all of my Trade routes were made with City-states. If you are in a position to have a successful war, you can find a former City-state that was conquered by one of the other Empires, liberate it, and then it will be your ally for the rest of the game. Giving them presents is how I usually do it, though. You can give them units or money. If your purpose is to get allies, money works best. But I do gift units in 2 circumstances. First, if I have obsolete units, giving them away might be better then deleting them. Second, if a City-state is under attack by another Empire. Gifting them units might help them hold out and make life difficult for a rival.

    The place where all of this is done is the City-state screen which opens up when you click on the bar above the City-state, which is where you handle all of your relationships. At the top of this screen you see your current status, which more often than not will be Neutral, which is how all City-state relationships start out. But you can get them angry by, for instance, moving a unit of your into their territory. If you only do it once, and give them time to get over it, they will go back to Neutral. You can also improve the relationship by pledging to protect them, but be careful. If they get attacked and you do not try to protect them, they will get very angry. Giving a gift opens a pop-up to say what kind of gift: 250 gold, 500 gold, 1000 gold, or a Unit. Note that a Unit is only worth 5 influence points, while 250 Gold is worth 20, so as I said Money is more powerful if your aim is to improve your status with them.

    So at Turn 242 I found the City-state of Singapore, and it appears that I was the first Empire to find them. So I immediately pledged to protect them. My Influence with them was 20, which is Neutral. We just met, and that is where things stand on first meeting. The be Friends you need to get to 30, and to be allies you need to get to 60. When I clicked Next Turn, I got a Quest from Singapore. They were worried about a Barbarian Encampment nearby, and if I cleared it out I would get additional influence with them. In this case, though, I let that go by. I want to move more quickly, and Singapore is across the Ocean from me. My influence with them at this point was 21, so only a modest increase. But I have 6038 Gold in my Treasury, and I am bringing in 102 per turn. So let’s see what a gift of 500 Gold will do. It brings me to 65 influence, so we are now Allies. But when I mouse-over Singapore, the pop-up window reminds me that my Influence will decrease by 1.12 per turn. For an Empire other than Austria this would mean a regular infusion of cash to keep up your status. And I have won Diplomatic victories with other Empires by saving up a lot of cash and dumping it on City-states just before the United Nations vote.

    But for Austria you have special ability called Diplomatic Marriage that lets you turn the City-state into a Puppet, and that is permanent. But it also presents some obstacles as we will see. We are allies now, but my influence will drop by 1 each turn, and I might lose my allyship before I can puppet them. But I can gift a unit and get another 5, and I happen to have a very obsolete Warrior unit that will serve the purpose. However, it takes three turns for the Unit to arrive, so I lose few more points. At Turn 247 I can now use the diplomatic Marriage option to make a puppet of Singapore. Prior to doing this I was fourth in score with 604, while the leader had 729. My Happiness Level was +25, and I now had 5833 Gold in my Treasury. Then I made Singapore a puppet, and now I am third in the game with a score of 664. My Treasury has fallen to 5258, which means it cost me 575 Gold. But most significant is that my Happiness fell from +25 to +9, which is a huge loss. I have enough gold to puppet 4-5 more City-states at this time but if I did I would have rebellions breaking out and my Empire would eventually collapse.

    This is the obstacle that Austria has to face. We need to promote Happiness before we go much further with making puppets. Civ is always a game of balances.

    Links

    https://civilization.fandom.com/wiki/City-state_(Civ5)

    https://civilization.fandom.com/wiki/Austrian_(Civ5)

    https://www.palain.com/gaming/civilization-v/playing-civilization-v-part-12/

    Provide feedback on this episode.
  • Hacker Public Radio

    HPR4649: What did I do at work today? Part 3 Section 2

    2026/05/28
    This show has been flagged as Explicit by the host.



    It is suggested reviewing the episode
    What did I do at work today? Part 3 Section 1
    prior to listening










    Test driven development
    - a way of writing code that involves writing an automated unit-level test case that fails, then writing just enough code to make the test pass, then refactoring both the test code and the production code, then repeating with another new test case. -
    https://en.wikipedia.org/wiki/Test-driven_development










    Joplin
    - Joplin is an open source, cross platform note-taking app. -
    https://joplinapp.org/










    PHP
    - A popular general-purpose scripting language that is especially suited to web development. Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world. -
    https://www.php.net/










    MySQL
    - MySQL is an open-source relational database management system. MariaDB is a community developed fork of MySQL, often installing the MySQL package on a Linux distribution will actually install MariaDB. -
    https://en.wikipedia.org/wiki/MySQL
    -
    https://mariadb.org/
    -
    https://www.mysql.com/










    Sublime Text
    - Cross platform text editor -
    https://www.sublimetext.com/










    Nmap
    - Network Mapper is a free and open source utility for network discovery and security auditing -
    https://nmap.org/










    Markdown Fenced code blocks
    - "A code fence is a sequence of at least three consecutive backtick characters (`) or tildes (~). (Tildes and backticks cannot be mixed.) A fenced code block begins with a code fence, preceded by up to three spaces of indentation. The line with the opening code fence may optionally contain some text following the code fence; this is trimmed of leading and trailing spaces or tabs and called the info string. ... Although this spec doesn’t mandate any particular treatment of the info string, the first word is typically used to specify the language of the code block."







    ```ruby
    def foo(x)
    return 3
    end
    ```









    from CommonMark Spec at
    https://commonmark.org/
    (CommonMark is a standard, interoperable and testable version of Markdown.)










    Writing to a Database with PHP








    The following PHP method is implemented within a database access class:







    function create_with_id($id, $name) {
    $born = time();
    $id = mysqli_real_escape_string($this->db, $id);
    $name = mysqli_real_escape_string($this->db, $name);
    $sql = "INSERT INTO object
    (object_id, display_name_text, born, died)
    VALUES
    ($id, '$name', $born, 0);
    ";
    db_run_sql($this->db, $sql);
    }









    Note




    db_run_sql




    is a helper function defined elsewhere, not a built in function, and the property




    db




    is a previously initialized




    mysqli




    object.


    Provide feedback on this episode.
  • Hacker Public Radio

    HPR4648: Simple Podcasting - Episode 4 - Audio Analysis Fun

    2026/05/27
    This show has been flagged as Clean by the host.

    01



    This is the fourth episode in a four part series on simple podcasting.







    02 Introduction



    In this episode we will discuss alternatives to Audacity when it comes to analyzing audio spectrums to find the sources of unwanted noise.



    I previously promised some gratuitous hackery, and we will get into that in this episode.







    03



    Recall that with Audacity you first import the audio file, then select the part of the audio you wish to analyze (or ctrl-A for all), and then select analyze > plot spectrum.



    This is in fact the only feature of Audacity that I know how to use. I am definitely not an audio expert.



    I do however have some background in processing and analyzing other signals, so some of the basics are familiar to me.







    04



    We can accomplish the same thing that Audacity does in this instance provided we can do the following.



    First, we need to get the data out of the audio file and into a form which we can import into other software.



    Second, we need to perform certain mathematical operations on this data.



    Finally, we need to be able to plot the results of these calculations on a chart.







    --------------------







    05 Fourier Transforms



    First though, we need a bit of mathematical background.



    What Audacity is doing when it shows a plot of frequency versus amplitude is that it is showing the results of a Fourier Transform.



    A Fourier Transforms is a mathematical operation that converts the time domain into the frequency domain.



    Any complex signal, audio or otherwise, can be broken down into a collection of sine waves of various frequencies.



    For example, a simple square wave signal of say 100 hertz can be represented as a sine wave of frequency 100 hertz plus a collection of higher frequency sine waves which add together to give the sharp corners.







    06



    A Fourier Transform finds these sine waves and sorts them out into separate bins, with each bin representing an individual frequency or a collection of closely related frequencies, depending on how fine grained the sorting is.







    07



    This is exactly what we want when we are trying to figure out how to filter out noise.



    Recall that earlier in this series we had to solve a problem with a high pitched background noise which was originating in my cheap microphone.



    Analyzing this audio by frequency showed that it was a series of individual tones at 1 kHz intervals.



    We were then able to use filters targeted at those frequencies to get rid of that noise.







    08



    There are several optimized versions of the Fourier Transform algorithm.



    A very common one is the Fast Fourier Transform, common abbreviated to just "FFT".



    This is so common that the term "FFT" is often used to simply mean any Fourier Transform even though this is not technically correct.







    09



    Typical FFT algorithms require that the number of data samples is exactly a power of two.



    So the number of samples we need may be something like 4096, 8192, or 65536, to give a few random examples.



    When we transform from the time domain to the frequency domain, each sample becomes a single frequency "bin". So the more samples we have, the finer the resolution we get in terms of frequency.







    10



    If we assume we are dealing with flac files recorded at a 44.1 kHz sample rate, that is, 44100 samples per second, then if we have 32768 samples, each "bin" represents slightly more than 1 hertz.



    If we have 65536 samples, then each "bin" represents a fraction of a hertz.



    For our purposes we will pick 65536 samples.



    That means we need 1.48 seconds of data.



    For simplicity's sake we will record at least 2 seconds of data and then just discard the samples that we don't need.







    11



    There is a further complication here. Fourier Transforms normally work with complex numbers.



    Recall from your school days that as well as integers and real numbers there are complex numbers.



    Each complex number consists of two parts, a real component and an imaginary component.



    I won't go into the details of this, just accept that each sample needs to have two components.



    Fortunately, if we don't have complex number data we can just set the imaginary component to zero and use that.







    This is enough talking about the theory, let's get into the practical details.







    --------------------











    12 Extracting Data from Audio Files



    First we will look at how to extract the data from the audio files.



    Fortunately, one of the programs which we have already been using can do this.







    To do this we will use Sox.



    I am not aware of an equivalent feature in ffmpeg.







    13



    Sox calls itself "SoX - Sound eXchange, the Swiss Army knife of audio manipulation"



    Sox is free software and is licensed under the GPLV2 or later.







    In this case we want to use a feature which allows us to convert a binary audio signal file to a text data file.







    To convert the file to text data we just give the output file a ".dat" file extension and Sox will do this for us.







    14



    Here is a command example.



    sox inputfile.flac tdata.dat







    15



    This gives us a file in the following format, assuming this is a mono audio recording.







    ; Sample Rate 44100



    ; Channels 1



    0 0.045471191406



    2.2675737e-05 0.055023193359



    4.5351474e-05 0.048217773438



    6.8027211e-05 0.053192138672







    etc.







    The first line states the sample frequency



    The second line states that the data is for channel 1.



    The data starts on the third line.



    Column 1 is the time in seconds.



    Column 2 is the waveform data point.







    16



    To analyze the data we want a subset of these samples.



    When we convert from the time domain to the frequency domain, our resolution will be determined by the number of samples. We would like therefore to have at least as many samples as the sampling rate.



    We also want the samples size to be an even multiple of two.



    The number of points we want to have is equal to the next even multiple of two above our chosen sampling rate, 44,100 Hz.



    This number would be 65536.







    17



    To extract this data from the file we can do the following.



    tail tdata.dat -n+3 | head -n65536 | awk '{printf "%s\n", $2}' > tdata.csv







    18



    We use tail to skip over the first three lines.



    We use head to take the next 65536 lines and discard the rest.



    We use awk to extract the second column which we will use as the real component.







    We now have this data as a csv file in one column.







    --------------------







    19 Analyzing the Data



    To analyze the data we need software which can calculate FFTs.



    I will now show two examples of this, a very simple case using Libre Office Calc, and a more complex but more complete one using GNU Octave.







    20 Using Libre Office



    We can do fourier analysis and plot charts using Libre Office.







    Take the csv file of data that we previously created.



    For this example I used data from a recording of silence so that I could see what internal noise was being generated by the headset.



    Open the csv file and import it into Libre Office Calc.







    21



    Now select all 65536 rows of column A.



    The Fourier function will automatically fill the imaginary component with zeros if we don't provide an column of imaginary numbers, so we don't need to provide a column of zeros.



    Then select Data > Statistics > Fourier Analysis.







    22



    A window will open allowing you to select various parameters.



    For Results to:, enter "D1".



    Grouped by Columns.



    Select OK.







    23



    New data should now appear starting in cell D1.



    The first line will say " Fourier Transform"



    The second line will state the input range.



    The third line will state "Real" in column D, and "Imaginary" in column E.



    The data will start in row 4.







    24



    For our simple example we will ignore the imaginary data and just use the real data, which will form our Y component when we plot it on a chart.



    We now need to create the X axis data.







    25



    Each cell is a "bin" of frequencies.



    Each cell therefore represents (sample frequency) / (Number of samples) Hz.







    26



    To create the X axis data showing frequency, enter the following formula in to column C to the left of each D column number.



    =((44100/65536) * (ROW() - 4)







    27



    We can now create an XY chart showing the frequency analysis.



    You may need to exclude the first couple of dozen rows as very low frequency components which cannot be heard may otherwise overwhelm the data we are interested in.



    Also, you only need the first half of the chart.



    The FFT mirrors the data from the first half of the array into the second half.







    28



    Because characterizing a sine wave requires a minimum of 2 points, although we have a sample frequency of 44.1 kHz, we really only have sound waves up to a maximum of half that, or 22.05 kHz.



    Create the chart with lines only.



    If you followed the above instructions, you should see something resembling what we saw in Audacity, except with each bin more sharply defined.







    29



    In the data that I had from a recording of unfiltered headset noise, I could see a distinct noise spike every 1000 hertz.







    30



    However, we have taken several shortcuts.



    First, the imaginary component of the data was ignored.



    Second, the magnitude (that is, Y axis) has both positive and negative peaks.



    Third, the data is not scaled to dB sound units, so we just have a relative measure.



    However, that by itself is enough to tell us where the frequencies are that we need to construct filters to deal with.







    31



    We could refine this spreadsheet a bit more to deal with the above issues, but I think we have demonstrated the basic principle, and working with a spreadsheet can be a bit awkward.







    However, if working with a spreadsheet is what you want to do, then you can add more columns and more formulae to improve on it.







    --------------------







    32 Other Analysis Software



    I will go on to GNU Octave in a moment, but I want to get a few other alternatives out of the way first.



    I won't go into any detail on them other than to point them out to people who want to have a go at trying these themselves.







    33 Grace



    There is math and plotting software called Grace.



    This is free software, released under the GPL V2.



    According to the documentation, it seems to have the features we need, including an FFT function.



    However, I could not get it to work properly on Ubuntu 24.04.



    I could not get it to load a data file and plot data.







    34



    The error messages were vague and unhelpful.



    The file navigation system didn't work.



    There was no obvious path to success, and if it isn't easy to use then there is no point to it.



    This is fairly old software, designed for X Window and Motif.



    I gave up on it as not suitable for this series as I am looking for some fairly low effort things for people to try themselves.



    If someone else can get it to work on their PC, perhaps they could do an HPR episode on this themselves.







    35 Command Line FFT Packages



    There are several command line FFT packages.



    They will read data from std in or from a file and output the FFT.



    However, these are not packaged for Ubuntu and appear to be distributed as C source code which you would download and compile.



    You can experiment with those if you wish, but I felt they were a bit out of scope for discussion here as I am looking at common tools that are ready to use.







    36



    Here are two examples.



    One is



    Command-line Fast Fourier Transform utility



    https://github.com/gregfjohnson/fft







    Another is



    cli-fft



    https://github.com/jonolafur/cli-fft







    37



    I have not tried these and cannot say whether they are any good or not.







    Similarly, there are a number of FFT packages that are libraries for languages such as Python.



    If you want to take the time to write a short program to go with them, you can create a dedicated FFT command line program.



    However, I felt that this too was out of scope for what I was trying to do here.







    38 Doing it the Hard Way



    Hypothetically, it may be possible to write an FFT function in bash bc, which is the arbitrary precision calculator language which is part of the standard shell package.







    I say hypothetically, because I have not tried it.



    I think it would be an interesting challenge, but I don't have the time at the moment to try it.



    If anyone feels motivated to give it a try, they're welcome to give it a go and then do a podcast episode on it.







    --------------------







    39 GNU Octave







    We have seen that as well as using features built into Audacity to analyze the audio spectrum to see the frequencies of undesired noises, we were able to do the same using a Libre Office spreadsheet.







    40



    Now we'll look at another bit of software, GNU Octave. GNU Octave is free software, licensed under the GPL V3 or later. It is a mathematical scripting language, very similar to Matlab. People use it for mathematical, engineering, and scientific work. It can be found in most Linux distros and is available for some other operating systems as well.







    41



    Octave has two features built in that we need for our purposes. It does FFTs, and it has a plotting system built in to produce graphs.







    --------------------







    42



    We will take the same audio test file that we used with Audacity and Libre Office and use it here as well.







    The bash script to convert the flac file to text data is essentially the same, with the exception that file extension on the output file as is ".txt" instead of ".csv". This latter change was an arbitrary decision on my part.







    43



    As a quick review, this bash script uses sox to convert a flac file to a text ".dat" file.



    Then it uses tail, head, and awk to extract the first 65536 rows of data, skipping over the header information and ignoring the first column of time data.



    This script will be in the show notes.







    --------------------







    #!/bin/bash







    # This version is for use with the GNU Octave script.







    sox hsnoisemono.flac hsnoisemono.dat







    tail hsnoisemono.dat -n+3 | head -n65536 | awk '{printf "%s\n", $2}' > hsnoisemono.txt







    --------------------







    44



    We now have a 1.1 MB file containing 65536 samples of data in text format.







    Now the next thing we need to do is to create a short Octave script file.



    I will just give a brief overview of the script here, the full script will be in the show notes.







    45



    I put the script in a file called "octavespectrum.m". I have never used Octave before now, but the convention seems to be to give the script a ".m" ending.







    The "she-bang" line is "#!/usr/bin/env octave". If you make the file executable you can run it like any other script, or you can type "octave" and then the name of the script to run.







    46



    I won't read out the script in detail, as that would be too hard to following along in a podcast.







    However, I pass several arguments to the script including the name of the data file, and then two integers that I use to limit the display area in the Y and X axes so I can have the chart focus on the areas of interest that I want to see.



    I also pass a string containing the name of the graphic file that I want the chart exported to.



    This was an arbitrary decision on my part and you can just hard code these values in if that is what you want to do.







    47



    The arguments are accessed by calling the "args()" function, which returns an array of strings.







    Next, it reads in the specified file using the "dlmread()" function. This reads all of the data into an array.







    48



    Next, it performs a hamming windowing function on the data. I'll explain that briefly.



    It is standard practice when doing FFT signal processing to "window" the signal.



    Since the signal sample is of finite length, it will stop at each end of the array.







    49



    Unless you were lucky enough for this to happen exactly at a zero crossing, this would produced an abrupt transition in the data which looks like "noise" to the FFT.



    The solution is to taper the signal off gradually towards the ends so that when it gets cut off the signal is fairly small at that point anyway.



    There are a variety of different windowing functions, but "hamming" seems to be the most commonly used.







    50



    Next, it does an FFT using the "fft()" function.







    51



    This gives us real and imaginary outputs.



    These are combined by summing the squares of each corresponding real and imaginary element and then taking the square root of each and storing that in a new array. This gives a single array of the same length as the originals, but combining the two output components.



    If anyone wants to tell me that this isn't how things are done in the audio world, they're welcome to make an HPR episode telling us all the right way to do things.







    52



    Then it does some scaling and selection of subsets of data so we get the X axis in hertz and just the number of samples that we wish to look at.







    If you are looking at the script, the thing to keep in mind is that Octave will work on entire arrays of data in a single operation. You don't need to write explicit loops for this. The looping is handled implicitly as part of the syntax.







    53



    It also does various other things that make the chart easier to read. The comments in the script describe these in more detail. Since this is a script it's easier to add these sorts of refinements than is the case for a spreadsheet so I have made the effort to add them.







    Finally it calls the "plot()" function.



    If an output graphics file name was provided, it also creates a PNG file containing the same image using the "saveas" function.







    54



    We now see the chart, and it looks more or less as expected.



    However, this chart is interactive.



    You can zoom and pan the data, something that you can't do with either Audacity or Libre Office.







    The chart window doesn't have a function for exporting the resulting chart to a "png" file, it will only save to an ".ofig" file. The ofig file is not a standard graphics file, it is a serialization of the chart data that can only be looked at using the Octave chart viewer.







    55



    Alternatively, you can just take a screenshot of the chart after you have interactively zoomed and panned to a point of interest.







    At the bottom left of the chart window is a pair of x-y coordinates which tell you the current position of the mouse pointer in chart units.



    This is very handy as it can be used to get the exact (or close to exact) frequency of each noise spike.







    56



    The Y axis is not scaled in any particular units such as dB, as I'm not sure how to do that according to audio industry conventions.



    On the other hand, I'm not sure that it's really necessary, as I don't know what dB means in tangible terms anyway.



    It does show relative sizes, so it helps to determine whether you have one noise frequency or multiple frequencies to worry about.







    57



    If anyone is familiar with how to scale the raw data from a flac file as exported by Sox into dB units according to audio industry convention, then they are welcome to create an HPR episode telling us how to do it.







    --------------------







    58 Comments on GNU Octave







    I had never used GNU Octave before this, although I had heard of it and it is quite a significant piece of software for a specific segment of users.







    59



    The syntax is a bit odd especially in how it deals with array operations, but I was able to google various examples and answers to eventually get this working.



    A few other peculiarities are that it uses the percent "%" character to denote a comment, and leaving out the semi-colon at the end of the line causes it to print the answer to the console after executing the statement.







    60



    The GNU Octave solution was harder to get working than the Libre Office method.



    However, once it was working it is easier to use repeatedly.







    If I were to want to automatically generate audio files with different filtering or other options and wanted to script the creation of a large number of images showing the results, this would be the way to do it.







    61



    When your run the Octave script you may get a warning which says something like



    "QSocketNotifier: Can only be used with threads started with QThread".



    This is apparently a routine warning message from the Qt graphics system which has no real significance in this context and can be ignored for our purposes.







    --------------------







    62



    We now have a bash script which will use sox to extract the data from a flac file, and a GNU Octave script which can be used to display the resulting frequency spectrum.







    This does more or less the same thing as "Plot Spectrum" does in Audacity, but allows for zooming and panning to get a more detailed look at the data.







    63



    However it doesn't give you an absolute reading of the sound levels in dB, something that Audacity does provide.







    What I wanted it for though was to find the frequencies of the audible noise in the signal, something that it does quite well.











    --------------------







    #!/usr/bin/env octave







    % Perform an FFT on the data in a file and plot the results.







    % ======================================================================







    % The sampling frequency. This must be changed to accommodate the



    % actual sampling frequency if it was something else.



    samplefreq = 44100;







    % Thickness of line on plot.



    linewidth = 2;







    % ======================================================================







    % The name of the data file is passed as a argument.



    args = argv();



    if length(args) < 3



    quit



    endif











    % File name.



    fname = args{1};



    % Clip the peak values.



    peakclip = str2double(args{2});



    % How much data to show, in kHz.



    rbound = str2double(args{3}) * 1000;



    % The optional file name to save a chart image to.



    if length(args) > 3



    chartfile = args{4};



    else



    chartfile = "";



    endif











    % ======================================================================



    % Read the data in from the file.



    sampledata = dlmread(fname);



    % Number of samples.



    samplecount = length(sampledata);







    % ======================================================================







    % Window the data. This helps deal with the discontinuity of data at



    % each end of the array and the effects this has on introducing apparent



    % noise into the signal.



    windoweddata = (hamming(samplecount) .* sampledata);







    % ======================================================================







    % Do the actual FFT.



    fftresults = fft(windoweddata);







    % Get real component.



    r = real(fftresults);



    % Get the imaginary component.



    i = imag(fftresults);







    % Combine the real and imaginary. In order to square each element of each



    % array, we must use the ".^" operator, not just "^".



    rfft = sqrt(r.^2 + i.^2);



    realfft = rfft(1:samplecount);







    % ======================================================================







    % Scale factor for frequency.



    fscale = samplefreq / samplecount;



    % X axis scale, scaled to frequency.



    f = (0:samplefreq/2) * fscale;



    % Take a subset of the data if specified. rbound has to be re-scaled



    % from kHz to array increments.



    freq = f(1:min(rbound / fscale,length(f)));











    % y axis. We take the absolute value and then limit (clip) the peaks



    % so that a few large peaks don't obscure the smaller ones.



    mag = min(abs(realfft(1: length(freq))), peakclip);











    % Plot the results.



    figure;



    whandle = plot(freq, mag, 'LineWidth', linewidth);



    title(["Audio Spectrum of ", fname]);



    xlabel("Frequency (Hz)");



    ylabel("Unscaled Magnitude");



    grid on;







    % If the appropriate optional argument was specified, save the chart



    % to a file of that name.



    if length(chartfile) > 4



    saveas(gcf, chartfile, "png");



    endif







    % Need this so the plot window stays open.



    waitfor(whandle);







    % ======================================================================







    --------------------







    This is the shell script used with the above Octave script.



    The arguments are



    1 - the file name for the input data file.



    2 - The value to clip the peaks at.



    3 - The upper frequency bound in kHz.



    4 - The output graphics file name.







    #!/bin/bash







    octave octavespectrum.m hsnoisemono.txt 10 12 hsnoisemono.png











    --------------------







    64 Episode Conclusion



    In this episode we covered the following topics.



    What Fourier transforms are.



    Extracting data from audio files using Sox.



    Analyzing the data using Libre Office.



    Analyzing the data using GNU Octave.



    And, several alternative analysis methods.











    65 Series Conclusion



    This is the end of a four part series on simple podcasting.







    In the first episode, we covered a simple podcast recording method. This first episode is all you really need to make a podcast.







    66



    In the second episode we covered basic filtering and a few other simple topics. The methods discussed in that episode provide basic improvements to your audio if you feel the need for it.







    67



    In the third episode we covered how to analyze audio noise problems using Audacity and additional filtering techniques to deal with specific problems that we may find.



    We also covered command line recording, playback, and getting information about an audio recording.







    68



    In the fourth episode we engaged in a bit of gratuitous hackery for the fun of it and showed how to use alternative software methods to analyze audio signals.







    69



    I hope that this series has been both useful and entertaining and that you will use the knowledge gained here to create and submit your own HPR podcast episodes.







    --------------------



    --------------------





    Provide feedback on this episode.
More Education podcasts
About Hacker Public Radio
Hacker Public Radio is an podcast that releases shows every weekday Monday through Friday. Our shows are produced by the community (you) and can be on any topic that are of interest to hackers and hobbyists.
Podcast website

Listen to Hacker Public Radio, The Mel Robbins Podcast and many other podcasts from around the world with the radio.net app

Get the free radio.net app

  • Stations and podcasts to bookmark
  • Stream via Wi-Fi or Bluetooth
  • Supports Carplay & Android Auto
  • Many other app features