Re: generating sound with createJavaScriptNode in an emulator

   Hello Chris

   Thank you very much for your reponse.

   1. Yes I did a litte hack rewriting the onaudioprocess function (in 
my computer the buffer doesn't change and works). In a previous version 
I did in the correct way, so fixing it sounds equal (at least in my 
computer). You can ear the bad sound by clicking the last link, and then 
pressing Enter.

   2. Sorry, I have forgotten the part that fills the "vb" array and 
init variables. This code is when Z80 outs a byte to the port. The only 
output port in ZX Spectrum is 0xFE (a0=0): bits 0..2 are for the border 
color and the important one (bit 4) is connected to the speaker.

function write_port(addr, val) {
   if( ~addr & 1 ){
     if( bor^val & 0x10 )
       vb[vbp]= flash*69888 + st,
       vbp= vbp+1 & 0xff;
     document.body.style.backgroundColor=  'rgb('
                                         + pal[(bor= val)&7].toString()
                                         + ')';
   }
}

init variables:
sample= playp= vbp= bor= 0;

   I don't want that you read and understand the code, so read only if 
you see it interestant.

   I think that the problem is in the javascript scheduler in Chrome. It 
seems that setInterval is never interrupted by the audio function.

   The emulator basically has only one process (run) called every 20ms. 
In the "run" function, it emulates 69888 cycles of Z80 (3.5MHz), paint 
the screen and generates a Z80 interrupt. Nothing else.

   There is another process, onaudioprocess, launched by 
createJavaScriptNode (not setInterval). In my case it's called every 
21.33ms (1024 samples/48000Hz).

   So I think that actually is very difficult to implement a javascript 
emulator. The other javascript emulator that I knows that implement 
html5 sound is the GBC emulator, by Grant Galitz (writes in this mailing 
list), and has the same problem.

   I have this 3 ideas for fixing it:
1. Allow pseudothreads (function called by setInterval) to be 
interrupted by onaudioprocess in Chrome.
2. Allow to choose custom sample rate.
3. Allow to choose any number of samples per buffer (not only a power of 2).

   Regards

El 18/05/11 20:47, Chris Rogers escribió:
> Hi Antonio,
>
> I can see couple of problems:
>
> 1. I notice that you're changing the "onaudioprocess" function, but in
> the first function you're setting "data".  The audio data buffer will
> change each and every callback, so you need to set "data" by calling
> getChannelData(0) again in each call to your buffer function.
>
> 2. I don't see where you're initializing the "sample" variable.  Also,
> it looks like you're doing a bit operation with "sample ^= 0x40".  The
> sample values should be floating point in a range from -1.0 -> +1.0, not
> an integer value.
>
> 3. Once you have everything else fixed, you'll probably want to increase
> the buffer size.
>
> Cheers,
> Chris
>
> On Wed, May 18, 2011 at 8:47 AM, Antonio José Villena Godoy
> <_@antoniovillena.es <http://antoniovillena.es>> wrote:
>
>
>       Hello Chris
>
>       I am new in this mailing list. My name is Antonio, I am a Spanish
>     developer. I have created this emulator:
>
>     http://jbacteria.antoniovillena.es/
>
>       I try to put sound in the emulator with this init code:
>
>     if(typeof webkitAudioContext == 'function')
>       cts= new webkitAudioContext(),
>       paso= 69888*50/cts.sampleRate,
>       node= cts.createJavaScriptNode(1024, 0, 1),
>       node.onaudioprocess= function (e){
>         data= e.outputBuffer.getChannelData(0);
>         node.onaudioprocess= buffer;
>       },
>       node.connect(cts.destination);
>
>       and the buffer function:
>
>     function buffer(e) {
>       play= flash*69888 + st - paso*1024;
>       j= 0;
>       while( j<1024 )
>         if( data[j++]= sample
>           , (play+= paso) > vb[playp] )
>           sample^= 0x40,
>           playp= playp+1 & 0xff;
>     }
>
>       But the quality of the sound is very bad. I have tried to increase
>     the buffer to 2048 and 4096 with worse result. I don't know if the
>     problem is mine or a bad Chrome implementation.
>
>       As you can see, the 48K sound is very simple, as the PC beeper. I
>     would like to implement 128K AY-8912 sound, later, if I can fix this
>     issue.
>
>       The source code is here:
>     http://jbacteria.antoniovillena.es/jBacteriaSourceCode.zip
>
>       And a game when you can hear the bad sound is for example:
>     http://jbacteria.antoniovillena.es/48?fernando
>
>       Regards (and sorry for my bad English)
>     --
>        ,       _            _       __   ___ _ _
>       /_\  _ _| |_ ___ _ _ (_)___   \ \ / (_) | |___ _ _  __ _
>       / _ \| ' \  _/ _ \ ' \| / _ \   \ V /| | | / -_) ' \/ _` |
>     /_/ \_\_||_\__\___/_||_|_\___/    \_/ |_|_|_\___|_||_\__,_|
>
>


-- 
    ,       _            _       __   ___ _ _
   /_\  _ _| |_ ___ _ _ (_)___   \ \ / (_) | |___ _ _  __ _
  / _ \| ' \  _/ _ \ ' \| / _ \   \ V /| | | / -_) ' \/ _` |
/_/ \_\_||_\__\___/_||_|_\___/    \_/ |_|_|_\___|_||_\__,_|

Received on Friday, 20 May 2011 06:57:00 UTC