Text To Speech issue - javascript

Relates specifically to one event: SpeechSynthesisUtterance.onboundry
Wasted so much time with window.speechSynthesis. CanIUse states that SpeechSynthesisUtterance.onboundry is supported in Chrome for Android, but the event never fires. Tried many examples online. Has anyone been able to get this event working on Android Chrome? BTW, the event fires perfectly on Desktop. I would even resort to a plugin to solve this if anybody knows of one? Any help would be appreciated
function playAudio() {
var msg = new SpeechSynthesisUtterance('Help me with this code please?');
msg.pitch = 0;
msg.rate = .6;
window.speechSynthesis.speak(msg);
var msg = new SpeechSynthesisUtterance();
var voices = window.speechSynthesis.getVoices();
msg.voice = voices[10]; // Note: some voices don't support altering params
msg.voiceURI = 'native';
msg.volume = 1; // 0 to 1
msg.rate = 1.2; // 0.1 to 10
msg.pitch = 2; //0 to 2
msg.text = 'Sure. This code plays "Hello World" for you';
msg.lang = 'en-US';
msg.onend = function (e) {
var msg1 = new SpeechSynthesisUtterance('Now code plays audios for you');
msg1.voice = speechSynthesis.getVoices().filter(function (voice) { return voice.name == 'Whisper'; })[0];
msg1.pitch = 2; //0 to 2
msg1.rate = 1.2; //0 to 2
// start your audio loop.
speechSynthesis.speak(msg1);
console.log('Finished in ' + e.elapsedTime + ' seconds.');
};
msg.onboundary = function (event) {
/* Never fires on Chrome for Android, but fires on Windows 10 Desktop Chrome */
document.body.style.backgroundColor = "red";
}
speechSynthesis.speak(msg);
}

Related

Removing console.log Breaks Code with Web Audio API

I'm playing with the Web Audio API and using this code:
function playTones(startFreq, numNotes) {
if (numNotes === 0) return;
var osc = AC.createOscillator();
osc.frequency.value = startFreq;
osc.onended = function() {
playTones(startFreq + 20, numNotes-1);
};
console.log(osc.onended);
osc.connect(AC.destination);
osc.start();
osc.stop(AC.currentTime + 1);
}
It's just supposed to play a series of notes, each one 20Hz higher than the previous. However, when I remove the console.log it doesn't work; it only plays the first note and then stops with the onended callback never being called. Why would this happen? Thanks for any and all help.
Hey you could try this:
var AC = new AudioContext();
function playTones(startFreq, numNotes) {
if (numNotes === 0) return;
var osc = AC.createOscillator();
osc.frequency.value = startFreq;
// console.log(osc.onended);
osc.connect(AC.destination);
osc.start();
osc.stop(AC.currentTime + 1);
setTimeout(function(){playTones(startFreq+20,10)},1000);
}
playTones(200, 10);

How can I get an AudioBufferSourceNode's current time?

When working with audio elements (<audio>) or contexts(AudioContext), you can check their currentTime property to know exactly the play time of your buffer.
All of this is fine an dandy until I created multiple sources (or AudioBufferSourceNode) in a single AudioContext.
The sources could be played at different times, therefore I would need to know their corresponding currentTime's, to illustrate:
Some base code for you to work off:
buffer1 = [0,1,0]; //not real buffers
buffer2 = [1,0,1];
ctx = new AudioContext();
source1 = ctx.createBufferSourceNode();
source1.buffer = buffer1;
source1.connect(ctx.destination);
source1.start(0);
source2 = ctx.createBufferSourceNode();
source2.buffer = buffer2;
source2.connect(ctx.destination);
setTimeout(1000/*some time later*/){
source2.start(0);
}
setTimeout(1500/*some more time later*/){
getCurrentTime();
}
function getCurrentTime(){
/* magic */
/* more magic */
console.log("the sources currentTime values are obviously 1500 (source1) and 500 (source2).");
}
What I usually do is create a wrapper for the audio source node that keeps track of the playback state. I've tried to minimise the code below to show the basics.
The core idea is to keep track of the time the sound is started and the time the sound is 'paused' and use those values to get the current time and to resume playback from the paused position.
I put a working example on codepen
function createSound(buffer, context) {
var sourceNode = null,
startedAt = 0,
pausedAt = 0,
playing = false;
var play = function() {
var offset = pausedAt;
sourceNode = context.createBufferSource();
sourceNode.connect(context.destination);
sourceNode.buffer = buffer;
sourceNode.start(0, offset);
startedAt = context.currentTime - offset;
pausedAt = 0;
playing = true;
};
var pause = function() {
var elapsed = context.currentTime - startedAt;
stop();
pausedAt = elapsed;
};
var stop = function() {
if (sourceNode) {
sourceNode.disconnect();
sourceNode.stop(0);
sourceNode = null;
}
pausedAt = 0;
startedAt = 0;
playing = false;
};
var getPlaying = function() {
return playing;
};
var getCurrentTime = function() {
if(pausedAt) {
return pausedAt;
}
if(startedAt) {
return context.currentTime - startedAt;
}
return 0;
};
var getDuration = function() {
return buffer.duration;
};
return {
getCurrentTime: getCurrentTime,
getDuration: getDuration,
getPlaying: getPlaying,
play: play,
pause: pause,
stop: stop
};
}
Old thread (and very useful! thanks!) , but maybe worth mentioning that in the example above instead of
function update() {
window.requestAnimationFrame(update);
info.innerHTML = sound.getCurrentTime().toFixed(1) + '/' + sound.getDuration().toFixed(1);
}
update();
it may be more precise and less resource intensive to use a createScriptProcessor
like explained in this post
const audioBuffer = await audioContext.decodeAudioData(response.data);
const chan = audioBuffer.numberOfChannels;
const scriptNode = audioContext.createScriptProcessor(4096, chan, chan);
scriptNode.connect(audioContext.destination);
scriptNode.onaudioprocess = (e) => {
// ---> audio loop <----
};
[Update]
Note: As of the August 29 2014 Web Audio API spec publication, this feature has been marked as deprecated, and was replaced by AudioWorklet (see AudioWorkletNode). https://developers.google.com/web/updates/2017/12/audio-worklet

JS mini-game in grid, browser frozen after first replication

I'm trying to create a small game that replicate neighbors cells in a grid. I use a web worker that draw replicate cells every seconds. I'm able to replicate the first second. If my initial cell is row3col3, the new replicated cells will be :
row3col2, row3col4
row2col3, row4col3
The problem is, after the first second (and the replication), the game freezes, and i'm not able to do something. Can't click on cells, etc.
EDIT : After few seconds, it go to '00:02' but Chrome crashed "Aw, Snap! Something went wrong...' [RELOAD]
EDIT 2 : After looking on the memory used, It appears I have an memory overflow, 16000 Mb ! My method is bad, so.
I know my code is not really optimised, and I think that is the problem. Unfortunatly, i'm not able to do more efficient code, so I ask some help to you guys, to give me some ways to explore.
Here the code :
var lastClicked;
var cellTab = Array();
var replicant = Array();
var newReplicant = Array();
var count = 5;
var rows = 20;
var cols = 20;
var randomRow = Math.floor((Math.random() * rows));
var randomCol = Math.floor((Math.random() * cols));
var grid = clickableGrid(rows, cols,randomRow,randomCol,cellTab, function(el,row,col,i){
console.log("You clicked on element:",el);
console.log("You clicked on row:",row);
console.log("You clicked on col:",col);
console.log("You clicked on item #:",i);
$(el).addClass('clicked');
lastClicked = el;
});
document.getElementById("game").appendChild(grid);
function clickableGrid( rows, cols, randomRow, randomCol, cellTab, callback ){
var i=0;
var grid = document.createElement('table');
grid.className = 'grid';
for (var r=0;r<rows;++r){
var tr = grid.appendChild(document.createElement('tr'));
for (var c=0;c<cols;++c){
var cell = tr.appendChild(document.createElement('td'));
$(cell).addClass('row'+r+'col'+c);
if(randomCol == c && randomRow == r)
{
storeCoordinate(r, c, replicant);
$(cell).css('background', '#000000');
}
storeCoordinate(r, c, cellTab);
cell.addEventListener('click',(function(el,r,c,i){
return function(){
callback(el,r,c,i);
}
})(cell,r,c,i),false);
}
}
return grid;
}
function storeCoordinate(xVal, yVal, array)
{
array.push({x: xVal, y: yVal});
}
function replicate(replicant)
{
for (var i = 0; i < replicant.length; i++) {
console.log(replicant);
var supRowX = replicant[i].x-1;
var supRowY = replicant[i].y;
storeCoordinate(supRowX, supRowY, newReplicant);
var subRowX = replicant[i].x+1;
var subRowY = replicant[i].y;
storeCoordinate(subRowX, subRowY, newReplicant);
var supColsX = replicant[i].x;
var supColsY = replicant[i].y-1;
storeCoordinate(supColsX, supColsY, newReplicant);
var subColsX = replicant[i].x;
var subColsY = replicant[i].y+1;
storeCoordinate(subColsX, subColsY, newReplicant);
}
}
function drawReplicant(replicant, cellTab)
{
for (var i = 0; i < replicant.length; i++) {
if($.inArray(replicant[i], cellTab))
{
$('.row'+replicant[i].x+'col'+replicant[i].y).css('background', '#000000');
}
}
}
var w = null; // initialize variable
// function to start the timer
function startTimer()
{
// First check whether Web Workers are supported
if (typeof(Worker)!=="undefined"){
// Check whether Web Worker has been created. If not, create a new Web Worker based on the Javascript file simple-timer.js
if (w==null){
w = new Worker("w.countdown.js");
}
// Update timer div with output from Web Worker
w.onmessage = function (event) {
document.getElementById("timer").innerHTML = event.data;
console.log(event.data);
replicate(replicant);
replicant = newReplicant;
drawReplicant(replicant, cellTab);
};
} else {
// Web workers are not supported by your browser
document.getElementById("timer").innerHTML = "Sorry, your browser does not support Web Workers ...";
}
}
// function to stop the timer
function stopTimer()
{
w.terminate();
timerStart = true;
w = null;
}
startTimer();
And here, the web worker :
var timerStart = true;
function myTimer(d0)
{
// get current time
var d=(new Date()).valueOf();
// calculate time difference between now and initial time
var diff = d-d0;
// calculate number of minutes
var minutes = Math.floor(diff/1000/60);
// calculate number of seconds
var seconds = Math.floor(diff/1000)-minutes*60;
var myVar = null;
// if number of minutes less than 10, add a leading "0"
minutes = minutes.toString();
if (minutes.length == 1){
minutes = "0"+minutes;
}
// if number of seconds less than 10, add a leading "0"
seconds = seconds.toString();
if (seconds.length == 1){
seconds = "0"+seconds;
}
// return output to Web Worker
postMessage(minutes+":"+seconds);
}
if (timerStart){
// get current time
var d0=(new Date()).valueOf();
// repeat myTimer(d0) every 100 ms
myVar=setInterval(function(){myTimer(d0)},1000);
// timer should not start anymore since it has been started
timerStart = false;
}
Maybe it's because I use jQuery ?

How to make motherboard beep via javascript? [duplicate]

I want my web page to beep whenever a user exceeds the maximum character limit of my <textarea>.
Solution
You can now use base64 files to produce sounds when imported as data URI. The solution is almost the same as the previous ones, except you do not need to import an external audio file.
function beep() {
var snd = new Audio("data:audio/wav;base64,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qJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=");
snd.play();
}
beep();
Compatibility
Data URI is supported on almost every browser now. More information on http://caniuse.com/datauri
Demo
http://jsfiddle.net/7EAgz/
Conversion Tool
And here is where you can convert mp3 or wav files into Data URI format:
https://dopiaza.org/tools/datauri/index.php
It's not possible to do directly in JavaScript. You'll need to embed a short WAV file in the HTML, and then play that via code.
An Example:
<script>
function PlaySound(soundObj) {
var sound = document.getElementById(soundObj);
sound.Play();
}
</script>
<embed src="success.wav" autostart="false" width="0" height="0" id="sound1"
enablejavascript="true">
You would then call it from JavaScript code as such:
PlaySound("sound1");
This should do exactly what you want - you'll just need to find/create the beep sound yourself, which should be trivial.
/*if you want to beep without using a wave file*/
var context = new AudioContext();
var oscillator = context.createOscillator();
oscillator.type = "sine";
oscillator.frequency.value = 800;
oscillator.connect(context.destination);
oscillator.start();
// Beep for 500 milliseconds
setTimeout(function () {
oscillator.stop();
}, 100);
The top answer was correct at the time but is now wrong; you can do it in pure javascript. But the one answer using javascript doesn't work any more, and the other answers are pretty limited or don't use pure javascript.
I made my own solution that works well and lets you control the volume, frequency, and wavetype.
//if you have another AudioContext class use that one, as some browsers have a limit
var audioCtx = new (window.AudioContext || window.webkitAudioContext || window.audioContext);
//All arguments are optional:
//duration of the tone in milliseconds. Default is 500
//frequency of the tone in hertz. default is 440
//volume of the tone. Default is 1, off is 0.
//type of tone. Possible values are sine, square, sawtooth, triangle, and custom. Default is sine.
//callback to use on end of tone
function beep(duration, frequency, volume, type, callback) {
var oscillator = audioCtx.createOscillator();
var gainNode = audioCtx.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
if (volume){gainNode.gain.value = volume;}
if (frequency){oscillator.frequency.value = frequency;}
if (type){oscillator.type = type;}
if (callback){oscillator.onended = callback;}
oscillator.start(audioCtx.currentTime);
oscillator.stop(audioCtx.currentTime + ((duration || 500) / 1000));
};
Someone suggested I edit this to note it only works on some browsers. However Audiocontext seems to be supported on all modern browsers, as far as I can tell. It isn't supported on IE, but that has been discontinued by Microsoft. If you have any issues with this on a specific browser please report it.
I wrote a function to beep with the new Audio API.
var beep = (function () {
var ctxClass = window.audioContext ||window.AudioContext || window.AudioContext || window.webkitAudioContext
var ctx = new ctxClass();
return function (duration, type, finishedCallback) {
duration = +duration;
// Only 0-4 are valid types.
type = (type % 5) || 0;
if (typeof finishedCallback != "function") {
finishedCallback = function () {};
}
var osc = ctx.createOscillator();
osc.type = type;
//osc.type = "sine";
osc.connect(ctx.destination);
if (osc.noteOn) osc.noteOn(0); // old browsers
if (osc.start) osc.start(); // new browsers
setTimeout(function () {
if (osc.noteOff) osc.noteOff(0); // old browsers
if (osc.stop) osc.stop(); // new browsers
finishedCallback();
}, duration);
};
})();
jsFiddle.
Using Houshalter's suggestion, I made this simple tone synthesizer demo.
Screenshot
Here is a screenshot. Try the live demo further down in this Answer (click Run code snippet).
Demo code
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>
You can clone and tweak the code here:
Tone synthesizer demo on JS Bin
Have fun!
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)
This will enable you to play the sound multiple times, in contrast to the top-voted answer:
var playSound = (function beep() {
var snd = new Audio("data:audio/wav;base64,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qJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=");
return function() {
snd.play();
}
})();
playSound(); // Play first time
playSound(); // Play second time
As we read in this answer, HTML5 will solve this for you if you're open to that route. HTML5 audio is supported in all modern browsers.
Here's a copy of the example:
var snd = new Audio("file.wav"); // buffers automatically when created
snd.play();
Now it easy enough with JavaScript AudioContext API. It fully supported by major desktop and mobile web browsers...
let context = null;
const beep = (freq = 520, duration = 200, vol = 100) => {
const oscillator = context.createOscillator();
const gain = context.createGain();
oscillator.connect(gain);
oscillator.frequency.value = freq;
oscillator.type = "square";
gain.connect(context.destination);
gain.gain.value = vol * 0.01;
oscillator.start(context.currentTime);
oscillator.stop(context.currentTime + duration * 0.001);
}
document.querySelector('button').addEventListener('click', function () {
context = new AudioContext();
beep();
});
I wrote a small application that plays music from the Mario game without any audio file, just runtime. In my opinion it’s interesting, you can see the source code and listen it.
Using CSS you can do it if you add the following style to a tag, but you will need a wav file:
<style type="text/css">
.beep {cue: url("beep.wav") }
</style>
var body=document.getElementByTagName("body");
body.className=body.className + " " + "beep";
Here's how I get it to beep using HTML5:
First I copy and convert the windows wav file to mp3, then I use this code:
var _beep = window.Audio("Content/Custom/Beep.mp3")
function playBeep() { _beep.play()};
It's faster to declare the sound file globally and refer to it as needed.
This code supports sequencing of multiple beeps, as well as gradual change in frequency ('ramp' flag). Both examples are given below.
<script>
var audioContext = null;
var oscillatorNode = null;
var stopTime = 0;
function beep (frequency, durationSec, ramp=false)
{
if (oscillatorNode == null) {
audioContext = new (window.AudioContext || window.webkitAudioContext) ();
stopTime = audioContext.currentTime;
oscillatorNode = audioContext.createOscillator();
oscillatorNode.type = "sine";
oscillatorNode.connect (audioContext.destination);
if (ramp) {
oscillatorNode.frequency.setValueAtTime (frequency, stopTime);
}
oscillatorNode.start ();
oscillatorNode.onended = function() {
oscillatorNode = null;
audioContext = null;
}
}
if (ramp) {
oscillatorNode.frequency.linearRampToValueAtTime (frequency, stopTime); // value in hertz
} else {
oscillatorNode.frequency.setValueAtTime (frequency, stopTime); // value in hertz
}
stopTime += durationSec;
oscillatorNode.stop (stopTime);
}
function test1()
{
beep (250, 0.5);
beep (1000, 0.2);
beep (550, 0.5);
}
function test2()
{
beep (50, 2, true);
beep (5000, 2, true);
beep (50, 0, true);
}
</script>
<button onclick='test1()'>Beep!</button>
<button onclick='test2()'>Beep(ramped)!</button>
There's no crossbrowser way to achieve this with pure javascript. Instead you could use a small .wav file that you play using embed or object tags.
function beep(wavFile){
wavFile = wavFile || "beep.wav"
if (navigator.appName == 'Microsoft Internet Explorer'){
var e = document.createElement('BGSOUND');
e.src = wavFile;
e.loop =1;
document.body.appendChild(e);
document.body.removeChild(e);
}else{
var e = document.createElement('AUDIO');
var src1 = document.createElement('SOURCE');
src1.type= 'audio/wav';
src1.src= wavFile;
e.appendChild(src1);
e.play();
}
}
Works on Chrome,IE,Mozilla using Win7 OS.
Requires a beep.wav file on the server.
function Sound(url, vol, autoplay, loop)
{
var that = this;
that.url = (url === undefined) ? "" : url;
that.vol = (vol === undefined) ? 1.0 : vol;
that.autoplay = (autoplay === undefined) ? true : autoplay;
that.loop = (loop === undefined) ? false : loop;
that.sample = null;
if(that.url !== "")
{
that.sync = function(){
that.sample.volume = that.vol;
that.sample.loop = that.loop;
that.sample.autoplay = that.autoplay;
setTimeout(function(){ that.sync(); }, 60);
};
that.sample = document.createElement("audio");
that.sample.src = that.url;
that.sync();
that.play = function(){
if(that.sample)
{
that.sample.play();
}
};
that.pause = function(){
if(that.sample)
{
that.sample.pause();
}
};
}
}
var test = new Sound("http://mad-hatter.fr/Assets/projects/FreedomWings/Assets/musiques/freedomwings.mp3");
test.play();
http://jsfiddle.net/sv9j638j/
Note:put this code in your javascript at the point you want the beep to occur.
and remember to specify the directory or folder where the beep sound is stored(source).
<script>
//Appending HTML5 Audio Tag in HTML Body
$('<audio id="chatAudio"><source src="sound/notify.ogg" type="audio/ogg"><source src="sound/notify.mp3" type="audio/mpeg"><source src="sound/notify.wav" type="audio/wav"></audio>').appendTo('body');
$('#chatAudio')[0].play();
</script>
Reference:http://www.9lessons.info/2013/04/play-notification-sound-using-jquery.html.
I implemented this in a social media i am developing and it works find, a notification like that of facebook when chatting, notifying you that you have a new chat message
<html>
<head>
<script src='https://surikov.github.io/webaudiofont/npm/dist/WebAudioFontPlayer.js'></script>
<script src='https://surikov.github.io/webaudiofontdata/sound/0000_JCLive_sf2_file.js'></script>
<script>
var selectedPreset=_tone_0000_JCLive_sf2_file;
var AudioContextFunc = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContextFunc();
var player=new WebAudioFontPlayer();
player.loader.decodeAfterLoading(audioContext, '_tone_0000_JCLive_sf2_file');
</script>
</head>
<body>
<p>Play a note</p>
<hr/>
<p>source</p>
</body>
listen here
https://jsbin.com/lamidog/1/edit?html,output
function beep(freq = 660, duration = 90, vol = 50) {
var context = new(window.AudioContext || window.webkitAudioContext);
const oscillator = context.createOscillator();
const gain = context.createGain();
gain.gain.setValueAtTime(0, context.currentTime);
gain.gain.linearRampToValueAtTime(1, context.currentTime + 0.002);
oscillator.connect(gain);
oscillator.frequency.value = freq;
oscillator.type = "square";
gain.connect(context.destination);
oscillator.start(context.currentTime);
oscillator.stop(context.currentTime + duration * .001);
oscillator.onended = () => context.close();
}
<br>
<center><button onclick="beep()">Beep!</button></center>
You need a sound file to be served from somewhere. Here's the code from Scriptaculous's Sound library:
//Default:
<embed style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>
//For Gecko:
if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){
if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 }))
Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>');
else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('Windows Media') != -1 }))
Sound.template = new Template('<object id="sound_#{track}_#{id}" type="application/x-mplayer2" data="#{url}"></object>');
else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('RealPlayer') != -1 }))
Sound.template = new Template('<embed type="audio/x-pn-realaudio-plugin" style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>');
else
Sound.play = function(){};
}

