Advertisement
Guest User

Untitled

a guest
Apr 19th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Source: https://jsfiddle.net/remotesynth/73cD5/embedded/result/
  2. window.AudioContext = window.AudioContext || window.webkitAudioContext;
  3. var ctx, o, g;
  4.  
  5. function pressKey(e) {
  6.   e.target.setAttribute("fill", "#55b7f9");
  7.   if (e.target.id) {
  8.     startNote(e.target.id);
  9.   }
  10. }
  11.  
  12. function leftKey(e) {
  13.   e.target.setAttribute("fill", "inherit");
  14.   stopNote();
  15. }
  16.  
  17. function initAudio() {
  18.   ctx = new AudioContext();
  19.   o = ctx.createOscillator();
  20.   o.start(0);
  21.   o.type = "triangle";
  22.   g = ctx.createGain();
  23.   g.gain.value = 0;
  24.   o.connect(g);
  25.   g.connect(ctx.destination);
  26.   window._AUDIO_READY = true;
  27. }
  28.  
  29. function startNote(note) {
  30.   !window._AUDIO_READY && initAudio();
  31.   o.frequency.value = notes[note];
  32.   g.gain.value = 0.0001;
  33. }
  34.  
  35. function stopNote() {
  36.   if (g) {
  37.     g.gain.value = 0;
  38.   }
  39. }
  40.  
  41. function fillKey(id) {
  42.   document.getElementById(id).setAttribute("fill", "#55b7f9")
  43. }
  44.  
  45. function unFillKey(id) {
  46.   document.getElementById(id).setAttribute("fill", "inherit")
  47. }
  48.  
  49. const keyboard = document.getElementsByTagName("use");
  50.  
  51. [...keyboard].forEach(el => {
  52.   el.addEventListener("mousedown", pressKey);
  53.   el.addEventListener("mouseup", leftKey);
  54.   el.addEventListener("mouseleave", leftKey);
  55. });
  56.  
  57. const notes = {
  58.   'c0': 16.35,
  59.   'c#0': 17.32,
  60.   'db0': 17.32,
  61.   'd0': 18.35,
  62.   'd#0': 19.45,
  63.   'eb0': 19.45,
  64.   'e0': 20.60,
  65.   'f0': 21.83,
  66.   'f#0': 23.12,
  67.   'gb0': 23.12,
  68.   'g0': 24.50,
  69.   'g#0': 25.96,
  70.   'ab0': 25.96,
  71.   'a0': 27.50,
  72.   'a#0': 29.14,
  73.   'bb0': 29.14,
  74.   'b0': 30.87,
  75.   'c1': 32.70,
  76.   'c#1': 34.65,
  77.   'db1': 34.65,
  78.   'd1': 36.71,
  79.   'd#1': 38.89,
  80.   'eb1': 38.89,
  81.   'e1': 41.20,
  82.   'f1': 43.65,
  83.   'f#1': 46.25,
  84.   'gb1': 46.25,
  85.   'g1': 49.00,
  86.   'g#1': 51.91,
  87.   'ab1': 51.91,
  88.   'a1': 55.00,
  89.   'a#1': 58.27,
  90.   'bb1': 58.27,
  91.   'b1': 61.74,
  92.   'c2': 65.41,
  93.   'c#2': 69.30,
  94.   'db2': 69.30,
  95.   'd2': 73.42,
  96.   'd#2': 77.78,
  97.   'eb2': 77.78,
  98.   'e2': 82.41,
  99.   'f2': 87.31,
  100.   'f#2': 92.50,
  101.   'gb2': 92.50,
  102.   'g2': 98.00,
  103.   'g#2': 103.83,
  104.   'ab2': 103.83,
  105.   'a2': 110.00,
  106.   'a#2': 116.54,
  107.   'bb2': 116.54,
  108.   'b2': 123.47,
  109.   'c3': 130.81,
  110.   'c#3': 138.59,
  111.   'db3': 138.59,
  112.   'd3': 146.83,
  113.   'd#3': 155.56,
  114.   'eb3': 155.56,
  115.   'e3': 164.81,
  116.   'f3': 174.61,
  117.   'f#3': 185.00,
  118.   'gb3': 185.00,
  119.   'g3': 196.00,
  120.   'g#3': 207.65,
  121.   'ab3': 207.65,
  122.   'a3': 220.00,
  123.   'a#3': 233.08,
  124.   'bb3': 233.08,
  125.   'b3': 246.94,
  126.   'c4': 261.63,
  127.   'c#4': 277.18,
  128.   'db4': 277.18,
  129.   'd4': 293.66,
  130.   'd#4': 311.13,
  131.   'eb4': 311.13,
  132.   'e4': 329.63,
  133.   'f4': 349.23,
  134.   'f#4': 369.99,
  135.   'gb4': 369.99,
  136.   'g4': 392.00,
  137.   'g#4': 415.30,
  138.   'ab4': 415.30,
  139.   'a4': 440.00,
  140.   'a#4': 466.16,
  141.   'bb4': 466.16,
  142.   'b4': 493.88,
  143.   'c5': 523.25,
  144.   'c#5': 554.37,
  145.   'db5': 554.37,
  146.   'd5': 587.33,
  147.   'd#5': 622.25,
  148.   'eb5': 622.25,
  149.   'e5': 659.26,
  150.   'f5': 698.46,
  151.   'f#5': 739.99,
  152.   'gb5': 739.99,
  153.   'g5': 783.99,
  154.   'g#5': 830.61,
  155.   'ab5': 830.61,
  156.   'a5': 880.00,
  157.   'a#5': 932.33,
  158.   'bb5': 932.33,
  159.   'b5': 987.77,
  160.   'c6': 1046.50,
  161.   'c#6': 1108.73,
  162.   'db6': 1108.73,
  163.   'd6': 1174.66,
  164.   'd#6': 1244.51,
  165.   'eb6': 1244.51,
  166.   'e6': 1318.51,
  167.   'f6': 1396.91,
  168.   'f#6': 1479.98,
  169.   'gb6': 1479.98,
  170.   'g6': 1567.98,
  171.   'g#6': 1661.22,
  172.   'ab6': 1661.22,
  173.   'a6': 1760.00,
  174.   'a#6': 1864.66,
  175.   'bb6': 1864.66,
  176.   'b6': 1975.53,
  177.   'c7': 2093.00,
  178.   'c#7': 2217.46,
  179.   'db7': 2217.46,
  180.   'd7': 2349.32,
  181.   'd#7': 2489.02,
  182.   'eb7': 2489.02,
  183.   'e7': 2637.02,
  184.   'f7': 2793.83,
  185.   'f#7': 2959.96,
  186.   'gb7': 2959.96,
  187.   'g7': 3135.96,
  188.   'g#7': 3322.44,
  189.   'ab7': 3322.44,
  190.   'a7': 3520.00,
  191.   'a#7': 3729.31,
  192.   'bb7': 3729.31,
  193.   'b7': 3951.07,
  194.   'c8': 4186.01
  195. };
  196. // is melody plays
  197. let playTimeout = null;
  198.  
  199. function dropPlayState() {
  200.   clearTimeout(playTimeout);
  201.   playTimeout = null;
  202.   [...keyboard].forEach(key => {
  203.     key.setAttribute("fill", "inherit");
  204.   });
  205.   playButton.disabled = false;
  206. }
  207.  
  208. window.playNotes = (melody) => {
  209.   if (playTimeout) return;
  210.   playButton.disabled = true;
  211.  
  212.   if (melody instanceof Array) {
  213.     let cache = JSON.parse(JSON.stringify(melody));
  214.     !window._AUDIO_READY && initAudio();
  215.     const player = ({ note, part = 1 }) => {
  216.       fillKey(note);
  217.       startNote(note);
  218.       playTimeout = setTimeout(() => {
  219.         stopNote();
  220.         unFillKey(note);
  221.         if (cache.length) {
  222.           setTimeout(() => {
  223.             player(cache.pop())
  224.           }, 50);
  225.         } else {
  226.           dropPlayState();
  227.         }
  228.       }, 1000*part);
  229.     };
  230.     cache = cache.reverse();
  231.     player(cache.pop());
  232.   }
  233. };
  234.  
  235. const myMelody = [
  236.   {
  237.     part: 1/8,
  238.     note: "e4"
  239.   },
  240.   {
  241.     part: 1/4,
  242.     note: "e4"
  243.   },
  244.   {
  245.     part: 1/4,
  246.     note: "e4"
  247.   },
  248.   {
  249.     part: 1/8,
  250.     note: "c4"
  251.   },
  252.   {
  253.     part: 1/4,
  254.     note: "e4"
  255.   },
  256.   {
  257.     part: 1/2,
  258.     note: "g4"
  259.   },
  260.   {
  261.     part: 1/2,
  262.     note: "g3"
  263.   },
  264.   {
  265.     part: 1/2,
  266.     note: "c4"
  267.   },
  268.   {
  269.     part: 1/2,
  270.     note: "g3"
  271.   },
  272.   {
  273.     part: 1/2,
  274.     note: "e3"
  275.   },
  276.   {
  277.     part: 1/4,
  278.     note: "a3"
  279.   },
  280.   {
  281.     part: 1/4,
  282.     note: "b3"
  283.   },
  284.   {
  285.     part: 1/8,
  286.     note: "bb3"
  287.   },
  288.   {
  289.     part: 1/4,
  290.     note: "a3"
  291.   },
  292.   {
  293.     part: 1/4,
  294.     note: "g3"
  295.   },
  296.   {
  297.     part: 1/8,
  298.     note: "e4"
  299.   },
  300.   {
  301.     part: 1/8,
  302.     note: "g4"
  303.   },
  304.   {
  305.     part: 1/4,
  306.     note: "a4"
  307.   },
  308.   {
  309.     part: 1/8,
  310.     note: "f4"
  311.   },
  312.   {
  313.     part: 1/4,
  314.     note: "g4"
  315.   },
  316.   {
  317.     part: 1/4,
  318.     note: "e4"
  319.   },
  320.   {
  321.     part: 1/8,
  322.     note: "c4"
  323.   },
  324.   {
  325.     part: 1/8,
  326.     note: "d4"
  327.   },
  328.   {
  329.     part: 1/4,
  330.     note: "b3"
  331.   },
  332. ]
  333.  
  334. const playButton = document.getElementsByClassName("play-button")[0];
  335. playButton.addEventListener("click", () => playNotes(myMelody));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement