I have created code to generate morse code sound using web audio api. Morse code sound is working perfect. I wanted to flash part of the screen with that sound.There are only two sounds dot(.) and dash(-). I wanted to show message by flashing part of the screen. I tried to set the background color of div as black and then hide/show that div to give flash effect. but it's not working as expected.please help me....Thanks in advance... I tried this :
$(document).ready(function() {
var context = new (window.AudioContext || window.webkitAudioContext());
var O= new MorseNode(context,20);
O.connect(context.destination);
O.playString(1,'.-- -..');
});
function MorseNode(ac, rate) {
// ac is an audio context.
this._oscillator = ac.createOscillator();
this._gain = ac.createGain();
this._gain.gain.value = 0;
this._oscillator.frequency.value = 550;
this._oscillator.connect(this._gain);
if(rate == undefined)
rate = 20;
this._dot = 1.2 / rate; // formula from Wikipedia.
this._oscillator.start(0);
}
MorseNode.prototype.connect = function(target) {
return this._gain.connect(target);
}
MorseNode.prototype.playChar = function(t, c) {
for(var i = 0; i < c.length; i++) {
switch(c[i]) {
case '.':
$('#flashBlock').hide(); //I tried this to flash the screen.
this._gain.gain.setValueAtTime(1.0, t);
t += this._dot;
this._gain.gain.setValueAtTime(0.0, t);
$('#flashBlock').show();
break;
case '-':
$('#flashBlock').hide();
this._gain.gain.setValueAtTime(1.0, t);
t += 3 * this._dot;
this._gain.gain.setValueAtTime(0.0, t);
$('#flashBlock').show();
break;
}
t += this._dot;
}
return t;
}
MorseNode.prototype.playString = function(t, w) {
w = w.toUpperCase();
for(var i = 0; i < w.length; i++) {
if(w[i] == ' ') {
t += 3 * this._dot; // 3 dots from before, three here, and
// 1 from the ending letter before.
}
else if(w[i] != undefined) {
t = this.playChar(t, w[i]);
t += 2 * this._dot;
}
}
return t;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<html>
<div id="flashBlock" style="Background:black;display:none;height:100px;width:100px">
</div>
</html>
The problem is the place where you are doing the element manipulation is going to be run before the audio context plays the sounds.
setValueAtTime()
sets up an event, in this case a gain change, to happen at a specific time. Your hide/show calls do not sync up with these event setups, since they are run right away, and so they run before the audio.You also have another problem that you ran
hide()
andshow()
nearly right after each other, this is going to basically cancel each other out. There needs to be a certain amount of time to have lapsed before calling the other method in order for the animation to render properly.What you will need to do is setup a timing system to execute the hide / show at the right times.
One way you can achieve this by creating an array that has objects detailing when to start and end a hide / show operation.
Then do a constant check of the audio stream to check its time, and if it is at the right time start the operation.