Skip to content

Instantly share code, notes, and snippets.

@hekras
Created July 31, 2021 17:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hekras/7d67e850cab30ffa182e3ea822499b3d to your computer and use it in GitHub Desktop.
Save hekras/7d67e850cab30ffa182e3ea822499b3d to your computer and use it in GitHub Desktop.
CMM2 tones tracker
'==================================
'Tones tracker
'By Henryk K 2021.07.18
'==================================
option explicit
'dim tones(16)
dim string note.name$(97)
dim float note.freq(97)
dim integer note.oct%=4
'instruments
dim integer i.counter=200
dim integer i.current%=0
dim integer i.waveform%(255)
dim float i.amplitude(255,200)
dim float i.freq = 0.0
'keyboard
dim integer s_tab%(255) 'shift/ctrl/alt modifiers
dim string eva$(6,255) 'eval strings for keyboard matrix
const s.nonne = 0
const s.shift = 1
const s.ctrl = 2
const s.alt = 3
const s.shift.ctrl = 4
const s.shift.alt = 5
const s.ctrl.alt = 6
const s.err = 16
dim integer s.gate% = 0 'gate keeper for keypress
'cursor coordinates
dim integer tc(4,1) 'track header
dim integer cc(100,4,1) 'tracks
const cc.x=0
const cc.y=1
'==================================
' Main loop
'==================================
Init_track_cc 0, 0
Init_notearrays
Init_s_tab
Init_eva
mode 15,8
font 7,1
page write 1
Render_keyboard 0, 900
Render_tracks
Render_instrument
do
page copy 1 to 0
Rt
Hk
tickmaster
' pause 500
loop
'==================================
' Handle keyboard
'==================================
sub Hk
local i%, k%, offset%, ged
text 300, 0, "Keyboard debug output", L,,,rgb(white)
text 300-5,10, "i%", R
text 300-5,20, "key" , R
text 300-5,30, "note" , R
for i%=0 to 8
k%=keydown(i%)
text 300+i%*25, 10, hex$(i%,2)
text 300+i%*25, 20, hex$(k%,2)
next i%
text 300, 30, hex$(s_tab(keydown(7)),2) + " " + str$(note.oct%) + " " + eva$(s_tab%(keydown(7)),keydown(1)) + space$(30)
on error skip 1
ged = eval(eva$(s_tab%(keydown(7)),keydown(1)))
text 300, 40, "Error:" + mm.errmsg$
text 300, 50, format$(i.counter, "%04.0f")
end sub
sub tickmaster
if i.counter<200 then
inc i.counter
PLAY SOUND 1, B, S, i.freq, i.amplitude(0, i.counter)
else
play stop
endif
end sub
sub Render_instrument
local i, amp
for i=0 to 200
amp = 25-25*i/25
if amp<0 then amp=0
i.amplitude(0,i) = amp
line 300+i,100,300+i,100-i.amplitude(0,i),1
next i
end sub
'==================================
' NOP
'==================================
function NOP()
if s.gate% then s.gate%=0
end function
'==================================
' TONE
'==================================
function TONE(f)
PLAY SOUND 1, B, S, f, 25
i.counter=0
i.freq=f
end function
'==================================
' update tones
'==================================
sub update_tones
local i%, d%, offset%
restore k_tab_data
do
read i%, d%
if i% = 0 then exit do
offset% = d% + note.oct%*12 + 3
if offset% < 97 then
eva$(s.nonne, i%)="TONE(" + str$(note.freq(offset%)) + ")"
end if
loop
end sub
'==================================
' INC_OCT increase octave
'==================================
function INC_OCT()
if not s.gate% and note.oct<7 then
inc note.oct, 1
inc s.gate%
update_tones
endif
end function
'==================================
' DEC_OCT decrease octave
'==================================
function DEC_OCT()
if not s.gate% and note.oct>0 then
inc note.oct, -1
inc s.gate%
update_tones
end if
end function
'==================================
' Run track
'==================================
sub Rt
static aa%=0
Render_track_line aa%, rgb(white), rgb(gray)
inc aa%
if aa% > 63 then aa%=0
Render_track_line aa%, rgb(red), rgb(white)
end sub
'==================================
' Render_track_line
'==================================
sub Render_track_line n%, fg, bg
local m%
text cc(n%,0,cc.x),cc(n%,0,cc.y), hex$(n%,2),C,1,1,fg,bg
for m%=1 to 4
text cc(n%,m%,cc.x), cc(n%,m%,cc.y), " - ",C,1,1,fg,bg
next m%
end sub
'==================================
' Render_track_header
'==================================
sub Render_track_header fg, bg
local m%
text tc(0,cc.x), tc(0,cc.y), "##",C,1,1,fg,bg
for m%=1 to 4
text tc(m%,cc.x), tc(m%,cc.y), " "+str$(m%)+" ",C,1,1,fg,bg
next m%
end sub
'==================================
' Init cc
' - calculate coordinats for the
' tracker and put them in correct
' places in cc
'==================================
sub Init_track_cc xoff%, yoff%
local i%, j%, m%, x%, y%, n%
tc(0,cc.y)=y%=yoff%
tc(0,cc.x)=10+xoff%
for m%=1 to 4
tc(m%,cc.y)=yoff%
tc(m%,cc.x)=m%*40+10+xoff%
next m%
n%=0
inc y%, 13
for j%=0 to 3
inc y%, 6
for i%=0 to 15
cc(n%,0,cc.x)=10+xoff%
cc(n%,0,cc.y)=y%
for m%=1 to 4
cc(n%,m%,cc.x)=m%*40+10+xoff%
cc(n%,m%,cc.y)=y%
next m%
inc y%, 13
inc n%
next i%
next j%
end sub
'==================================
' Render_tracks
'==================================
sub Render_tracks
local n%
Render_track_header rgb(255,0,255),rgb(black)
for n%=0 to 63
Render_track_line n%, rgb(white), rgb(gray)
next n%
end sub
'==================================
' Render_keyboard
'==================================
sub Render_keyboard xoff%, yoff%
local integer w%, x%, y%
local string k$
colour RGB(yellow), rgb(black)
font 7, 1
RESTORE note_keys
w%=10
y%=yoff%
x%=xoff%+w%*7
do
read k$
if (k$ <> "") then
box x%, y%, w%, 30, 1, rgb(gray), rgb(white)
TEXT w%\2 + x%, y%+20, k$, C, , , rgb(gray), rgb(white)
end if
iNC x%, w%
loop while k$<>""
x%=xoff%+w%*7
do
read k$
if k$ <> "" and k$<>"-" then
box x%+w%\2, y%, w%, 15, 1, rgb(gray), rgb(black)
TEXT w% + x%, y%+5, k$, C, , , rgb(white), rgb(black)
end if
iNC x%, w%
loop while k$<>""
w%=10
y%=yoff%+30
x%=xoff%
do
read k$
if (k$ <> "") then
box x%, y%, w%, 30, 1, rgb(gray), rgb(white)
TEXT w%\2 + x%, y%+20, k$, C, , , rgb(gray), rgb(white)
end if
iNC x%, w%
loop while k$<>""
x%=xoff%
do
read k$
if k$ <> "" and k$<>"-" then
box x%+w%\2, y%, w%, 15, 1, rgb(gray), rgb(black)
TEXT w% + x%, y%+5, k$, C, , , rgb(white), rgb(black)
end if
iNC x%, w%
loop while k$<>""
end sub
'==================================
' Read note names and frequncies into arrays
'==================================
sub Init_notearrays
local i%
restore note_data
for i%=0 to 96
read note.name$(i%), note.freq(i%)
next i%
end sub
' | | | | | | | | | | | | | |
' | | 2 | 3 | | | 5 | 6 | 7 | | | 9 | 0 | | Key
' | | | | | | | | | | | | | |
' | |C#2|D#2| | |F#2|G#2|A#2| | |C#3|D#3| | Note
' | |___|___| | |___|___|___| | |___|___| |
' | | | | | | | | | | |
' | Q | W | E | R | T | Y | U | I | O | P | Key
' | | | | | | | | | | |
' |C-2|D-2|E-2|F-2|G-2|A-2|B-2|C-3|D-3|E-3| Note
' |___|___|___|___|___|___|___|___|___|___|
'| | | | | | | | | | | | | |
'| | S | D | | | G | H | J | | | L | ; | | Key
'| | | | | | | | | | | | | |
'| |C#1|D#1| | |F#1|G#1|A#1| | |C#2|D#2| | Note
'| |___|___| | |___|___|___| | |___|___| |´
'| | | | | | | | | | |
'| Z | X | C | V | B | N | M | , | . | / | key
'| | | | | | | | | | |
'|C-1|D-1|E-1|F-1|G-1|A-1|B-1|C-2|D-2|STP| Note
'|___|___|___|___|___|___|___|___|___|___|
'==================================
' Init keyboard eva table
'==================================
sub Init_eva
local i%, j%, d%, offset%
for j%=0 to 6
for i%=0 to 255
eva$(j%, i%)="NOP()"
next i%,j%
update_tones
eva$(s.alt, 128) = "INC_OCT()"
eva$(s.alt, 129) = "DEC_OCT()"
' kbdmx%(s.alt, 129) = f.dec_octave
end sub
'==================================
' Init keyboard modifier table
' for shift, ctrl alt keys
'==================================
sub Init_s_tab
local i%, d%
for i%=0 to bound(s_tab%(0))
s_tab%(i%)=s.nonne
next i%
s_tab%(0) = s.nonne
s_tab%(8) = s.shift
s_tab%(128) = s.shift
s_tab%(2) = s.ctrl
s_tab%(32) = s.ctrl
s_tab%(1) = s.alt
s_tab%(16) = s.alt
s_tab%(8+2) = s.shift.ctrl
s_tab%(128+2) = s.shift.ctrl
s_tab%(8+32) = s.shift.ctrl
s_tab%(128+32) = s.shift.ctrl
s_tab%(8+1) = s.shift.alt
s_tab%(128+1) = s.shift.alt
s_tab%(8+16) = s.shift.alt
s_tab%(128+16) = s.shift.alt
s_tab%(2+1) = s.ctrl.alt
s_tab%(32+1) = s.ctrl.alt
s_tab%(2+16) = s.ctrl.alt
s_tab%(32+16) = s.ctrl.alt
end sub
'==================================
' keyboard tones index table
' used by update_tones
'==================================
k_tab_data:
data 122, 0 'Z
data 115, 1 'S
data 120, 2 'X
data 100, 3 'D
data 99, 4 'C
data 118, 5 'V
data 103, 6 'G
data 98, 7 'B
data 104, 8 'H
data 110, 9 'N
data 106, 10 'J
data 109, 11 'M
data 44, 12 ',
data 108, 13 'L
data 46, 14 '.
data 59, 15 ';
data 47, 16 '/
'upper_keyboard
data 113, 12 'Q
data 50, 13 '2
data 119, 14 'W
data 51, 15 '3
data 101, 16 'E
data 114, 17 'R
data 53, 18 '5
data 116, 19 'T
data 54, 20 '6
data 121, 21 'Y
data 55, 22 '7
data 117, 23 'U
data 105, 24 'I
data 57, 25 '9
data 111, 26 'O
data 48, 27 '0
data 112, 28 'P
data 0, 0 'end of data
'==================================
' Legacy code
'==================================
note_keys:
data "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", ""
data "2","3","-","5","6","7","-","9","0", ""
data "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", ""
data "S", "D", "-", "G", "H", "J", "-", "L", ";", ""
note_data:
DATA "A-0", 27.500
DATA "A#0", 29.135
DATA "B-0", 30.868
DATA "C-1", 32.703
DATA "C#1", 34.648
DATA "D-1", 36.708
DATA "D#1", 38.891
DATA "E-1", 41.203
DATA "F-1", 43.654
DATA "F#1", 46.249
DATA "G-1", 48.999
DATA "G#1", 51.913
DATA "A-1", 55.000
DATA "A#1", 58.270
DATA "B-1", 61.735
DATA "C-2", 65.406
DATA "C#2", 69.296
DATA "D-2", 73.416
DATA "D#2", 77.782
DATA "E-2", 82.407
DATA "F-2", 87.307
DATA "F#2", 92.499
DATA "G-2", 97.999
DATA "G#2", 103.826
DATA "A-2", 110.000
DATA "A#2", 116.541
DATA "B-2", 123.471
DATA "C-3", 130.813
DATA "C#3", 138.591
DATA "D-3", 146.832
DATA "D#3", 155.563
DATA "E-3", 164.814
DATA "F-3", 174.614
DATA "F#3", 184.997
DATA "G-3", 195.998
DATA "G#3", 207.652
DATA "A-3", 220.000
DATA "A#3", 233.082
DATA "B-3", 246.942
DATA "C-4", 261.626
DATA "C#4", 277.183
DATA "D-4", 293.665
DATA "D#4", 311.127
DATA "E-4", 329.628
DATA "F-4", 349.228
DATA "F#4", 369.994
DATA "G-4", 391.995
DATA "G#4", 415.305
DATA "A-4", 440.000
DATA "A#4", 466.164
DATA "B-4", 493.883
DATA "C-5", 523.251
DATA "C#5", 554.365
DATA "D-5", 587.330
DATA "D#5", 622.254
DATA "E-5", 659.255
DATA "F-5", 698.456
DATA "F#5", 739.989
DATA "G-5", 783.991
DATA "G#5", 830.609
DATA "A-5", 880.000
DATA "A#5", 932.328
DATA "B-5", 987.767
DATA "C-6", 1046.502
DATA "C#6", 1108.731
DATA "D-6", 1174.659
DATA "D#6", 1244.508
DATA "E-6", 1318.510
DATA "F-6", 1396.913
DATA "F#6", 1479.978
DATA "G-6", 1567.982
DATA "G#6", 1661.219
DATA "A-6", 1760.000
DATA "A#6", 1864.655
DATA "B-6", 1975.533
DATA "C-7", 2093.005
DATA "C#7", 2217.461
DATA "D-7", 2349.318
DATA "D#7", 2489.016
DATA "E-7", 2637.020
DATA "F-7", 2793.826
DATA "F#7", 2959.955
DATA "G-7", 3135.963
DATA "G#7", 3322.438
DATA "A-7", 3520.000
DATA "A#7", 3729.310
DATA "B-7", 3951.066
DATA "C-8", 4186.009
DATA "C#8", 4434.922
DATA "D-8", 4698.636
DATA "D#8", 4978.032
DATA "E-8", 5274.041
DATA "F-8", 5587.652
DATA "F#8", 5919.911
DATA "G-8", 6271.927
DATA "G#8", 6644.875
DATA "A-8", 7040.000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment