Winamp 2.9 (2.X) and AAC+

So SLAM!FM was bought by RTL, which means their internet stream now uses the RTL streaming server provided by IS.NL instead of TRUE.NL :( Enough ramblings. The internet stream now uses AAC+ which Winamp2.9x does not do out of the box. However! in_mp3.dll from Winamp 5.08 is compatible with Winamp 2.9x. Simply unzip and place the file in C:\Program Files(x86)\Winamp\Plugins\ and yay, AAC+ support. Download here: in_mp3.zip.

Wednesday, February 1st, 2012 General, Transcoding No Comments

Math pow in Assembly

I was programming some assembly the other day, and I noticed this specific example cannot be found anywhere! So I thought I’d post it :)

To run… save the file as power.s, then run

gcc -o power.o power.s -m32

(-m32 only if your on a 64bit system)

chmod +x power.o
./power.o

power.s

# ************************************************************************
# * Program name : pow                                                   *
# * Description  : Assembly Power function                               *
# * Author       : nicktc@gmail.com                                      *
# * Date         : 2011-05-26                                            *
# * License      : CC BY-NC-SA http://www.creativecommons.org            *
# ************************************************************************
.text

asknrstr:       .asciz "Please enter a natural number:"
asknrstr2:      .asciz "To the power of:"
printnrstr:     .asciz "%d^%d="
formatstr:      .asciz "%d" # Used in inout subroutine

.global main

# ************************************************************************
# * Subroutine  : main                                                   *
# * Description : application entry point                                *
# ************************************************************************
main:   movl    %esp, %ebp      # initialize the base pointer

ask:
        # Get number
        pushl   $asknrstr       # Push ask string
        call    printf          # Pop and print ask string
        subl    $4,%esp         # Reserve stack space for int
        leal    -4(%ebp), %eax  # Load address of stack space into %eax
        pushl   %eax            # Push argument of scanf
        pushl   $formatstr      # Push string
        call    scanf           # Scan number

        pushl   $asknrstr2      # Push ask string
        call    printf          # Pop and print ask string
        subl    $4,%esp         # Reserve stack space for int
        leal    -8(%ebp), %eax  # Load address of stack space into %eax
        pushl   %eax            # Push argument of scanf
        pushl   $formatstr      # Push string
        call    scanf           # Scan number

        pushl   -8(%ebp)        # Push number
        pushl   -4(%ebp)        # Push number
        pushl   $printnrstr     # Push print string
        call    printf          # Printf

        addl    $12,%esp        # Move stack pointer

        pushl   -8(%ebp)
        pushl   -4(%ebp)
        call    pow             # Call pow subroutine

        pushl   %eax            #
        pushl   $formatstr      # Push string format
        call    printf          # Print

end:    movl    $0,(%esp)       # push program exit code
        call    exit            # exit the program

# ************************************************************************
# * Subroutine  : pow                                                    *
# * Description : ask user for number and print sum                      *
# ************************************************************************
pow:
        pushl   %ebp            # Stack base pointer
        movl    %esp, %ebp      # Store stack pointer in %ebp

        movl    $1,%eax         # Store 1 in RESULT
        movl    8(%ebp),%ebx    # Store 'multiply by' in %ebx
        movl    12(%ebp),%ecx   # Store COUNT in %ecx

pow2:
        cmp     $0,%ecx
        jle     pow3

        subl    $1,%ecx         # Substract 1 from COUNT
        mul     %ebx            # Multiply %eax * %ecx (RESULT * NUMBER)

        cmp     $0,%ecx         # Compare COUNT to 0
        jg      pow2            # COUNT > 0 = jump to pow2
pow3:
        movl    %ebp, %esp      # Clear local variables from stack
        popl    %ebp            # Restore base pointer
        ret
Friday, June 10th, 2011 Programming, TU-Delft No Comments

Monitor Concurrent Connections from Wowza Media Server in Munin

So.. theres a professional way to do this (can be found on the Wowza Media Server forums[click]), but it requires you to bounce Wowza, which is less ideal.

Heres the hack:

First..

apt-get install php5-cli php5-curl

/etc/munin/wowzaget.php

#!/usr/bin/php
<?php
 function xml2array($xml) {
      $arXML=array();
      $arXML['name']=trim($xml->getName());
      $arXML['value']=trim((string)$xml);
      $t=array();
      foreach($xml->attributes() as $name => $value) $t[$name]=trim($value);
      $arXML['attr']=$t;
      $t=array();
      foreach($xml->children() as $name => $xmlchild) $t[$name]=xml2array($xmlchild);
      $arXML['children']=$t;
      return($arXML);
   }

function getIt($host,$user,$pass){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://".$host.":8086/connectioncounts");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERPWD, $user.":".$pass);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
    $output = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);

    $xml = simplexml_load_string ($output);
    $x = xml2array($xml);
    return array($x["children"]["ConnectionsTotal"]["value"],$x["children"]["ConnectionsCurrent"]["value"]);
}

$x = getIt("localhost","USERNAME","PASSWORD!");

echo $x[0]." ".$x[1];

?>

/etc/munin/plugins/munin_wowza (credit goes to georgi

#!/bin/sh

case $1 in
   config)
        cat <<'EOM'
graph_title Wowza connections
graph_scale no
graph_category wowza
graph_vlabel connections
total_connections.label total connections
live_connections.label live connections
total_connections.draw AREA
live_connections.draw LINE1
EOM
        exit 0;;
esac

cons=`/etc/munin/wowzaget.php`

tot=`echo $cons | cut -d' ' -f1`
live=`echo $cons | cut -d' ' -f2`

echo -n "total_connections.value "
echo $tot

echo -n "live_connections.value "
echo $live

Make sure you

