function DataAnalyzer() {
    var samples = []; // array of samples : timestamp, volume
    //var smoother = new SmoothArray(SAMPLES_SMOOTHING); // array object used for caluclating smooth value
    var cutoff = CUTOFF_PROIOR;
    //var speakThreashold = SPEAK_THRESHOLD_PRIOR;
    var slidingPower = new SlidingPower(NOISE_POWER_SAMPLES);
    //var signalMean = new MedianArray(POWER_SAMPLES_MEAN);
    var meanArray = new FixedLengthArray(POWER_SAMPLES_MEAN);
    var mean = MEAN_INIT_VALUE;

    this.purgeSamples = function (timestamp) {
        while (samples.length > 0 && (timestamp - samples[0].timestamp > BUFFER_LENGTH)) {
            //dataLog("Removing from samples:",samples[0]);
            samples.shift();
        }
    }.bind(this);

    this.addChunk = function (chunk) {
        var startTime = chunk.ts;
        var startTimeMs = chunk.ts_ms; // start time is a combination of timestamp and fractional part (ms)
        var sampleDuration = chunk.sampleDelay;
        var samples = chunk.samples;
        var analyzer = this;
        $.each(samples, function (i, volume) {
            analyzer.addSample(volume, startTime * 1000 + startTimeMs + sampleDuration * i, sampleDuration);
        });

    }.bind(this);

    // Adds a sample. Code assumes that the timestamp is monotonically increasing
    // Code will only add samples newer than the last timestamp
    this.addSample = function (vol, timestamp, duration) {
        // is it a new sample?
        if (samples.length > 0) {
            var lastTimestamp = samples[samples.length - 1].timestamp;
            if (timestamp <= lastTimestamp) {
                //dataLog("Skipping existing sample: "+timestamp+" "+dateToString(timestamp));
                return false;
            }
        }

        // remove old objects samples array
        this.purgeSamples(timestamp);

        // clip the sample
        var volClipped = vol > cutoff ? cutoff : vol;

        // update mean/median tracking array
        meanArray.push(volClipped);

        // smooth it
        //var volClippedSmooth = smoother.push(volClipped);
        var volClippedSmooth = volClipped;

        // and check if it's above the threshold
        var volPower = slidingPower.push(volClipped,mean);
        var isSpeak = volPower > NOISE_POWER_THRESHOLD ? 1 : 0;

        // add sample to array
        samples.push({
            'volRaw': vol,
            'volClipped': volClipped,
            'volClippedSmooth': volClippedSmooth,
            'cutoff': cutoff,
            'volPower': volPower,
            'mean': mean,
            'isSpeak': isSpeak,
            'timestamp': timestamp,
            'duration': duration
        });

        return true;
    }.bind(this);

    // updates the mean / median (we don't want to do this for every sample)
    this.updateMean = function() {
        var tempMean = median(meanArray.getSamplesArray());
        if (tempMean) {
            mean = median(meanArray.getSamplesArray());
        }
    }

    // updates the cutoff
    this.updateCutoff = function () {
        if (samples.length == 0) {
            return CUTOFF_PROIOR;
        }

        var m = meanAndStd(samples, function (sample) {
            return sample.volRaw
        });
        cutoff = (CUTOFF_PROIOR * PRIOR_WEIGHT) + (m.mean + 2 * m.std) * (1 - PRIOR_WEIGHT);
        dataLog("Cutoff prior,value,mean and std:"+ CUTOFF_PROIOR+" "+cutoff+" "+m.mean+" "+m.std);// calc adjusted cutoff (using samples and prior)
    }.bind(this);

    // updates the threshold
    /*
    this.updateSpeakThreshold = function () {
        if (samples.length == 0) {
            return SPEAK_THRESHOLD_PRIOR;
        }
        var m = meanAndStd(samples, function (sample) {
            return sample.volClippedSmooth
        });
        speakThreashold = (SPEAK_THRESHOLD_PRIOR * PRIOR_WEIGHT) + (m.mean - 2 * m.std) * (1 - PRIOR_WEIGHT);
        dataLog("Speak priotr,threashold, mean and std:"+ SPEAK_THRESHOLD_PRIOR +" "+ speakThreashold + " " + m.mean + " "+  m.std);
    }.bind(this);
    */

    this.getSamples = function () {
        return samples;
    }.bind(this);

    this.clearData = function() {
        var samples = [];
        var smoother = new SmoothArray();
    }.bind(this);
}
/*
 This class stores samples for a badge and convert them into talking intervals
 */
