DIR : /home/kozerus/public_html/ko/sound4.html

/home/kozerus/public_html/ko

<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width">
<!--
	<title>Creating Sounds with AudioContext &lt; JavaScript | The Art of Web</title>
	<meta name="description" content="An introduction to creating sounds with the built-in AudioContext interface which is now supported in all modern browsers.">
	<meta name="author" content="Chirp Internet">
	<meta name="theme-color" content="#333914">
	-->


<!--
	<link rel="stylesheet" href="/A.style.css,,q2+chirp_lightbox.css,Mcc.IRTz1vAmfc.css.pagespeed.cf.9UddlHi30d.css"/>
	-->
  
<!--	
	<link rel="alternate" type="application/rss+xml" title="RSS: New and updated articles" href="/rss.xml"> 
	-->


<style type="text/css">#analyser{display:flex;align-items:flex-end;margin:1em 0;height:100px;border:1px solid #ccc}#analyser>div{flex:1;border-top:2px solid green;transition:.1s}#piano{display:flex;margin:0 auto;max-width:80%}#piano>div{flex:1;position:relative;height:240px;margin:0 1px;border:1px solid #999;border-radius:1px 1px 5px 5px;box-shadow:2px 2px 5px rgba(0,0,0,.4);cursor:pointer}#piano>div::after{position:absolute;bottom:1em;width:100%;text-align:center;content:attr(data-note);font-size:1.5em}#piano>div>div{position:absolute;top:-1px;left:70%;height:160px;width: calc(60% + 2px);background:#000;border-radius:1px 1px 5px 5px;box-shadow:2px 2px 5px rgba(0,0,0,.4);cursor:pointer;z-index:10}</style>

	<script id=script_soundplayer src=soundplayer.js></script>
	</head>

<body>

<!--htdig_noindex-->
<a class="chirplink" accesskey="S" href="#content">skip to content</a>
<!--/htdig_noindex-->

<header id="header">
<a href="/"><img src="/images/banner-taow.png" width="737" height="87" alt="The Art of Web"></a>
<!--htdig_noindex-->
<nav id="menu" itemscope itemtype="http://schema.org/WebSite">
<meta itemprop="url" content="https://www.the-art-of-web.com/">
<form id="searchbox" itemprop="potentialAction" itemscope itemtype="http://schema.org/SearchAction" method="POST" action="/searchresult.html" accept-charset="UTF-8" onsubmit="return (words.value != '');">
<meta itemprop="target" content="https://www.the-art-of-web.com/searchresult.html?words={words}">
<input aria-label="site search" id="sitesearch" itemprop="query-input" type="search" results="10" autosave="searches" name="words" placeholder="Search">
<ul id="suggest"><li></li></ul>
</form>
<ul>
  <li id="menu_trigger"><a href="#" accesskey="M">&#x2261;</a></li>
  <li><a accesskey="1" href="/">Home</a></li>
  <li><a accesskey="2" href="/html/">HTML</a></li>
  <li><a accesskey="3" href="/css/">CSS</a></li>
  <li><a accesskey="4" href="/javascript/">JavaScript</a></li>
  <li><a accesskey="5" href="/php/">PHP</a></li>
  <li><a accesskey="6" href="/sql/">SQL</a></li>
  <li><a accesskey="7" href="/system/">System</a></li>
  <li><a accesskey="8" href="/links/">Links</a></li>
</ul>
</nav>
<!--/htdig_noindex-->
</header>

<aside id="rhs">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- The Art of Web - RWD Top -->
<ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-9789897350102210" data-ad-slot="8956648230" data-ad-format="auto"></ins>
<script>(adsbygoogle=window.adsbygoogle||[]).push({});</script>
</aside>

<main id="content">
<!--htdig_noindex-->
<aside id="ad_content" class="noprint">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- The Art of Web - RWD Content -->
<ins class="adsbygoogle" style="display: block;" data-ad-client="ca-pub-9789897350102210" data-ad-slot="1433381437" data-ad-format="auto"></ins>
<script>(adsbygoogle=window.adsbygoogle||[]).push({});</script>
</aside>

<!--/htdig_noindex-->

<div id="titlebox">
<div>
<h1><span class="nomobile">JavaScript: </span>Creating Sounds with AudioContext</h1>

