precalc vera freq to not use floating point math anymore

This commit is contained in:
Irmen de Jong 2022-07-02 19:28:24 +02:00
parent 223b725a10
commit f8658f6afa
3 changed files with 48 additions and 91 deletions

View File

@ -23,10 +23,10 @@ psg {
; ; this would rely on floating point math to convert hertz to vera frequency ; ; this would rely on floating point math to convert hertz to vera frequency
; ; TODO should be replaced by integer math maybe with a lookup table? ; ; TODO should be replaced by integer math maybe with a lookup table?
; uword vera_freq = (hertz / 0.3725290298461914) as uword ; uword vera_freq = (hertz / 0.3725290298461914) as uword
; freq_vera(voice_num, vera_freq) ; freq(voice_num, vera_freq)
; } ; }
sub freq_vera(ubyte voice_num, uword vera_freq) { sub freq(ubyte voice_num, uword vera_freq) {
cx16.vpoke(1, $f9c1 + voice_num*4, msb(vera_freq)) cx16.vpoke(1, $f9c1 + voice_num*4, msb(vera_freq))
cx16.vpoke(1, $f9c0 + voice_num*4, lsb(vera_freq)) cx16.vpoke(1, $f9c0 + voice_num*4, lsb(vera_freq))
} }
@ -53,47 +53,49 @@ psg {
} }
sub silent() { sub silent() {
ubyte voice for cx16.r9L in 0 to 15 {
for voice in 0 to 15 { volume(cx16.r9L, 0)
volume(voice, 0) envelope_volumes[cx16.r9L] = 0
envelope_volumes[voice] = 0 envelope_states[cx16.r9L] = 1
envelope_states[voice] = 1
} }
} }
sub envelopes_irq() { sub envelopes_irq() {
ubyte vera_ctrl = cx16.VERA_CTRL ; cx16.r0 = the volume word (volume scaled by 256)
ubyte vera_addr_h = cx16.VERA_ADDR_H ; cx16.r15L = the voice number
ubyte vera_addr_m = cx16.VERA_ADDR_M ; the other virtual registers are used to backup vera registers.
ubyte vera_addr_l = cx16.VERA_ADDR_L
uword vol_word cx16.r13L = cx16.VERA_CTRL
ubyte voice cx16.r13H = cx16.VERA_ADDR_L
for voice in 0 to 15 { cx16.r14L = cx16.VERA_ADDR_M
if envelope_states[voice] { cx16.r14H = cx16.VERA_ADDR_H
for cx16.r15L in 0 to 15 {
if envelope_states[cx16.r15L] {
; release ; release
vol_word = envelope_volumes[voice] - envelope_releases[voice] cx16.r0 = envelope_volumes[cx16.r15L] - envelope_releases[cx16.r15L]
if msb(vol_word) & %11000000 { if msb(cx16.r0) & %11000000 {
vol_word = 0 cx16.r0 = 0
envelope_releases[voice] = 0 envelope_releases[cx16.r15L] = 0
} }
envelope_volumes[voice] = vol_word envelope_volumes[cx16.r15L] = cx16.r0
volume(voice, msb(vol_word)) volume(cx16.r15L, msb(cx16.r0))
} else { } else {
; attack ; attack
vol_word = envelope_volumes[voice] + envelope_attacks[voice] cx16.r0 = envelope_volumes[cx16.r15L] + envelope_attacks[cx16.r15L]
if msb(vol_word) & %11000000 or envelope_attacks[voice]==0 { if msb(cx16.r0) & %11000000 or envelope_attacks[cx16.r15L]==0 {
vol_word = mkword(63, 0) cx16.r0 = mkword(63, 0)
envelope_attacks[voice] = 0 envelope_attacks[cx16.r15L] = 0
envelope_states[voice] = 1 ; start release envelope_states[cx16.r15L] = 1 ; start release
} }
envelope_volumes[voice] = vol_word envelope_volumes[cx16.r15L] = cx16.r0
volume(voice, msb(vol_word)) volume(cx16.r15L, msb(cx16.r0))
} }
} }
cx16.VERA_CTRL = vera_ctrl cx16.VERA_CTRL = cx16.r13L
cx16.VERA_ADDR_L = vera_addr_l cx16.VERA_ADDR_L = cx16.r13H
cx16.VERA_ADDR_M = vera_addr_m cx16.VERA_ADDR_M = cx16.r14L
cx16.VERA_ADDR_H = vera_addr_h cx16.VERA_ADDR_H = cx16.r14H
} }
ubyte[16] envelope_states ubyte[16] envelope_states

View File

@ -3,7 +3,9 @@ TODO
For next release For next release
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
... - optimize msb(cx16.r0) -> cx16.r0H, lsb(cx16.r0) -> cx16.r0L
- convert the sounds in cx16 tehtriz to use the psg module instead
- notify petaxian that it could use the psg module too?
Need help with Need help with
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^

View File

@ -1,6 +1,5 @@
%import textio %import textio
%import syslib %import syslib
%import floats
%import psg %import psg
main { main {
@ -20,18 +19,16 @@ main {
for note in notes { for note in notes {
ubyte note0 = lsb(note) ubyte note0 = lsb(note)
ubyte note1 = msb(note) ubyte note1 = msb(note)
psg.freq_vera(0, vera_freq(note0)) psg.freq(0, vera_freqs[note0])
psg.freq_vera(1, vera_freq(note1)) psg.freq(1, vera_freqs[note1])
psg.envelope(0, 255, 6) psg.envelope(0, 255, 6)
psg.envelope(1, 255, 6) psg.envelope(1, 255, 6)
print_notes(note0, note1) print_notes(note0, note1)
sys.wait(10) sys.wait(10)
} }
} }
}
sub vera_freq(ubyte note) -> uword { psg.silent()
return (freqs_hz[note-10] / 0.3725290298461914) as uword
} }
sub print_notes(ubyte n1, ubyte n2) { sub print_notes(ubyte n1, ubyte n2) {
@ -67,56 +64,12 @@ main {
$3532, $322e, $2e29, $2926, $2730, $242c, $2027, $1420 $3532, $322e, $2e29, $2926, $2730, $242c, $2027, $1420
] ]
float[] freqs_hz = [ uword[] vera_freqs = [
; first 10 are unused so should index by i-10 0,0,0,0,0,0,0,0,0,0, ; first 10 notes are not used
44.6, 120, 127, 135, 143, 152, 160, 170, 180, 191, 203,
47.4, 215, 227, 240, 255, 270, 287, 304, 320, 341, 360,
50.4, 383, 405, 429, 455, 479, 509, 541, 573, 607, 640,
53.4, 682, 720, 766, 810, 859, 910, 958, 1019, 1082, 1147,
56.6, 1215, 1280, 1364, 1440, 1532, 1621, 1718, 1820, 1917]
59.6,
63.5,
67.1,
71.3,
75.5,
80.0,
84.7,
89.3,
94.9,
100.7,
106.8,
113.2,
119.3,
127.1,
134.1,
142.7,
151.0,
160.0,
169.5,
178.5,
189.7,
201.4,
213.6,
226.3,
238.5,
254.1,
268.3,
285.3,
301.9,
320.0,
339.0,
357.0,
379.5,
402.9,
427.3,
452.6,
477.0,
508.2,
536.5,
570.7,
603.8,
639.9,
678.0,
714.1
]
} }