Several volume mixer settings are mapped to two different mixer register
addresses: one for higher precision, and a lower precision one for
legacy reasons.
Windows 98 uses the new registers and leaves the legacy registers
untouched (which have a value of zero), but when v86 restores from a
state file, the old legacy registers are being re-written to and
incorrectly overwrites the new register values with zero.
mixer_full_update now skips over legacy register values. The new, higher
precision registers are the single source of truth and legacy register
values should be calculated from the new registers.
Fixes the Windows 98 sound demo.
Previous sb16 dma transfer size heuristic led to block sizes that were
not divisible into the two channels, resulting in the Right audio
channel missing a single sample, and samples getting mixed up between
the two channels.
This commit fixes some nasty sound distortion.
Fixes sample rate conversion problem.
Introduces new timing problems: to be fixed by letting speaker drive the
timings for dma.
Todo: reuse audio buffers - keep them in a pool.
First attempt: when pausing, clear the output buffers once using .fill(0)
during the onaudioprocess event, and set a flag so that it doesn't
have to continuously .fill(0) the buffers when paused.
Problem with first attempt: It appears that performing .fill(0) once does
not guarantee clearing all the buffer that is given to the onaudioprocess
event, probably because the output buffers given are a subarray of a larger
buffer.
In this second attempt, we simply disconnect the processor node from the
destination node, and reconnect them when unpaused.
Problem: transferring ownership of the audio Float32Array buffers from
the speaker adapter to sb16 does not appear to work.
Demo: https://jsbin.com/vilafof/edit?html,js,output
This is probably because:
> the returned AudioBuffer is only valid in the scope of the
> onaudioprocess function.
(https://developer.mozilla.org/en-US/docs/Web/API/AudioProcessingEvent)
and probably because transferring ownership will make the buffer
unreadable in the non-worker thread.
Solution: send data through to the speaker adapter directly using the
bus. The sb16.dac_buffers has been modified to allow shifting out a chunk of
consequtive elements more efficiently.
Previously, when the cpu is paused, sb16 continues to perform dma
transfers and the speaker continues to play the audio stored in the
buffer (looping), which is not what we want.
More importantly, when we pause the cpu to save the machine state,
because sb16 was continuing with its dma transfers, the machine might
restore back into a confused and muddled state.
Instead of registering an on_unmask listener every time we want a
transfer, and unregistering the listener every time we're done with it,
SB16 now registers a handler during init, and keeps this handler
registered throughout the session. The handler function is moved to SB16's
prototype.
The dma_waiting_transfer flag indicates whether the handler should
actually carry out the transfer.
- Constant variable names to uppercase.
- Consistent use of spacing and semicolons.
- Avoid recursion.
- Prefer bitwise operators.
- Place operators before line continuation (to disambiguate problems
associated with automatic semicolon insertion).
Not just working, but super smooth and crisp with no distortion.
Well, except for the wrong pitch due to a very cheap method of sampling
rate conversion. However, that's an aesthetic problem for the future.
🎉 Celebrate? 🎉
After "fixing" the dma address incrementation, the sounds are now
highly distorted with seemingly garbage signal. The dma block size is
increased to investigate this newly formed bug.
That way, speaker process samples can be large to reduce the clicking
noises, while at the same time the dma block size can be small to
improve counter accuracy.
Fix: forgot to double the sample count to get the dac size needed.
Increased DMA_BLOCK_SAMPLES to reduce distortion caused by some lag in
the scriptprocessornode