chmod +x /etc/munin/wowzaget.php
chmod +x /etc/munin/plugins/munin_wowza

And replace the username/password with those found in
/usr/local/WowzaMediaServer/admin.password

Then viola, wowza in munin.
(If you look at the script, you can also use 1 server to monitor _ALL_, but you must enable your wowza control (on port 8086) to respond to external connections (which is unsafe))

Tags:

Saturday, March 19th, 2011 PHP 3 Comments

TI-1200 Opdracht 8

I imagine a lot of people don’t know how to do this Java exercise, so here is some code :) Please do NOT copy it!!!

(I cannot redistribute the original assignment as this would be a breach of copyright. Please see blackboard here)

Adres.java

//	Practicum TI1200,	Opdracht 8
//	Auteur N.Cate,		Studienummer 1342169
//	Datum 11-11-2010
//	NetID ntencate

import java.util.Scanner;

public class Adres {

	//post: creert een nieuw adres, met de opgegeven waarden.

	private String straat;
	private String huisNummer;
	private String postcode;
	private String plaats;

	/** Create a new adres
	 * @param straat
	 * @param huisNummer
	 * @param postcode
	 * @param plaats
	 */
	public Adres(String straat, String huisNummer, String postcode, String plaats)
	{
		this.straat = straat;
		this.huisNummer = huisNummer;
		this.postcode = postcode;
		this.plaats = plaats;
	}

	//post: retourneert een String-representatie van dit adres
	public String toString()
	{
		return "<Adres<straat=" + this.straat + ", huisNummer=" + this.huisNummer + ", postcode=" + this.postcode + ", plaats=" + this.plaats + ">>";
	}

	//post: retourneert true als other hetzelfde adres is ( zelfde postcode en huisnummer) als dit.
	public boolean equals(Object other)
	{
		if(other instanceof Adres)
		{
			Adres other2 = (Adres)other;

			if(other2.huisNummer == this.huisNummer
				&& other2.straat == this.straat
				&& other2.plaats == this.plaats
				&& other2.postcode == this.postcode
			)
				return true;
		}
		return false;
	}

	//
	/** Create an address from a scanner string
	 * pre: sc bevat een rij tokens die een adres voorstellen
	 * post: retourneert een Adres, opgebouwd uit de waarden die sc teruggeeft
	 * @param scanner text containing the address
	 */
	public static Adres read(Scanner scanner)
	{
		// scanner text ==
		// Emmalaan 23
		// 3051JC Rotterdam
		String straat = scanner.next();
		String huisNummer = scanner.next();
		String postcode = scanner.next();
		String plaats = scanner.next();

        return new Adres(straat, huisNummer, postcode, plaats);
	}

}

Adres_test.java

//	Practicum TI1200,	Opdracht 8
//	Auteur N.Cate,		Studienummer 1342169
//	Datum 11-11-2010
//	NetID ntencate

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;

public class Adres_test {

	public static void main(String [] args)
	{
		FileReader fileString;
		Adres test;

		System.out.println("test = Adres.read(sc);");
		try {
			fileString = new FileReader("src/Adres_test_text.txt");
			Scanner sc = new Scanner(fileString);

			 test = Adres.read(sc);

			System.out.println(test);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		System.out.println("---");

		Adres test1 = new Adres("Lorentzplein", "55", "2522EE", "Den Haag");
		Adres test2 = new Adres("Lorentzplein", "55", "2522EE", "Den Haag");

		System.out.println("test1:" + test1);
		System.out.println("test2:" + test2);
		System.out.println("test1.equals(test2):" + test1.equals(test2));

		System.out.println("---");

		test1 = new Adres("Buitenhof", "20", "2513AG", "Den Haag");
		System.out.println("test1:" + test1);
		System.out.println("test2:" + test2);
		System.out.println("test1.equals(test2):" + test1.equals(test2));
	}
}

Woning.java

//	Practicum TI1200,	Opdracht 8
//	Auteur N.Cate,		Studienummer 1342169
//	Datum 11-11-2010
//	NetID ntencate

import java.util.Scanner;

public class Woning {
	private Adres adres;
	private int kamers;
	private int vraagPrijs;

	/** Create a Woning object
	 * post: creeert een Woning met de opgegeven waarden
	 *
	 * @param adres
	 * @param kamers
	 * @param vraagPrijs
	 */
	public Woning(Adres adres, int kamers, int vraagPrijs)
	{
		this.adres = adres;
		this.kamers = kamers;
		this.vraagPrijs = vraagPrijs;
	}

	//post: retourneert een String-representatie van deze woning
	public String toString()
	{
		return  "<Woning<adres=" + this.adres + ", kamers=" + this.kamers + ", vraagPrijs=" + this.vraagPrijs + ">>";
	}

	/** Check if the price is max
	 * post: retourneert true als vraagprijs = maxprijs
	 *
	 * @param maxprijs
	 * @return
	 */
	public boolean kostHooguit(int maxprijs)
	{
		return (this.vraagPrijs <= maxprijs);
	}

	//post: retourneert true als other dezelfde woning is (dwz hetzelfde adres) als deze.
	public boolean equals(Object other)
	{
		if(other instanceof Woning)
		{
			Woning otherWoning = (Woning) other;
			if(otherWoning.kamers == this.kamers
				&& otherWoning.vraagPrijs == this.vraagPrijs
				&& otherWoning.adres.equals(this.adres)
				)
				return true;

		}
		return false;
	}

	/** Read Woning from file
	 * pre: sc bevat een rij tokens die een woning voorstellen
	 * post: retourneert een Woning, opgebouwd uit de waarden die sc teruggeeft
	 *
	 * @param sc Scanner text input
	 * @return
	 */
	public static Woning read(Scanner sc)
	{
		/*
		 * Text ==
		 * Emmalaan 23
		 * 3051JC Rotterdam
		 * 7 kamers
		 * prijs 300000
		 */
		Adres adres = Adres.read(sc);
		int kamers = sc.nextInt();
		sc.next();
		sc.next();
		int price = sc.nextInt();

		return new Woning(adres,kamers,price);
	}

}

Woning_test_text.txt

Emmalaan 23
3051JC Rotterdam
7 kamers
prijs 300000

Woning_test.java

//	Practicum TI1200,	Opdracht 8
//	Auteur N.Cate,		Studienummer 1342169
//	Datum 11-11-2010
//	NetID ntencate

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;

public class Woning_test {

	public static void main(String [] args)
	{
		FileReader fileString;
		Woning test0;

		System.out.println("test0 = Woning.read(sc);");
		try {
			fileString = new FileReader("src/Woning_test_text.txt");
			Scanner sc = new Scanner(fileString);

			test0 = Woning.read(sc);

			System.out.println("test0:" + test0);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		System.out.println("---");

		Adres adres1 = new Adres("Lorentzplein", "55", "2522EE", "Den Haag");
		Adres adres2 = new Adres("Buitenhof", "20", "2513AG", "Den Haag");

		Woning test1 = new Woning(adres1,10,99);
		Woning test2 = new Woning(adres2,10,99);

		System.out.println("test1:" + test1);
		System.out.println("test2:" + test2);
		System.out.println("test1.equals(test2):" + test1.equals(test2));

		System.out.println("---");

		Woning test3 = new Woning(adres2,11,99);
		System.out.println("test3:" + test3);
		System.out.println("test2:" + test2);
		System.out.println("test3.equals(test2):" + test3.equals(test2));

		System.out.println("---");

		Woning test4 = new Woning(adres2,10,99);
		System.out.println("test4:" + test4);
		System.out.println("test2:" + test2);
		System.out.println("test4.equals(test2):" + test4.equals(test2));
	}
}

Portefeuille.java

//	Practicum TI1200,	Opdracht 8
//	Auteur N.Cate,		Studienummer 1342169
//	Datum 11-11-2010
//	NetID ntencate

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;

public class Portefeuille {

	private ArrayList<Woning> woningen;

	/** Initialize new Portefeuille
	 *
	 */
	public Portefeuille()
	{
		this.woningen = new ArrayList<Woning>();
	}

	/** Add a woning
	 * post: voegt de woning toe - tenminste als hij er nog niet in zat
	 * @param woning
	 */
	public void voegToe(Woning woning)
	{
		this.woningen.add(woning);
	}

	/** Get a list of woning'n with a max price
	 * post: retourneert een lijst met alle woningen die maxprijs of minder als vraagprijs	hebben
	 * @param maxprijs
	 * @return
	 */
	public ArrayList<Woning> woningenTot(int maxprijs)
	{
		Iterator<Woning> iter = this.woningen.iterator();
		ArrayList<Woning> result = new ArrayList<Woning>();

		Woning temp;

		while(iter.hasNext())
		{
			temp = iter.next();
			if(temp.kostHooguit(maxprijs))
				result.add(temp);
		}

		return result;
	}

	/** Get a Protefeuille from file
	 * pre : infile is de naam van een tekstbestand waarin op bovenbeschreven wijze een aantal woningen staan
	 * post: retourneert een Portefeuille, die de woningen, gelezen uit dit tekstbestand bevat
	 *
	 * @param infile filename
	 * @return
	 */
	public static Portefeuille read(String infile)
	{
		/*
		 * SAMPLE TEXT==
		 * 3
		 * Emmalaan 23
		 * 3051JC Rotterdam
		 * 7 kamers
		 * prijs 300000
		 * Javastraat 88
		 * 4078KB Eindhoven
		 * 3 kamers
		 * prijs 50000
		 * Javastraat 93
		 * 4078KB Eindhoven
		 * 4 kamers
		 * prijs 55000
		 */

		Portefeuille result = new Portefeuille();
		FileReader fileString;

		try {
			fileString = new FileReader(infile);
			Scanner sc = new Scanner(fileString);

			int amount = sc.nextInt();
			for(int i = 0; i < amount; i++)
				result.voegToe(Woning.read(sc));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		return result;
	}

	public String toString()
	{
		String result;

		result = "<Portefeuille<woningen:";
		Iterator<Woning> iter = this.woningen.iterator();
		while(iter.hasNext())
		{
			result = result + iter.next() + ",";
		}
		result  = result + ">>";

		return result;
	}
}

Portefeuille_test_text.txt

3
Emmalaan 23
3051JC Rotterdam
7 kamers
prijs 300000
Javastraat 88
4078KB Eindhoven
3 kamers
prijs 50000
Javastraat 93
4078KB Eindhoven
4 kamers
prijs 55000

WoningDriver.java

//	Practicum TI1200,	Opdracht 8
//	Auteur N.Cate,		Studienummer 1342169
//	Datum 11-11-2010
//	NetID ntencate

import java.util.Iterator;
import java.util.Scanner;

public class Woningdriver {

