0

Im trying to create a simple countdown timer that plays a beep when it's done. My countdown timer is working. My sound file has been created and is in place. The script to play the sound file is not working, and thats what Im asking for help with.

Ive looked around for answers, and most recommend hooking up to an external JS library, which I do not want to do. That being said, here is my code:

<script language="Javascript">

var countdown;
var countdown_number;

var audio = new Audio('audio/beep.mp3'); 


function countdown_init() {
    countdown_number = 11;
    countdown_trigger();
}

function countdown_trigger() {
    if(countdown_number > 0) {
        countdown_number--;
        document.getElementById('countdown_text').innerHTML = countdown_number;
        if(countdown_number > 0) {
            countdown = setTimeout('countdown_trigger()', 1000);

if(countdown_number === 0) { audio.play(); }

        }

    }
}

function countdown_clear() {
    clearTimeout(countdown);
}





</script>





<div>
    <input type="button" value="start countdown" onClick="countdown_init()" />
    <input type="button" value="stop countdown" onClick="countdown_clear()" /> <br /><br />
</div>
<div id="countdown_text">Placeholding text</div>
wolfgangpwnz
  • 37
  • 1
  • 9
  • 1
    `var audio = new Audio('/audio/beep.mp3'); audio.play()` – adeneo Mar 20 '15 at 02:12
  • I like yours better than mine, its simpler. But, this is playing as soon as the page loads now. I tried putting the "audio.play()" into the countdown === 0 section, but that didnt work. – wolfgangpwnz Mar 20 '15 at 02:55
  • @adeneo: would that work if the track takes a while to load? – dandavis Mar 20 '15 at 02:55
  • Thank you! This coupled with the extra help I got below and it worked perfectly! – wolfgangpwnz Mar 20 '15 at 03:28
  • You should be cautious about using a string as the first argument to setTimeout(), as this actually becomes an eval() statement - which is evil. Additionally, all of your functions and variables are in the global scope - which is also evil. Finally, use of the -- operator should be avoided when possible. I'd recommend using a linter such as [JSHint](http://jshint.com/) – dperish Mar 20 '15 at 03:37
  • Im an newbie with javascript, trying to teach myself. I dont really understand what anything you just said means. – wolfgangpwnz Mar 20 '15 at 05:05
  • @wolfgangpwnz notice in the `setTimeout` functions you have `setTimeout('countdown_trigger()')` but in the answers below people have used `setTimeout(countdown_trigger)` This is because the setTimeout method can take a function (without brackets) and it will execute it. This is the preferred approach. If you pass a string (wrapped in quotes `''`) then the timeout method will try to `eval` the function which means searching for functions with the same name and executing it. This is bad :) – jasonscript Mar 20 '15 at 07:56
  • Ohhh. I changed that around and pasted it into JSHint and it said there werent anymore errors. And it still works. Thanks! Im always willing to learn new stuff about syntax, because thats the part I cant really learn by myself without a class, and my college totally skimmed over javascript when teaching us. So Ive been on my own lol – wolfgangpwnz Mar 20 '15 at 14:57

4 Answers4

1

The issue with your sound manager was that you needed to call createSound after the onready event:

 var countdown;
var countdown_number;
var mySoundObject;

function countdown_trigger() {
    if (countdown_number > 0) {
        countdown_number--;
        document.getElementById('countdown_text').innerHTML = countdown_number;
        if (countdown_number > 0) {
            countdown = setTimeout(countdown_trigger, 1000);
        }

        if (countdown_number === 0) {
            mySoundObject.play();
        }
    }
}

function countdown_clear() {
    clearTimeout(countdown);
}

function countdown_init() {
    countdown_number = 11;
    countdown_trigger();
}

document.getElementById('start').onclick = countdown_init;
document.getElementById('stop').onclick = countdown_clear;

soundManager.setup({
    url: 'http://ivdemo.chaseits.co.uk/SoundManager2-2.97a.20131201/swf/soundmanager2_flash_xdomain/soundmanager2_flash9_debug.swf',
    flashVersion: 9,
    useHTML5Audio: true,
    html5Test: 'maybe',
    preferFlash: false,
    onready: function () {
        mySoundObject = soundManager.createSound({
            id: 'mySound',
            url: 'http://www.freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3'
        });
    }
});

JSFiddle Demo http://jsfiddle.net/TBS8C/16/

EDIT

It looks like you changed your question to not using soundManager anymore. Here's a demo with HTML5 audio only.

var countdown;
var countdown_number;
var audio = new Audio('http://www.freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3');

