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
; ; TODO should be replaced by integer math maybe with a lookup table?
; 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, $f9c0 + voice_num*4, lsb(vera_freq))
}
@ -53,47 +53,49 @@ psg {
}
sub silent() {
ubyte voice
for voice in 0 to 15 {
volume(voice, 0)
envelope_volumes[voice] = 0
envelope_states[voice] = 1
for cx16.r9L in 0 to 15 {
volume(cx16.r9L, 0)
envelope_volumes[cx16.r9L] = 0
envelope_states[cx16.r9L] = 1
}
}
sub envelopes_irq() {
ubyte vera_ctrl = cx16.VERA_CTRL
ubyte vera_addr_h = cx16.VERA_ADDR_H
ubyte vera_addr_m = cx16.VERA_ADDR_M
ubyte vera_addr_l = cx16.VERA_ADDR_L
uword vol_word
ubyte voice
for voice in 0 to 15 {
if envelope_states[voice] {
; cx16.r0 = the volume word (volume scaled by 256)
; cx16.r15L = the voice number
; the other virtual registers are used to backup vera registers.
cx16.r13L = cx16.VERA_CTRL
cx16.r13H = cx16.VERA_ADDR_L
cx16.r14L = cx16.VERA_ADDR_M
cx16.r14H = cx16.VERA_ADDR_H
for cx16.r15L in 0 to 15 {
if envelope_states[cx16.r15L] {
; release
vol_word = envelope_volumes[voice] - envelope_releases[voice]
if msb(vol_word) & %11000000 {
vol_word = 0
envelope_releases[voice] = 0
cx16.r0 = envelope_volumes[cx16.r15L] - envelope_releases[cx16.r15L]
if msb(cx16.r0) & %11000000 {
cx16.r0 = 0
envelope_releases[cx16.r15L] = 0
}
envelope_volumes[voice] = vol_word
volume(voice, msb(vol_word))
envelope_volumes[cx16.r15L] = cx16.r0
volume(cx16.r15L, msb(cx16.r0))
} else {
; attack
vol_word = envelope_volumes[voice] + envelope_attacks[voice]
if msb(vol_word) & %11000000 or envelope_attacks[voice]==0 {
vol_word = mkword(63, 0)
envelope_attacks[voice] = 0
envelope_states[voice] = 1 ; start release
cx16.r0 = envelope_volumes[cx16.r15L] + envelope_attacks[cx16.r15L]
if msb(cx16.r0) & %11000000 or envelope_attacks[cx16.r15L]==0 {
cx16.r0 = mkword(63, 0)
envelope_attacks[cx16.r15L] = 0
envelope_states[cx16.r15L] = 1 ; start release
}
envelope_volumes[voice] = vol_word
volume(voice, msb(vol_word))
envelope_volumes[cx16.r15L] = cx16.r0
volume(cx16.r15L, msb(cx16.r0))
}
}
cx16.VERA_CTRL = vera_ctrl
cx16.VERA_ADDR_L = vera_addr_l
cx16.VERA_ADDR_M = vera_addr_m
cx16.VERA_ADDR_H = vera_addr_h
cx16.VERA_CTRL = cx16.r13L
cx16.VERA_ADDR_L = cx16.r13H
cx16.VERA_ADDR_M = cx16.r14L
cx16.VERA_ADDR_H = cx16.r14H
}
ubyte[16] envelope_states

View File

@ -3,7 +3,9 @@ TODO
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
^^^^^^^^^^^^^^

View File

@ -1,6 +1,5 @@
%import textio
%import syslib
%import floats
%import psg
main {
@ -20,18 +19,16 @@ main {
for note in notes {
ubyte note0 = lsb(note)
ubyte note1 = msb(note)
psg.freq_vera(0, vera_freq(note0))
psg.freq_vera(1, vera_freq(note1))
psg.freq(0, vera_freqs[note0])
psg.freq(1, vera_freqs[note1])
psg.envelope(0, 255, 6)
psg.envelope(1, 255, 6)
print_notes(note0, note1)
sys.wait(10)
}
}
}
sub vera_freq(ubyte note) -> uword {
return (freqs_hz[note-10] / 0.3725290298461914) as uword
psg.silent()
}
sub print_notes(ubyte n1, ubyte n2) {
@ -67,56 +64,12 @@ main {
$3532, $322e, $2e29, $2926, $2730, $242c, $2027, $1420
]
float[] freqs_hz = [
; first 10 are unused so should index by i-10
44.6,
47.4,
50.4,
53.4,
56.6,
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
]
uword[] vera_freqs = [
0,0,0,0,0,0,0,0,0,0, ; first 10 notes are not used
120, 127, 135, 143, 152, 160, 170, 180, 191, 203,
215, 227, 240, 255, 270, 287, 304, 320, 341, 360,
383, 405, 429, 455, 479, 509, 541, 573, 607, 640,
682, 720, 766, 810, 859, 910, 958, 1019, 1082, 1147,
1215, 1280, 1364, 1440, 1532, 1621, 1718, 1820, 1917]
}