changeset 51:68d01fea1e8d

Added a unit testing project, and did some commenting. Also moved python-module into a modules-and-plug-ins folder
author Adam Stark <adamstark@users.noreply.github.com>
date Tue, 21 Jan 2014 10:24:33 +0000
parents bb3803edaa17
children 45231107c9d6
files .hgignore modules-and-plug-ins/python-module/btrack_python_module.cpp modules-and-plug-ins/python-module/setup.py python-module/btrack_python_module.cpp python-module/setup.py src/BTrack.cpp src/BTrack.h unit-tests/BTrack Tests.xcodeproj/project.pbxproj unit-tests/BTrack Tests/BTrack_Tests.1 unit-tests/BTrack Tests/main.cpp
diffstat 10 files changed, 811 insertions(+), 451 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Jan 21 01:45:36 2014 +0000
+++ b/.hgignore	Tue Jan 21 10:24:33 2014 +0000
@@ -1,1 +1,8 @@
-python-module/build
\ No newline at end of file
+syntax: glob
+
+python-module/build
+unit-tests/Build
+xcuserdata
+.DS_Store
+
+*.xcworkspace
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules-and-plug-ins/python-module/btrack_python_module.cpp	Tue Jan 21 10:24:33 2014 +0000
@@ -0,0 +1,362 @@
+#include <iostream>
+#include <Python.h>
+#include "../../src/OnsetDetectionFunction.h"
+#include "../../src/BTrack.h"
+#include <numpy/arrayobject.h>
+
+static PyObject * btrack_onsetdf(PyObject *dummy, PyObject *args) 
+{
+    PyObject *arg1=NULL;
+    PyObject *arr1=NULL;
+    
+    if (!PyArg_ParseTuple(args, "O", &arg1)) 
+    {
+        return NULL;
+    }
+    
+    arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); 
+    if (arr1 == NULL) 
+    {
+        return NULL;
+    }
+
+
+    
+    ////////// GET INPUT DATA ///////////////////
+    
+    // get data as array
+    double* data = (double*) PyArray_DATA(arr1);
+    
+    // get array size
+    int signal_length = PyArray_Size((PyObject*)arr1);
+    //int k = (int) theSize;
+    
+    // get data type 
+    char type = PyArray_DESCR(arr1)->type;
+    
+    ////////// BEGIN PROCESS ///////////////////
+    int hsize = 512;
+    int fsize = 1024;
+    int df_type = 6;
+    int numframes;
+    double buffer[hsize];	// buffer to hold one hopsize worth of audio samples
+
+    
+    // get number of audio frames, given the hop size and signal length
+	numframes = (int) floor(((double) signal_length) / ((double) hsize));
+    
+    OnsetDetectionFunction onset(hsize,fsize,df_type,1);
+
+    double df[numframes];
+    
+
+    
+    ///////////////////////////////////////////
+	//////// Begin Processing Loop ////////////
+	
+	for (int i=0;i < numframes;i++)
+	{		
+		// add new samples to frame
+		for (int n = 0;n < hsize;n++)
+		{
+			buffer[n] = data[(i*hsize)+n];
+		}
+		
+		df[i] = onset.getDFsample(buffer);
+		
+	}
+	
+	///////// End Processing Loop /////////////
+	///////////////////////////////////////////
+    
+    
+    ////////// END PROCESS ///////////////////
+    
+    
+    
+    ////////// CREATE ARRAY AND RETURN IT ///////////////////
+    int nd=1;
+    npy_intp m= numframes;
+    //double fArray[5] = {0,1,2,3,4};
+    
+    PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
+    
+    void *arr_data = PyArray_DATA((PyArrayObject*)c);
+        
+    memcpy(arr_data, df, PyArray_ITEMSIZE((PyArrayObject*) c) * m); 
+    
+     
+    Py_DECREF(arr1);  
+    Py_INCREF(Py_None); 
+    //return Py_None;
+    
+    return (PyObject *)c;
+    
+    //return Py_BuildValue("c", type);
+    //return Py_BuildValue("d", sum);
+    //return Py_BuildValue("i", k);
+/*    
+fail:
+    Py_XDECREF(arr1); 
+    Py_XDECREF(arr2); 
+    PyArray_XDECREF_ERR(oarr); 
+    return NULL;*/
+}
+
+
+static PyObject * btrack_btrack(PyObject *dummy, PyObject *args) 
+{
+    PyObject *arg1=NULL;
+    PyObject *arr1=NULL;
+    
+    if (!PyArg_ParseTuple(args, "O", &arg1)) 
+    {
+        return NULL;
+    }
+    
+    arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); 
+    if (arr1 == NULL) 
+    {
+        return NULL;
+    }
+    
+    
+    
+    ////////// GET INPUT DATA ///////////////////
+    
+    // get data as array
+    double* data = (double*) PyArray_DATA(arr1);
+    
+    // get array size
+    int signal_length = PyArray_Size((PyObject*)arr1);
+    //int k = (int) theSize;
+    
+    // get data type 
+    char type = PyArray_DESCR(arr1)->type;
+    
+    ////////// BEGIN PROCESS ///////////////////
+    int hsize = 512;
+    int fsize = 1024;
+    int df_type = 6;
+    int numframes;
+    double buffer[hsize];	// buffer to hold one hopsize worth of audio samples
+    
+    
+    // get number of audio frames, given the hop size and signal length
+	numframes = (int) floor(((double) signal_length) / ((double) hsize));
+    
+    OnsetDetectionFunction onset(hsize,fsize,df_type,1);
+    BTrack b;
+    
+    b.initialise((int) hsize);	// initialise beat tracker
+	
+	// set parameters
+    //b.setparams(0.9,5);
+    
+    double df[numframes];
+    double beats[5000];
+    int beatnum = 0;
+    float df_val;
+    
+    ///////////////////////////////////////////
+	//////// Begin Processing Loop ////////////
+	
+	for (int i=0;i < numframes;i++)
+	{		
+		// add new samples to frame
+		for (int n = 0;n < hsize;n++)
+		{
+			buffer[n] = data[(i*hsize)+n];
+		}
+		
+		df[i] = onset.getDFsample(buffer);
+        
+        df_val = (float) (df[i] + 0.0001);
+                
+		b.process(df_val);				// process df sample in beat tracker
+		
+		if (b.playbeat == 1)
+		{
+			beats[beatnum] = (((double) hsize) / 44100) * ((double) i);
+			beatnum = beatnum + 1;	
+		}
+		
+	}
+	
+	///////// End Processing Loop /////////////
+	///////////////////////////////////////////
+    
+    
+    ////////// END PROCESS ///////////////////
+    
+    double beats_out[beatnum];          // create output array
+    
+    // copy beats into output array
+    for (int i = 0;i < beatnum;i++)     
+    {
+        beats_out[i] = beats[i];
+    }
+    
+    
+    
+    ////////// CREATE ARRAY AND RETURN IT ///////////////////
+    int nd=1;
+    npy_intp m= beatnum;
+    //double fArray[5] = {0,1,2,3,4};
+    
+    PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
+    
+    void *arr_data = PyArray_DATA((PyArrayObject*)c);
+    
+    memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); 
+    
+    
+    Py_DECREF(arr1);  
+    Py_INCREF(Py_None); 
+    //return Py_None;
+    
+    return (PyObject *)c;
+    
+    //return Py_BuildValue("c", type);
+    //return Py_BuildValue("d", sum);
+    //return Py_BuildValue("i", k);
+    /*    
+     fail:
+     Py_XDECREF(arr1); 
+     Py_XDECREF(arr2); 
+     PyArray_XDECREF_ERR(oarr); 
+     return NULL;*/
+}
+
+static PyObject * btrack_btrack_df(PyObject *dummy, PyObject *args) 
+{
+    PyObject *arg1=NULL;
+    PyObject *arr1=NULL;
+    
+    if (!PyArg_ParseTuple(args, "O", &arg1)) 
+    {
+        return NULL;
+    }
+    
+    arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); 
+    if (arr1 == NULL) 
+    {
+        return NULL;
+    }
+    
+    
+    
+    ////////// GET INPUT DATA ///////////////////
+    
+    // get data as array
+    double* data = (double*) PyArray_DATA(arr1);
+    
+    // get array size
+    int numframes = PyArray_Size((PyObject*)arr1);
+    //int k = (int) theSize;
+    
+    // get data type 
+    char type = PyArray_DESCR(arr1)->type;
+    
+    ////////// BEGIN PROCESS ///////////////////
+    int hsize = 512;
+
+    BTrack b;
+    
+    b.initialise((int) hsize);	// initialise beat tracker
+	
+	// set parameters
+    //b.setparams(0.9,5);
+    
+    double beats[5000];
+    int beatnum = 0;
+    float df_val;
+    
+    ///////////////////////////////////////////
+	//////// Begin Processing Loop ////////////
+	
+	for (int i=0;i < numframes;i++)
+	{		
+        df_val = (float) (data[i] + 0.0001);
+        
+		b.process(df_val);				// process df sample in beat tracker
+		
+		if (b.playbeat == 1)
+		{
+			beats[beatnum] = (((double) hsize) / 44100) * ((double) i);
+			beatnum = beatnum + 1;	
+		}
+		
+	}
+	
+	///////// End Processing Loop /////////////
+	///////////////////////////////////////////
+    
+    
+    ////////// END PROCESS ///////////////////
+    
+    double beats_out[beatnum];          // create output array
+    
+    
+    // copy beats into output array
+    for (int i = 0;i < beatnum;i++)     
+    {
+        beats_out[i] = beats[i];
+    }
+    
+    
+    ////////// CREATE ARRAY AND RETURN IT ///////////////////
+    int nd=1;
+    npy_intp m= beatnum;
+    //double fArray[5] = {0,1,2,3,4};
+    
+    PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
+    
+    void *arr_data = PyArray_DATA((PyArrayObject*)c);
+    
+    memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); 
+    
+    
+    Py_DECREF(arr1);  
+    Py_INCREF(Py_None); 
+    //return Py_None;
+    
+    return (PyObject *)c;
+    
+    //return Py_BuildValue("c", type);
+    //return Py_BuildValue("d", sum);
+    //return Py_BuildValue("i", k);
+    /*    
+     fail:
+     Py_XDECREF(arr1); 
+     Py_XDECREF(arr2); 
+     PyArray_XDECREF_ERR(oarr); 
+     return NULL;*/
+}
+
+
+
+static PyMethodDef btrack_methods[] = {
+    { "onsetdf",btrack_onsetdf,METH_VARARGS,"onset detection function"},
+    { "btrack",btrack_btrack,METH_VARARGS,"beat tracker"},
+    { "btrack_df",btrack_btrack_df,METH_VARARGS,"beat tracker with detection function input"},
+    {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+PyMODINIT_FUNC initbtrack(void)
+{
+    (void)Py_InitModule("btrack", btrack_methods);
+    import_array();
+}
+
+int main(int argc, char *argv[])
+{
+    /* Pass argv[0] to the Python interpreter */
+    Py_SetProgramName(argv[0]);
+    
+    /* Initialize the Python interpreter.  Required. */
+    Py_Initialize();
+    
+    /* Add a static module */
+    initbtrack();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules-and-plug-ins/python-module/setup.py	Tue Jan 21 10:24:33 2014 +0000
@@ -0,0 +1,16 @@
+# setup.py
+# build command : python setup.py build build_ext --inplace
+from numpy.distutils.core import setup, Extension
+import os, numpy
+
+name = 'btrack'
+sources = ['btrack_python_module.cpp','../../src/OnsetDetectionFunction.cpp','../../src/BTrack.cpp']
+
+include_dirs = [
+                numpy.get_include(),'/usr/local/include'
+                ]
+
+setup( name = 'BTrack',
+      include_dirs = include_dirs,
+      ext_modules = [Extension(name, sources,libraries = ['fftw3','samplerate'])]
+      )
\ No newline at end of file
--- a/python-module/btrack_python_module.cpp	Tue Jan 21 01:45:36 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,362 +0,0 @@
-#include <iostream>
-#include <Python.h>
-#include "../src/OnsetDetectionFunction.h"
-#include "../src/BTrack.h"
-#include <numpy/arrayobject.h>
-
-static PyObject * btrack_onsetdf(PyObject *dummy, PyObject *args) 
-{
-    PyObject *arg1=NULL;
-    PyObject *arr1=NULL;
-    
-    if (!PyArg_ParseTuple(args, "O", &arg1)) 
-    {
-        return NULL;
-    }
-    
-    arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); 
-    if (arr1 == NULL) 
-    {
-        return NULL;
-    }
-
-
-    
-    ////////// GET INPUT DATA ///////////////////
-    
-    // get data as array
-    double* data = (double*) PyArray_DATA(arr1);
-    
-    // get array size
-    int signal_length = PyArray_Size((PyObject*)arr1);
-    //int k = (int) theSize;
-    
-    // get data type 
-    char type = PyArray_DESCR(arr1)->type;
-    
-    ////////// BEGIN PROCESS ///////////////////
-    int hsize = 512;
-    int fsize = 1024;
-    int df_type = 6;
-    int numframes;
-    double buffer[hsize];	// buffer to hold one hopsize worth of audio samples
-
-    
-    // get number of audio frames, given the hop size and signal length
-	numframes = (int) floor(((double) signal_length) / ((double) hsize));
-    
-    OnsetDetectionFunction onset(hsize,fsize,df_type,1);
-
-    double df[numframes];
-    
-
-    
-    ///////////////////////////////////////////
-	//////// Begin Processing Loop ////////////
-	
-	for (int i=0;i < numframes;i++)
-	{		
-		// add new samples to frame
-		for (int n = 0;n < hsize;n++)
-		{
-			buffer[n] = data[(i*hsize)+n];
-		}
-		
-		df[i] = onset.getDFsample(buffer);
-		
-	}
-	
-	///////// End Processing Loop /////////////
-	///////////////////////////////////////////
-    
-    
-    ////////// END PROCESS ///////////////////
-    
-    
-    
-    ////////// CREATE ARRAY AND RETURN IT ///////////////////
-    int nd=1;
-    npy_intp m= numframes;
-    //double fArray[5] = {0,1,2,3,4};
-    
-    PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
-    
-    void *arr_data = PyArray_DATA((PyArrayObject*)c);
-        
-    memcpy(arr_data, df, PyArray_ITEMSIZE((PyArrayObject*) c) * m); 
-    
-     
-    Py_DECREF(arr1);  
-    Py_INCREF(Py_None); 
-    //return Py_None;
-    
-    return (PyObject *)c;
-    
-    //return Py_BuildValue("c", type);
-    //return Py_BuildValue("d", sum);
-    //return Py_BuildValue("i", k);
-/*    
-fail:
-    Py_XDECREF(arr1); 
-    Py_XDECREF(arr2); 
-    PyArray_XDECREF_ERR(oarr); 
-    return NULL;*/
-}
-
-
-static PyObject * btrack_btrack(PyObject *dummy, PyObject *args) 
-{
-    PyObject *arg1=NULL;
-    PyObject *arr1=NULL;
-    
-    if (!PyArg_ParseTuple(args, "O", &arg1)) 
-    {
-        return NULL;
-    }
-    
-    arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); 
-    if (arr1 == NULL) 
-    {
-        return NULL;
-    }
-    
-    
-    
-    ////////// GET INPUT DATA ///////////////////
-    
-    // get data as array
-    double* data = (double*) PyArray_DATA(arr1);
-    
-    // get array size
-    int signal_length = PyArray_Size((PyObject*)arr1);
-    //int k = (int) theSize;
-    
-    // get data type 
-    char type = PyArray_DESCR(arr1)->type;
-    
-    ////////// BEGIN PROCESS ///////////////////
-    int hsize = 512;
-    int fsize = 1024;
-    int df_type = 6;
-    int numframes;
-    double buffer[hsize];	// buffer to hold one hopsize worth of audio samples
-    
-    
-    // get number of audio frames, given the hop size and signal length
-	numframes = (int) floor(((double) signal_length) / ((double) hsize));
-    
-    OnsetDetectionFunction onset(hsize,fsize,df_type,1);
-    BTrack b;
-    
-    b.initialise((int) hsize);	// initialise beat tracker
-	
-	// set parameters
-    //b.setparams(0.9,5);
-    
-    double df[numframes];
-    double beats[5000];
-    int beatnum = 0;
-    float df_val;
-    
-    ///////////////////////////////////////////
-	//////// Begin Processing Loop ////////////
-	
-	for (int i=0;i < numframes;i++)
-	{		
-		// add new samples to frame
-		for (int n = 0;n < hsize;n++)
-		{
-			buffer[n] = data[(i*hsize)+n];
-		}
-		
-		df[i] = onset.getDFsample(buffer);
-        
-        df_val = (float) (df[i] + 0.0001);
-                
-		b.process(df_val);				// process df sample in beat tracker
-		
-		if (b.playbeat == 1)
-		{
-			beats[beatnum] = (((double) hsize) / 44100) * ((double) i);
-			beatnum = beatnum + 1;	
-		}
-		
-	}
-	
-	///////// End Processing Loop /////////////
-	///////////////////////////////////////////
-    
-    
-    ////////// END PROCESS ///////////////////
-    
-    double beats_out[beatnum];          // create output array
-    
-    // copy beats into output array
-    for (int i = 0;i < beatnum;i++)     
-    {
-        beats_out[i] = beats[i];
-    }
-    
-    
-    
-    ////////// CREATE ARRAY AND RETURN IT ///////////////////
-    int nd=1;
-    npy_intp m= beatnum;
-    //double fArray[5] = {0,1,2,3,4};
-    
-    PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
-    
-    void *arr_data = PyArray_DATA((PyArrayObject*)c);
-    
-    memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); 
-    
-    
-    Py_DECREF(arr1);  
-    Py_INCREF(Py_None); 
-    //return Py_None;
-    
-    return (PyObject *)c;
-    
-    //return Py_BuildValue("c", type);
-    //return Py_BuildValue("d", sum);
-    //return Py_BuildValue("i", k);
-    /*    
-     fail:
-     Py_XDECREF(arr1); 
-     Py_XDECREF(arr2); 
-     PyArray_XDECREF_ERR(oarr); 
-     return NULL;*/
-}
-
-static PyObject * btrack_btrack_df(PyObject *dummy, PyObject *args) 
-{
-    PyObject *arg1=NULL;
-    PyObject *arr1=NULL;
-    
-    if (!PyArg_ParseTuple(args, "O", &arg1)) 
-    {
-        return NULL;
-    }
-    
-    arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); 
-    if (arr1 == NULL) 
-    {
-        return NULL;
-    }
-    
-    
-    
-    ////////// GET INPUT DATA ///////////////////
-    
-    // get data as array
-    double* data = (double*) PyArray_DATA(arr1);
-    
-    // get array size
-    int numframes = PyArray_Size((PyObject*)arr1);
-    //int k = (int) theSize;
-    
-    // get data type 
-    char type = PyArray_DESCR(arr1)->type;
-    
-    ////////// BEGIN PROCESS ///////////////////
-    int hsize = 512;
-
-    BTrack b;
-    
-    b.initialise((int) hsize);	// initialise beat tracker
-	
-	// set parameters
-    //b.setparams(0.9,5);
-    
-    double beats[5000];
-    int beatnum = 0;
-    float df_val;
-    
-    ///////////////////////////////////////////
-	//////// Begin Processing Loop ////////////
-	
-	for (int i=0;i < numframes;i++)
-	{		
-        df_val = (float) (data[i] + 0.0001);
-        
-		b.process(df_val);				// process df sample in beat tracker
-		
-		if (b.playbeat == 1)
-		{
-			beats[beatnum] = (((double) hsize) / 44100) * ((double) i);
-			beatnum = beatnum + 1;	
-		}
-		
-	}
-	
-	///////// End Processing Loop /////////////
-	///////////////////////////////////////////
-    
-    
-    ////////// END PROCESS ///////////////////
-    
-    double beats_out[beatnum];          // create output array
-    
-    
-    // copy beats into output array
-    for (int i = 0;i < beatnum;i++)     
-    {
-        beats_out[i] = beats[i];
-    }
-    
-    
-    ////////// CREATE ARRAY AND RETURN IT ///////////////////
-    int nd=1;
-    npy_intp m= beatnum;
-    //double fArray[5] = {0,1,2,3,4};
-    
-    PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
-    
-    void *arr_data = PyArray_DATA((PyArrayObject*)c);
-    
-    memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); 
-    
-    
-    Py_DECREF(arr1);  
-    Py_INCREF(Py_None); 
-    //return Py_None;
-    
-    return (PyObject *)c;
-    
-    //return Py_BuildValue("c", type);
-    //return Py_BuildValue("d", sum);
-    //return Py_BuildValue("i", k);
-    /*    
-     fail:
-     Py_XDECREF(arr1); 
-     Py_XDECREF(arr2); 
-     PyArray_XDECREF_ERR(oarr); 
-     return NULL;*/
-}
-
-
-
-static PyMethodDef btrack_methods[] = {
-    { "onsetdf",btrack_onsetdf,METH_VARARGS,"onset detection function"},
-    { "btrack",btrack_btrack,METH_VARARGS,"beat tracker"},
-    { "btrack_df",btrack_btrack_df,METH_VARARGS,"beat tracker with detection function input"},
-    {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-PyMODINIT_FUNC initbtrack(void)
-{
-    (void)Py_InitModule("btrack", btrack_methods);
-    import_array();
-}
-
-int main(int argc, char *argv[])
-{
-    /* Pass argv[0] to the Python interpreter */
-    Py_SetProgramName(argv[0]);
-    
-    /* Initialize the Python interpreter.  Required. */
-    Py_Initialize();
-    
-    /* Add a static module */
-    initbtrack();
-}
\ No newline at end of file
--- a/python-module/setup.py	Tue Jan 21 01:45:36 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-# setup.py
-# build command : python setup.py build build_ext --inplace
-from numpy.distutils.core import setup, Extension
-import os, numpy
-
-name = 'btrack'
-sources = ['btrack_python_module.cpp','../src/OnsetDetectionFunction.cpp','../src/BTrack.cpp']
-
-include_dirs = [
-                numpy.get_include(),'/usr/local/include'
-                ]
-
-setup( name = 'BTrack',
-      include_dirs = include_dirs,
-      ext_modules = [Extension(name, sources,libraries = ['fftw3','samplerate'])]
-      )
\ No newline at end of file
--- a/src/BTrack.cpp	Tue Jan 21 01:45:36 2014 +0000
+++ b/src/BTrack.cpp	Tue Jan 21 10:24:33 2014 +0000
@@ -28,8 +28,7 @@
 
 
 
-//-------------------------------------------------------------------------------
-// Constructor
+//=======================================================================
 BTrack :: BTrack()
 {	
 	float rayparam = 43;
@@ -82,15 +81,15 @@
 	tempofix = 0;
 }
 
-//-------------------------------------------------------------------------------
-// Destructor
+//=======================================================================
 BTrack :: ~BTrack()
 {	
 	
 }
 
-//-------------------------------------------------------------------------------
-// Initialise with frame size and set all frame sizes accordingly
+
+
+//=======================================================================
 void BTrack :: initialise(int fsize)
 {	
 	framesize = fsize;
@@ -116,8 +115,7 @@
 	}
 }
 
-//-------------------------------------------------------------------------------
-// Add new sample to buffer and apply beat tracking
+//=======================================================================
 void BTrack :: process(float df_sample)
 {	 
 	m0--;
@@ -153,8 +151,7 @@
 	}
 }
 
-//-------------------------------------------------------------------------------
-// Set the tempo of the beat tracker
+//=======================================================================
 void BTrack :: settempo(float tempo)
 {	 
 	
@@ -221,9 +218,7 @@
 	m0 = (int) round(((float) new_bperiod)/2);
 }
 
-
-//-------------------------------------------------------------------------------
-// fix tempo to roughly around some value
+//=======================================================================
 void BTrack :: fixtempo(float tempo)
 {	
 	// firstly make sure tempo is between 80 and 160 bpm..
@@ -253,16 +248,14 @@
 	tempofix = 1;	
 }
 
-//-------------------------------------------------------------------------------
-// do not fix the tempo anymore
+//=======================================================================
 void BTrack :: unfixtempo()
 {	
 	// set the tempo fix flag
 	tempofix = 0;	
 }
 
-//-------------------------------------------------------------------------------
-// Convert detection function from N samples to 512
+//=======================================================================
 void BTrack :: dfconvert()
 {
 	float output[512];
@@ -291,8 +284,7 @@
 	}
 }
 
-//-------------------------------------------------------------------------------
-// To calculate the current tempo expressed as the beat period in detection function samples
+//=======================================================================
 void BTrack :: calcTempo()
 {
 	// adaptive threshold on input
@@ -378,8 +370,7 @@
 	//cout << bperiod << endl;
 }
 
