Saturday, November 22, 2014

Better speech compression with Opus

In a previous post, we looked at configuring Audex for ripping CDs to the superior Opus format. While that was good for general purpose audio encoding, it doesn’t let us take advantage of Opus’ immense versatility, it’s ability to get excellent results across a wide range of bit rates.


You will notice at the low end of that graph are codecs that typically specialize in speech, because speech is more compressible that complex audio sources like music. Speex, for instance, can get excellent compression of speech with acceptable quality, yielding much smaller file size than MP3 or Vorbis. One of the benefits of Opus is that it should be able to replace this usage as well.

As you might have guessed, the opusenc commands we gave Audex can also be used directly on the command line. If you want to target a lower bit rate for speech encoding, all you need to do is add the --bitrate option. For speech, try something in the range of 16-48. In Audex, you might add two different profiles for compressing speech with Opus, just as there are multiple profiles for different qualities of compression with Vorbis.

opusenc takes raw, Wave, AIFF, or FLAC input (FLAC is still the preferred format for archival storage). If you pass a FLAC file that is already tagged with metadata, opusenc will incorporate that metadata automatically, so there is no need to pass it on the command line.

opusenc --bitrate 16 input.flac output.opus

For comparison, a 40 minute audio recording ripped as an uncompressed Wave file was about 403 MB, compressed with FLAC it was about 103 MB, opusenc with default settings got it down to about 26 MB, while the above command reduced it to about 4.5 MB. So targeting the lower bit rate was a space savings of over 80% and made it small enough to share by email.

Saturday, November 15, 2014

Ripping CD to .opus with Audex on Debian

The Opus codec is basically the one codec to rule them all. It is an open standard (RFC 6716) and it outperforms almost all other codecs, open and proprietary, over a huge range of bitrates. It also has a very low latency which is important for internet applications involving real-time communications and it is already supported by modern browsers like Firefox, Chrome, and Opera. But if you want to start storing your music in the best available format, you might have difficulty finding convenient tools that support it. Well, here is one that worked for me, so I’ll share it. It was pretty simple, although not entirely obvious.

Audex is a graphical CD ripper for KDE. It does not support ripping to Opus out-of-box, but it does have a feature to add a new encoder. For this, we will just use the command-line encoder found in opus-tools, so install the packages audex and opus-tools. Now, when you run Audex, go to “Settings” > “Configure Audex...”, select the “Profiles” section, and then “Add...”. Name the new profile “Opus”. Under the “Encoder” tab, select “Custom” from the first drop down. Under “Command pattern:”, put in “opusenc $i $o”, and under “Suffix:” put in “opus”. You can look at some of the other options if you wish (I set mine to replace spaces with underscores), but that is all that is necessary to get it working. Save your new profile, select the profile from the main window, and begin ripping your favorite discs.


If you also want to capture metadata, you will need a newer version of opus-tools than what is in Wheezy. You can download the source, and build it yourself. You will need to have the wheezy-backports repository enabled to get some of the dependencies:

sudo aptitude -t wheezy-backports install libogg-dev libflac-dev libopus-dev

Once the dependencies are met, you should be able to configure and install opus-tools:

cd opus-tools-src-dir
./configure
make
sudo make install


Now, you can change the “Command pattern:” in Audex to “opusenc --title "$ttitle" --artist "$tartist" --album "$title" --date "date" --genre "$genre" $i $o”. This will capture metadata and embed it in your new Opus files.

Update: If you are looking to get better compression for speech recordings, such as lectures, sermons, speeches, etc, see this post.

Thursday, November 13, 2014

Setting up root SSH login on CyanogenMod

I did this with the latest CyanogenMod 11 snapshots on a Nexus 4 and a Nexus 5. I recommend buying a device with an unlockable bootloader, like the Google Nexus devices, because it makes rooting and installing custom ROMs, etc, much more straightforward. Besides, if you buy a device you ought to own it, so why give your money to a company that tries to lock you out of your own devices, as if they still own it even after you have bought and paid for it? If you already have a device that is locked down, you may have to search the web to find a hack to get access to it (Good luck!), but I won’t be covering that here. What I found to be difficult to find and poorly documented elsewhere was how to configure your device for root login via ssh, after installing CyanogenMod. This can be useful for a variety of reasons, for instance, you can easily make a full back up of the phone securely over your wireless network. But as always, exercise caution when using root!

Before you begin, make sure you have a few options set on the Android device. Under “Developer options” make sure that “Android debugging” is enabled, “Root access” is set to “Apps and ADB”, and while you are here, set “Device hostname” to something memorable. (You should have learned to access the hidden “Developer options” menu while install CyanogenMod.) Now, with phone connected by USB, login from your computer with:

adb shell

then start setting up ssh by copying over the template configuration file:

cp /system/etc/ssh/sshd_config /data/ssh
vim /data/ssh/sshd_config

and add the line:

PermitRootLogin without-password

This does not do what it sounds like. It will not allow you to login without authenticating, rather, it disables authentication with a password and requires you to use public key authentication which we will set up in a minute. Next:

mkdir /data/local/userinit.d
cd /data/local/userinit.d
cp /system/bin/start-ssh 90sshd
vim 90sshd


and change:

   # don't daemonize - otherwise we can't stop the sshd service
   /system/bin/sshd -f /system/etc/ssh/sshd_config -D


to:

   # don't daemonize - otherwise we can't stop the sshd service
   ## Actually, yes, do daemonize (remove -D option)
   /system/bin/sshd -f /system/etc/ssh/sshd_config


Now, if you don’t already have one, you will need to generate an RSA key for ssh. On your computer (not the adb shell that is already logged into your Android device) run:

ssh-keygen

and with the default options you will get a ~/.ssh containing id_rsa and id_rsa.pub. You will need to copy id_rsa.pub to your Android device in order to be able to login. Still working from your computer:

adb push ~/.ssh/id_rsa.pub /sdcard/

Now, on the Android device:

cd /data/.ssh
touch authorized_keys
cat /sdcard/id_rsa.pub >> authorized_keys
chmod 600 authorized_keys


Note that the authorized keys file must not be readable by anyone else or ssh will refuse to use it and authentication will fail. Now, you should be able to reboot and login to your Android device:

ssh root@AndroidHostname

If you set a password for the RSA key you generated for ssh, it will prompt you for that password, but it will not prompt for a password for root on the Android device (because it is using the key instead). If you want to login from other devices, make sure you have an authorized key on that device as well. To add more authorized keys, simply concatenate them onto the authorized_keys file, the same way we did the first one. Now you can remotely access your Android device via ssh.