Loading tmux on Boot in Linux


tmux is a wonderful tool for displaying virtual consoles on the linux command prompt screen. It’s the next best thing to getting actual GUI windows controllable with a mouse.

Mainly, I use it for ssh purposes. Where I can ssh to a pc that I know has tmux already launched in the background and type.

tmux a

which attaches the session to the on-going tmux background session, allowing you to see everything that is going on in that process. This is especially useful for embedded systems where there are multiple processes launched in the background and you want to monitor them all.

So I have a tmux script launcher.sh here:



#allow re-launch
/usr/bin/tmux has-session -t $SESSION 2> /dev/null && /usr/bin/tmux kill-session -t $SESSION
/usr/bin/tmux -2 new-session -d -s $SESSION

echo "Launching tmux"

/usr/bin/tmux split-window -h
/usr/bin/tmux split-window -v
/usr/bin/tmux select-pane -t 0

/usr/bin/tmux send-keys -t $SESSION.0 "cd /path/to/binary1folder" C-m
/usr/bin/tmux send-keys -t $SESSION.0 "./binary1" C-m

/usr/bin/tmux send-keys -t $SESSION.1 "cd /path/to/binary2folder" C-m
/usr/bin/tmux send-keys -t $SESSION.1 "./binary2" C-m

/usr/bin/tmux send-keys -t $SESSION.2 "cd /path/to/binary3folder" C-m
/usr/bin/tmux send-keys -t $SESSION.2 "./binary3" C-m

This basically opens up , three panes and splits the window horizontally first, then splitting again one of the split windows vertically. It then launches a binary in each of the window panes. I won’ t go too much into the scripting here as there are plenty of resources for doing so, like this.

Configuring tmux to boot on startup on CentOS 7

Normally this should be pretty straightforward, but I ran into some hiccups.


sudo nano /etc/rc.local

And edit the rc.local file to include

su -c /path/toyourscript/launcher.sh -l your_user_id

-l your_user_id means that you do the launch of the script launcher.sh as the user your_user_id.

Make sure your rc.local is executable.

sudo chmod +x /etc/rc.local

And by right it should launch when CentOS boots, launching launcher.sh in the background which in turn launches tmux. However, I found that one of the abrt startup scripts, abrt-console-notification.sh was interfering with the launching of the tmux process/binaries. It would hang at the console terminal of the tmux screens. Doing the following resolved the problem for me.

cd /etc/profile.d/
chmod -r abrt-console-notification.sh

Basically, make abrt-console-notification.sh non-readable, allowing the profile.d startup process to skip over this particular script. It’s kind of a hack, but it worked. I reckon at most I don’t get the automatic bug reporting tool notifications at the console. Note that this script is run depending on what type of installation you chose when installing CentOS. I think that the minimal installl doesn’t run into this issue.

Hope this it useful to you, let me know!

ps. Here’s a tmux cheat sheet. https://gist.githubusercontent.com/afair/3489752/raw/e7106ac93c8f9602d3843696692a87cfb43c2d21/tmux.cheat

Sign Bit Extension

Sometimes you can get a value like this :

For example, something that is 12-bit in a 16-bit short int.

shortIntValue = 0b0000 1100 1110 1100

The latter 12 bits are the actual value. It is a negative value by the 12th bit being 1. And you really want :

0b1111 1100 1110 1100

You can do

shortIntValue <<= 4;

followed by

shortIntValue >>= 4;

Volia! Sign bit extension! This is useful for 2’s complement values which are put into a primitive integer size. (As above)

iOS Launch Images Madness

I was struggling with the iOS launch images. The easiest way I found was to not use image assets, or the launch image file. Just put these images under Resources in your project in XCode and iOS will find them.

  • Default.png (iPhone)
  • Default@2x.png (iPhone Retina 3.5 inch)
  • Default@3x.png (iPhone 6 Plus landscape)
  • Default-568h@2x.png (iPhone Retina 4 inch) 
  • Default-667h@2x.png (iPhone 6 portrait)
  • Default-736h@3x.png (iPhone 6 Plus portrait)
  • Default-Portrait.png (iPad in portrait orientation)
  • Default-Portrait@2x.png (iPad Retina in portrait orientation)
  • Default-Portrait@3x.png (iPhone 6 Plus portrait)
  • Default-Landscape.png (iPad in landscape orientation)
  • Default-Landscape@2x.png (iPad Retina in landscape orientation)

Oh my god, such a trivial thing.. why did Apple make it so difficult??

Quickly Plot in Python with Text File Values

Python has this wonderful command in numpy, np.loadtxt.
In this case, I use np.loadtxt to load a file consisting of several ADC real values to do a quick plot for visualization. The rule is that each row in the text file has to have the same number of elements. In this case it is simply.

and so on...


import matplotlib.pyplot as plt
import numpy as np

data = np.loadtxt('/path/to/your/file')

# get x-axis bins
x_axis = np.arange(data.size) * 960 / data.size

#plot time domain

# plot frequency domain
spc = np.fft.fft(data)
plt.plot(x_axis, 20*np.log10(abs(spc)))

That’s all. Pretty quick and nifty!

Thoughts on Open Source


