Showing posts with label tips. Show all posts
Showing posts with label tips. Show all posts

Time-coding audio files

One day you'll need to include real-time UTC timestamps in audio. It's useful when reconstructing events from long, unsupervised surveillance microphone recordings, or when constantly monitoring and logging radio channels.

There's no standard method for doing this with WAV or FLAC files. One method would be to log the start time in the filename and calculate the time based on audio position. However, this is not possible with voice-activated or squelched recorders. It also relies on the accuracy and stability of the ADC clock.

I'll take a look at some ways to include an accurate timestamp directly in the in-band audio.

Least significant bit

Time information can be encoded in the least significant bit (LSB) of the 16-bit PCM samples. This "steganographic" method requires a lossless file format and lossless conversions. The script below truncates all samples of a raw single-channel signed-integer PCM stream to 15 bits and inserts a 20-byte ISO 8601 timestamp in ASCII roughly every second, preceded by a "mark" start bit. When played back, the LSB can be zeroed out to get rid of the timestamps. The WAV can also be played as such; the "ticking" sound will be practically inaudible at an amplitude of −96 dB. The outgoing PCM stream is then sent to SoX for WAV encoding.

#!/usr/bin/perl
use strict;
use warnings;
use DateTime;
 
my $snum    = 0;
my $writing = 0;
my $pos     = 0;
my $code    = "";
 
open my $out, '-|', 'sox -t .raw -e unsigned-integer -b 16 -r 44100 '.
                    '-c 1 - stamped.wav';
 
while (read STDIN, my $sample, 2) {
  $sample = unpack "s", $sample;
  my $bit = 0;
 
  if ($writing) {
    $bit = (ord(substr $code, $pos >> 3, 1) >> ($pos % 8)) & 1;
    if (++$pos >= length $code << 3) {
      $writing = 0;
      $bit     = 0;
    }
  } elsif ($snum++ % 44100 == 0) {
    $writing = 1;
    $pos     = 0;
    $bit     = 1;
    $code    = DateTime->now()->iso8601();
  }
 
  print $out pack "S", ($sample + 0x7FFF) & 0xFFFE | $bit;
  
}
close $out;

Note that the start bit of the timestamp will mark the moment the sample reached this script, and it could differ hundreds of milliseconds from the actual moment of reception at the microphone. Also, the timestamp does not mark the start of a second, but is rather timed by an arbitrary sample counter. One could also poll and write the timestamps in a continuous manner.

The above script could be modified to interface with my squelch script, by only inserting timestamps when squelch is not active. The resulting audio could then be efficiently encoded as FLAC.

lsb-time-read.pl reads back the timestamps, also printing the sample position of each. Below is a sound sample of a clean signal followed by a timestamped one.

Lossy-friendly approach

Lossy compression, by definition, does not retain the numeric values of samples, so they can't be treated as bit fields. Instead, we can use an analog modulation scheme like binary FSK. MP3 and Ogg Vorbis encoders will, at a reasonable bit rate, retain the structure of a sufficiently slow FSK burst. This method will work even if the timestamping phase is followed by an analog conversion.

Using the ultrasonic part of the spectrum comes to mind; but unfortunately such high frequencies are mainly ignored by a LPF at the encoder. However, we can use the higher end of the remaining spectrum and filter it out afterwards, if the recording consists of narrow-band speech. In the case of squelched conversation, we could write the timestamp only in the beginning of each transmission. This way it could even be in the speech frequencies.

fsk-timestamp.pl embeds the timestamps into PCM data; they can be read back using minimodem --rx --mark 11000 --space 13000 --file stamped.wav -q 1200.

A sound sample follows.

LAN file transfer with netcat

Need to quickly transfer a file from one computer to another? They don't have AirDrop and you can't find a memory stick? No worries; netcat comes to the rescue. This tip works on Linux as well as OSX.

I'm going to suppose you're on the same LAN, and you want to transfer a file called photos.zip. First, open up a terminal on the receiving computer and type ifconfig|grep "inet " to find out its IP address:

$ ifconfig|grep "inet "
         inet 127.0.0.1 netmask 0xff000000
         inet 192.168.1.243 netmask 0xffffff00 broadcast 192.168.1.255
$ █

The IP address is 192.168.1.243. (We don't want 127.0.0.1, because that's a loopback address that only works locally.)

Then make netcat listen to a port by typing nc -l 12345 > photos.zip. On the sending side, type nc 192.168.1.243 12345 < photos.zip (or whatever the IP address and file name are). And magic happens!