function countdown_trigger() {
    if (countdown_number > 0) {
        countdown_number--;
        document.getElementById('countdown_text').innerHTML = countdown_number;
        if (countdown_number > 0) {
            countdown = setTimeout(countdown_trigger, 1000);
        }

        if (countdown_number === 0) {
            audio.play()
        }
    }
}

function countdown_clear() {
    clearTimeout(countdown);
}

function countdown_init() {
    countdown_number = 11;
    countdown_trigger();
}

document.getElementById('start').onclick = countdown_init;
document.getElementById('stop').onclick = countdown_clear;
<input type="button" value="start countdown" id="start" />
<input type="button" value="stop countdown" id="stop" />
<div id="countdown_text"></div>

JSFiddle Demo http://jsfiddle.net/nsmp8mfv/1/

Miguel Mota
  • 20,135
  • 5
  • 45
  • 64
0

I think you should use

soundManager.getSoundById("mySound").play()
Gokul
  • 1,236
  • 1
  • 14
  • 26
0

Here's a cleaner solution using pure javascript with the HTML5 Audio element.

/*jslint browser: true*/
/*global window */

(function () {

    'use strict';

    var _count = 10,
        _countdownTimer;
    
    function resetCounter() {
        if (_countdownTimer) {
            window.clearInterval(_countdownTimer);
        }
        _countdownTimer = null;
        _count = 10;
        document.getElementById("countdownDiv").innerText = "";
    }
  
    function startCountdown() {
              
        if (!_countdownTimer) {
          
            _countdownTimer = window.setInterval(function () {
              
                document.getElementById("countdownDiv").innerText = _count;
                _count = _count - 1;
                
                if (_count < 0) {
                    resetCounter();                  
                    document.getElementById("countdownDiv").innerText = "Beep";
                    document.getElementById("beepAudio").play();
                }
                
            }, 1000); 
          
        }
    }

    function stopCountdown() {
        resetCounter();
    }
  
    
    // Init
    document.getElementById("beepAudio").src = "http://soundbible.com/grab.php?id=1252&type=mp3";
    document.getElementById("beepAudio").load();
    
    document.getElementById("startButton").onclick = startCountdown;
    document.getElementById("stopButton").onclick = stopCountdown;
    
}());
<audio id="beepAudio"></audio>
<div>
    <input id="startButton" type="button" value="Start" />
    <input id="stopButton" type="button" value="Stop" />
    <br />
    <br />
</div>
<div id="countdownDiv"></div>
dperish
  • 1,493
  • 16
  • 27
0

You could use the tone synthesizer in this demo:

enter image description here

audioCtx = new(window.AudioContext || window.webkitAudioContext)();

show();

function show() {
  frequency = document.getElementById("fIn").value;
  document.getElementById("fOut").innerHTML = frequency + ' Hz';

  switch (document.getElementById("tIn").value * 1) {
    case 0: type = 'sine'; break;
    case 1: type = 'square'; break;
    case 2: type = 'sawtooth'; break;
    case 3: type = 'triangle'; break;
  }
  document.getElementById("tOut").innerHTML = type;

  volume = document.getElementById("vIn").value / 100;
  document.getElementById("vOut").innerHTML = volume;

  duration = document.getElementById("dIn").value;
  document.getElementById("dOut").innerHTML = duration + ' ms';
}

function beep() {
  var oscillator = audioCtx.createOscillator();
  var gainNode = audioCtx.createGain();

  oscillator.connect(gainNode);
  gainNode.connect(audioCtx.destination);

  gainNode.gain.value = volume;
  oscillator.frequency.value = frequency;
  oscillator.type = type;

  oscillator.start();

  setTimeout(
    function() {
      oscillator.stop();
    },
    duration
  );
};
frequency
<input type="range" id="fIn" min="40" max="6000" oninput="show()" />
<span id="fOut"></span><br>
type
<input type="range" id="tIn" min="0" max="3" oninput="show()" />
<span id="tOut"></span><br>
volume
<input type="range" id="vIn" min="0" max="100" oninput="show()" />
<span id="vOut"></span><br>
duration
<input type="range" id="dIn" min="1" max="5000" oninput="show()" />
<span id="dOut"></span>
<br>
<button onclick='beep();'>Play</button>

Have fun!

I got the solution from Houshalter here: How do I make Javascript beep?

You can clone and tweak the code here: Tone synthesizer demo on JS Bin

Compatible browsers:

  • Chrome mobile & desktop
  • Firefox mobile & desktop Opera mobile, mini & desktop
  • Android browser
  • Microsoft Edge browser
  • Safari on iPhone or iPad

Not Compatible

  • Internet Explorer version 11 (but does work on the Edge browser)
Community
  • 1
  • 1
CaptureWiz
  • 1,685
  • 1
  • 15
  • 15