Show:

File: src/utils/SignalScope.js

/**
 * Based on SignalScope.as originally written in as3.
 * Copyright (c) the Funnel development team
 * http://www.funnel.cc
 *
 * Copyright (c) 2011-2012 Jeff Hoefs <soundanalogous@gmail.com>
 *
 * Released under the MIT license. See LICENSE file for details.
 */

JSUTILS.namespace('JSUTILS.SignalScope');

JSUTILS.SignalScope = (function() {

  var SignalScope;

  /**
   * A simple 2 channel scope to view analog input data.
   *
   * @class SignalScope
   * @constructor
   * @param {String} canvasId The id of the canvas element to
   * use to draw the signal.
   * @param {Number} width The width of the canvas element.
   * @param {Number} height The height of the canvas element.
   * @param {Number} rangeMin The minimum range of the scope.
   * @param {Number} rangeMax The maximum range of the scope.
   * @param {String} ch1Color [optional] The hex color value to use
   * for the channel 1 signal (default = #FF0000).
   * @param {String} ch2Color [optional] The hex colorvalue to use
   * for the channel 2 signal (default = #0000FF).
   */
  SignalScope = function(canvasId, width, height, rangeMin, rangeMax, ch1Color, ch2Color) {

    this.name = "SignalScope";

    this._canvas = document.getElementById(canvasId);
    this._ctx = this._canvas.getContext("2d");

    this._width = width;
    this._height = height;
    this._rangeMin = rangeMin;
    this._rangeMax = rangeMax;

    this._ch1Color = ch1Color || '#FF0000';
    this._ch2Color = ch2Color || '#0000FF';
    this._markers = null;

    this._ch1Values = new Array(width);
    this._ch2Values = new Array(width);

    // inital all values to 0.0
    for (var i = 0; i < width; i++) {
      this._ch1Values[i] = 0.0;
      this._ch2Values[i] = 0.0;
    }

    this._range = 1 / (rangeMax - rangeMin) * 100;

  };

  /**
   * Call this method at the desired frame rate in order
   * to draw the input signal.
   * @method update
   * @param {Number} input1 The channel 1 input signal
   * @param {Number} input2 [optional] The channel 2 input signal
   */
  SignalScope.prototype.update = function(input1, input2) {
    // clear the canvas
    this._ctx.clearRect(0, 0, this._width, this._height);

    this._ch1Values.push(input1);
    this._ch1Values.shift();
    this.drawChannel(this._ch1Values, this._ch1Color);

    if (input2 !== undefined) {
      this._ch2Values.push(input2);
      this._ch2Values.shift();
      this.drawChannel(this._ch2Values, this._ch2Color);
    }

    this.drawMarkers();
  };

  /**
   * @private
   * @method drawChannel
   */
  SignalScope.prototype.drawChannel = function(values, color) {
    var offset = 0.0;

    this._ctx.strokeStyle = color;
    this._ctx.lineWidth = 1;
    this._ctx.beginPath();
    this._ctx.moveTo(0, this._height);

    // draw channel 1
    for (var i = 0, len = values.length; i < len; i++) {
      offset = (this._rangeMax - values[i]) * this._range;
      this._ctx.lineTo(i, offset);
    }
    this._ctx.stroke();
  };

  /**
   * @private
   * @method drawMarkers
   */
  SignalScope.prototype.drawMarkers = function() {
    var offset = 0.0;

    if (this._markers !== null) {
      for (var i = 0, num = this._markers.length; i < num; i++) {
        offset = (this._rangeMax - this._markers[i][0]) * this._range;
        this._ctx.strokeStyle = this._markers[i][1];
        this._ctx.lineWidth = 0.5;
        this._ctx.beginPath();
        this._ctx.moveTo(0, offset);
        this._ctx.lineTo(this._width, offset);
        this._ctx.stroke();
      }
    }
  };

  /**
   * Add a horizontal marker to the scope. 1 or more markers can be added.
   * @method addMarker
   * @param {Number} level The value of the marker within the input value range.
   * @param {String} color The hex color value for the marker.
   */
  SignalScope.prototype.addMarker = function(level, color) {
    if (this._markers === null) {
      this._markers = [];
    }
    this._markers.push([level, color]);
  };

  /**
   * Remove all markers from the scope.
   * @removeAllMarkers
   */
  SignalScope.prototype.removeAllMarkers = function() {
    this._markers = null;
  };

  return SignalScope;

}());