I used to not understand open source.

Why would people give away their source code for free? Going through the software revolution of the 90s, Microsoft was the king of software. I followed the Microsoft’s decimation of WordPerfect, Borland, Lotus 1-2-3 and Netscape as a kid. And Microsoft didn’t give away software for free, no, let alone source code! Microsoft charged folks for Office, Windows, Visual Studio, etc. To their credit, they still do to a certain extent. So to me, it all seemed counter-intuitive – something that was free, in my mind, would not see any quick progress due to the lack of economic motivation behind it. My overall train of thought could be summarised by this grumpy nerd’s post.

Then Linux Torvalds came along with this :

Hello everybody out there using minix –

I’m doing a (free) operating system (just a hobby, won’t be big and professional like gnu) for 386(486) AT clones. This has been brewing since april, and is starting to get ready. I’d like any feedback on things people like/dislike in minix, as my OS resembles it somewhat (same physical layout of the file-system (due to practical reasons) among other things).

— Linus Torvalds

And it’s amazing how others have contributed to the project ever since. Linux is probably the most successful example of open-source software. From the Linux kernel, countless distributions have emerged. Heck, even Android has the Linux kernel in it. Red Hat, CentOS, Ubuntu, Debian, Linux Mint they all share the linux kernel, which is actively being maintained by the Linux Foundation.

There’s a lot of open source software out there, and it’s all a beautiful mess. Companies leveraging on open-source software have been successfully built. Red Hat is a prime example of this, which generates revenue through support and training contracts. http://www.zdnet.com/article/red-hat-nearing-1-billion-in-revenue-not-bad-for-free-software/ And did you know that WordPress, the blog software that you are reading this on, is open-source?

The problem with proprietary software is this : When you don’t know what’s going on, you don’t know what’s going on. Proprietary APIs usually hide the implementation details of a function, so you are at the mercy of whoever holds the proprietary software implementation. You would be in danger even. I’m sure Snowden would agree. With open source, all the implementation details are out there, whether you want to understand it or not. Furthermore, with proprietary software, once the company decides that it is no longer in their financial interests to continue with the work, it is thrown away.

I’ve concluded that to make large scale software without a whole Fortune 500 company like Microsoft or Google behind you, open source is the way to go. I use ZeroMQ in my work, and this is a great example of this. The author has successfully built a community from which many other projects have sprung.  Once folks find that the open source code is useful to them, they will have it in their hearts to contribute back. Even if it is just fixing a bug or two.

My other open source loves are CSound and  AudioKit , all great audio programming open source projects from which one can learn. AudioKit is fairly new, but has enjoyed quick growth due to many developers wanting a Swift audio development framework (pun intended).  It was the CSound code that inspired me to delve into DSP code.

Revenue for the little guy? I’d like to think of somehow who buys stuff I make as paying me to keep it going. It is not easy maintaining a piece of software amidst the ever-changing tech landscape.I would say it takes more energy to maintain software than to shit one out.

Open source is simply a developmental methodology that was ahead of its time. It’s a methodology that places community over software. It’s a reflection of the human need to contribute and make a difference. I that software, like nature, given enough time undergoes evolution. Great software stays and gets better with time.

[ERRFMT] using Poco Logger

When using the poco logger to log values like this, many at times the logged value is displayed as [ERRFMT]. The poco logger is saying that it does not recognize the input parameter as the one being specified by the identifier. Poco is extremely finicky regarding this!

For example,

float stddev = 3.53525f
 m_log.debug("Std dev = %f", stddev);


Std dev = [ERRFMT]

The correct formatting to be used for Poco :

bool %b
char %c
int %d, %i
unsigned %u
short %hd
unsigned short %hu
long %ld
unsigned long %lu
long long %Ld
unsigned long long %Lu
unsigned (octal) %o
unsigned (hex) %x, %X
double %f, %e, %E
float %hf, %he, %hE
std::string %s
std::size_t %z

Hence the example above should be :

 m_log.debug("Std dev = %hf", stddev);

Printf in C automatically promotes variables to the appropriate format for print out, which is why you don’t have this hassle when using printf.

Using libtiff for luminance/grayscale images

Libtiff is a library for reading and writing TIFF, a small collection of tools for doing simple manipulations of TIFF images on UNIX systems.


const int width = 256;
 const int height = 256;
 const int sampleperpixel = 1;
 uint8_t image[height*width];

int main()
 for (int r=0; r < height; r++) {
 for (int c=0; c < width; c++) {
 image[r*width+c] = (r + c) % 256;

TIFF *tif = TIFFOpen("output.tif", "w");
 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, sampleperpixel);
 // TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, width*sampleperpixel));

for (int r=0; r < height; r++) {
 TIFFWriteScanline(tif, &image[r*width], r, 0);


For TIFFTAG_PHOTOMETRIC, you need to set it to PHOTOMETRIC_MINISBLACK for the desired results using 1 sample per pixel, 8 bits per sample. This is for grayscale images with only a single channel.

The default from the libtiff examples is PHOTOMETRIC_RGB. This is for conventional images with 3 channels RGB.

Download libtiff here:  http://dl.maptools.org/dl/libtiff/