function Duration(num, denom)
{
    /**
     * the numerator part of the fraction
     */
    this.fNum = 0;
    if( num )
	this.fNum = num;
    else
	this.fNum = 0;

    /**
     * the denominator part of the fraction
     */
    this.fDenom = 0;
    if( denom )
	this.fDenom = denom;

    /**
     * add a duration to this duration
     * @param o {Duration} duration to add
     */
    this.add = function(o) {
    	this._addSubtract(o, true);
    }

    /**
     * subtract a duration to this duration
     * @param o {Duration} duration to subtract
     */
    this.subtract = function(o) {
    	this._addSubtract(o, false);
    }

    /**
     * is this a zero duration?
     * @return true or false as to whether duration is zero
     * @type boolean
     */
    this.isZero = function() {
    	if( this.fNum == 0 ) { return true; }
	return false;
    }

    /**
     * make this a zero duration
     */
    this.setZero = function() {
	this.fNum = 0;
    }

    /**
     * is the duration a whole number i.e. no fractional part?
     * @return true or false as to whether duration is a whole number
     * @type boolean
     */
    this.isWhole = function() {
	if(this.fDenom == 1 ) return true;
	else return false;
    }

    /**
     * return the whole part of the duration
     * @return if the duration is > 1, return the whole part, else return 0
     * @type int
     */
    this.wholePart = function() {
	if( this.isZero() ) return 0;
	else if( this.fDenom != 0 && this.fNum >= this.fDenom ) {
	    return parseInt( this.fNum/this.fDenom );
	}
	return 0;
    }

    /**
     * compare the duration with another and return a value indicating if it equal,
     * greater than or less than
     * @param {Duration} d	duration to be compared against
     * @return 1 if this duration is > d, -1 if it is < d, and 0 if it is equal
     */
    this.compare = function(d) {
	// get zero cases out first
	if( d.isZero() ) {
	    if(this.isZero() ) return 0;
	    else return 1;
	}
	else if( this.isZero() ) {
	    if(d.isZero() ) return 0;
	    else return -1;
	}

	// create clone of us
	var d1 = new Duration(this.fNum, this.fDenom);

	// subtract d from our clone
	d1.subtract(d);

	// check the numerator if zero, we are equal, if < 0, then d was greater than us
	if( d1.fNum == 0 || d1.fDenom == 0 ) return 0;
	if( d1.fNum < 0 || d1.fDenom < 0 ) return -1;
	return 1;
    }

    /**
     * internal routine that adds/subtracts a duration to/from this duration
     * @param o {Duration} 	duration to add or subtract
     * @param add {boolean}	true or false indicating if we are to add or
     *				subtract
     * @private
     */
    this._addSubtract = function(o, add) {
	var denom;
	var m1 = this.fDenom;
	var m2 = o.fDenom;

	// handle case when we or "o" is zero
	if( o.isZero() ) 
	    return;
	else if( this.isZero() ) {
	    if( add ) {
		this.fDenom = o.fDenom;
		this.fNum   = o.fNum;
	    }
	    else {
		this.fNum   = -o.fNum;
		this.fDenom = o.fDenom;
	    }
	    return;
	}

	if( this.fDenom == o.fDenom ) {
	    m1 = 1;
	    m2 = 1;
	    denom = this.fDenom;
	}
	else if( this.fDenom > o.fDenom && (this.fDenom % o.fDenom) == 0 ) {
	    denom = this.fDenom;
	    m1    = this.fDenom / o.fDenom;
	    m2    = 1;
	}
	else if( o.fDenom > this.fDenom && (o.fDenom % this.fDenom) == 0 ) {
	    denom = o.fDenom;
	    m1    = 1;
	    m2    = o.fDenom / this.fDenom;
	}
	else
	    denom = o.fDenom * this.fDenom;

	var num;
	if ( add ) 
	    num = (o.fNum*m1) + (this.fNum*m2);
	else
	    num = (this.fNum*m2) - (o.fNum*m1);

	if( num == 0 ) {
	    this.fNum   = 0;
	    this.fDenom = denom;
	}
	if( num == denom ) {
	    this.fNum = 1;
	    this.fDenom = 1;
	}
	else if( num > denom && (num%denom) == 0 ) {
	    this.fNum = parseInt(num/denom);
	    this.fDenom = 1;
	}
	else if( denom > num && (denom%num) == 0 ) {
	    this.fNum = 1;
	    this.fDenom = parseInt(denom/num);
	}
	else {
	    this.fNum = num;
	    this.fDenom = denom;

	    if( !this.isZero()  )
	    {
		// reduce
		while( (this.fNum%2) == 0 && (this.fDenom%2) == 0 )
		{
		    this.fNum = parseInt(this.fNum/2);
		    this.fDenom = parseInt(this.fDenom/2);
		}
	    }
	}
    }

    /**
     * debug routine that stringizes the duration
     * @type String
     */
    this.toString = function() {
	if( this.fNum == 0 ) return "0";
	else return this.fNum + "/" + this.fDenom;
    }

    /**
     * debug routine that prints (on Safari only) out the duration
     */
    this.print = function() {
	if( window.console ) window.console.log ( this.toString() );
    }
}
/**
 * @class
 * represents a note duration as a fraction
 * @constructor
 * @param {int} num 	the numerator of the fraction
 * @param {int} denom the denominator of the fraction
 */