	public static void main(String [] args)
	{
		System.out.println("Wat is de maximale prijs?");

		Scanner sc = new Scanner(System.in);
		int maxPrijs = sc.nextInt();

		Portefeuille port = Portefeuille.read("src/Portefeuille_test_text.txt");

		System.out.println("-----");

		Iterator<Woning> iter = port.woningenTot(maxPrijs).iterator();
		while(iter.hasNext())
			System.out.println(iter.next());
	}

}

Tags:

Friday, December 3rd, 2010 Hardware, TU-Delft No Comments

Debian Lenny Rotating Screen without Drivers

Had to write this down somewhere..

/boot/grub/menu.lst
Kernel options

video=vesa:ywrap,mtrr vga=794 fbcon=rotate:3

VGA mode is described in

http://wiki.antlinux.com/pmwiki.php?n=HowTos.VgaModes

Then for Xorg server
/etc/X11/xorg.conf

Section "Device"
 Driver      "fbdev"
Option "Rotate" "CCW"

Tags: , ,

Monday, November 22nd, 2010 Hardware No Comments

DD-WRT WPA2/Enterprise Connection Fail

So after installing about 15 access points in an enterprise enviroment, I discovered that the NAS (wireless driver from Broadcom) proccess included in DD-WRT v24 fails miserably at WPA2 with a radius server. Any ‘rejected’ or ‘failed’ or ‘interuppted’ or ‘packet dropped’ authentication request will stall all future authentication requests for that MAC address.

To fix this very irritating problem, you can change your OS to OpenWRT (hostapd does not have this issue). However, not all devices can run OpenWRT.

The other work around is to restart NAS every once in a while.

In your startup scripts add

echo "#!/bin/sh \n killall -TERM nas \n nas -P /tmp/nas.wl0lan.pid -H 34954 -l br0 -i eth1 -A -m 64 -r RADIUS_KEY -s SSID_USED -w 4 -g 3600 -h RADIUS_SERVER_IP -p RADIUS_SERVER_PORT" >> /tmp/root/nasReset.sh
echo ' * 5 * * * root /tmp/root/nasReset.sh' >> /tmp/crontab
startservice cron

Adjust the cronjob (* 5 * * *) to restart it more/less often. Restarting the NAS proccess will kill all data connectivity on that SSID, but WinXP/Mac OS don’t even notice. Android devices will disconnect/reconnect.

Tags: , ,

Monday, November 22nd, 2010 Router 2 Comments

Using PHP to read out a EMP800 Coin Collector

A friend at netcompany called me up a long time ago and said “Nick, I have this coin collector, I need to be able to read out its values in PHP!” so I naturally said “ok!” :)

This script works on CC-Talk enabled EMP800 coin collectors. Theoretically it should work on any CC-Talk enabled coin collector, but never been tested.

CoinCollector.php

<?php

/*********************************
* EMP800 USB
* Written/hacked-up by Nick ten Cate / nicktencate.com
*********************************/

class CoinCollector
{
	private $_handle;						 // Open Connection
	private $_device;
	private $_maxCoinType = 16;  // Maximum different types of coins to accept
	private $_eventCounter = 0;  // Event Counter

	function CoinCollector($device = "/dev/ttyUSB0", $deviceAddress = "2", $myAddress = "1")
	{
		$this->_device = $device;
		$this->_deviceAddress = $deviceAddress;
		$this->_myAddress = $myAddress;

		$this->setPortMode();
		$this->connect();
	}

	/********************************
	| Set Port Mode Correctly
	********************************/
	function setPortMode()
	{
		exec("chown root:root ".$this->_device);
		exec("stty -F ".$this->_device." -brkint -icrnl -imaxbel -opost -isig -icanon -echo");
	}

	/********************************
	| Initiate Connection
	| returns true/false
	********************************/
	function connect()
	{
		if($this->_handle = fopen($this->_device,"w+"))
		{
			return true;
		}
		else
		{
			throw new Exception('Could not open device'. $this->_device);
		}
		return false;
	}

	/********************************
	| Calculate Package CheckSum
	| $commands = array of integers
	********************************/
	function calcCheckSum($commands)
	{
		return 256-(array_sum($commands)%256);
	}

	/********************************
	| Send commands to coin collector
	| $commands = array of integers
	| returns # of commands done
	********************************/
	function sendCommands($commands)
	{
		// Add commands to send
		$c = array();
		$c[] = $this->_deviceAddress;    // Target Device Address
		$c[] = count($commands)-1;		   // Amount of DATA bits we are sending (excluding header bit (first one))
		$c[] = $this->_myAddress;		     // My Address

		foreach($commands as $x)		     // Add header bit + commands
		{
			$c[] = $x;
		}

		$c[] = $this->calcCheckSum($c);  // Add the checksum

		foreach($c as $command)			     // Send each command to device
		{
			if(!fputs($this->_handle,chr($command)))			// Convert to byte
				throw new Exception('Could not execute command: '. $command);
		}

		return count($c);
	}

	/********************************
	| Return results from coin collector
	| $count = amount of commands sent
	| return array of integers
	********************************/
	function getResults($count)
	{
		$results = array();
		$resultCounter = 1;
		$command = true;
		// Fetch first result
		// & fetch all others after it, until check sum completes.
		// This should be re-written, the 2nd byte is # of data being returned.
		do
		{
			$char = fgetc($this->_handle);	// Each Byte represents something. 1=Source, 2=Amount of Data, 3=Target, 4=Data1, 5=Data2, #=checksum

			if($resultCounter > $count)
			{
				$command = false;
				$results[] = ord($char);
			}

			$resultCounter++;
		} while($command 	|| $this->calcCheckSum($results) != 256);

		array_pop($results);	// Remove last byte, the checksum 

		unset($results[0]);	// Remove 'source address'
		unset($results[1]); // Remove 'amount of data'
		unset($results[2]);	// Remove 'target address'
		return $results;
	}

	/********************************
	| Run the commands and return the results
	| Return array of results
	********************************/
	function execute($commands)
	{
		$count = $this->sendCommands($commands);
		$results = $this->getResults($count);
		return $results;
	}