<p class="social_counters"><a class="tweets" title="Share on Twitter" target="_blank" href="https://twitter.com/intent/tweet?text=Creating+Sounds+with+AudioContext:&amp;url=https%3A%2F%2Fwww.the-art-of-web.com%2Fjavascript%2Fcreating-sounds%2F&amp;via=theartofweb"><span>&nbsp;<span>Tweet</span></span></a><a class="likes" title="Share on Facebook" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwww.the-art-of-web.com%2Fjavascript%2Fcreating-sounds%2F"><span>5<span> Shares</span></span></a><a class="reddit" title="Post to Reddit" target="_blank" href="http://www.reddit.com/submit?title=Creating+Sounds+with+AudioContext&amp;url=https%3A%2F%2Fwww.the-art-of-web.com%2Fjavascript%2Fcreating-sounds%2F"><span>0<span> Tweets</span></span></a><a class="feedback" title="User Commentc" href="#user_comments" accesskey="C"><span>3<span> Comments</span></span></a></p>

</div>
<div>
<div id="submenu"><!-- --></div>
</div>
</div>



<p>Did you know that it's now possible to generate sounds from scratch 
using only JavaScript.  Previously this required Flash/Shockwave or 
loading an audio file.</p>

<p>Playing audio files became much easier in HTML5, but can now be done 
away with entirely if you only want to play simple harmonics.</p>


<h2>Creating an oscillating soundwave</h2>

<p>The AudioContext interface is extremely powerful letting you chain 
together various effects.  For our purposes we are using only the 
OscillatorNode (represents a periodic waveform) and gainNode (a change 
in volume) to create our sounds.</p>

<p>Here we've set up two control forms, each controlling a separate 
OscialltorNode (frequency, wave type) and GainNode (volume) to create a 
constant tone which can then be manipulated.  The code for each form is 
otherwise identical.</p>

<div style="display: flex; justify-content: space-between;">
<form id="soundForm" style="width: 48%">
<fieldset>
<legend>Sound Player 1</legend>
<label>Frequency</label><span><input type="range" name="freq" value="261" min="220" max="880" oninput="myPlayer.setFrequency(this.value);"></span>
<label>Volume</label><span><input type="range" name="vol" value="50" min="0" max="200" oninput="myPlayer.setVolume(this.value/100);"></span>
<label>Wave Type</label><span>
<label><input type="radio" name="wave" value="sine" checked onclick="myPlayer.setWaveType(this.value);"> sine</label><br>
<label><input type="radio" name="wave" value="square" onclick="myPlayer.setWaveType(this.value);"> square</label><br>
<label><input type="radio" name="wave" value="sawtooth" onclick="myPlayer.setWaveType(this.value);"> sawtooth</label><br>
<label><input type="radio" name="wave" value="triangle" onclick="myPlayer.setWaveType(this.value);"> triangle</label>
</span>
<span>
<input name="play" type="button" onclick="
  myPlayer.play(form.freq.value, form.vol.value/100, checkRadio(form.wave));
  this.style.display = 'none';
  form.stop.style.display = 'inline';
" value="Play &#9658;">
<input name="stop" style="display: none;" type="button" onclick="
  myPlayer.stop();
  form.play.style = 'inline';
  this.style.display = 'none';
" value="Stop &#10073;&#10073;"></span>
</fieldset>
</form>

<form id="soundForm2" style="width: 48%;">
<fieldset>
<legend>Sound Player 2</legend>
<label>Frequency</label><span><input type="range" name="freq" value="392" min="220" max="880" oninput="myPlayer2.setFrequency(this.value);"></span>
<label>Volume</label><span><input type="range" name="vol" value="25" min="0" max="200" oninput="myPlayer2.setVolume(this.value/100);"></span>
<label>Wave Type</label><span>
<label><input type="radio" name="wave" value="sine" onclick="myPlayer2.setWaveType(this.value);"> sine</label><br>
<label><input type="radio" name="wave" value="square" checked onclick="myPlayer2.setWaveType(this.value);"> square</label><br>
<label><input type="radio" name="wave" value="sawtooth" onclick="myPlayer2.setWaveType(this.value);"> sawtooth</label><br>
<label><input type="radio" name="wave" value="triangle" onclick="myPlayer2.setWaveType(this.value);"> triangle</label>
</span>
<span>
<input name="play" type="button" onclick="
  myPlayer2.play(form.freq.value, form.vol.value/100, checkRadio(form.wave));
  this.style.display = 'none';
  form.stop.style.display = 'inline';
