Sunday, October 20, 2013

Karaoke on OS X (Mac)

Here's the way that I setup my Macbook to do karaoke for not too much money ~$80. Like any good recipe I'll start with the ingredients:

  1. MacBook Pro 2011 running OS X 10.8 (Mountain Lion)
  2. Linein (
  3. Spotify with tunewiki (
  4. Logitech X-140 2.0 Speakers (
  5. Audio-Technica ATR2100-USB Cardioid Dynamic USB/XLR Microphone (
For the hardware setup simply plug the speakers into the headphone line out and plug the microphone into a USB port. One mistake that I initially made was that I bought a standard mic with 3.5mm jack and just plugged it into the mic input on the mac. It turns out that the input voltage on that setup is way too low and I could barely hear the microphone. One solution would have been to buy a little preamp and plug the mic into that and then plug the preamp into the computer but I found the mic listed above on amazon for less than the preamp. One other mic note is that you need to make sure to buy a directional microphone otherwise you'll pickup the speakers and get nasty feedback. My final hardware comment is that if you plan to copy my setup exactly I'm happy with the speakers given my usage, however, they are the weak link in the setup. The mic sounds great and the speakers are not bad but not great.

Now for the software. 

The one trick in the process is getting the mic to output to the speakers. This is done by launching linein and selecting the USB microphone as the input and the built in output headphones as the output. Then just click pass though and you should here the mic over the speakers.

Once you have spotify installed just go to the app finder and add tunewiki. Tunewiki has the lyrics to tons of songs and if you highlight it while playing a song on spotify it will display the lyrics in time with the song. 

Finally I used the built in OS X utility Audio Midi Setup to control the mic volume. Simply highlight the USB mic and you can control the output volume of the mic. For the song volume use the spotify volume control and the master volume can be controlled by the usual mac interface.

Now all you need are a couple of sake bombs and you should be good to go....

Saturday, October 19, 2013

Getting A Range of Cells With NPOI (POI)

I'm embarrassed to admit it but I write C# code. Recently I've been doing some very lightweight Excel file manipulation and with minimal research started using NPOI. I was surprised to find that there wasn't any GetRange() type of function (that I saw). So here's my implementation:

        public static ICell[,] GetRange(ISheet sheet, string range)
            string[] cellStartStop = range.Split(':');

            CellReference cellRefStart = new CellReference(cellStartStop[0]);
            CellReference cellRefStop = new CellReference(cellStartStop[1]);

            ICell[,] cells = new ICell[cellRefStop.Row - cellRefStart.Row + 1, cellRefStop.Col - cellRefStart.Col + 1];

            for (int i = cellRefStart.Row; i < cellRefStop.Row + 1; i++)
                IRow row = sheet.GetRow(i);
                for (int j = cellRefStart.Col; j < cellRefStop.Col + 1; j++)
                    cells[i - cellRefStart.Row, j - cellRefStart.Col] = row.GetCell(j);

            return cells;

And then an easy way to get the desired values:

        public static T1[,] GetCellValues<T1>(ICell[,] cells)
            T1[,] values = new T1[cells.GetLength(0), cells.GetLength(1)];

            for (int i = 0; i < values.GetLength(0); i++)
                for (int j = 0; j < values.GetLength(1); j++)
                    if (typeof(T1) == typeof(double) || typeof(T1) == typeof(int) || 
                        typeof(T1) == typeof(float) || typeof(T1) == typeof(long))
                        values[i, j] = (T1)Convert.ChangeType(cells[i, j].NumericCellValue, typeof(T1));
                    else if (typeof(T1) == typeof(DateTime))
                        values[i, j] = (T1)Convert.ChangeType(cells[i, j].DateCellValue, typeof(T1));
                    else if (typeof(T1) == typeof(string))
                        values[i, j] = (T1)Convert.ChangeType(cells[i, j].StringCellValue, typeof(T1));

            return values;

Concatenating Lines With AWK

So this is my first blog post and it's a nerdy one at that, but now that I think about it all my blog posts are going to be nerdy so let's get started.

My brother asked the following question the other day: 

"I have a text file similar to this


And I need it to be:


So, I need the lines not to be word wrapped below the lines demarcated by >.  Any idea how to do this?  Do you guys know anyone who is a text editor pro or is their a simple script that can be written?"

And he included a sample file "ns4.txt". Here's my short answer:

awk '/>/{if (x)print x;print;x="";next}{x=(!x)?$0:x""$0;}END{print x;}' nsP4.txt > nsP4New.txt

And the long answer:

If you break it apart it's easier to follow. So awk has the following input structure: 

    awk 'program' FILE

Where 'program' is the program to execute and then FILE is the input file. The file is nsP4.txt and the program in this case is:

    />/{if (x)print x;print;x="";next}{x=(!x)?$0:x""$0;}END{print x;}

Where />/{....}{....} is a regular expression that means if a line contains ">" execute the first set of curly braces and if it doesn't execute the second set of curly braces. So in the first set of curly braces you execute the following if the line contains ">":

    if (x)                                    
        print x;

So if x is not empty print x then print a line then assign the empty string to x finally go to the next line.

We execute the second set of curly braces if the line doesn't contain ">"

    x = (!x)?$0:x""$0;

This is a ternary operator and is the same as saying:

    if (!x)
        x = $0
        x = x""$0

This means if x is not not empty (so empty) then assign the current line to x otherwise assign the concatenation of x, "" and the value of the input line. You could actually simplify this whole section in your case to:

    x = x$0;

The extra code in there is if you want to add some sort of delimiter where you currently have "". For example if you wanted to separate the base sequences with a comma. In that case you'd have:

    x = (!x)?$0:x","$0;

Then the last thing that awk does is:

    END{print x;}

So when it gets to the end of the file print out the value of x.

The very last thing is that awk would just spit all of this out to the terminal window unless you tell it to put it somewhere else so the line:

...... > nsP4New.txt 

Is a bash command to take the output of awk and send it to a new file nsP4New.txt that will be created.