Digital Koto
A while back, I wrote a little piano program. It includes song player. It's just a little simple music player, so I used BEEP instead of MML command. However, I'm rather curious since most of the code is created for the interface. In other words, drawing the piano keys. So, I'm wondering whether or not it's simpler to just draw the keys straight. Well, what kind of musical instrument is like that? The answer is simple: Japanese Koto. In truth, different cultures have different ideas and names for what basically amounts to a bunch of strings mounted on a board.
Still, the idea of it is interesting, and it's simple enough for me to do. So, let' do it! There are several different parts, but generally speaking, once you touch the screen, you come up with a string number and beep the appropriate sound. That's just look up table. Touch screen is easy. About the only thing that's difficult is drawing the strings proportionately. A little mathematic should do it.
- INIT
- Build BEEP table
- Build Note table
- Build String table
- LOOP
- Draw Strings
- If Touch screen
- Highlight nearest string
- Play BEEP sound
- GOTO LOOP
So, do you think this will take you one hour to do? Time for another "Hour of Code" challenge!
- ACLS:CLEAR
- DIM BP[49]:'BEEP TABLE
- DIM NT$[49]:'NOTE TABLE
- DIM ST[16]:'STRING TABLE
- BREPEAT 0,60,12
- BREPEAT 1,60,12
- BREPEAT 2,60,12
- BREPEAT 3,60,12
- @INIT
- NSI=0
- P=4096/12:T$="CcDdEFfGgAaB"
- FOR I=-24 TO 24:J=I+24
- BP[J]=P*I
- NT$[J]=MID$(T$,(J%12),1)
- NEXT
- ST[0]=14:ST[1]=19
- ST[2]=21:ST[3]=22
- ST[4]=26:ST[5]=27
- ST[6]=31:ST[7]=33
- ST[8]=34:ST[9]=38
- ST[10]=39:ST[11]=43
- ST[12]=45:ST[13]=0
- ST[14]=0:ST[15]=0
- ACLS
That's about it for the Initialization table. I want to fiddle with the string, so I'll put in button interface so I can change the string values on the fly.
- @LOOP
- NS=13:A=256/NS:B=A/2
- VSYNC 1:BT=BTRIG():TX=FLOOR(TCHX*NS/256)
- IF NS<1 THEN NS=1
- FOR I=0 TO NS-1
- GLINE B+I*A,16,B+I*A,192,15
- LOCATE (B+I*A)/8,0:?FLOOR(ST[I]/12)
- LOCATE (B+I*A)/8,0:?NT$[ST[I]]
- NEXT
- GLINE B+TX*A,16,B+TX*A,192,8
- IF TCHTIME>0 THEN BEEP 20,BP[ST[TX]]
- GOTO @LOOP
And that's about it. 35 minutes so far, and that's because I was having trouble with the math. The truth is, had I did the math correctly beforehand, I wouldn't have had so much trouble and I wouldn't have spend the time debugging.
Oh, yeah, about the tuning on the fly. I think that it is nice to be able to change the notes. So, what I'll do is add some button interface. That's what the BREPEAT command is for. Also, I may as well throw the instrument along with it. Instead of the locked in BEEP 20, I substitute it with a variable that will allow you to choose your own instrument.
Finally, we're going to move the whole thing down to the lower screen for ease of play. What should we put on the top of the screen? I don't know. Title screen, maybe? Or some internal variables?
- REM DIGITAL KOTO
- REM BY HARRY HARDJONO
- REM DEC 2013
- ACLS:CLEAR
- DIM BP[49]:'BEEP TABLE
- DIM NT$[49]:'NOTE TABLE
- DIM ST[16]:'STRING TABLE
- BREPEAT 0,60,12
- BREPEAT 1,60,12
- BREPEAT 2,60,12
- BREPEAT 3,60,12
- PNLTYPE "OFF"
- @INIT
- NSI=0
- CI=16:'CURRENT INSTRUMENT
- P=4096/12:T$="CcDdEFfGgAaB"
- FOR I=-24 TO 24:J=I+24
- BP[J]=P*I
- NT$[J]=MID$(T$,(J%12),1)
- NEXT
- ST[0]=14:ST[1]=19
- ST[2]=21:ST[3]=22
- ST[4]=26:ST[5]=27
- ST[6]=31:ST[7]=33
- ST[8]=34:ST[9]=38
- ST[10]=39:ST[11]=43
- ST[12]=45:ST[13]=0
- ST[14]=0:ST[15]=0
- GPAGE 1:ACLS
- @LOOP
- NS=13:A=256/NS:B=A/2
- VSYNC 1:BT=BTRIG():TX=FLOOR(TCHX*NS/256)
- IF NS<1 THEN NS=1
- GPAGE 1,1,1
- FOR I=0 TO NS-1
- GLINE B+I*A,16,B+I*A,192,15
- LOCATE (B+I*A)/8,0:?FLOOR(ST[I]/12)
- LOCATE (B+I*A)/8,0:?NT$[ST[I]]
- NEXT
- GLINE B+TX*A,16,B+TX*A,192,8
- IF TCHTIME>0 THEN BEEP CI,BP[ST[TX]]
- IF BT AND 1 THEN ST[NSI]=ST[NSI]+1
- IF BT AND 2 THEN ST[NSI]=ST[NSI]-1
- IF BT AND 4 THEN NSI=NSI-1
- IF BT AND 8 THEN NSI=NSI+1
- IF BT AND 16 THEN CI=CI+1:GOSUB @DISP
- IF BT AND 32 THEN CI=CI-1:GOSUB @DISP
- NSI=(NSI+NS)%NS
- ST[NSI]=(ST[NSI]+49)%49
- CI=(CI+70)%70
- GOTO @LOOP
- @DISP
- ACLS
- ?"INST: ";CI
- FOR I=0 TO 15
- ?I,ST[I]
- NEXT
- RETURN
Oh, by the way. The actual problem is so simple, that you can actually fit the minimalistic version of the program into one screen. That's right. It's another single screen challenge program!
- REM DIGITAL KOTO
- REM BY HARRY HARDJONO
- ACLS:CLEAR:DIM BP[49]
- DIM NT$[49]:DIM ST[16]
- P=4096/12:T$="CcDdEFfGgAaB"
- FOR I=-24 TO 24:J=I+24
- BP[J]=P*I
- NT$[J]=MID$(T$,(J%12),1):NEXT
- ST[0]=14:ST[1]=19:ST[2]=21
- ST[3]=22:ST[4]=26:ST[5]=27
- ST[6]=31:ST[7]=33:ST[8]=34
- ST[9]=38:ST[10]=39:ST[11]=43
- ST[12]=45:ST[13]=0:ST[14]=0
- @LOOP
- NS=13:A=256/NS:B=A/2
- VSYNC 1:TX=FLOOR(TCHX*NS/256)
- GPAGE 1,1,1:FOR I=0 TO NS-1
- GLINE B+I*A,0,B+I*A,192,15
- NEXT
- GLINE B+TX*A,16,B+TX*A,192,8
- SD=BP[ST[TX]]
- IF TCHTIME>0 THEN BEEP 16,SD
- GOTO @LOOP
No comments:
Post a Comment