2017-09-01 8 views
0

J'ai créé un code pour générer du son morse à l'aide de l'API web audio. Le son du code Morse fonctionne parfaitement. Je voulais faire clignoter une partie de l'écran avec ce son. Il n'y a que deux sons (.) Et un tiret (-). Je voulais montrer un message en faisant clignoter une partie de l'écran. J'ai essayé de définir la couleur d'arrière-plan de div comme noir, puis masquer/montrer cette div pour donner un effet de flash. mais cela ne fonctionne pas comme expected.please me aider .... Merci à l'avance ... Je essayé ceci:Flash Partie de l'écran Avec son créé à l'aide de l'API audio web pour le code Morse (contexte audio)

$(document).ready(function() { 
 
\t var context = new (window.AudioContext || window.webkitAudioContext()); 
 
\t var O= new MorseNode(context,20); 
 
\t O.connect(context.destination); 
 
\t 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"> 
 
\t \t </div> 
 
</html>

Répondre

0

Le problème est l'endroit où vous faites l'élément la manipulation va être lancée avant que le contexte audio joue les sons. setValueAtTime() configure un événement, dans ce cas un changement de gain, à un moment donné. Vos appels hide/show ne se synchronisent pas avec ces configurations d'événements, car ils sont exécutés immédiatement, et donc ils s'exécutent avant l'audio.

Vous avez également un autre problème que vous avez exécuté hide() et show() presque juste après l'autre, cela va fondamentalement s'annuler mutuellement. Il doit y avoir un certain laps de temps avant d'appeler l'autre méthode pour que l'animation soit correctement affichée.

Ce que vous devez faire est de configurer un système de chronométrage pour exécuter le cacher/montrer au bon moment. Pour ce faire, créez un tableau contenant des objets détaillant quand commencer et terminer une opération hide/show.

var flashBlock = $('#flashBlock'); //cache this so you dont create it each time 

//in constructor 
this.flashTimes = []; 

//in playChar() 
this.flashTimes.push({ 
    timestamp:t, 
    end:t+this._dot // or t+(3*this._dot) 
}); 

Ensuite, faire une vérification constante du flux audio pour vérifier son temps, et si elle est au bon moment commencer l'opération.

MorseNode.prototype.flashLoop = function(){ 
    var ct = ac.currentTime; 
    var currentFlash = this.flashTimes[0]; 
    if(ct >= currentFlash.timestamp && ct < currentFlash.end){ 
    // remove it from the queued 
    this.flashTimes.shift(); 
    // determine how much time the animation can 
    // last between now and when it is supposed to end. 
    let duration = ac.currentTime - currentFlash.end; 

    // first argument to hide/show is duration of animation, 
    // the second is a callback to be called when animation is done 
    flashBlock.hide(duration-100,()=>{ 
     flashBlock.show(100); 
    }); 
    } 
    requestAnimationFrame(()=>this.flashLoop()); 
} 

requestAnimationFrame(()=>this.flashLoop()); 

var flashBlock = null; 
 
$(document).ready(function() { 
 
    flashBlock = $('#flashBlock'); 
 
    var context = new(window.AudioContext || window.webkitAudioContext()); 
 
    var O = new MorseNode(context, 20); 
 
    O.connect(context.destination); 
 
    O.playString(1, '.-- -.. ... - . --- .-. --.'); 
 
}); 
 

 
function MorseNode(ac, rate) { 
 
    this.flashTimes = []; 
 
    this.ac = ac; 
 
    
 
    // 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) { 
 
    switch (c) { 
 
    case '.': 
 
     this.flashTimes.push({ 
 
     timestamp: t, 
 
     end: t + this._dot 
 
     }); 
 
     this._gain.gain.setValueAtTime(1.0, t); 
 
     t += this._dot; 
 
     this._gain.gain.setValueAtTime(0.0, t); 
 
     break; 
 
    case '-': 
 
     this.flashTimes.push({ 
 
     timestamp: t, 
 
     end: t + (3 * this._dot) 
 
     }); 
 
     this._gain.gain.setValueAtTime(1.0, t); 
 
     t += 3 * this._dot; 
 
     this._gain.gain.setValueAtTime(0.0, t); 
 
     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; 
 
    } else if (w[i] != undefined) { 
 
     t = this.playChar(t, w[i]); 
 
     t += 2 * this._dot; 
 
    } 
 
    } 
 
    requestAnimationFrame(() => this.flashLoop()); 
 
    return t; 
 
} 
 

 
MorseNode.prototype.flashLoop = function() { 
 
    var ct = this.ac.currentTime; 
 
    var currentFlash = this.flashTimes[0]; 
 
    if (!currentFlash) return; 
 

 
    if (ct >= currentFlash.timestamp && ct < currentFlash.end) { 
 
    this.flashTimes.shift(); // remove it from the queued actions 
 
    let duration = this.ac.currentTime - currentFlash.end; 
 
    flashBlock.hide(duration - 100,() => { 
 
     flashBlock.show(100); 
 
    }); 
 
    } 
 
    requestAnimationFrame(() => this.flashLoop()); 
 
}
<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>

+0

Il fonctionne perfect..I apprécient votre response..Thank rapide u so much !! :) – user3357709

+0

L'animation n'était pas comme l'effet flash .. donc, j'ai modifié hide/show code dans la fonction flashloop comme "flashBlock.show(). Delay (durée) .fadeOut (-80);" ... reste du code est fonctionnant comme prévu .. merci encore :) – user3357709

+0

son et flash ne fonctionne pas simultanément. Je veux garder ce bloc qui clignote avec ce son. Si le son est en cours de lecture pendant 3 secondes, ce flash doit rester visible pendant 3 secondes, puis masquer instantanément ce bloc. help plzzzzzz – user3357709