" value="Play &#9658;">
<input name="stop" style="display: none;" type="button" onclick="
  myPlayer2.stop();
  form.play.style = 'inline';
  this.style.display = 'none';
" value="Stop &#10073;&#10073;"></span>
</fieldset>
</form>
</div>

<div id="analyser">
</div>

<p>If you're feeling masochistic, try playing some sounds with adjacent 
frequencies.</p>


<h2>AudioContext Mechanics</h2>

<p>For the effects demonstrated on this page we're using the following 
interfaces:</p>

<p style="text-align: center;"><img src="/images/soundplayer.png" width="477" height="150" alt="SoundPlayer Node configuration diagram"></p>

<p>Rather than operating on them directly, we've created a 
<tt>SoundPlayer</tt> class which does most of the work, including 
ramping the volume up and down to avoid that annoying clicking 
sound as the wave is truncated at the start and finish.</p>

<p>Complications arise when trying to play sounds in series, because 
commands are processed relative to the current time 
(baseAudioContext.currentTime) which represents a hardware timestamp 
starting from zero once the system is activated.</p>


<h2>SoundPlayer.js class</h2>

<p>Our SoundPlayer class enables all the example on this page, plus the 
sound effects in our new <a href="/javascript/graph-game/">JavaScript 
Graphing Game</a>.</p>

<p>The constructor accepts an AudioContext object, after which a single 
sound/note can be started and have it's properties controlled.  A single 
AudioContext is sufficient for all sounds on the page.</p>

<code id="box1" class="final" style="height: 400px;"><i>// Original JavaScript code by Chirp Internet: chirpinternet.eu</i>
<i>// Please acknowledge use of this code by including this header.</i>

function SoundPlayer(audioContext, filterNode) {
  this.audioCtx = audioContext;
  this.gainNode = this.audioCtx.createGain();
  if(filterNode) {
    <i>// run output through extra filter (already connected to audioContext)</i>
    this.gainNode.connect(filterNode);
  } else {
    this.gainNode.connect(this.audioCtx.destination);
  }
  this.oscillator = null;
}

SoundPlayer.prototype.setFrequency = function(val, when) {
  if(this.oscillator !== null) {
    if(when) {
      this.oscillator.frequency.setValueAtTime(val, this.audioCtx.currentTime + when);
    } else {
      this.oscillator.frequency.setValueAtTime(val, this.audioCtx.currentTime);
    }
  }
  return this;
};

SoundPlayer.prototype.setVolume = function(val, when) {
  if(when) {
    this.gainNode.gain.exponentialRampToValueAtTime(val, this.audioCtx.currentTime + when);
  } else {
    this.gainNode.gain.setValueAtTime(val, this.audioCtx.currentTime);
  }
  return this;
};

SoundPlayer.prototype.setWaveType = function(waveType) {
  this.oscillator.type = waveType;
  return this;
};

SoundPlayer.prototype.play = function(freq, vol, wave, when) {
  this.oscillator = this.audioCtx.createOscillator();
  this.oscillator.connect(this.gainNode);
  this.setFrequency(freq);
  if(wave) {
    this.setWaveType(wave);
  }
  this.setVolume(1/1000);
  if(when) {
    this.setVolume(1/1000, when - 0.02);
    this.oscillator.start(when - 0.02);
    this.setVolume(vol, when);
  } else {
    this.oscillator.start();
    this.setVolume(vol, 0.02);
  }
  return this;
};

SoundPlayer.prototype.stop = function(when) {
  if(when) {
    this.gainNode.gain.setTargetAtTime(1/1000, this.audioCtx.currentTime + when - 0.05, 0.02);
    this.oscillator.stop(this.audioCtx.currentTime + when);
  } else {
    this.gainNode.gain.setTargetAtTime(1/1000, this.audioCtx.currentTime, 0.02);
    this.oscillator.stop(this.audioCtx.currentTime + 0.05);
  }
  return this;
};
</code>
<p style="margin-top: 0; text-align: right;"><small><a href="#box1" onclick="document.getElementById('box1').style['height'] = 'auto'; this.parentNode.style['display'] = 'none'; return true;">expand code box</a></small></p>


<h4>Public methods</h4>

<p>The SoundPlayer class has the following public methods:</p>

<dl>
  <dt>__construct(<span><i>AudioContext</i></span>)</dt>
  <dd>creates a GainNode and connects it to the destination.</dd>
  <dt>play(<span><i>frequency, gain, waveType[, when]</i></span>)</dt>
  <dd>creates an OscillatorNode to play the specified sound and starts playing, now or in the future.</dd>
  <dt>stop(<span><i>[when]</i></span>)</dt>
  <dd>stops playing, now or in the future.</dd>
  <dt>setFrequency(<span><i>frequency[, when]</i></span>)</dt>
  <dd>changes the frequency in Hz, now or in the future.</dd>
  <dt>setVolume(<span><i>gain[, when]</i></span>)</dt>
  <dd>changes the volume multiplier, now or in the future.</dd>
  <dt>setWaveType(<span><i>type</i></span>)</dt>
  <dd>changes the wave type (sine, square, sawtooth or triangle).</dd>
</dl>

<p>Notably, these functions can all be chained. For example, to play a 
particular sound for a half second:</p>

<code>&lt;script src=&quot;<a href="/soundplayer.js">/soundplayer.js</a>&quot;&gt;&lt;/script&gt;
&lt;script&gt;

  const AudioContext = window.AudioContext || window.webkitAudioContext;
  const audio = new AudioContext();

  (new SoundPlayer(audio)).play(440.0, 0.8, "sine").stop(0.5);

&lt;/script&gt;</code>

<button onclick='(new SoundPlayer(audio)).play(440.0, 0.8, "sine").stop(0.5);'>Run Example &#x266A;</button>

<p>And to play a sound with a frequency transition:</p>

<code>(new SoundPlayer(audio)).play(440, 0.5, "square").setFrequency(880, 0.1).stop(0.2);</code>

<button onclick='(new SoundPlayer(audio)).play(440, 0.5, "square").setFrequency(880, 0.1).stop(0.2);'>Run Example &#x266b;</button>


<p>This approach is used in the piano keyboard demonstration below and, 
in most browsers, the commands can even be pasted directly into the 
Browser Console.</p>


<h2>Piano Keyboard</h2>

<p>Using our new SoundPlayer class we can easily attach it using event 
listeners to elements on the page to play different notes.  For example, 
here we've set up a piano keyboard where each key plays the respective 
note:</p>

<div id="piano">
<div data-frequency="261.626" data-note="C">
  <div data-frequency="277.18" data-note="C#"></div>
</div>
<div data-frequency="293.665" data-note="D">
  <div data-frequency="311.127"></div>
</div>
<div data-frequency="329.628" data-note="E"></div>
<div data-frequency="349.228" data-note="F">
  <div data-frequency="369.994"></div>
</div>
<div data-frequency="391.995" data-note="G">
  <div data-frequency="415.305"></div>
</div>
<div data-frequency="440.000" data-note="A">
  <div data-frequency="466.164"></div>
</div>
<div data-frequency="493.883" data-note="B"></div>
<div data-frequency="523.251" data-note="C">
  <div data-frequency="554.365"></div>
</div>
<div data-frequency="587.330" data-note="D">
  <div data-frequency="622.254"></div>
</div>
<div data-frequency="659.255" data-note="E"></div>
<div data-frequency="698.457" data-note="F">
  <div data-frequency="739.989"></div>
</div>
<div data-frequency="783.991" data-note="G">
  <div data-frequency="830.609"></div>
</div>
<div data-frequency="880.000" data-note="A">
  <div data-frequency="932.328"></div>
</div>
<div data-frequency="987.767" data-note="B"></div>
<div data-frequency="1046.50" data-note="C"></div>
</div>

<p style="text-align: center;"><small><label style="cursor: pointer;"><input type="checkbox" onclick="changePianoMode(this.checked);"> play notes on mouseover</label> (initial click needed)</small></p>

<p>Using HTML to mark up the keys as follows:</p>