This class stores samples for a badge and convert them into talking intervals
This class stores samples for a badge and convert them into talking intervals
function DataAnalyzer() {
    var samples = []; 
    var cutoff = CUTOFF_PROIOR;
    var slidingPower = new SlidingPower(NOISE_POWER_SAMPLES);
    var meanArray = new FixedLengthArray(POWER_SAMPLES_MEAN);
    var mean = MEAN_INIT_VALUE;
    this.purgeSamples = function (timestamp) {
        while (samples.length > 0 && (timestamp - samples[0].timestamp > BUFFER_LENGTH)) {
            samples.shift();
        }
    }.bind(this);
    this.addChunk = function (chunk) {
        var startTime = chunk.ts;
        var startTimeMs = chunk.ts_ms; 
        var sampleDuration = chunk.sampleDelay;
        var samples = chunk.samples;
        var analyzer = this;
        $.each(samples, function (i, volume) {
            analyzer.addSample(volume, startTime * 1000 + startTimeMs + sampleDuration * i, sampleDuration);
        });
    }.bind(this);
    this.addSample = function (vol, timestamp, duration) {
        if (samples.length > 0) {
            var lastTimestamp = samples[samples.length - 1].timestamp;
            if (timestamp <= lastTimestamp) {
                return false;
            }
        }
        this.purgeSamples(timestamp);
        var volClipped = vol > cutoff ? cutoff : vol;
        meanArray.push(volClipped);
        var volClippedSmooth = volClipped;
        var volPower = slidingPower.push(volClipped,mean);
        var isSpeak = volPower > NOISE_POWER_THRESHOLD ? 1 : 0;
        samples.push({
            'volRaw': vol,
            'volClipped': volClipped,
            'volClippedSmooth': volClippedSmooth,
            'cutoff': cutoff,
            'volPower': volPower,
            'mean': mean,
            'isSpeak': isSpeak,
            'timestamp': timestamp,
            'duration': duration
        });
        return true;
    }.bind(this);
    this.updateMean = function() {
        var tempMean = median(meanArray.getSamplesArray());
        if (tempMean) {
            mean = median(meanArray.getSamplesArray());
        }
    }
    this.updateCutoff = function () {
        if (samples.length == 0) {
            return CUTOFF_PROIOR;
        }
        var m = meanAndStd(samples, function (sample) {
            return sample.volRaw
        });
        cutoff = (CUTOFF_PROIOR * PRIOR_WEIGHT) + (m.mean + 2 * m.std) * (1 - PRIOR_WEIGHT);
        dataLog("Cutoff prior,value,mean and std:"+ CUTOFF_PROIOR+" "+cutoff+" "+m.mean+" "+m.std);
    }.bind(this);
    this.getSamples = function () {
        return samples;
    }.bind(this);
    this.clearData = function() {
        var samples = [];
        var smoother = new SmoothArray();
    }.bind(this);
}
function DataAnalyzer ( ) { var samples = [ ] ; var cutoff = CUTOFF_PROIOR ; var slidingPower = new SlidingPower ( NOISE_POWER_SAMPLES ) ; var meanArray = new FixedLengthArray ( POWER_SAMPLES_MEAN ) ; var mean = MEAN_INIT_VALUE ; this . purgeSamples = function ( timestamp ) { while ( samples . length > 0 && ( timestamp - samples [ 0 ] . timestamp > BUFFER_LENGTH ) ) { samples . shift ( ) ; } } . bind ( this ) ; this . addChunk = function ( chunk ) { var startTime = chunk . ts ; var startTimeMs = chunk . ts_ms ; var sampleDuration = chunk . sampleDelay ; var samples = chunk . samples ; var analyzer = this ; $ . each ( samples , function ( i , volume ) { analyzer . addSample ( volume , startTime * 1000 + startTimeMs + sampleDuration * i , sampleDuration ) ; } ) ; } . bind ( this ) ; this . addSample = function ( vol , timestamp , duration ) { if ( samples . length > 0 ) { var lastTimestamp = samples [ samples . length - 1 ] . timestamp ; if ( timestamp <= lastTimestamp ) { return false ; } } this . purgeSamples ( timestamp ) ; var volClipped = vol > cutoff ? cutoff : vol ; meanArray . push ( volClipped ) ; var volClippedSmooth = volClipped ; var volPower = slidingPower . push ( volClipped , mean ) ; var isSpeak = volPower > NOISE_POWER_THRESHOLD ? 1 : 0 ; samples . push ( { 'volRaw' : vol , 'volClipped' : volClipped , 'volClippedSmooth' : volClippedSmooth , 'cutoff' : cutoff , 'volPower' : volPower , 'mean' : mean , 'isSpeak' : isSpeak , 'timestamp' : timestamp , 'duration' : duration } ) ; return true ; } . bind ( this ) ; this . updateMean = function ( ) { var tempMean = median ( meanArray . getSamplesArray ( ) ) ; if ( tempMean ) { mean = median ( meanArray . getSamplesArray ( ) ) ; } } this . updateCutoff = function ( ) { if ( samples . length == 0 ) { return CUTOFF_PROIOR ; } var m = meanAndStd ( samples , function ( sample ) { return sample . volRaw } ) ; cutoff = ( CUTOFF_PROIOR * PRIOR_WEIGHT ) + ( m . mean + 2 * m . std ) * ( 1 - PRIOR_WEIGHT ) ; dataLog ( "Cutoff prior,value,mean and std:" + CUTOFF_PROIOR + " " + cutoff + " " + m . mean + " " + m . std ) ; } . bind ( this ) ; this . getSamples = function ( ) { return samples ; } . bind ( this ) ; this . clearData = function ( ) { var samples = [ ] ; var smoother = new SmoothArray ( ) ; } . bind ( this ) ; }
This class stores samples for a badge and convert them into talking intervals
This class stores samples for a badge and convert them into talking intervals
// array of samples : timestamp, volume //var smoother = new SmoothArray(SAMPLES_SMOOTHING); // array object used for caluclating smooth value //var speakThreashold = SPEAK_THRESHOLD_PRIOR; //var signalMean = new MedianArray(POWER_SAMPLES_MEAN); //dataLog("Removing from samples:",samples[0]); // start time is a combination of timestamp and fractional part (ms) // Adds a sample. Code assumes that the timestamp is monotonically increasing // Code will only add samples newer than the last timestamp // is it a new sample? //dataLog("Skipping existing sample: "+timestamp+" "+dateToString(timestamp)); // remove old objects samples array // clip the sample // update mean/median tracking array // smooth it //var volClippedSmooth = smoother.push(volClipped); // and check if it's above the threshold // add sample to array // updates the mean / median (we don't want to do this for every sample) // updates the cutoff // calc adjusted cutoff (using samples and prior) // updates the threshold /*
    this.updateSpeakThreshold = function () {
        if (samples.length == 0) {
            return SPEAK_THRESHOLD_PRIOR;
        }
        var m = meanAndStd(samples, function (sample) {
            return sample.volClippedSmooth
        });
        speakThreashold = (SPEAK_THRESHOLD_PRIOR * PRIOR_WEIGHT) + (m.mean - 2 * m.std) * (1 - PRIOR_WEIGHT);
        dataLog("Speak priotr,threashold, mean and std:"+ SPEAK_THRESHOLD_PRIOR +" "+ speakThreashold + " " + m.mean + " "+  m.std);
    }.bind(this);
    */