-//-------------------------------------------------------------------------------
-// calculates an adaptive threshold which is used to remove low level energy from detection function and emphasise peaks
+//=======================================================================
 void BTrack :: adapt_thresh(float x[],int N)
 {
 	//int N = 512; // length of df
@@ -421,8 +412,7 @@
 	}
 }
 
-//-------------------------------------------------------------------------------
-// returns the output of the comb filter
+//=======================================================================
 void BTrack :: getrcfoutput()
 {
 	int numelem;
@@ -446,8 +436,7 @@
 	}
 }
 
-//-------------------------------------------------------------------------------
-// calculates the balanced autocorrelation of the smoothed detection function
+//=======================================================================
 void BTrack :: acf_bal(float df_thresh[])
 {
 	int l, n = 0;
@@ -469,9 +458,7 @@
 	}
 }
 
-
-//-------------------------------------------------------------------------------
-// calculates the mean of values in an array from index locations [start,end]
+//=======================================================================
 float BTrack :: mean_array(float array[],int start,int end)
 {
 	int i;
@@ -495,8 +482,7 @@
     }
 }
 
-//-------------------------------------------------------------------------------
-// normalise the array
+//=======================================================================
 void BTrack :: normalise(float array[],int N)
 {
 	double sum = 0;
@@ -518,20 +504,7 @@
 	}
 }
 