@class
represents a note duration as a fraction
@constructor
@param {int} num     the numerator of the fraction
@param {int} denom the denominator of the fraction
@class represents a note duration as a fraction @constructor @param { int } num the numerator of the fraction @param { int } denom the denominator of the fraction
function Duration(num, denom)
{
    this.fNum = 0;
    if( num )
	this.fNum = num;
    else
	this.fNum = 0;
    this.fDenom = 0;
    if( denom )
	this.fDenom = denom;
    this.add = function(o) {
    	this._addSubtract(o, true);
    }
    this.subtract = function(o) {
    	this._addSubtract(o, false);
    }
    this.isZero = function() {
    	if( this.fNum == 0 ) { return true; }
	return false;
    }
    this.setZero = function() {
	this.fNum = 0;
    }
    this.isWhole = function() {
	if(this.fDenom == 1 ) return true;
	else return false;
    }
    this.wholePart = function() {
	if( this.isZero() ) return 0;
	else if( this.fDenom != 0 && this.fNum >= this.fDenom ) {
	    return parseInt( this.fNum/this.fDenom );
	}
	return 0;
    }
    this.compare = function(d) {
	if( d.isZero() ) {
	    if(this.isZero() ) return 0;
	    else return 1;
	}
	else if( this.isZero() ) {
	    if(d.isZero() ) return 0;
	    else return -1;
	}
	var d1 = new Duration(this.fNum, this.fDenom);
	d1.subtract(d);
	if( d1.fNum == 0 || d1.fDenom == 0 ) return 0;
	if( d1.fNum < 0 || d1.fDenom < 0 ) return -1;
	return 1;
    }
    this._addSubtract = function(o, add) {
	var denom;
	var m1 = this.fDenom;
	var m2 = o.fDenom;
	if( o.isZero() ) 
	    return;
	else if( this.isZero() ) {
	    if( add ) {
		this.fDenom = o.fDenom;
		this.fNum   = o.fNum;
	    }
	    else {
		this.fNum   = -o.fNum;
		this.fDenom = o.fDenom;
	    }
	    return;
	}
	if( this.fDenom == o.fDenom ) {
	    m1 = 1;
	    m2 = 1;
	    denom = this.fDenom;
	}
	else if( this.fDenom > o.fDenom && (this.fDenom % o.fDenom) == 0 ) {
	    denom = this.fDenom;
	    m1    = this.fDenom / o.fDenom;
	    m2    = 1;
	}
	else if( o.fDenom > this.fDenom && (o.fDenom % this.fDenom) == 0 ) {
	    denom = o.fDenom;
	    m1    = 1;
	    m2    = o.fDenom / this.fDenom;
	}
	else
	    denom = o.fDenom * this.fDenom;
	var num;
	if ( add ) 
	    num = (o.fNum*m1) + (this.fNum*m2);
	else
	    num = (this.fNum*m2) - (o.fNum*m1);
	if( num == 0 ) {
	    this.fNum   = 0;
	    this.fDenom = denom;
	}
	if( num == denom ) {
	    this.fNum = 1;
	    this.fDenom = 1;
	}
	else if( num > denom && (num%denom) == 0 ) {
	    this.fNum = parseInt(num/denom);
	    this.fDenom = 1;
	}
	else if( denom > num && (denom%num) == 0 ) {
	    this.fNum = 1;
	    this.fDenom = parseInt(denom/num);
	}
	else {
	    this.fNum = num;
	    this.fDenom = denom;
	    if( !this.isZero()  )
	    {
		while( (this.fNum%2) == 0 && (this.fDenom%2) == 0 )
		{
		    this.fNum = parseInt(this.fNum/2);
		    this.fDenom = parseInt(this.fDenom/2);
		}
	    }
	}
    }
    this.toString = function() {
	if( this.fNum == 0 ) return "0";
	else return this.fNum + "/" + this.fDenom;
    }
    this.print = function() {
	if( window.console ) window.console.log ( this.toString() );
    }
}
function Duration ( num , denom ) { this . fNum = 0 ; if ( num ) this . fNum = num ; else this . fNum = 0 ; this . fDenom = 0 ; if ( denom ) this . fDenom = denom ; this . add = function ( o ) { this . _addSubtract ( o , true ) ; } this . subtract = function ( o ) { this . _addSubtract ( o , false ) ; } this . isZero = function ( ) { if ( this . fNum == 0 ) { return true ; } return false ; } this . setZero = function ( ) { this . fNum = 0 ; } this . isWhole = function ( ) { if ( this . fDenom == 1 ) return true ; else return false ; } this . wholePart = function ( ) { if ( this . isZero ( ) ) return 0 ; else if ( this . fDenom != 0 && this . fNum >= this . fDenom ) { return parseInt ( this . fNum / this . fDenom ) ; } return 0 ; } this . compare = function ( d ) { if ( d . isZero ( ) ) { if ( this . isZero ( ) ) return 0 ; else return 1 ; } else if ( this . isZero ( ) ) { if ( d . isZero ( ) ) return 0 ; else return - 1 ; } var d1 = new Duration ( this . fNum , this . fDenom ) ; d1 . subtract ( d ) ; if ( d1 . fNum == 0 || d1 . fDenom == 0 ) return 0 ; if ( d1 . fNum < 0 || d1 . fDenom < 0 ) return - 1 ; return 1 ; } this . _addSubtract = function ( o , add ) { var denom ; var m1 = this . fDenom ; var m2 = o . fDenom ; if ( o . isZero ( ) ) return ; else if ( this . isZero ( ) ) { if ( add ) { this . fDenom = o . fDenom ; this . fNum = o . fNum ; } else { this . fNum = - o . fNum ; this . fDenom = o . fDenom ; } return ; } if ( this . fDenom == o . fDenom ) { m1 = 1 ; m2 = 1 ; denom = this . fDenom ; } else if ( this . fDenom > o . fDenom && ( this . fDenom % o . fDenom ) == 0 ) { denom = this . fDenom ; m1 = this . fDenom / o . fDenom ; m2 = 1 ; } else if ( o . fDenom > this . fDenom && ( o . fDenom % this . fDenom ) == 0 ) { denom = o . fDenom ; m1 = 1 ; m2 = o . fDenom / this . fDenom ; } else denom = o . fDenom * this . fDenom ; var num ; if ( add ) num = ( o . fNum * m1 ) + ( this . fNum * m2 ) ; else num = ( this . fNum * m2 ) - ( o . fNum * m1 ) ; if ( num == 0 ) { this . fNum = 0 ; this . fDenom = denom ; } if ( num == denom ) { this . fNum = 1 ; this . fDenom = 1 ; } else if ( num > denom && ( num % denom ) == 0 ) { this . fNum = parseInt ( num / denom ) ; this . fDenom = 1 ; } else if ( denom > num && ( denom % num ) == 0 ) { this . fNum = 1 ; this . fDenom = parseInt ( denom / num ) ; } else { this . fNum = num ; this . fDenom = denom ; if ( ! this . isZero ( ) ) { while ( ( this . fNum % 2 ) == 0 && ( this . fDenom % 2 ) == 0 ) { this . fNum = parseInt ( this . fNum / 2 ) ; this . fDenom = parseInt ( this . fDenom / 2 ) ; } } } } this . toString = function ( ) { if ( this . fNum == 0 ) return "0" ; else return this . fNum + "/" + this . fDenom ; } this . print = function ( ) { if ( window . console ) window . console . log ( this . toString ( ) ) ; } }
@class
 represents a note duration as a fraction
 @constructor
 @param {int} num     the numerator of the fraction
 @param {int} denom the denominator of the fraction
@class represents a note duration as a fraction @constructor @param { int } num the numerator of the fraction @param { int } denom the denominator of the fraction
/**
     * the numerator part of the fraction
     */ /**
     * the denominator part of the fraction
     */ /**
     * add a duration to this duration
     * @param o {Duration} duration to add
     */ /**
     * subtract a duration to this duration
     * @param o {Duration} duration to subtract
     */ /**
     * is this a zero duration?
     * @return true or false as to whether duration is zero
     * @type boolean
     */ /**
     * make this a zero duration
     */ /**
     * is the duration a whole number i.e. no fractional part?
     * @return true or false as to whether duration is a whole number
     * @type boolean
     */ /**
     * return the whole part of the duration
     * @return if the duration is > 1, return the whole part, else return 0
     * @type int
     */ /**
     * compare the duration with another and return a value indicating if it equal,
     * greater than or less than
     * @param {Duration} d	duration to be compared against
     * @return 1 if this duration is > d, -1 if it is < d, and 0 if it is equal
     */ // get zero cases out first // create clone of us // subtract d from our clone // check the numerator if zero, we are equal, if < 0, then d was greater than us /**
     * internal routine that adds/subtracts a duration to/from this duration
     * @param o {Duration} 	duration to add or subtract
     * @param add {boolean}	true or false indicating if we are to add or
     *				subtract
     * @private
     */ // handle case when we or "o" is zero // reduce /**
     * debug routine that stringizes the duration
     * @type String
     */ /**
     * debug routine that prints (on Safari only) out the duration
     */