	/********************************
	| Get array of coin types and ids
	| Return array KEY=id, VALUE=coin
	********************************/
	function getCoinTypes()
	{
		$results = array();
		for($x = 1; $x < $this->_maxCoinType+1; $x++)
		{
			$result = $this->execute(array(184,$x));
			$string = "";
			foreach($result as $xx)
			{
				$string .= chr($xx);
			}
			$string = str_replace(" ","",$string);

			unset($t);
			$t = array();
			$t["currency"] = substr($string,1,2);
			$t["value"] = round(substr($string,3,3)/100,2)*1.00;
			$t["denomination"] = "1";
			$t["coinId"] = $x;

			$results[$x] = $t;
		}
		return $results;
	}

	/********************************
	| Set coinIds open
	| (send command + binary bytes->int for each id)
	********************************/
	function allowCoinEntry($array = 1)
	{
		$binary = array();

		if($array == 1)
		{
			$binary[] = "255";
			$binary[] = "255";
		}
		else
		{
			// Make empty array
			$settings = array();
			for($x = 1; $x < $this->_maxCoinType; $x++)
			{
				$settings[$x] = "0";
			}
			// Transform into correct array
			foreach($array as $key => $x)
			{
				$settings[$key] = $x;
			}

			// Create binary
			$tempBinary = "";
			foreach($array as $key => $x)
			{
				if($key%8 == 0)
				{
					$binary[] = bindec($tempBinary);
					$tempBinary = "";
				}

				if($x == 1)
					$binary .= "1";
				else
					$binary .= "0";
			}
		}

		$commands = array_merge(array('231'),$binary);

		$this->execute($commands);
	}

	/********************************
	| Poll for coins
	| Return array KEY=coinId VALUE=# of coins
	********************************/
	function poll()
	{
		$results = $this->execute(array(229));
		//Results Array Definitions
		// 4  = event counter
		// 5  = Event A Key ==> 0 (ERROR) || 1 - $_maxCoinType (COIN ID)
		// 6  = Event A Value ==> Error Id  || 0
		// 7  = Event B Key
		// 8  = Event B Value
		// 9  = Event C Key
		// 10  = Event C Value
		// 11  = Event D Key
		// 12  = Event D Value
		// 13  = Event E Key
		// 14  = Event E Value
		if($this->_eventCounter > 0)
			$diff = $results[4] - $this->_eventCounter;
		else
			$diff = 0;

		$coins = array();
		for($x = 1; $x < $this->_maxCoinType; $x++)
		{
			$coins[$x] = 0;
		}

		for($x = 0; $x < $diff; $x++)
		{
			$coinId = $results[(5+(2*$x))];

			// Add to coin amount
			$coins[$coinId] = $cois[$coinId] + 1;
		}

		// Set Event Counter
		$this->_eventCounter = $results[4];
		return $coins;
	}

	function debug($text)
	{
		echo "DEBUG:: $text \r\n";
	}

	/********************************
	| Called when coin is put
	| $coins = array of key=coinId, value=# of coins
	********************************/
	function onCoinEvent($coins)
	{
		// Do something
		echo "Got Coin(s)! ";
		foreach($coins as $k => $v)
		{
			if($v > 0)
			{
				echo $v."x".$k."-";
			}
		}
		echo "\r\n";
	}

	/********************************
	| Calculate Total Value
	| Return total value
	********************************/
	function calculateValue($coins, $coinTypes = false)
	{
		if($coinTypes == false)
		{
			$coinTypes = $this->getCoinTypes();
		}

		$total = 0;

		foreach($coins as $coinId => $amount)
		{
			$total += $coinTypes[$coinId]["value"] * $amount;
		}
		return $total;
	}

