- 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