Safari 6.0.2 does not call onaudioprocess

I've previously used JavaScriptAudioNode in the Web Audio API to synthesize and mix audio in Chrome and Safari 6.0. However, the latest version of Safari no longer works because it does not call onaudioprocess to fill the original buffers.

This is a simplified example that reproduces only silence and adds text to the body of the document every time onaudiprorocess is called:

<html>
<head>  
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript">    
$(document).ready(function() {
  $("a").click(function() {    
    var context = new webkitAudioContext(); 
    var mixerNode=context.createJavaScriptNode(2048, 0, 2);                

    mixerNode.onaudioprocess=function(ape) {                     
      var buffer=ape.outputBuffer;
      for(var s=0;s<buffer.length;s++)
      {  
        buffer.getChannelData(0)[s]=0;      
        buffer.getChannelData(1)[s]=0;       
      }
      $("body").append("buffering<br/>");
    };               

    $("body").html("");               
    mixerNode.connect(context.destination);               
    return false;
  });                                                          
});                         
</script>    
</head>  
<body>  
<a href="#">start</a>        
</body>  
</html>

      

The above example works in Chrome as expected, but not on Safari desktop. The iOS version of Safari also doesn't work, but it never worked for me in the first place.

The call to context.createJavaScriptNode returns the correct JavaScriptAudioNode object and connecting it to the target node does not throw any exceptions. context.activeSourceCount stays at zero, but this is also the case in Chrome, as it seems to only consider active nodes of type AudioBufferSourceNode. context.currentTime also increases as expected.

Am I doing something wrong here or is this a real bug or missing feature in Safari? There is no mention of JavaScriptAudioNode (or the new name ScriptProcessorNode) in Apple documentation, but it worked before in the first version of Safari 6. Requiring iOS Safari for user input does not help, as the example above should take care of that.

A simple example can be found here , and a more complex one is my Protracker module player , which demonstrates the same behavior.

+3


source to share


1 answer


There are several bugs in the Safari Web Audio API implementation that you will need. The first is in the constructor createJavaScriptNode

... it looks like with the "input channels" parameter set to 0. Try changing it to this:

createJavaScriptNode(2048, 1, 2)

      



The second problem has to do with garbage collection (I think); after your mixerNode variable goes out of scope, Safari seems to stop firing the callback onaudioprocess

. One solution is to inject mixerNode into the top level area (i.e. Declare var mixerNode;

at the top of your script) and then store your JavaScriptNode in that top level variable. If you plan to dynamically create multiple mixerNodes, you can achieve the same effect by storing references to them in a top-level array variable.

If you make these two changes (the input channel parameter is set to 1 while maintaining a link to mixerNode), then your script should work as expected in Safari.

+4


source







All Articles