Javascript only works in IE Quirks, 7 and Chrome and Firefox. Doesn't work in IE 8 or 9 Standards

My code makes a number of divisions appear to orbit around an invisible horizontal axis on a plane. How it works: it fires a mouseevent listener onMouseDown, and captures the X of the user's cursor relative to the window. onMouseUp is simulated by a setTimeout function that is called 90 milliseconds later, it does the same and then subtracts the two values to determine the distance and direction to spin.
My question is: Why does it work correctly in FF, Chrome, and IE Quirks and IE 7 Standards, but not IE 8 Standards or IE 9 Standards?
IE8: the model breaks down and the divisons float away outside the containing boundary division. IE9: No response from the JS whatsoever.
The following contains the entire javascript on the page, which can be found # http://electrifiedpulse.com/360.html :
<script type=text/javascript>
var objectCount = 8; var pixel = new Array(); var size = new Array();
var command = "Stop"; var panel = new Array('0','Back','Front','Front','Back','Front','Back','Front','Back');
var quadrant = new Array(); var originalSize = 50;
var WindowWidth = 360; var WindowWidthHalf = WindowWidth/2; var sTime=0; var s1=0; var scrollSpeed;
var myX, myY;
function myMove(evt) {
if (window.event){myX = event.clientX;myY = event.clientY;}
else{myX = evt.clientX;myY = evt.clientY;}
}
document.onmousemove = myMove;
if (!window.event) {document.captureEvents(Event.MOUSEMOVE);}
function iScrollStop(){
sTime = sTime - 10;
document.getElementById('I_CONTROLS').innerHTML = sTime + ", " + scrollSpeed;
if(sTime<=0) command = "Stop";
else setTimeout(function(){iScrollStop()},10);
}
function iScrollPause(){
setTimeout(function(){this.checkPause()},100);
this.checkPause = function(){if(s1>sTime){command="Stop"; sTime=0; s1=0;}}
}
var iInitialX; //var d='Up';
function iScrollListen(d){
if(d=='Down'){ iInitialX = myX; setTimeout(function(){iScrollListen('Up')},90); iScrollPause();
}else if(d=='Up'){
var spinDirection = 'Right';
var iDifference = myX - iInitialX; if(iDifference < 0){ spinDirection = 'Left'; iDifference = Math.abs(iDifference);}
if (command!=spinDirection){sTime=0;s1=0;} var doScroll=0; if(command=='Stop') doScroll=1;
command = spinDirection; s1=sTime; sTime+=(iDifference*15); if(s1<=0)iScrollStop();
if(doScroll==1) iScroll();
}
}
function iScrollControl(c){command = c; if((c=='Left')||(c=='Right')) iScroll();}
function iScroll(){
scrollSpeed=(sTime<=1)? 1 : Math.ceil(sTime/1000);
if(scrollSpeed>=10)scrollSpeed=10;
scrollSpeed = 15 - scrollSpeed;
if(command=='Left') pixelDirection=2;
else if(command=='Right') pixelDirection=(0-2);
pixelDirectionNeg = (0-pixelDirection);
for(i=1;i<=objectCount;i++){
iObj = document.getElementById("iObject" + i);
pixel[i] = iObj.offsetLeft;
if((pixel[i]>=WindowWidthHalf)&&(pixel[i]<=WindowWidth)){
if(panel[i]=="Front") quadrant[i] = 4;
else quadrant[i] = 3;
}
if((pixel[i]>=0)&&(pixel[i]<=WindowWidthHalf)){
if(panel[i]=="Front") quadrant[i] = 1;
else quadrant[i] = 2;
}
if(quadrant[i]==1){
iObj.style.left = pixel[i]-pixelDirection;
size[i] = (pixel[i]-pixelDirection)*(1/(WindowWidthHalf/(originalSize/2))) + (originalSize/2);
Attribute(iObj,size[i]);
if(pixel[i]-pixelDirection<=0){quadrant[i]=2; panel[i]='Back';}
if(pixel[i]-pixelDirection>=WindowWidthHalf){quadrant[i]=4; panel[i]='Front';}
}
if(quadrant[i]==2){
iObj.style.left = pixel[i]-pixelDirectionNeg;
size[i] = (pixel[i]-pixelDirectionNeg)*(-1/(WindowWidthHalf/(originalSize/2))) + (originalSize/2);
Attribute(iObj,size[i]);
if(pixel[i]-pixelDirectionNeg<=0){quadrant[i]=1; panel[i]='Front';}
if(pixel[i]-pixelDirectionNeg>=WindowWidthHalf){quadrant[i]=3; panel[i]='Back';}
}
if(quadrant[i]==3){
iObj.style.left = pixel[i]-pixelDirectionNeg;
size[i] = (WindowWidth-(pixel[i]-pixelDirectionNeg))*(-1/(WindowWidthHalf/(originalSize/2))) + (originalSize/2);
Attribute(iObj,size[i]);
if(pixel[i]-pixelDirectionNeg<=WindowWidthHalf){quadrant[i]=2; panel[i]='Back';}
if(pixel[i]-pixelDirectionNeg>=WindowWidth){quadrant[i]=4; panel[i]='Front';}
}
if(quadrant[i]==4){
iObj.style.left = pixel[i]-pixelDirection;
size[i] = (WindowWidth-(pixel[i]-pixelDirection))*(1/(WindowWidthHalf/(originalSize/2))) + (originalSize/2);
Attribute(iObj,size[i]);
if(pixel[i]-pixelDirection<=WindowWidthHalf){quadrant[i]=1; panel[i]='Front';}
if(pixel[i]-pixelDirection>=WindowWidth){quadrant[i]=3; panel[i]='Back';}
}
}
if((command=='Left')||(command=='Right')) setTimeout(function(){iScroll()},scrollSpeed);
}
function Attribute(iObj,s){
iObj.style.width = s; iObj.style.height = s; iObj.style.top='50%'; iObj.style.marginTop = (0-(s/2))+"px"; iObj.style.zIndex = s;
}
</script>
I don't know what may or may not be relevant to you, so I included the entire script. If you want you could ignore the longest function,
iScroll()
#RyanStortz. Try to register events in this maner:
var isMouseCaptured=false;
function i_boundary_mousedown(ev) {
isMouseCaptured=true;
iScrollListen("Down");
}
function doc_mousemove(ev) {
if(isMouseCaptured) {
ev=ev||event;
myX=ev.clientX;
myY=ev.clientY;
}
}
function doc_mouseup(ev) {
if(isMouseCaptured) {
isMouseCaptured=false;
ev=ev||event;
myX=ev.clientX;
myY=ev.clientY;
}
}
var i_boundaryObj=document.getElementById('I_BOUNDARY');
if(window.addEventListener) {
i_boundaryObj.addEventListener('mousedown',i_boundary_mousedown,false);
document.addEventListener('mousemove',doc_mousemove,false);
document.addEventListener('mouseup',doc_mouseup,false)
}
else if(window.attachEvent) {
i_boundaryObj.attachEvent('onmousedown',i_boundary_mousedown)
document.attachEvent('onmousemove',doc_mousemove);
document.attachEvent('onmouseup',doc_mouseup)
}
else ;//
Add for DIV with class "I_BOUNDARY" id attribute "I_BOUNDARY" and remove onmousedown attribute.

Categories

Resources