- From: Chris Rogers <crogers@google.com>
- Date: Wed, 18 May 2011 13:10:46 -0700
- To: Antonio José Villena Godoy <_@antoniovillena.es>
- Cc: public-audio@w3.org
- Message-ID: <BANLkTi=W25UrFAWg_gg5wcaZUw0iUAqZ9w@mail.gmail.com>
Antonio, which platform are you running on? I've very recently (as of yesterday) landed a patch to fix Grant's GameBoy problem on the Mac, but now we need to get it working on Windows... On Wed, May 18, 2011 at 1:03 PM, Antonio José Villena Godoy <_@ antoniovillena.es> wrote: > > 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 Wednesday, 18 May 2011 20:11:12 UTC