wave command generates sine wave

In 2012, I was trying to find a simple command that can play a sound at certain frequency, but I couldn’t find any which did that and only that. Three years has almost passed on, it’s 2015, and I finally found it. wave does exactly what I wanted, although it does not actually play the audio itself, only generating, therefore you need some helpful program to play the sound, such as aplay.

I’ve also made a video for it on my YouTube channel, you can hear the sounds.

For example, the following command plays C4 (261.63 Hz) and E4 (329.63 Hz) for 0.1 seconds on my system:

% wave -s 4800 261.63 329.63 |
  aplay -f FLOAT_LE -r 48000 -c 1 -q

As you can see, wave can generate more one frequency of sine wave.

The default sampling rate is at 48k Hz, and it plays 48000 samples, which is equivalent to 1 seconds. You can also change the amplitude of the wave. The detail options are:

-a, --amplitude
takes an integer for the amplitude of the wave. defaults to 1.
-s, --samples
how many samples do we need? defaults to 48000. (one second).
-r, --rate
at what rate are we to sample? defaults to 48kHz.
-f, --file
do we want input from a file? if so, which one?

You can even generate from music notes directly with help of an M4 music.m4f, for example:

% echo 0.1 1 C4 E4 | m4 -R music.m4f -Q -
0.1 1  261.63  329.63

% echo 0.1 1 C4 E4 | m4 -R music.m4f -Q - |
  awk '{$1 = $1*48000; print $0}'
4800 1  261.63  329.63

You can pipe it to wave command and it will play. There is a chopsticks.txt, which you can play:

% m4 -R music.m4f -Q chopsticks.txt |
  awk '{$1 = $1*48000; print $0}'   |
  wave                              |
  aplay -f FLOAT_LE -r 48000 -c 1 -q

One and a half years ago, I wrote a Bash function, beeps, it would somewhat emulate notification using dzen and audio files. The sound is now played using the following code:

for i in {1..5}; do
  {
    wave -s 4800 -a 0.75 $((100 * i))
    wave -s 4800 -a 0.75 $((200 * i))
  } | aplay -f FLOAT_LE -r 48000 -c 1 -q
  sleep 0.1
done &

wave was born on 2013-07-07, in C99 and GNU m4 for music.m4f, by Erick Eduardo Ochoa Lopez, licensed under the MIT License.

watch to retry with timeout

Last night, I ran $CMD $ARG manually a few times, because the server kept returning errors causing the command exited with non-zero exit status. It was late, and I wouldn’t want to stay late just to keep doing that, so I issued the following simple one-liner shell script:

while ! $CMD $ARG; do sleep 1m; done

It really was a simple loop, it negated the exit status using !, so it would keep running the loop every time $CMD fails with an interval of one minute until the command finally exits successfully causing the loop to end, therefore the script finishes.

This morning after the command finally executed normally, I was wondering if there is a retry command. I had written the similar loops a few times whenever I needed to rerun a command because of failures.

After a few searches, I couldn’t find one. However, this is one close to what I have in mind, without writing a shell script, although it still uses !:

watch -n $INTERVAL -e ! timeout $TIMEOUT $CMD $ARG

With watch, $CMD can be executed with $INTERVAL if it fails, there is also a timeout to make sure the command doesn’t run too longer. ! will make successful execution of the command become an error, for which, -e options would take action to stop watching, and that is the result we want.

Normally, for retrying, there should be a number of retires option for maximal retires, but not with these commands.

I would believe somewhere out there, someone has done it in one simple command that you can run something like:

$RETRY -r $RETRIES -i $INTERVAL -t $TIMEOUT $CMD $ARG

If you know of such command or a better way to deal with this kind of task, please let me know.

.bash_history on tmpfs

After recovered hstr (BASH History Search Box) (video), I was looking for a way to reduce disk I/O, because of the continuous synchronization on each issued command:

export PROMPT_COMMAND="history -a; history -n; ${PROMPT_COMMAND}"   # mem/file sync

I decided to change to history file to /tmp/.bash_history, which is on a tmpfs filesystem, this way I can be sure no physical disk I/O. The problem was I didn’t sure how to synchronize it, but I think now I have got it.

In .bash_profile or .bash_login:

cp -au $HOME/.bash_history /tmp

-a keeps mode, ownership, and timestamp. -u makes sure no unnecessary copy would be done, only copying when the destination file is older or missing.

Every time a Bash shell is started, the history file shall be copied if that’s very first shell since the boot. It takes care of the preparation of the history file, I’d need to copy it back.

In .bash_logout, very similar, just the other way around:

cp -au /tmp/.bash_history $HOME

Understandably, if computer crashes, the logout script will not be executed, some history could be lost, but I think that wouldn’t be happening often, can’t remember when the last time my computer crashed.

From my personal usage of terminal window, I split my tmux very often, and panes are closed also often, I am not worried about too much, the history file will still be written back frequent, but not as often as doing on every command.

It’s not complicated, all the essential code is only two lines. In my opinion, it’s quite simple, but there might be a more robust way to handle this.

TickTick embeds JSON in Bash script

TickTick is “just a fun hack.” But it does look intriguing, it has some APIs for manipulations and accessing, and it doesn’t just parse JSON, but also manipulate using the APIs that it provides.

The example.sh tells a lot what it can do.

First, you load the library:

#!/bin/bash

. ticktick.sh

Then, you embed the JSON, note that you can parameter expand:

bob=Bob

``
  people = {
    "HR" : [
      "Alice",
      $bob,
      "Carol"
    ],
    "Sales": {
      "Gale": { "profits" : 1000 },
      "Harry": { "profits" : 500 }
    }
  }
``

One more thing I noticed is the syntax highlighting works quite well even for the `` block in Vim.

You can insert new objects, in this case, an Engineering department of three employees:

echo Base Assignment
`` people.Engineering = [ "Darren D", "Edith E", "Frank F" ] ``
printEmployees

The printEmployees function utilizes a loop on the expanded results of the TickTick:

function printEmployees() {
  echo
  echo "  The ``people.Engineering.length()`` Employees listed are:"

  for employee in ``people.Engineering.items()``; do
    printf "    - %s\n" "${!employee}"
  done

  echo
}

This part produces the following result:

Base Assignment

  The 3 Employees listed are:
    - Darren D
    - Edith E
    - Frank F

More operations such as push and pop, shift, and index:

newPerson="Isaac I"
echo Pushed a new element by variable, $newPerson onto the array
`` people.Engineering.push($newPerson) ``
printEmployees

echo Shifted the first element off: `` people.Engineering.shift() ``
printEmployees

echo Popped the last value off: `` people.Engineering.pop() ``
printEmployees

echo Indexing an array, doing variable assignments

person0=``people.HR[0]``
echo $person0 ``people.HR[1]``

The results are:

Pushed a new element by variable, Isaac I onto the array

  The 4 Employees listed are:
    - Darren D
    - Edith E
    - Frank F
    - Isaac I

Shifted the first element off: Darren D

  The 3 Employees listed are:
    - Edith E
    - Frank F
    - Isaac I

Popped the last value off: Isaac I

  The 2 Employees listed are:
    - Edith E
    - Frank F

Indexing an array, doing variable assignments
Alice Bob

TickTick was born on 2011-12-02, just three years ago, it is based on JSON.sh, therefore under the MIT License and Apache License Version 2.0, written by Chris McKenzie, currently git-05453ed (2014-11-28, post v1.0 (2012-08-20)).

The code is little over 10 KB in file size and 277 lines, not a small one, but not huge, either. I don’t know if it runs fast enough, the performance can be only drawback, as it already said “You may want to consider using mature languages like Ruby or Perl to solve actual real life problems.”