<commit_before>'use strict';

var EnvGen = require('../../index');
var createGrapher = require('./grapher');

var audioContext = new (window.AudioContext || window.webkitAudioContext)();

// since ConstantSourceNode is not yet widely available
function createConstantNode(audioContext, v) {
  var constantBuffer = audioContext.createBuffer(1, 2, audioContext.sampleRate);
  var constantData = constantBuffer.getChannelData(0);
  constantData[0] = v;
  constantData[1] = v;
  var node = audioContext.createBufferSource();
  node.buffer = constantBuffer;
  node.loop = true;
  node.start();
  return node;
}

// Create nodes
var oscNode = audioContext.createOscillator();
oscNode.frequency.value = 440;
oscNode.type = 'sine';
oscNode.start();

var vcaNode = audioContext.createGain();
vcaNode.gain.value = 0;

var constNode = createConstantNode(audioContext, 1);

var envGainNode = audioContext.createGain();
envGainNode.gain.value = 0;

var grapherNode = createGrapher(audioContext, document.querySelector('#env-graph'), 1024);

// Connect everything up
oscNode.connect(vcaNode);
vcaNode.connect(audioContext.destination);
constNode.connect(envGainNode);
var egen = new EnvGen(audioContext, envGainNode.gain);
envGainNode.connect(grapherNode);
grapherNode.connect(vcaNode.gain); // We have to insert it 'inline' otherwise it seems to get GC'd

// Hook up gate controls
var gateButtonElem = document.querySelector('#gate-button');
gateButtonElem.addEventListener('mousedown', function(e) {
  e.preventDefault();
  egen.gateOn();
});
gateButtonElem.addEventListener('mouseup', function(e) {
  e.preventDefault();
  egen.gateOff();
});

// Hook up setting controls
var SETTINGS = [
  {name: 'mode', options: [['AD', 'AD'], ['ASR', 'ASR'], ['ADSR', 'ADSR']]},
  {name: 'attackShape', options: [[egen.LINEAR, 'linear']]},
  {name: 'attackTime'},
  {name: 'attackLevel'},
  {name: 'decayShape', options: [[egen.LINEAR, 'linear'], [egen.EXPONENTIAL, 'exponential']]},
  {name: 'decayTime'},
  {name: 'sustainFraction'},
  {name: 'releaseShape', options: [[egen.LINEAR, 'linear'], [egen.EXPONENTIAL, 'exponential']]},
  {name: 'releaseTime'},
];

var settingsElem = document.querySelector('#settings');

function addSetting(setting) {
  var wrapperElem = document.createElement('div');
  wrapperElem.className = 'setting-wrapper';

  var labelElem = document.createElement('label');

  var controlElem;
  if (setting.options) {
    controlElem = document.createElement('select');
    for (var j = 0; j < setting.options.length; j++) {
      var option = setting.options[j];
      var optionElem = document.createElement('option');
      optionElem.value = option[0];
      optionElem.textContent = option[1];
      controlElem.appendChild(optionElem);
    }
  } else {
    controlElem = document.createElement('input');
    controlElem.type = 'number';
    controlElem.step = 'any';
  }
<commit_msg>Add a bit more validation to settings controls<commit_after>'use strict';

var EnvGen = require('../../index');
var createGrapher = require('./grapher');

var audioContext = new (window.AudioContext || window.webkitAudioContext)();

// since ConstantSourceNode is not yet widely available
function createConstantNode(audioContext, v) {
  var constantBuffer = audioContext.createBuffer(1, 2, audioContext.sampleRate);
  var constantData = constantBuffer.getChannelData(0);
  constantData[0] = v;
  constantData[1] = v;
  var node = audioContext.createBufferSource();
  node.buffer = constantBuffer;
  node.loop = true;
  node.start();
  return node;
}

// Create nodes
var oscNode = audioContext.createOscillator();
oscNode.frequency.value = 440;
oscNode.type = 'sine';
oscNode.start();

var vcaNode = audioContext.createGain();
vcaNode.gain.value = 0;

var constNode = createConstantNode(audioContext, 1);

var envGainNode = audioContext.createGain();
envGainNode.gain.value = 0;

var grapherNode = createGrapher(audioContext, document.querySelector('#env-graph'), 1024);

// Connect everything up
oscNode.connect(vcaNode);
vcaNode.connect(audioContext.destination);
constNode.connect(envGainNode);
var egen = new EnvGen(audioContext, envGainNode.gain);
envGainNode.connect(grapherNode);
grapherNode.connect(vcaNode.gain); // We have to insert it 'inline' otherwise it seems to get GC'd

// Hook up gate controls
var gateButtonElem = document.querySelector('#gate-button');
gateButtonElem.addEventListener('mousedown', function(e) {
  e.preventDefault();
  egen.gateOn();
});
gateButtonElem.addEventListener('mouseup', function(e) {
  e.preventDefault();
  egen.gateOff();
});

// Hook up setting controls
var SETTINGS = [
  {name: 'mode', options: [['AD', 'AD'], ['ASR', 'ASR'], ['ADSR', 'ADSR']]},
  {name: 'attackShape', options: [[egen.LINEAR, 'linear']]},
  {name: 'attackTime', min: 0},
  {name: 'attackLevel'},
  {name: 'decayShape', options: [[egen.LINEAR, 'linear'], [egen.EXPONENTIAL, 'exponential']]},
  {name: 'decayTime', min: 0},
  {name: 'sustainFraction', min: 0, max: 1},
  {name: 'releaseShape', options: [[egen.LINEAR, 'linear'], [egen.EXPONENTIAL, 'exponential']]},
  {name: 'releaseTime', min: 0},
];

var settingsElem = document.querySelector('#settings');

function addSetting(setting) {
  var wrapperElem = document.createElement('div');
  wrapperElem.className = 'setting-wrapper';

  var labelElem = document.createElement('label');

  var controlElem;
  if (setting.options) {
    controlElem = document.createElement('select');
    for (var j = 0; j < setting.options.length; j++) {
      var option = setting.options[j];
      var optionElem = document.createElement('option');
      optionElem.value = option[0];
      optionElem.textContent = option[1];
      controlElem.appendChild(optionElem);
    }
  } else {
    controlElem = document.createElement('input');
    controlElem.type = 'number';
    controlElem.step = 'any';
    if (setting.hasOwnProperty('min')) {
      controlElem.min = setting.min;
    }
    if (setting.hasOwnProperty('max')) {
      controlElem.max = setting.max;
    }
  }

{'fraction_non_alphanumeric': 0.15612024580634445, 'fraction_numerical': 0.006809500083042684, 'mean_word_length': 5.022, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '1627561', 'n_tokens_mistral': 1905, 'n_tokens_neox': 1867, 'n_words': 429}