<code>&lt;div id=&quot;<i>piano</i>&quot;&gt;
  &lt;div data-frequency=&quot;261.626&quot; data-note=&quot;C&quot;&gt;
    &lt;div data-frequency=&quot;277.18&quot; data-note=&quot;C#&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div data-frequency=&quot;293.665&quot; data-note=&quot;D&quot;&gt;
    &lt;div data-frequency=&quot;311.127&quot; data-note=&quot;D#&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div data-frequency=&quot;329.628&quot; data-note=&quot;E&quot;&gt;&lt;/div&gt;
  &lt;div data-frequency=&quot;349.228&quot; data-note=&quot;F&quot;&gt;
    &lt;div data-frequency=&quot;369.994&quot; data-note=&quot;F#&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
  <i>...</i>
&lt;/div&gt;</code>

<p>The data attributes are used to determine which note (frequency in 
Hz) to play when the key is clicked, and to display the key labels.</p>

<p>The source code is simplicity itself:</p>

<code>&lt;script src=&quot;<a href="/soundplayer.js">/soundplayer.js</a>&quot;&gt;&lt;/script&gt;
&lt;script&gt;

  const AudioContext = window.AudioContext || window.webkitAudioContext;
  const audio = new AudioContext();

  const playNote = (e) => {
    <i>// play note according to data-frequency attribute</i>
    (new SoundPlayer(audio)).play(e.target.dataset.frequency, 0.8, &quot;sine&quot;).stop(0.5);
    e.cancelBubble = true;
  };

  for(let el of document.getElementById(&quot;<i>piano</i>&quot;).getElementsByTagName(&quot;DIV&quot;)) {
    el.addEventListener(&quot;click&quot;, playNote, false);
  }

&lt;/script&gt;</code>

<p>For those not familar with the new <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions" target="_blank">arrow functions</a> syntax, <tt>(e) =&gt;</tt> in the 
above code snippets is equivalent to <tt>function(e)</tt>.</p>

<p>Depending on your system capabilities there may be some distortion 
when playing overlapping notes.  To reduce that we can add a <a href="https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode" target="_blank">DynamicsCompressorNode</a> to the mix:</p>

<code class="final">&lt;script src=&quot;<a href="/soundplayer.js">/soundplayer.js</a>&quot;&gt;&lt;/script&gt;
&lt;script&gt;

  const AudioContext = window.AudioContext || window.webkitAudioContext;
  const audio = new AudioContext();
<span>  const compressor = audio.createDynamicsCompressor();
  compressor.connect(audio.destination);</span>

  const playNote = (e) => {
    <i>// play note according to data-frequency attribute</i>
    (new SoundPlayer(audio<span>, compressor</span>)).play(e.target.dataset.frequency, 0.8, &quot;sine&quot;).setVolume(1/1000, 0.55).stop(0.6);
    e.cancelBubble = true;
  };

  for(let el of document.getElementById(&quot;<i>piano</i>&quot;).getElementsByTagName(&quot;DIV&quot;)) {
    el.addEventListener(&quot;click&quot;, playNote, false);
  }

&lt;/script&gt;</code>

<p>Now all the notes should be clean even if you jam your hands down on 
the keyboard.  We've also tweaked the note decay profile.</p>

<p>What's actually happening behing the scenes is illustrated below:</p>

<p style="text-align: center;"><img src="/images/soundplayer2.png" width="640" height="150" alt="SoundPlayer Node configuration diagram"></p>

<p>So our Soundplayer class is handling the frequency, wave type and 
volume, while the output (AudioContext.destination) and any intervening 
filter nodes are supplied from outside code.</p>


<h2>Playing a series of notes</h2>

<p>To play notes in series (without using a buffer or 
<tt>requestAnimationFrame</tt> for timing) we just need to specifiy a 
start and end time in seconds.</p>

<p>You might recognise this tune, for example:</p>

<code>(new SoundPlayer(audio)).play(587.3, 0.5, "sine").stop(0.25);
(new SoundPlayer(audio)).play(587.3, 0.5, "sine", 0.3).stop(0.35);
(new SoundPlayer(audio)).play(659.3, 0.5, "sine", 0.4).stop(0.55);
(new SoundPlayer(audio)).play(587.3, 0.5, "sine", 0.6).stop(0.75);
(new SoundPlayer(audio)).play(784.0, 0.5, "sine", 0.8).stop(0.95);
(new SoundPlayer(audio)).play(740.0, 0.5, "sine", 1.0).stop(1.40);</code>