	/********************************
	| Poll for coins
	| Return array of coins
	********************************/
	function pollTimeOut($time = 5)
	{
		$originalTime = $time;
		$totalCoins = array();

		for($x = 1; $x < $this->_maxCoinType; $x++)
		{
			$totalCoins[$x] = 0;
		}

		while($time > 0)
		{
			$runAmount = 3;
			for($x = 0; $x < $runAmount; $x++)
			{
				$coins = $this->poll();		// Poll for coins
				if(array_sum($coins) > 0)	// Accepted Coin
				{
					$this->onCoinEvent($coins);

					$time = $originalTime;	// Reset Timeout
					foreach($coins as $k => $v)	// Add-up coins
					{
						$totalCoins[$k] += $coins[$k];
					}
				}

				usleep((1000000/$runAmount)); // Wait for 500ms
			}

			$this->debug("Time is: $time");
			$time--;
		}
		return $totalCoins;

	}

}

?>

Heres a quick implementation

<?php

include("CoinCollector.php");

$collector = new CoinCollector();

$a = $collector->getCoinTypes();

print_r($a);

$coins = $collector->pollTimeOut(10);

print_r($coins);

echo "Total Value \r\n";
echo $collector->calculateValue($coins);
echo " EURO";

?>

Tags: , , , , ,

Wednesday, October 13th, 2010 Hardware No Comments

librtmp + ffmpeg + vlc 1.1.4.1 on Debian Lenny 64-bit

This is a pain to get working, at least if you want to use the newer versions of everything. However, it does work! Below is what I pieced together. To install either copy paste all the commands, or put them into a bash file. (vim go.sh, copy paste, ./go.sh)

Note: this by far does not cover all the items you can include in vlc. it just includes the ones I needed.
Note2: none of this is recommended. using the repo is much better (but outdated..)

#################################################
# Get Apt Sorted
echo "deb http://mirrors.nl.kernel.org/debian/ lenny main contrib non-free" >> /etc/apt/sources.list
echo "deb http://www.debian-multimedia.org lenny main non-free" >> /etc/apt/sources.list
wget http://www.debian-multimedia.org/pool/main/d/debian-multimedia-keyring/debian-multimedia-keyring_2008.10.16_all.deb
dpkg -i debian-multimedia-keyring_2008.10.16_all.deb
apt-get update

###################################################
# FFMPEG INSTALL

apt-get install zlib1g-dev libssl-dev pkg-config --yes --force-yes
wget "http://rtmpdump.mplayerhq.hu/download/rtmpdump-2.3.tgz"
tar -xvvf rtmpdump-2.3.tgz
cd rtmpdump-2.3
make
make install

cd ..

wget -O faac-1.28.tar.gz "http://downloads.sourceforge.net/project/faac/faac-src/faac-1.28/faac-1.28.tar.gz?r=http%3A%2F%2Fwww.audiocoding.com%2Fdownloads.html&ts=1286909210&use_mirror=kent"
tar -xvvf faac-1.28.tar.gz
cd faac-1.28
./configure
make
make install

cd ..

wget "http://www.tortall.net/projects/yasm/releases/yasm-1.1.0.tar.gz"
tar -xvvf yasm-1.1.0.tar.gz
cd yasm-1.1.0
./configure
make
make install

cd ..

apt-get install git-core --yes --force-yes
git clone git://git.videolan.org/x264.git
cd x264
CFLAGS="-m64 -mtune=athlon64 -pipe -fPIC" ./configure --enable-pic --enable-shared
make
make install

cd ..

apt-get install subversion --yes --force-yes
svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg
cd ffmpeg
CFLAGS="-m64 -mtune=athlon64 -pipe -fPIC" ./configure --cc="gcc -m64 -mtune=athlon64 -pipe" --enable-version3 --enable-libfaac --enable-libx264 --enable-pthreads --enable-gpl --enable-nonfree --enable-librtmp --enable-shared --enable-postproc
make
make install

cd ..

###################################################
# VLC INSTALL

# Some packages that are usefull
apt-get install libtool autoconf libdbus-1-dev liblua5.1-0-dev libxcb-shm0-dev libqt4-dev libgcrypt-dev --yes --force-yes

#libmad
wget "ftp://ftp.mars.org/pub/mpeg/libmad-0.15.1b.tar.gz"
tar -xvf libmad-0.15.1b.tar.gz
cd libmad-0.15.1b
cp configure configure_backup
sed 's/optimize="$optimize -fforce-mem"/#optimize="$optimize -fforce-mem"/g' configure_backup > configure
./configure
make
make install

cd ..

#liblame
wget -O lame-3.98.4.tar.gz "http://downloads.sourceforge.net/project/lame/lame/3.98.4/lame-3.98.4.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Flame%2Ffiles%2Flame%2F&ts=1286919122&use_mirror=kent"
tar -xvf lame-3.98.4.tar.gz
cd lame-3.98.4
./configure
make
make install

cd ..

#libogg
wget "http://downloads.xiph.org/releases/ogg/libogg-1.2.0.tar.gz"
tar -xvf libogg-1.2.0.tar.gz
cd libogg-1.2.0
./configure
make
make install

cd ..

#libvorbis
wget "http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.1.tar.gz"
tar -xvf libvorbis-1.3.1.tar.gz
cd libvorbis-1.3.1
./configure
make
make install

cd ..

#libtheora
wget "http://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2"
tar -xvf libtheora-1.1.1.tar.bz2
cd libtheora-1.1.1
./configure
make
make install

cd ..

#libxv
apt-get install libxv-dev --yes --force-yes
wget -O libdv-1.0.0.tar.gz "http://downloads.sourceforge.net/project/libdv/libdv/1.0.0/libdv-1.0.0.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Flibdv%2F&ts=1286919451&use_mirror=kent"
tar -xvf libdv-1.0.0.tar.gz
cd libdv-1.0.0
./configure
make
make install

cd ..

# liba52
wget "http://liba52.sourceforge.net/files/a52dec-0.7.4.tar.gz"
tar -xvf a52dec-0.7.4.tar.gz
cd a52dec-0.7.4
CFLAGS="-m64 -mtune=athlon64 -pipe -fPIC" ./configure --enable-shared --disable-static
make
make install

cd ..

# mpeg2 libraries
wget "http://libmpeg2.sourceforge.net/files/libmpeg2-0.5.1.tar.gz"
tar -xvf libmpeg2-0.5.1.tar.gz
cd libmpeg2-0.5.1
./configure
make
make install

cd ..	

#libdvbpsi
wget "http://download.videolan.org/pub/libdvbpsi/0.1.7/libdvbpsi-0.1.7.tar.bz2"
tar -xvf libdvbpsi-0.1.7.tar.bz2
cd libdvbpsi-0.1.7
./configure
make
make install

cd ..

#live555
wget "http://www.live555.com/liveMedia/public/live555-latest.tar.gz"
tar -xvf live555-latest.tar.gz
cd live
./genMakefiles linux-64bit
make

cd ..

#libfaad
wget "http://downloads.sourceforge.net/faac/faad2-2.7.tar.gz"
tar -xvf faad2-2.7.tar.gz
cd faad2-2.7
./configure
make
make install

cd ..

#twolame
wget "http://downloads.sourceforge.net/twolame/twolame-0.3.12.tar.gz"
tar -xvf twolame-0.3.12.tar.gz
cd twolame-0.3.12
./configure
make
make install

cd ..

#libraw1394
wget -O libraw1394-2.0.5.tar.gz "http://sourceforge.net/projects/libraw1394/files/libraw1394/libraw1394-2.0.5.tar.gz/download"
tar -xvf libraw1394-2.0.5.tar.gz
cd libraw1394-2.0.5
./configure
make
make install

cd ..

#libdc1394
wget -O libdc1394-2.1.2.tar.gz "http://sourceforge.net/projects/libdc1394/files/libdc1394-2/2.1.2/libdc1394-2.1.2.tar.gz/download";
tar -xvf libdc1394-2.1.2.tar.gz
cd libdc1394-2.1.2
./configure
make
make install

cd ..

#libavc1394
wget -O libavc1394-0.5.4.tar.gz "http://sourceforge.net/projects/libavc1394/files/libavc1394/libavc1394-0.5.4.tar.gz/download";
tar -xvf libavc1394-0.5.4.tar.gz
cd libavc1394-0.5.4
./configure
make
make install

cd ..

#v4l
wget -O v4l.tar.bz2 "http://freshmeat.net/urls/5ecd7149a259c2cb1cc8b84ae8d3efe1"
tar -xvf v4l.tar.bz2
cd v4l-utils-0.8.1
make
make install

cd ..

#libdca
wget "http://download.videolan.org/pub/videolan/libdca/0.0.5/libdca-0.0.5.tar.bz2"
tar -xvf libdca-0.0.5.tar.bz2
cd libdca-0.0.5
./configure
make
make install

cd ..

#flac
wget -O flac-1.2.1.tar.gz "http://sourceforge.net/projects/flac/files/flac-src/flac-1.2.1-src/flac-1.2.1.tar.gz/download"
tar -xvf flac-1.2.1.tar.gz
cd flac-1.2.1
sed -i  '1i #include <cstring>' examples/cpp/encode/file/main.cpp
./configure
make
make install

cd ..

#speex
wget "http://downloads.xiph.org/releases/speex/speex-1.2rc1.tar.gz"
tar -xvf speex-1.2rc1.tar.gz
cd speex-1.2rc1
./configure
make
make install

cd ..

#alsa
wget "ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.9rc4.tar.bz2"
tar -xvf alsa-lib-1.0.9rc4.tar.bz2
cd alsa-lib-1.0.9rc4
./configure
make
make install

cd ..

#freetype
wget -O freetype-2.4.3.tar.gz "http://sourceforge.net/projects/freetype/files/freetype2/2.4.3/freetype-2.4.3.tar.gz/download"
tar -xvf freetype-2.4.3.tar.gz
cd freetype-2.4.3
./configure
make
make install

cd ..

#fribidi
wget "http://fribidi.org/download/fribidi-0.10.9.tar.gz"
tar -xvf fribidi-0.10.9.tar.gz
cd fribidi-0.10.9
./configure
make
make install

cd ..

# VLC finally..
apt-get install lua5.1 libxcb-shm0-dev libxcb-xv0-dev libxcb-keysyms1-dev libxcb-randr0-dev libx11-xcb-dev --yes --force-yes
wget "http://download.videolan.org/pub/vlc/1.1.4.1/vlc-1.1.4.1.tar.bz2"
tar -xvvf vlc-1.1.4.1.tar.bz2
cd vlc-1.1.4.1
./configure --disable-nls --disable-mozilla --disable-xcb --enable-live555 --with-live555-tree="../live/"
./configure --enable-xvideo --disable-nls --disable-mozilla --enable-sdl --enable-avcodec --enable-avformat --enable-swscale --enable-mad --enable-a52 --enable-libmpeg2 --enable-dvdnav --enable-faad --enable-vorbis --enable-ogg --enable-theora --enable-mkv --enable-speex --enable-live555 --with-live555-tree="../live/" --enable-skins2 --enable-alsa --enable-qt4 --enable-ncurses --enable-realrtsp --enable-twolame --enable-real --enable-x264
make
make install

# Fix vlc links
ln -s /usr/local/lib/libvlc* /usr/lib/
ln -s /usr/local/lib/libx264.a /usr/lib/
ln -s /usr/local/lib/vlc /usr/lib/vlc

After this.. you can run vlc!

nick@debian:/home/nick/vlc-1.1.4.1$ ./vlc
VLC media player 1.1.4.1 The Luggage (revision exported)

Tags: , , , ,

Wednesday, October 13th, 2010 Transcoding No Comments

DD-WRT v24 pre-SP2 SNMP Clients on eth1(wl0) and wl0.1

So for a pet project I recently had to record and graph how many clients were on any SSID at one time, accross all 30+ dd-wrt enabled routers. It seems the built in SNMP client does not have this capability :( So naturally, I had to figure out my own. Here’s how I did it.

First, host this script on a webserver that can be reached by all intended routers. For this guide, it will be placed at http://192.168.1.2/ddwrtSnmpScript.txt

#!/bin/sh

place=".1.3.6.1.4.1.2021.254"

refresh() {

  # Calc total clients Eth1
  wlId="eth1"
  totalClientsEth1=0
  for mac in $(wl -i $wlId assoclist | cut -d" " -f2)
  do
   let totalClientsEth1=$totalClientsEth1+1
  done

  # Calc total clients Wl0.1
  wlId="wl0.1"
  totalClientsWl01=0

  for mac in $(wl -i $wlId assoclist | cut -d" " -f2)
  do
   let totalClientsWl01=$totalClientsWl01+1
  done

  let totalClients=$totalClientsWl01+$totalClientsEth1

  eval getnext_1361412021254="$place.3.54.1.3.32.1.27.1"

  # DESCRIPTIONS
  # Total Clients
  eval value_136141202125435413321271="Total_Clients_on_AP"
  eval type_136141202125435413321271="string"

  # Total Clients eth1
  eval getnext_136141202125435413321271="$place.3.54.1.3.32.1.27.2"
  eval value_136141202125435413321272="Total_Clients_using_eth1_on_AP"
  eval type_136141202125435413321272="string"

  # Total Clients wl0.1
  eval getnext_136141202125435413321272="$place.3.54.1.3.32.1.27.3"
  eval value_136141202125435413321273="Total_Clients_using_wl0.1_on_AP"
  eval type_136141202125435413321273="string"

  eval getnext_136141202125435413321273="$place.3.54.1.3.32.1.28.1"

  # VALUES

  # Total Clients
  eval value_136141202125435413321281=$totalClients
  eval type_136141202125435413321281="integer"

  # Total Clients eth1
  eval getnext_136141202125435413321281="$place.3.54.1.3.32.1.28.2"
  eval value_136141202125435413321282=$totalClientsEth1
  eval type_136141202125435413321282="integer"

  # Total Clients wl0.1
  eval getnext_136141202125435413321282="$place.3.54.1.3.32.1.28.3"
  eval value_136141202125435413321283=$totalClientsWl01
  eval type_136141202125435413321283="integer"

  eval getnext_13614120212543541332128${lastid}="NONE"
}

LASTREFRESH=0

while read CMD
do
  case "$CMD" in
    PING)
      echo PONG
      continue
      ;;
    getnext)
      read REQ
      let REFRESH=$(date +%s)-$LASTREFRESH
      if test $REFRESH -gt 30
      then
        LASTREFRESH=$(date +%s)
        refresh
      fi

