<commit_before>var Board = require("../lib/board.js"),
  Timer = require("nanotimer");

function Piezo(opts) {

  Board.Device.call(
    this, opts = Board.Options(opts)
  );

  // Hardware instance properties
  this.mode = this.io.MODES.OUTPUT;
  this.pin = opts.pin || 3;

  this.io.pinMode(this.pin, this.mode);

  // Piezo instance properties
  this.isPlaying = false;
}

Piezo.Notes = {
  "c4": 262,
  "c#4": 277,
  "d4": 294,
  "d#4": 311,
  "e4": 330,
  "f4": 349,
  "f#4": 370,
  "g4": 392,
  "g#4": 415,
  "a4": 440,
  "a#4": 466,
  "b4": 494,
  "c5": 523,
  "c#5": 554,
  "d5": 587,
  "d#5": 622,
  "e5": 659,
  "f5": 698,
  "f#5": 740,
  "g5": 784,
  "g#5": 831,
  "a5": 880,
  "a#5": 932,
  "b5": 988,
  "c6": 1047
};

function clearTimer() {
  if(!this.timer) {
    return;
  }

  this.timer.clearInterval();
  delete this.timer;
}

Piezo.prototype.tone = function(tone, duration) {
  clearTimer.call(this);

  this.timer = new Timer();
  var value = 1;

  this.timer.setInterval(function() {
    value = value === 1 ? 0 : 1;
    this.io.digitalWrite(this.pin, value);
  }.bind(this), null, tone + "u", function() {});

  this.timer.setTimeout(clearTimer.bind(this), null, duration + "m");

  return this;
};

Piezo.prototype.frequency = function(frequency, duration) {
  var period = 1 / frequency;
  var duty = period / 2;
  var tone = Math.round(duty * 1000000);

  return this.tone(tone, duration);
};

Piezo.prototype.play = function(tune) {
  var duration;
  var note = null;
  var beat = 1;
  var tempo = tune.tempo || 150;
  var song = tune.song || [];
  var i = 0;
  var next = function() {
    var myNote;

    if (Array.isArray(song[i])) {
      note = song[i][0] || null; // First argument is the note
      beat = song[i][1] || 1; // Second argument is the beat
    }

    duration = beat * tempo;<commit_msg>Remove the race condition with clearing the timers.  Because stopping the tone was based on a timeout.  Two consecutive notes could cause the first timer to clear, but then the callback would clear the next (wrong) timer.<commit_after>var Board = require("../lib/board.js"),
  Timer = require("nanotimer");

function Piezo(opts) {

  Board.Device.call(
    this, opts = Board.Options(opts)
  );

  // Hardware instance properties
  this.mode = this.io.MODES.OUTPUT;
  this.pin = opts.pin || 3;

  this.io.pinMode(this.pin, this.mode);

  // Piezo instance properties
  this.isPlaying = false;
}

Piezo.Notes = {
  "c4": 262,
  "c#4": 277,
  "d4": 294,
  "d#4": 311,
  "e4": 330,
  "f4": 349,
  "f#4": 370,
  "g4": 392,
  "g#4": 415,
  "a4": 440,
  "a#4": 466,
  "b4": 494,
  "c5": 523,
  "c#5": 554,
  "d5": 587,
  "d#5": 622,
  "e5": 659,
  "f5": 698,
  "f#5": 740,
  "g5": 784,
  "g#5": 831,
  "a5": 880,
  "a#5": 932,
  "b5": 988,
  "c6": 1047
};

function clearTimer() {
  if(!this.timer) {
    return;
  }

  this.timer.clearInterval();
  delete this.timer;
}

Piezo.prototype.tone = function(tone, duration) {
  clearTimer.call(this);

  var timer = this.timer = new Timer();
  var value = 1;

  timer.setInterval(function() {
    value = value === 1 ? 0 : 1;
    this.io.digitalWrite(this.pin, value);

    if((timer.difTime / 1000000) > duration) {
      clearTimer.call(this);
    }
  }.bind(this), null, tone + "u", function() {});

  return this;
};

Piezo.prototype.frequency = function(frequency, duration) {
  var period = 1 / frequency;
  var duty = period / 2;
  var tone = Math.round(duty * 1000000);

  return this.tone(tone, duration);
};

Piezo.prototype.play = function(tune) {
  var duration;
  var note = null;
  var beat = 1;
  var tempo = tune.tempo || 150;
  var song = tune.song || [];
  var i = 0;
  var next = function() {
    var myNote;

    if (Array.isArray(song[i])) {
      note = song[i][0] || null; // First argument is the note
      beat = song[i][1] || 1; // Second argument is the beat
    }

    duration = beat * tempo;
{'fraction_non_alphanumeric': 0.18167821401077752, 'fraction_numerical': 0.0649217346676931, 'mean_word_length': 2.909729187562688, 'pattern_counts': {'":': 50, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5233175', 'n_tokens_mistral': 1749, 'n_tokens_neox': 1515, 'n_words': 391}