<p><button onclick='(new SoundPlayer(audio)).play(587.3, 0.5, "sine").stop(0.25);
(new SoundPlayer(audio)).play(587.3, 0.5, "sine", 0.3).stop(0.35);
(new SoundPlayer(audio)).play(659.3, 0.5, "sine", 0.4).stop(0.55);
(new SoundPlayer(audio)).play(587.3, 0.5, "sine", 0.6).stop(0.75);
(new SoundPlayer(audio)).play(784.0, 0.5, "sine", 0.8).stop(0.95);
(new SoundPlayer(audio)).play(740.0, 0.5, "sine", 1.0).stop(1.40); return false;'>Happy Birthday To You &#x266b;</button></p>

<p>Note that Safari (12.0.3) will not play sounds automatically on page 
load.  Instead they are queued until a user action invokes the 
AudioContext interface.</p>


<h2 id="related">Related Articles - Audio</h2>

<ul class="sectioned">
  <li><span>JavaScript</span> <b>Creating Sounds with AudioContext</b></li>
</ul>



<h2>References</h2>

<ul>
  <li><a href="http://marcgg.com/blog/2016/11/01/javascript-audio/" target="_blank">Generate Sounds Programmatically With Javascript</a></li>
  <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API" target="_blank">MDN: Web Audio API</a></li>
  <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode" target="_blank">MDN: OscillatorNode</a></li>
  <li><a href="https://www.doctormix.com/blog/note-to-frequency-chart" target="_blank">Note to Frequency Chart</a></li>
</ul>

<p class="noprint"><a href="/javascript/">&lt; JavaScript</a></p>

<script src="/soundplayer.js.pagespeed.jm.quKwRx6x0j.js"></script>
<script>

  const checkRadio = (field) => {
    if((typeof field.length == "undefined") && (field.type == "radio")) {
      if(field.checked) return field.value;
    } else {
      for(let i=0; i < field.length; i++) {
        if(field[i].checked) return field[i].value;
      }
    }
    return false;
  };

  const changePianoMode = (active) => {
    for(let el of piano.getElementsByTagName("DIV")) {
      if(active) {
        el.addEventListener("mouseover", playNote, false);
      } else {
        el.removeEventListener("mouseover", playNote, false);
      }
    }
  };

  const AudioContext = window.AudioContext || window.webkitAudioContext;
  const audio = new AudioContext();

  const analyser = audio.createAnalyser();

  let analyserDisplay = document.getElementById("analyser");
  let myPlayer, myPlayer2;
  if(analyser.getFloatTimeDomainData) {
    analyser.fftSize = 512;
    analyser.connect(audio.destination);
    myPlayer = new SoundPlayer(audio, analyser);
    myPlayer2 = new SoundPlayer(audio, analyser);
    for(let i=0; i < analyser.fftSize; i++) {
      analyserDisplay.appendChild(document.createElement("DIV"));
    }
    let dataArray = new Float32Array(analyser.fftSize);
    setInterval(function() {
      analyser.getFloatTimeDomainData(dataArray);
      for(let i=0; i < dataArray.length; i++) {
        analyserDisplay.children[i].style.height = (50 + (10 * dataArray[i])) + "px";
      }
    }, 500);
  } else {
    // getFloatTimeDomainData not supported
    myPlayer = new SoundPlayer(audio);
    myPlayer2 = new SoundPlayer(audio);
    analyserDisplay.style.display = "none";
  }

  const compressor = audio.createDynamicsCompressor();
  compressor.connect(audio.destination);

  const playNote = (e) => {
    (new SoundPlayer(audio, compressor)).play(e.target.dataset.frequency, 0.8, "sine").setVolume(1/1000, 0.55).stop(0.6);
    e.cancelBubble = true;
  };

  let piano = document.getElementById("piano");
  for(let el of piano.getElementsByTagName("DIV")) {
    el.addEventListener("click", playNote, false);
  }

</script>

<div class="clear"></div>

<ul id="share">
  <li class="fbook"><a title="Share on Facebook" target="_blank" href="http://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwww.the-art-of-web.com%2Fjavascript%2Fcreating-sounds%2F"><!-- --></a></li>
  <li class="tweet"><a title="Tweet This" target="_blank" href="https://twitter.com/intent/tweet?text=JavaScript%3A+Creating+Sounds+with+AudioContext&amp;url=http%3A%2F%2Fwww.the-art-of-web.com%2Fjavascript%2Fcreating-sounds%2F&amp;via=theartofweb"></a></li>