      oid=$(echo $REQ | tr -d .)
      eval ret=\$getnext_${oid}
      if test "x$ret" = "xNONE"
      then
        echo NONE
        continue
      fi
      ;;
    *)
      read REQ
      if test "x$REQ" = "x$place"
      then
        echo NONE
        continue
      else
        ret=$REQ
      fi
      ;;
  esac

  oid=$(echo $ret | tr -d .)
  if eval test "x\$type_${oid}" != "x"
  then
    echo $ret
    eval echo "\$type_${oid}"
    eval echo "\$value_${oid}"
  else
    echo NONE
  fi

done

Next, go to your DD-WRT “Services” -> “Services” and enable SNMP (http://192.168.1.1/Services.asp).

Then go to your DD-WRT “Administration” -> “Commands” (http://192.168.1.1/Diagnostics.asp) and enter the following into your startup script.

wget http://192.168.1.2/ddwrtSnmpScript.txt -O /tmp/root/snmp.sh
chmod +x /tmp/root/snmp.sh
echo "pass_persist .1.3.6.1.4.1.2021.254 /tmp/root/snmp.sh" >> /var/snmp/snmpd.conf
killall -TERM snmpd
snmpd -c /var/snmp/snmpd.conf

Restart your router…

Then viola!

root@MONITOR-1:~# snmpwalk -v2c -c public 192.168.1.1 1.3.6.1.4.1.2021.254
UCD-SNMP-MIB::ucdavis.254.3.54.1.3.32.1.27.1 = STRING: "Total_Clients_on_AP"
UCD-SNMP-MIB::ucdavis.254.3.54.1.3.32.1.27.2 = STRING: "Total_Clients_using_eth1_on_AP"
UCD-SNMP-MIB::ucdavis.254.3.54.1.3.32.1.27.3 = STRING: "Total_Clients_using_wl0.1_on_AP"
UCD-SNMP-MIB::ucdavis.254.3.54.1.3.32.1.28.1 = INTEGER: 73
UCD-SNMP-MIB::ucdavis.254.3.54.1.3.32.1.28.2 = INTEGER: 64
UCD-SNMP-MIB::ucdavis.254.3.54.1.3.32.1.28.3 = INTEGER: 9

Tags: , ,

Wednesday, October 13th, 2010 Router 3 Comments

ffmpeg + x264 + rtmp on Debian Lenny 64-bit

Getting ffmpeg to work with x264 support on Debian Lenny (2.6.26-2-amd64) can prove to be a challenge. Here is what works ‘right now’.

I’ve used non-dep sources, since the dep sources are all very outdated. Take caution when upgrading your system after installing these.

Prep your sources.

echo "deb http://mirrors.nl.kernel.org/debian/ lenny main contrib non-free" >> /etc/apt/sources.list
echo "deb http://www.debian-multimedia.org lenny main non-free" >> /etc/apt/sources.list
wget http://www.debian-multimedia.org/pool/main/d/debian-multimedia-keyring/debian-multimedia-keyring_2008.10.16_all.deb
dpkg -i debian-multimedia-keyring_2008.10.16_all.deb
apt-get update

Install librtmp (included in rtmpdump)

apt-get install zlib1g-dev libssl-dev pkg-config
wget http://rtmpdump.mplayerhq.hu/download/rtmpdump-2.3.tgz
tar -xvvf rtmpdump-2.3.tgz
cd rtmpdump-2.3
make
make install
cd ..

Get libfaac

wget -O faac-1.28.tar.gz http://downloads.sourceforge.net/project/faac/faac-src/faac-1.28/faac-1.28.tar.gz?r=http%3A%2F%2Fwww.audiocoding.com%2Fdownloads.html&ts=1286909210&use_mirror=kent
tar -xvvf faac-1.28.tar.gz
cd faac-1.28
./configure
make
make install
cd ..

Get YASM

wget http://www.tortall.net/projects/yasm/releases/yasm-1.1.0.tar.gz
tar -xvvf yasm-1.1.0.tar.gz
cd yasm-1.1.0
./configure
make
make install
cd ..

Get x264 (git, so latest version! Probably not desired for a production use system)

apt-get install git-core
git clone git://git.videolan.org/x264.git
cd x264
CFLAGS="-m64 -mtune=athlon64 -pipe -fPIC" ./configure --enable-pic --enable-shared
make
make install
cd ..

Get ffmpeg (svn, so latest version! Probably not desired for a production use system)

apt-get install subversion
svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg
cd ffmpeg
CFLAGS="-m64 -mtune=athlon64 -pipe -fPIC" ./configure --cc="gcc -m64 -mtune=athlon64 -pipe" --enable-version3 --enable-libfaac --enable-libx264 --enable-pthreads --enable-gpl --enable-nonfree --enable-librtmp --enable-shared
make
make install
cd ..

All done :)

Tags: , , , ,

Tuesday, October 12th, 2010 Transcoding 2 Comments