-
Notifications
You must be signed in to change notification settings - Fork 4
optimisations dmg audio
currently there's 2 main components of dmg audio that gets regularly clocked.
- 4 psg channels
- frame sequencer
these are currently on the scheduler.
the psg channels get clocked at a variable rate and can be disabled.
the min clock rates are:
- square: 16 cycles
((2048 - 2047) * 16)
- wave: 8 cycles
((2048 - 2047) * 8)
- noise: 32 cycles
(divisor_code = 0, clock shift = 0) = (8 * 4)
these are pretty often. although clocking the wave and square are cheap, it's still expensive to enter the scheduler fire loop and then re-sort and re-add events as well as the function pointer overhead.
NOTE: the frame sequencer is clocked at a fixed rate of 32768
clocks, which is not very frequent, so it does not need further optimising.
the idea is simple, clock the channel on sample.
eg, the frontend wants to sample at 48000, so we do 16853760 / 48000 = 351
.
so every 351 samples, we clock all 4 channels and then generate a sample.
in order to keep track of the time, on trigger, save the scheduler time, then on sample, do current_scheulder_time - old_scheulder_time = diff
and diff will be the number of cycles to clock the channels for!
an exception to this is on scheduler overflow event which resets the scheduler timer to prevent an overflow happening. i just simply need to apply the adjusted time to the apu channels.
(this is very similar to my timer code!)
first, aliasing!
huge amounts of aliasing, but i have long accepted that me and math don't get along so getting perfect sounding audio just isn't possible for me.
secondly, sweep(?)
sweep adjusts the clock rate of channel 1, this may effect the timing slightly.