Siren

In this example below you will see how to do a Siren with some HTML / CSS and Javascript

Demonstrates the use of a custom oscillator in Web Audio to create an LFO that modulates a carrier to produce a siren sound.

Thumbnail
This awesome code was written by Clafou, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright Clafou ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Siren</title>
  
  
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/cascade-framework/1.5.0/css/build-full.min.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <h1>Siren with displayed output</h1>
<button onclick="play();toggle();">Play</button>  
<button onclick="stop();toggle();" style="display:none">Stop</button>
<canvas id="canvas" width="600" height="250"></canvas>
  <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://rawgit.com/corbanbrook/dsp.js/a7b2e97b1385a43083e50ed6dc81d697f0e57e28/dsp.js'></script>
<script src='https://rawgit.com/Clafou/AudioContext-MonkeyPatch/gh-pages/AudioContextMonkeyPatch.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/Clafou/siren-pjyRQR */
button
{
  margin: 10px;
  padding: 10px;
  border-radius: 10px;
  font-size: 20px;
}

/*Downloaded from https://www.codeseek.co/Clafou/siren-pjyRQR */
var audioContext = new AudioContext();

if (!window.OfflineAudioContext && window.webkitOfflineAudioContext) {
  window.OfflineAudioContext = window.webkitOfflineAudioContext;
}

function sharkFin(x) {
  if (x < 0) return 0;
  x = x * 2 % 2 + 0.05;
  if (x < 1) {
    return 1 + Math.log(x) / 4;
  }
  return Math.pow(-x, -2);
}

var count = 128;
var sharkFinValues = new Array(count);
for (var i = 0; i < count; i++) {
  sharkFinValues[i] = sharkFin(i / count);
}
var ft = new DFT(sharkFinValues.length);
ft.forward(sharkFinValues);

var lfoTable = audioContext.createPeriodicWave(ft.real, ft.imag);

function toggle() {
  $("button").toggle();
}

function play() {

  osc = audioContext.createOscillator();
  osc.frequency.value = 1200;

  lfo = audioContext.createOscillator();
  lfo.setPeriodicWave(lfoTable);
  lfo.frequency.value = 1 / 0.380;

  lfoGain = audioContext.createGain();
  lfoGain.gain.value = 450;

  lfo.connect(lfoGain);
  lfoGain.connect(osc.frequency);
  osc.connect(audioContext.destination);

  osc.start(0);
  lfo.start(0);
}

function stop() {
  osc.disconnect();
  lfoGain.disconnect();
  lfo.disconnect();
}

// Draw the output of sharkFin on the canvas
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
for (var x = 0; x < 1 * canvas.width; x++) {
  var y = sharkFin(x / 200) * 200;
  ctx.lineTo(x, y);
}
ctx.stroke();

function showOutput(data) {
  ctx.beginPath();
  for (var x = 0; x < 1 * canvas.width; x++) {
    //var y = sharkFin(x / 200) * 200;
    var y = 100 + data[x] * 100;
    ctx.lineTo(x * 2, y);
  }
  ctx.strokeStyle = '#ff0000'  
  ctx.stroke();
}

var offlineCtx = new OfflineAudioContext(1, 4410, 44100);
offlineCtx.oncomplete = function(event) {
  var data = event.renderedBuffer.getChannelData(0);
  showOutput(data);
}
var osc = offlineCtx.createOscillator();
osc.setPeriodicWave(lfoTable);
osc.frequency = 1;

osc.connect(offlineCtx.destination);
osc.start(offlineCtx.currentTime);
osc.stop(offlineCtx.currentTime + 1);
offlineCtx.startRendering();

Comments