The Opus of Measium
Take Two is the best band ever.
August 28th - 30th
Went over the syllabus, and some minor review on pointers. Went over more initial junk (IRC, opus, reversion control, etc). After talking about the initial stuff, we got talking about our first project some more (writing a FreeCell style game). After that, we started writing a program to do some review of pointers. Began working on my FreeCell game. Created a program which initializes a deck of cards, and then shuffles it and prints out the list of cards.
September 4th - 6th
Today in class, we did a review of structs (structsgonewild!!). While the rest of the class was reviewing, I finished my datatypes program, then went on to do some more work on my card shuffler. Not in class, but, from what I gather from my sources, code for a linked list was begun. Turned in our datatypes program, and then continued talking about the linked list. Today, we wrote code to insert something into the linked list.
September 11th - 13th
Today we finished the code to insert into our linked list. We fixed so that we could insert something to the first position of the list. Began talking about the doubly linked list. We wrote a very simple doubly linked list (without insertion), and then on our own wrote functions to both display the list forward and backwards.
September 18th-20th
This week, a big portion of the week was spent working on the singly linked list program on our own. We also spent time as a class adding the insert and remove functions to the doubly linked list. I've been having some issues getting my sort to work in my singly linked list, so, that's what I've spent most of my time this week banging my head against a wall trying to figure out.
September 25th-27th
Finally got the sort working on my singly linked list. I was having an error where the list was “technically” sorting correctly, but it was erasing the highest value and replacing it with the second highest value (entering 5, 4, 3, 2, 1 would return 1, 2, 3, 4, 4). It was a pretty easy fix. I was storing two values, one of tmp and one of tmp→next, and then switching them if tmp was greater. The issue was that I was switching them in the wrong order, and was erasing tmp in the process.
October 2nd-4th
Knowledge assessment break, woo!
October 9th-11th
Talkin' 'bout 'dem stacks! Stacks have four important things. pop(), push(), peek(), and a pointer to the top of the stack. pop() takes an element off the top of the stack, push() adds an element to the top of the stack, and peek() pops an element from the stack, then pushes it back to the stack.
If we were to push() four things onto a stack in the following order: 1 2 3 4, we would then pop() them in the order: 4 3 2 1
Well, apparently, I need to get better at my organization of this, so, here goes my rundown of the rest of what happened after October 11th. There really wasn't much left in the way of things to learn, since we only had queues and binary trees left to go over. A large portion of the remaining few weeks of class were simply spent working on stuff, ironing out bugs, and all that jazz. The last few days in particular were quite stressful. I actually reached a point where I thought there was no way I was going to get everything done. But, I slowly started getting things done. Once I finished the C++ implementation of the list, the stack and queue were quite simple. The binary tree took a little more work and research, but, I eventually got through that as well. Finally, I got onto FreeCell. At first, I was really thinking “No way, I can't do this all in a day, that's impossible”. But, after a very, very intense five hour long coding marathon on Wednesday, I got it all done and working (at least to the fullest extent of my knowledge).
As far as queues and b-trees though, here is a quick rundown of what we learned about both of them:
Queues
Queues are much like stacks, except a little different. While a stack is “first in, last out”, a queue is “first in, first out”. As far as the important aspects of queues, there are two methods/functions, enqueue() and dequeue(), and two pointers, front and back. Enqueue() will add an element to the back of the queue, whereas dequeue() will remove an element from the front of the queue().
If we were to enqueue() four things onto a stack in the following order: 1 2 3 4, we would then dequeue() them in the order: 1 2 3 4.
Binary Trees
Binary trees are a very unique data structure. A binary tree starts with a root. The root then has two child nodes. Each of those two child nodes has two child nodes. And so on and so forth. Binary trees are great for efficient searching and sorting. We didn't get into everything covered in binary trees (because there is a LOT), but, what we went over were the basics. A few of the basic functions of a binary tree are insert(), remove(), search(), and print(). These are all quite self explanatory. Insert() will add a value, remove() searches for and removes a value, search() searches for a value, and print() prints the tree. The nice thing about a binary tree is that when properly implemented, the values are organized. Smaller values will be placed on the left branch of the tree, whereas larger values will go to the right. This makes traversing the tree very simple.
August 28th
Went over the class expectations, and talked about Raspberry Pis a little.
August 29th
Got the network for the Raspberry Pi table hooked up, and started messing around on the one we have all set up a little. Found that you can overclock the Raspberry Pi post setup by editing the /boot/config.txt file. I then found that when I attempted to upload something to GitHub, from the Raspberry Pi, for some reason the authentication wasn't working. I was definitely typing the right password and username, but it kept failing to authenticate. I suspect it's because for some reason the Pi is trying to push the changes to “https://www.github.com”, whereas when I push them from a different location (my dedicated server), the changes are pushed to “https://github.com”. I fixed this by editing my Git config file. I changed the url from “https://www.github.com/Shawn5961/src” to “https://github.com/Shawn5961/src” which seems to have fixed the issue.
August 30th
Continued with setting up the Raspberry Pi's. We did this by using the dd command to copy the Raspbian image to the Raspberry Pi. We did this with the following command“:
$ dd bs=1M if=path_to_image of=device_path_of_sd_card
The given arguments are as follows. bs refers to the number of bytes to read and write at a time. if refers to the infile, the source file or image we're using. And of is the /dev path of the device to write the image to.
After setting up all the Raspberry Pi's, I went through and checked all of them to be sure they were up and running correctly.
September 4th
Did some more work on setting up the RiPi table.
September 5th
Finally got into doing some real fun with our RiPi's. We used the links Matt provided us which showed some of the technical specs for the RiPi's, and another one which had some sample code of how to light up an LED with the RiPi. I got the code all typed up, but didn't really have enough time to actually get the physical portion of it done.
September 13th
Today, I finally began work on the projects for Data Comm. I pretty quickly and easily got the first three done. The first project was simply using the echo command to turn an LED on and off. Project 2 was writing a simple C program to blink and LED. After writing project 2, I messed around a little more getting two LEDs to toggle between each other. I then moved onto project 3, creating a binary counter. This was a little more difficult, and required some thinking. I finally figured out how to get the LED's to count by using a pretty simple loop, which did modulus calculations to know when to turn the LEDs on or off, and at the end incremented a counter value, then slept for 1 second. The loop was as follows:
while( 1 ) { if( (counter % 2) == 1 ) GPIO_SET = 1 << 7; else GPIO_CLR = 1 << 7; if( (counter % 4) >= 2 ) GPIO_SET = 1 << 11; else GPIO_CLR = 1 << 11; if( (counter % 8) >= 4 ) GPIO_SET = 1 << 9; else GPIO_CLR = 1 << 9; if( (counter % 16) >= 8 ) GPIO_SET = 1 << 10; else GPIO_CLR = 1 << 10; sleep(1); counter++; }
September 18th - 20th
I didn't get much done this week in Data Comm. The main reason for this is I think I was pretty much the only one who had finished my counter project, and I really needed someone else to move on to the next project. On Friday, Josh and I began setting up for the next project. We made sure our RiPi's had the LEDs in the same GPIO pins, and then we hooked our RiPis together. Since we were running low on the lead wires, we took an old ethernet cable, and used some of the copper wire from that to connect our RiPi's. It was a lot of fun basically creating our own RiPi connection cable.
September 27th-29th
While waiting for other people to get caught up to start working on the connecting of the RiPis, we took an old speaker and started working with some cool GPIO output using it. Making notes and sirens and such. (Moved to an HPC project)
October 2nd-4th
Yet another week of waiting to continue on with the telegraph projects. Just ran into a string of bad luck as far as not having two people to work on it, so, more work on HPC stuff with the RiPi this week.
The rest of the semester was spent continuing on with the projects laid out for us. We finally got two RiPis hooked together and began working on the projects involving those. For the most part, there were very few issues along the way, most of which were relatively minor. The RiPi → RiPi counter project had one minor bug in which for some reason, the LEDs on the receiving RiPi would all default to on when the counter wasn't running. But, as soon as the counter on the sending RiPi was started, they functioned correctly. We never really came to a concrete reason of why it was doing that. All the GPIO pins had been turned off, the code was correct, but, for some reason, some sort of input was being sent.
The next project, sending morse code to an LED on a receiving RiPi, we had to change a little, but I feel it was for the better. The project was to use an external switch connected to RiPi A, and use it to light up an LED on RiPi B. Unfortunately, we were running into some issues with the switches being subpar, and they were picking up a lot of line noise, which made it difficult to accurately do. It would work sometimes, and sometimes it was just getting a constant on from other wires, or our hands. So, as an alternative, I went ahead and combined part of project 6 into project 5. I wrote the program so that you could enter in any string on RiPi A, and it would then transmit that string to RiPi B's LED in morse code. While not the actual requirements of the project, I feel as if it was a bit above and beyond.
And then, we come to project 6. This project was a jerk, and I think we all will attest to that. I first experienced the RiPi's latency issues when I was working with the GPIO speaker output (sometimes notes would work perfect, and sometimes they would just produce garbage sounds). But, here we really ran into the issue. Sometimes, it would work great. We were mainly using 1ms as our dot, and 3ms as our dash. Sometimes, we would input a letter, and get it back just right. But, sometimes there was just a bit of a sync issue due to the latency, and it would combine two digits together. We finally got looking into using some sort of line interrupt to get the output correctly, using the select() function.
August 28th
Went over the structure of the course quickly.
August 29th
Worked on my remote music playing script. It's a short two line script which (on my dedicated server) pulls a video from YouTube using the youtube-dl package and extracts the audio from it. It then runs cat on the .wav file output and streams it to my LAIR PC, which then pipes it to aplay to play the audio. The script is as follows:
#!/bin/bash ssh shawn@highwind youtube-dl -f 18 http://www.youtube.com/watch?v=(insert YouTube video link here) --extract-audio --audio-format wav ssh shawn@highwind cat (insert YouTube video link here).wav | aplay
Where I've added ”(insert YouTube video link here)“, the identifier for the YouTube video is added (I believe it's always an 11 digit number after “watch?v=). I have two plans for the future with this script. One is to have the program accept command line arguments for the YouTube video, and one is to add the option to use arecord and pipe it to aplay to stream audio that you are recording with a microphone or other device.
August 30th
Continued with and finished setting up my own personal Raspberry Pi.
September 4th
Added functionality to my music.sh script to accept command line arguments. The script is now:
#!/bin/bash ssh shawn@192.155.90.226 youtube-dl -f 18 $1 --extract-audio --audio-format wav audio=`echo $1 | cut -f 2 -d'='` ssh shawn@192.155.90.226 cat $audio.wav | aplay
The program takes a command line argument in the form of a full YouTube link (example: http://www.youtube.com/watch?v=eh7lp9umG2I ). It uses that argument in the youtube-dl command. It then cuts only the YouTube video specifier (the 11 digit alphanumeric identifier) and sets the variable $audio equal to that. The $audio variable is then used in the cat | aplay command, because the output file of the youtube-dl command is the alphanumeric identifier.
September 18th-20th
Tom and I did a little bit of work on the LAIRWall. For some reason, Tom was being obstinate (fancy that?) and was trying to download Wheezy from RIT on three computers at once, and complaining that it was going slow. He was doing this even though he had a flash drive with Wheezy on it. We attempted to install Wheezy from the flash drive, but, the install appeared to be having some issues. Since the full image was on the flash drive, I put in a second flash drive, and used the dd command to binary copy the image from Tom's flash drive to the blank flash drive. We then booted off the second flash drive, and managed to get the install working. Next week, we'll have to do the install on the other five computers for the LAIRWall.
So, for HPC this semester, I did a lot of really random things (in this instance, “The Rest of the Stuff” is a very accurate description). A big portion of the semester was spent on some maintenance things. I upgraded my VPS to Ubuntu 13.04 (which had some nasty side effects, like killing my vsftpd, so I switched over to proftpd). I switched my LAIRmachine OS from Mint to Elementary OS. I spent some time learning security based stuff for our security competition (a big portion of which was Kali Linux based attack stuff, along with some defensive things, such as iptables). And the semester ended with some work on the LAIRWall, including doing some research into future upgrades for the LAIRWall.
As far as some of the larger projects I worked on, here's a quick rundown of them, and their outcomes.
Raspberry Pi speaker fun
While waiting to do some stuff for DataComm, Josh got the bright idea to hook a speaker up to a Raspberry Pi and have some fun with it. I kind of took his idea, and ran with it. Starting out, I used some crappy little unpowered speaker. I wrote functions to play a few different notes. These functions worked using usleep. They would cause the GPIO pin the speaker was hooked to to usleep for the duration between oscillations of the note. For example, a 440hz A looked something like this.
usleep((1000000 / 440) + 80)
This calculation caused the GPIO to be either on or off for the correct duration. The 80 added to the end was a cause of the system latency of the Raspberry Pi. Through some extensive trial and error testing, I found that 80 was about the average latency. Sometimes, it would still be off by a bit, depending on what the system was running, but, it worked for the most part. The next function I wrote was a simple ascending/descending note function. Instead of being a hardcoded note, it accepted an int argument. Using this, I could pass it in ever changing values, and change the note being produced. I used a simple counter in my main, and set it to increase once every time through the main loop of the program, until it hit a certain point at which a flag would be set, and the counter would decrease. I used a 220hz A as the low point, and an 880hz A as the high point. This caused the program to oscillate through two octaves, first ascending, then descending, and then repeating.
Once I became a little more invested in this project, I moved onto speaker #2. Speaker #2 was a stereo PC speaker. After wiring up wires to the tip, ring, and ground, I hooked it up to two GPIO pins at once. Because it was a stereo speaker, I could now hook it up to two GPIO pins at once. This led to some even more fun things. I could play two notes at once, and create a (VERY) basic chord. The downside to doing this however was that it greatly increased the system latency, which through off the note calculations, to a point that I couldn't find any real correlation between them. Afterward, I decided to switch over to my second program, which used the ascending/descending function. Using both of these at once, I could create a sort of siren (which was great for scaring the UNIX peeps).
My final work done on this project was in using even more optimal speakers. While speaker #2 was great, since it was stereo, it was a full sized computer speaker and required a power outlet. So, in order to reduce the tripping hazard, I took two amplified PC speakers out of some of the old computers destroyed by the flood. These speakers were amplified, but only required 3.5v power, which the Raspberry Pi has outputs of. So, with these, I could hook each one up to one of the RiPi's 3.5v outputs, a GPIO pin, and a ground. While I did lose the volume control that I had with the full sized computer speaker, the size and ease of use of the PC speakers more than made up for it.
YouTube streaming from my VPS
This was a project that I was really focused on for quite a while, until I figured out that in the long run, it wasn't going to help much. Since YouTube hates my home internet, I can't stream anything about 360p. But, bandwidth wise, I should have been able to handle 480p. So, I decided to write myself a script on my server which would download YouTube videos with the youtube-dl tool I found a few months back. The reason I needed a script was because of the way YouTube videos work now. It used to be that they had combined video and audio streams. This is still true in some cases (There are 360p and 720p mp4 containers that have both streams). But, since YouTube switched to the DASH streaming protocol, it now has separate streams for audio and video. My plan was to write myself a script which would download my video and audio formats of choice (480p video and 128kbps audio), then run an ffmpeg command which would combine the video and audio streams into one file, so that I could stream it. During my initial testing, however, I found out that the bandwidth requirements were just a little high for me to stream it. My internet runs around 1 mbps +- .05 mbps. And unfortunately, the combined video+audio streams tended to average around 1.3 mbps. I attempted to solve this by doing some re-encoding, but, ran into two issues there that just made it not worth doing. First off, the amount of time to re-encode the video was quite large. I was attempting a two pass re-encode, and my server just didn't have enough power to do that quickly enough. It was about a 20 FPS re-encode, which was just ridiculously low. Second, in order to get a fully streamable video, a lot of quality had to be sacrificed, to the point that the artifacting of the video looked like garbage.
A webhosted life counter for Magic: The Gathering
When we decided to have a few Magic drafts at Jacob's house, I got thinking. You know what would be great? If I had an easily accessible life counter for this. There are plenty of apps for it on both the Android and iOS markets, but, I thought to myself “This could be simpler”. So, I decided to take my first delve into JavaScript. I wrote a (very primitive) two player life tracker, which works on web browsers, and on mobile devices. It's quite simple and easy to use, relying on click/touch dragging on a hitbox. The only real issue it had is that the tracking was locked to the hitbox, and if the hitbox was small, it could lead to some funky locked tracking. I decided to rectify this by changing from a click/touch drag to alter the value, to some simple arbitrary buttons. +1, -1, +5, and -5. I got the logic for them working wonderfully, and then hit a CSS brick wall. Since I've never really taken anything intensive as far as web-dev courses go, it was really giving me some issues. The player 1, which was displayed in the top left, worked great. But, unfortunately, I could never quite get the player 2 bottom right display to work right. It's something I plan on revisiting, once I get some time to do a little more reading on CSS, or alternative forms of web layout (like simply using JavaScript to do the layout).
An installation of Mac OSX on my Intel Laptop This was going to be my “big” project for this semester. I've really wanted to have a way to use OSX regularly, because it's something I've never done, and something I should probably learn. I had initially just planned on creating a virtual machine of OSX, and running that inside VirtualBox. However, I ran into a very, very large issue with that. Because of the way OSX works, it does not like VirtualBox's video drivers. At all. No matter how much memory I allocated for video, OSX would only see 4 MB of video memory. This resulted in a very, very sluggish machine. Resizing a window was a chore, attempting to open some things like LaunchPad resulted in about a two minute system halt, and other myriad graphical issues. If I was running OSX simply as a dev environment, I probably could have gotten by with these issues. But, I was more or less attempting to run it to get used to the OS as a whole.
So, then I looked up how to actually install OSX onto an Intel machine. From everything I read, it seemed quite simple and straightforward. Download the OS. Download a program called UniBeast which would make a bootable USB drive to install. Download a program called MultiBeast which would fix drivers and such. And then it would be good to go. The biggest trick to these things is they had to be done within OSX. So, I got everything all downloaded (Which took forever, mind you, thanks to some funky issues I was having with rsync and my virtual OSX's network connection acting funky). When I finally got everything all download, I attempted to run UniBeast and create the bootable drive, and kept getting kernel panics. The system would just shut down. I figured it had something to do with VirtualBox, my host USB ports, and OSX just not working well together. So, I borrowed Tom's MacBook to do it on an actual machine, where that wouldn't be an issue. At first, everything seemed to be going well. But, then the UniBeast installer ran into some sort of script error. I attempted to look up the error, and all I could find were other people who had the error, with no solution. By this point, I had spent almost three weeks working on this project, from its inception as a virtual machine, and I decided that it was time to give up, and sometimes no matter how hard you bash your head, there are no solutions.