</ul>

<script>document.getElementById("share").addEventListener("touchstart",function(e){e.target.className="hover";},{passive:true});</script>
<div id="feedback"><!-- --></div>

<h2 id="user_comments">User Comments</h2>

<a class="post_comment show-feedback">Post your comment or question</a>

<div id="comments">
<div class="comment" data-hash="e6ef5d2910f804804d76486d9b9e94ba" itemscope itemtype="http://schema.org/Comment">
<p class="comment_author"><big itemprop="author">kev</big> <span class="comment_time" itemprop="dateCreated">16 August, 2022</span></p>
<div itemprop="text"><p>how to download the sound of the frequency you change?</p></div>
</div>
<div class="comment" data-hash="ac4fa445c3dea16b8cc04ae8ccf1cfa5" itemscope itemtype="http://schema.org/Comment">
<p class="comment_author"><big itemprop="author">Paul</big> <span class="comment_time" itemprop="dateCreated">27 June, 2022</span></p>
<div itemprop="text"><p>Can I do frequency modulation.<br>
Fm = sin( a + m sin(b))</p></div>
</div>
<div class="comment" data-hash="475f40bdb6c14f6b02b7ae9c5ea14983" itemscope itemtype="http://schema.org/Comment">
<p class="comment_author"><big itemprop="author">Pete K</big> <span class="comment_time" itemprop="dateCreated">14 February, 2021</span></p>
<div itemprop="text"><p>Great stuff .. but it does not play after page loads, only when button clicked ...</p></div>
<div class="response">
<p>Most modern browsers prevent auto-playing sound, the same way they stop videos from auto-playing.  It's just something we have to work with. <img src="/smilies/icon_sad.gif" width="15" height="15" alt=""></p>
</div>
</div>
</div>

<script>var loadAllCommentsAjax=function(value,target){var params={page:"/javascript/creating-sounds/"};return(new AjaxRequestXML()).post("/scripts/loadallcomments.xml",params);};var comments_onload=function(e){document.querySelectorAll("#comments .comment[data-hash]").forEach(function(current){current.style.backgroundImage="url(//www.gravatar.com/avatar/"+current.getAttribute("data-hash")+".jpg?s=48&d=mm)";});};window.addEventListener("DOMContentLoaded",comments_onload,false);</script>

<div class="clear"></div>
</main>

<footer id="copyright">
<a href="/copyright.html">&copy; Copyright 2023</a> <a href="https://www.chirpinternet.eu/" target="_blank">Chirp Internet</a> 
- Page Last Modified: 1 March 2019 
- <a href="/cookies.html">Privacy &amp; Cookies</a>
</footer>

<a class="totop" href="#content" onclick="document.getElementById('content').scrollIntoView({behavior: 'smooth'}); return false;">top</a>

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-7GVHBLHJYW"></script>
<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag("js",new Date());gtag("config","G-7GVHBLHJYW");</script>
<script src="/scripts,_AjaxRequestXML.js+combined.js,q4.pagespeed.jc.2GMK_FJYoU.js"></script><script>eval(mod_pagespeed_8zQntuxrgR);</script>
<script>eval(mod_pagespeed_pRKjWkw7ND);</script>
<script>var mySuggest=new Suggestor("sitesearch","suggest","/scripts/autosuggest.xml",{regex:/^.{3,12}$/});window.onerror=function(msg,url,line){if(encodeURIComponent){var AjaxTarget="/scripts/logerror.xml";var params={"msg":msg,"url":url,"line":line};if(typeof AjaxRequestXML=="undefined"){var script=document.createElement("script");script.onload=function(){(new AjaxRequestXML()).post(AjaxTarget,params);}
script.src="/scripts/AjaxRequestXML.js";document.head.appendChild(script);return true;}else{return(new AjaxRequestXML()).post(AjaxTarget,params);}}return false;}</script>

<!-- web development by chirp internet -->
</body>
</html>

//


koh5_pano



Your browser does not support the HTML5 canvas element.


Drag mouse to navigate.

Navigation





17.Aug.2010, Martin Wengenmayer