lda #8 sta $d418 This code toggles the low bit of the output. lda #9 sta $d418Over an average of time, this is the same as:
lda #8.5 But we can't really do this. sta $d418This idea can be used to easily do 5 bit sound. Basically, we take a 5 bit sample, shift right, then add 0. If bit 0 was high, it will increment the 4 bit number. Then as this adding takes place, toggling bit 0, it will average out to give half a bit.
This is actually called pulse width modulation. It is a good example for illustrating sample dithering. For example, you can play TRUE 16 bit sound, even with one bit. To do this, take the 16 bit sample, add a 12 bit random number, then play the high 4 bits of this result. Also remember the clipping problem as mentioned above.
There are some more advanced technical issues to this. The kind of random number you choose affects the results. You need a triangle density function for perfect linearity (ie., for no distortion). This is the relationship of random numbers in the sequence, and does not affect the probability distribution, which should be equal. The choice of density function is a tradeoff between added noise and linearity. I used pulse density function in my demo, which is non-filtered random numbers, and it's ok but I can still hear some noise pumping.
Memory map: 3: start page of sample 4: end page of sample 5: sample period (remmber to play twice normal speed) fb,fc: pointer to sample start lda 3 sta $fc lda #0 sta $fb ; initialize sample pointer lda #$b sta $d011 ; blank screen for better timing sei ; disable interrupts for better timing play lda ($fb),y lsr sta $d418 ; push sample ldx 5 d dex bne d pha nop adc #0 cmp #$10 beq s1 sta $d418 bpl s s1 nop nop nop s pla ldx 5 d1 dex bne d1 iny bne play inc fc lda fc cmp 4 bne play lda #$1b sta $d011 cli end rts