How I made my Ubuntu usable again

Many fellow Ubuntu users have been protesting the recent developments in user interface design, call it Unity/Gnome 3/whatever. But what can a user do? Of course one could migrate [back] to Debian. But I happen to really like the way Ubuntu has done many other things. And I've found a way to restore its usability. I'll also share a few extra tips that I've found useful with Ubuntu.

Moving to Xfce

First, I replaced the default desktop environment with Xfce. It's a full-fledged, light-weight, easy-to-use desktop environment that by default has kind of an OSX-style look but is extremely customizable. It also comes with a simple compositor. Installing Xfce is simple:

$ sudo apt-get install xubuntu-desktop
$ sudo apt-get --purge remove ubuntu-desktop
$ █

This will also rebrand your distro as Xubuntu. Despite this superficial change, it will use the same repositories and, for the most part, will work exactly the same way as you're used to.

No more PulseAudio

Secondly, and less importantly, I eradicated PulseAudio which is another common source of mischief:

$ sudo apt-get --purge remove pulseaudio
Scan finger on UPEK TouchStrip Sensor-only
█


One of the most satisfying biometric sudo moments!

Cool little terminal

My terminal emulator of choice is rxvt-unicode, also known as urxvt. Living up to its name, it has great support for Unicode in addition to being fast and lightweight. It can be daemonized, which shortens the startup time of new windows even more. Needless to say, it's very customizable via Xresources. It also comes with a bunch of optional Perl extensions.

Keyboard tips

These keyboard tips work in Xubuntu and Xfce, but could be applied to other environments, too.

Some shortcuts

[Image: Keyboard settings window with the Application Shortcuts tab open.]

Keyboard shortcuts can be added in Application Menu → Settings → Keyboard → Application Shortcuts. For example, I've set the command urxvtcd to be executed when the section (§) key is pressed. This way you can map a seldom-used key to do something more useful, in this case open a new terminal window.

I've also made it easy to copy text from XA_PRIMARY (the "mouse cursor" clipboard) to XA_CLIPBOARD (the "Ctrl+C Ctrl+V" clipboard) by adding a shortcut key to launch the command /bin/sh -c "xclip -f -out | xclip -selection clipboard".

Compose key

The Compose key can also be useful. It lets you quickly input many special characters not directly present on the keymap, using simple mnemonics.

To map the Windows key to work as a Compose key, add keycode 133 = Multi_key to your ~/.Xmodmap:

$ echo keycode 133 = Multi_key >> ~/.Xmodmap
$ █

Also, make Xfce read the config at startup by adding xmodmap /home/username/.Xmodmap to your Settings → Session and Startup → Application Autostart:

[Image: Session and Startup settings window with the Application Autostart tab open and the popup Add application.]

Some compose key sequences and the characters they produce:

Cmp + S + O§
Cmp + O + C©
Cmp + A + Eæ
Cmp + + >

Unicode input

To input an arbitrary Unicode character that you know the code point of, press Ctrl+Shift+U, then the code point in hexadecimal, and commit it with Enter or Space. Like so:

Ctrl + Shift + U
21D2 space
221B space
5B97 space
2620 space

Over-enthusiastic Sticky keys

You can disable gdm's Sticky Keys and Slow Keys accessibility helpers by adding xkbset -a to the aforementioned Autostart list.

Done!

There you go! Make sure to choose Xfce or Xubuntu session from the greeter when you log in. And here's a screenshot of my Xubuntu session with root-tail, conky, rxvt-unicode, vim, and Firefox:

[Image: Full-desktop screenshot of Ubuntu.]

Google Earth on 64-bit Linux

Google Earth is a fun toy. But it's not always straightforward to get it to work on a 64-bit Linux (Ubuntu) system, since it's a 32-bit program, even when the .deb package says amd64. I wrote this post as a reminder for myself and others who run into similar problems.

* * *

Sometimes Google Earth wouldn't find a file called libGL.so.1:

  ./googleearth-bin: error while loading shared libraries: libGL.so.1:
  cannot open shared object file: No such file or directory

You can work around this by installing the 32-bit libraries and helping Google Earth find the file. Assuming your Earth installation is in ~/google-earth/:

$ sudo apt-get install ia32-libs
$ ln -s /usr/lib32/mesa/libGL.so.1 ~/google-earth/libGL.so.1

* * *

Sometimes this cryptic error message would also show up:

/usr/bin/google-earth: 43: ./googleearth-bin: not found

Luckily, fixing it is easy:

$ sudo apt-get --reinstall install lsb-core libc6:i386