Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <script type="text/javascript">
function value(curve, x) {
  for (var i = 0; i < curve.length && curve[i][0] <= x; i++)
    ;
  if (i == curve.length)
    i--;
  var x1 = curve[i-1][0];
  var y1 = curve[i-1][1];
  var x2 = curve[i][0];
  var y2 = curve[i][1];
  if (x2 == x1)
    return y1;
  return y1+(y2-y1)/(x2-x1)*(x-x1);
}
function comp() {
  //
  // Convert curves from Pianoteq's format to JS array
  //
  
  var f_ptq = JSON.parse(document.getElementById("f_ptq_txt").value
                     .replace(/.*(\[.+\]).*/,"$1")
                     .replace(';', ','));
  var g_ptq = JSON.parse(document.getElementById("g_ptq_txt").value
                     .replace(/.*(\[.+\]).*/,"$1")
                     .replace(';', ','));
  var f = [[0,0]];
  var f_size = f_ptq.length/2;
  for (var i = 0; i < f_size; i++) {
    f.push([f_ptq[i], f_ptq[i+f_size]]);
  }
  if (f[f_size][0] != 127)
    f.push([127,f[f_size][1]]);
  
  var g = [[0,0]];
  var g_size = g_ptq.length/2;
  for (var i = 0; i < g_size; i++) {
    g.push([g_ptq[i], g_ptq[i+g_size]]);
  }
  if (g[g_size][0] != 127)
    g.push([127,g[g_size][1]]);
  //
  // Find sufficient set of x'es for the composition curve
  //
  
  var g_inv = g.map(function(p) {return [p[1], p[0]];})
    .sort(function(p, q) {return p[0]-q[0];});
    
  var g_xs = g.map(function(p) {return p[0];});
  var f_xs = f.map(function(p) {return value(g_inv, p[0]);});
  
  var xs = g_xs.concat(f_xs)
    .sort(function(a, b) {return a-b;})
    .filter(function(x, i, a) {return i === 0 || a[i] != a[i-1];})
    .filter(function(x) {return x <= 127;});
  //
  // Calculate composition curve
  //
  
  var fg = [];
  xs.forEach(function(x) {
    fg.push([x, value(f, value(g, x))]);
  });
  
  //
  // Output using Pianoteq's format
  //
  
  var out = '[';
  for (var i = 0; i < fg.length; i++) {
    if (i != 0) out += ', ';
    out += (fg[i][0]).toFixed();
  }
  out += '; ';
  for (var i = 0; i < fg.length; i++) {
    if (i != 0) out += ', ';
    out += (fg[i][1]).toFixed();
  }
  out += ']'; 
  document.getElementById("out_ptq_txt").value = out;
}
    
function go() {
  try {
    comp();
  }
  catch (e) {
    document.getElementById("out_ptq_txt").value = "Error! Sorry..."
  }
}
    
  </script>
</head>
<body>
  
  Preset's curve<br><i>f =</i> <input type="text" id="f_ptq_txt" size="70" value="[0, 127; 0, 127]">
  <br><br>
  Keyboard's curve<br><i>g = </i> <input type="text" id="g_ptq_txt" size="70" value="[0, 127; 0, 127]">
  <br><br>
  <button onclick="go()">Calculate</button>
  <br><br>
  Composition<br><i>f∘g = </i> <input type="text" id="out_ptq_txt" size="70" value="[0, 127; 0, 127]">
  
</body>
</html>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
ross2718pro
0viewers