-//-------------------------------------------------------------------------------
-// plot contents of detection function buffer
-void BTrack :: plotdfbuffer()
-{	 
-	for (int i=0;i < dfbuffer_size;i++)
-	{
-		cout << dfbuffer[i] << endl;
-	}
-	
-	cout << "--------------------------------" << endl;
-}
-
-//-------------------------------------------------------------------------------
-// update the cumulative score
+//=======================================================================
 void BTrack :: updatecumscore(float df_sample)
 {	 
 	int start, end, winsize;
@@ -583,8 +556,7 @@
 		
 }
 
-//-------------------------------------------------------------------------------
-// plot contents of detection function buffer
+//=======================================================================
 void BTrack :: predictbeat()
 {	 
 	int winsize = (int) bperiod;
@@ -664,7 +636,7 @@
 		
 	
 	// set beat
-	beat = beat;
+	//beat = beat;
 	
 	// set next prediction time
 	m0 = beat+round(bperiod/2);
--- a/src/BTrack.h	Tue Jan 21 01:45:36 2014 +0000
+++ b/src/BTrack.h	Tue Jan 21 10:24:33 2014 +0000
@@ -22,28 +22,29 @@
 #ifndef __BTRACK_H
 #define __BTRACK_H
 
-//#include "fftw3.h"
-
 class BTrack {
 	
 public:
-	BTrack();				// constructor
-	~BTrack();				// destructor	
+    
+    /** constructor */
+	BTrack();
+    
+    /** destructor */
+	~BTrack();		
 	
+    /** Initialise with frame size and set all frame sizes accordingly */
 	void initialise(int fsize);
+    
+    /** Add new sample to buffer and apply beat tracking */
 	void process(float df_sample);
-	void plotdfbuffer();
-	void updatecumscore(float df_sample);
-	void predictbeat();
-	void dfconvert();
-	void calcTempo();
-	void adapt_thresh(float x[],int N);
-	float mean_array(float array[],int start,int end);
-	void normalise(float array[],int N);
-	void acf_bal(float df_thresh[]);
-	void getrcfoutput();
+   
+    /** Set the tempo of the beat tracker */
 	void settempo(float tempo);
+    
+    /** fix tempo to roughly around some value */
 	void fixtempo(float tempo);
+    
+    /** do not fix the tempo anymore */
 	void unfixtempo();
 	
 	int playbeat;
@@ -51,24 +52,53 @@
 	float est_tempo;
 			
 private:
+    
+    /** Convert detection function from N samples to 512 */
+	void dfconvert();
+    
+    /** update the cumulative score */
+	void updatecumscore(float df_sample);
+	
+    /** predicts the next beat */
+    void predictbeat();
+    
+    /** Calculates the current tempo expressed as the beat period in detection function samples */
+    void calcTempo();
+    
+    /** calculates an adaptive threshold which is used to remove low level energy from detection 
+     * function and emphasise peaks 
+     */
+	void adapt_thresh(float x[],int N);
+    
+    /** calculates the mean of values in an array from index locations [start,end] */
+	float mean_array(float array[],int start,int end);
+    
+    /** normalises a given array */
+	void normalise(float array[],int N);
+    
+    /** calculates the balanced autocorrelation of the smoothed detection function */
+	void acf_bal(float df_thresh[]);
+    
+    /** returns the output of the comb filter */
+	void getrcfoutput();
 	
 	// buffers
-	float *dfbuffer;			// to hold detection function
-	float df512[512];			// to hold resampled detection function 
-	float *cumscore;			// to hold cumulative score
+	float *dfbuffer;			/**< to hold detection function */
+	float df512[512];			/**< to hold resampled detection function */
+	float *cumscore;			/**<  to hold cumulative score */
 	
-	float acf[512];				// to hold autocorrelation function
+	float acf[512];				/**<  to hold autocorrelation function */
 	
-	float wv[128];				// to hold weighting vector
+	float wv[128];				/**<  to hold weighting vector */
 	
-	float rcf[128];				// to hold comb filter output
-	float t_obs[41];			// to hold tempo version of comb filter output
+	float rcf[128];				/**<  to hold comb filter output */
+	float t_obs[41];			/**<  to hold tempo version of comb filter output */
 	
-	float delta[41];			// to hold final tempo candidate array
-	float prev_delta[41];		// previous delta
-	float prev_delta_fix[41];	// fixed tempo version of previous delta
+	float delta[41];			/**<  to hold final tempo candidate array */
+	float prev_delta[41];		/**<  previous delta */
+	float prev_delta_fix[41];	/**<  fixed tempo version of previous delta */
 	
-	float t_tmat[41][41];		// transition matrix
+	float t_tmat[41][41];		/**<  transition matrix */
 	
 	
 	// parameters
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unit-tests/BTrack Tests.xcodeproj/project.pbxproj	Tue Jan 21 10:24:33 2014 +0000
@@ -0,0 +1,254 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		E38214F0188E7AED00DDD7C8 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38214EF188E7AED00DDD7C8 /* main.cpp */; };
+		E38214F2188E7AED00DDD7C8 /* BTrack_Tests.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = E38214F1188E7AED00DDD7C8 /* BTrack_Tests.1 */; };
+		E3A45DB9188E7BCD00B48CE4 /* BTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A45DB5188E7BCD00B48CE4 /* BTrack.cpp */; };
+		E3A45DBA188E7BCD00B48CE4 /* OnsetDetectionFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A45DB7188E7BCD00B48CE4 /* OnsetDetectionFunction.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		E38214EA188E7AED00DDD7C8 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = /usr/share/man/man1/;
+			dstSubfolderSpec = 0;
+			files = (
+				E38214F2188E7AED00DDD7C8 /* BTrack_Tests.1 in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		E38214EC188E7AED00DDD7C8 /* BTrack Tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "BTrack Tests"; sourceTree = BUILT_PRODUCTS_DIR; };
+		E38214EF188E7AED00DDD7C8 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+		E38214F1188E7AED00DDD7C8 /* BTrack_Tests.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = BTrack_Tests.1; sourceTree = "<group>"; };
+		E3A45DB5188E7BCD00B48CE4 /* BTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BTrack.cpp; sourceTree = "<group>"; };
+		E3A45DB6188E7BCD00B48CE4 /* BTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTrack.h; sourceTree = "<group>"; };
+		E3A45DB7188E7BCD00B48CE4 /* OnsetDetectionFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OnsetDetectionFunction.cpp; sourceTree = "<group>"; };
+		E3A45DB8188E7BCD00B48CE4 /* OnsetDetectionFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnsetDetectionFunction.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		E38214E9188E7AED00DDD7C8 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		E38214E3188E7AED00DDD7C8 = {
+			isa = PBXGroup;
+			children = (
+				E38214EE188E7AED00DDD7C8 /* BTrack Tests */,
+				E38214ED188E7AED00DDD7C8 /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		E38214ED188E7AED00DDD7C8 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				E38214EC188E7AED00DDD7C8 /* BTrack Tests */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		E38214EE188E7AED00DDD7C8 /* BTrack Tests */ = {
+			isa = PBXGroup;
+			children = (
+				E38214EF188E7AED00DDD7C8 /* main.cpp */,
+				E3A45DB4188E7BCD00B48CE4 /* src */,
+				E38214F1188E7AED00DDD7C8 /* BTrack_Tests.1 */,
+			);
+			path = "BTrack Tests";
+			sourceTree = "<group>";
+		};
+		E3A45DB4188E7BCD00B48CE4 /* src */ = {
+			isa = PBXGroup;
+			children = (
+				E3A45DB5188E7BCD00B48CE4 /* BTrack.cpp */,
+				E3A45DB6188E7BCD00B48CE4 /* BTrack.h */,
+				E3A45DB7188E7BCD00B48CE4 /* OnsetDetectionFunction.cpp */,
+				E3A45DB8188E7BCD00B48CE4 /* OnsetDetectionFunction.h */,
+			);
+			name = src;
+			path = ../../src;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		E38214EB188E7AED00DDD7C8 /* BTrack Tests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = E38214F5188E7AED00DDD7C8 /* Build configuration list for PBXNativeTarget "BTrack Tests" */;
+			buildPhases = (
+				E38214E8188E7AED00DDD7C8 /* Sources */,
+				E38214E9188E7AED00DDD7C8 /* Frameworks */,
+				E38214EA188E7AED00DDD7C8 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "BTrack Tests";
+			productName = "BTrack Tests";
+			productReference = E38214EC188E7AED00DDD7C8 /* BTrack Tests */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		E38214E4188E7AED00DDD7C8 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0500;
+				ORGANIZATIONNAME = "Adam Stark";
+			};
+			buildConfigurationList = E38214E7188E7AED00DDD7C8 /* Build configuration list for PBXProject "BTrack Tests" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = E38214E3188E7AED00DDD7C8;
+			productRefGroup = E38214ED188E7AED00DDD7C8 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				E38214EB188E7AED00DDD7C8 /* BTrack Tests */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+		E38214E8188E7AED00DDD7C8 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				E3A45DBA188E7BCD00B48CE4 /* OnsetDetectionFunction.cpp in Sources */,
+				E3A45DB9188E7BCD00B48CE4 /* BTrack.cpp in Sources */,
+				E38214F0188E7AED00DDD7C8 /* main.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		E38214F3188E7AED00DDD7C8 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+			};
+			name = Debug;
+		};
+		E38214F4188E7AED00DDD7C8 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				SDKROOT = macosx;
+			};
+			name = Release;
+		};
+		E38214F6188E7AED00DDD7C8 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		E38214F7188E7AED00DDD7C8 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		E38214E7188E7AED00DDD7C8 /* Build configuration list for PBXProject "BTrack Tests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				E38214F3188E7AED00DDD7C8 /* Debug */,
+				E38214F4188E7AED00DDD7C8 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		E38214F5188E7AED00DDD7C8 /* Build configuration list for PBXNativeTarget "BTrack Tests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				E38214F6188E7AED00DDD7C8 /* Debug */,
+				E38214F7188E7AED00DDD7C8 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = E38214E4188E7AED00DDD7C8 /* Project object */;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unit-tests/BTrack Tests/BTrack_Tests.1	Tue Jan 21 10:24:33 2014 +0000
@@ -0,0 +1,79 @@
+.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
+.\"See Also:
+.\"man mdoc.samples for a complete listing of options
+.\"man mdoc for the short list of editing options
+.\"/usr/share/misc/mdoc.template
+.Dd 21/01/2014               \" DATE 
+.Dt BTrack Tests 1      \" Program name and manual section number 
+.Os Darwin
+.Sh NAME                 \" Section Header - required - don't modify 
+.Nm BTrack Tests,
+.\" The following lines are read in generating the apropos(man -k) database. Use only key
+.\" words here as the database is built based on the words here and in the .ND line. 
+.Nm Other_name_for_same_program(),
+.Nm Yet another name for the same program.
+.\" Use .Nm macro to designate other names for the documented program.
+.Nd This line parsed for whatis database.
+.Sh SYNOPSIS             \" Section Header - required - don't modify
+.Nm
+.Op Fl abcd              \" [-abcd]
+.Op Fl a Ar path         \" [-a path] 
+.Op Ar file              \" [file]
+.Op Ar                   \" [file ...]
+.Ar arg0                 \" Underlined argument - use .Ar anywhere to underline
+arg2 ...                 \" Arguments
+.Sh DESCRIPTION          \" Section Header - required - don't modify
+Use the .Nm macro to refer to your program throughout the man page like such:
+.Nm
+Underlining is accomplished with the .Ar macro like this:
+.Ar underlined text .
+.Pp                      \" Inserts a space
+A list of items with descriptions:
+.Bl -tag -width -indent  \" Begins a tagged list 
+.It item a               \" Each item preceded by .It macro
+Description of item a
+.It item b
+Description of item b
+.El                      \" Ends the list
+.Pp
+A list of flags and their descriptions:
+.Bl -tag -width -indent  \" Differs from above in tag removed 
+.It Fl a                 \"-a flag as a list item
+Description of -a flag
+.It Fl b
+Description of -b flag
+.El                      \" Ends the list
+.Pp
+.\" .Sh ENVIRONMENT      \" May not be needed
+.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
+.\" .It Ev ENV_VAR_1
+.\" Description of ENV_VAR_1
+.\" .It Ev ENV_VAR_2
+.\" Description of ENV_VAR_2
+.\" .El                      
+.Sh FILES                \" File used or created by the topic of the man page
+.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
+.It Pa /usr/share/file_name
+FILE_1 description
+.It Pa /Users/joeuser/Library/really_long_file_name
+FILE_2 description
+.El                      \" Ends the list
+.\" .Sh DIAGNOSTICS       \" May not be needed
+.\" .Bl -diag
+.\" .It Diagnostic Tag
+.\" Diagnostic informtion here.
+.\" .It Diagnostic Tag
+.\" Diagnostic informtion here.
+.\" .El
+.Sh SEE ALSO 
+.\" List links in ascending order by section, alphabetically within a section.
+.\" Please do not reference files that do not exist without filing a bug report
+.Xr a 1 , 
+.Xr b 1 ,
+.Xr c 1 ,
+.Xr a 2 ,
+.Xr b 2 ,
+.Xr a 3 ,
+.Xr b 3 
+.\" .Sh BUGS              \" Document known, unremedied bugs 
+.\" .Sh HISTORY           \" Document history if command behaves in a unique manner
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unit-tests/BTrack Tests/main.cpp	Tue Jan 21 10:24:33 2014 +0000
@@ -0,0 +1,18 @@
+//
+//  main.cpp
+//  BTrack Tests
+//
+//  Created by Adam Stark on 21/01/2014.
+//  Copyright (c) 2014 Adam Stark. All rights reserved.
+//
+
+#include <iostream>
+
+int main(int argc, const char * argv[])
+{
+
+    // insert code here...
+    std::cout << "Hello, World!\n";
+    return 0;
+}
+