Friday, December 27, 2013

Petit Computer Journal #31



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.


  1. INIT
  2. Build BEEP table
  3. Build Note table
  4. Build String table
  5. LOOP
  6. Draw Strings
  7. If Touch screen
  8. Highlight nearest string
  9. Play BEEP sound
  10. GOTO LOOP


So, do you think this will take you one hour to do? Time for another "Hour of Code" challenge!


  1. ACLS:CLEAR
  2. DIM BP[49]:'BEEP TABLE
  3. DIM NT$[49]:'NOTE TABLE
  4. DIM ST[16]:'STRING TABLE
  5. BREPEAT 0,60,12
  6. BREPEAT 1,60,12
  7. BREPEAT 2,60,12
  8. BREPEAT 3,60,12

  9. @INIT
  10. NSI=0
  11. P=4096/12:T$="CcDdEFfGgAaB"
  12. FOR I=-24 TO 24:J=I+24
  13. BP[J]=P*I
  14. NT$[J]=MID$(T$,(J%12),1)
  15. NEXT
  16. ST[0]=14:ST[1]=19
  17. ST[2]=21:ST[3]=22
  18. ST[4]=26:ST[5]=27
  19. ST[6]=31:ST[7]=33
  20. ST[8]=34:ST[9]=38
  21. ST[10]=39:ST[11]=43
  22. ST[12]=45:ST[13]=0
  23. ST[14]=0:ST[15]=0

  24. 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.


  1. @LOOP
  2. NS=13:A=256/NS:B=A/2
  3. VSYNC 1:BT=BTRIG():TX=FLOOR(TCHX*NS/256)
  4. IF NS<1 THEN NS=1
  5. FOR I=0 TO NS-1
  6. GLINE B+I*A,16,B+I*A,192,15
  7. LOCATE (B+I*A)/8,0:?FLOOR(ST[I]/12)
  8. LOCATE (B+I*A)/8,0:?NT$[ST[I]]
  9. NEXT
  10. GLINE B+TX*A,16,B+TX*A,192,8
  11. IF TCHTIME>0 THEN BEEP 20,BP[ST[TX]]
  12. 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?


  1. REM DIGITAL KOTO
  2. REM BY HARRY HARDJONO
  3. REM DEC 2013

  4. ACLS:CLEAR
  5. DIM BP[49]:'BEEP TABLE
  6. DIM NT$[49]:'NOTE TABLE
  7. DIM ST[16]:'STRING TABLE
  8. BREPEAT 0,60,12
  9. BREPEAT 1,60,12
  10. BREPEAT 2,60,12
  11. BREPEAT 3,60,12
  12. PNLTYPE "OFF"

  13. @INIT
  14. NSI=0
  15. CI=16:'CURRENT INSTRUMENT
  16. P=4096/12:T$="CcDdEFfGgAaB"
  17. FOR I=-24 TO 24:J=I+24
  18. BP[J]=P*I
  19. NT$[J]=MID$(T$,(J%12),1)
  20. NEXT
  21. ST[0]=14:ST[1]=19
  22. ST[2]=21:ST[3]=22
  23. ST[4]=26:ST[5]=27
  24. ST[6]=31:ST[7]=33
  25. ST[8]=34:ST[9]=38
  26. ST[10]=39:ST[11]=43
  27. ST[12]=45:ST[13]=0
  28. ST[14]=0:ST[15]=0

  29. GPAGE 1:ACLS

  30. @LOOP
  31. NS=13:A=256/NS:B=A/2
  32. VSYNC 1:BT=BTRIG():TX=FLOOR(TCHX*NS/256)
  33. IF NS<1 THEN NS=1
  34. GPAGE 1,1,1
  35. FOR I=0 TO NS-1
  36. GLINE B+I*A,16,B+I*A,192,15
  37. LOCATE (B+I*A)/8,0:?FLOOR(ST[I]/12)
  38. LOCATE (B+I*A)/8,0:?NT$[ST[I]]
  39. NEXT
  40. GLINE B+TX*A,16,B+TX*A,192,8
  41. IF TCHTIME>0 THEN BEEP CI,BP[ST[TX]]

  42. IF BT AND 1 THEN ST[NSI]=ST[NSI]+1
  43. IF BT AND 2 THEN ST[NSI]=ST[NSI]-1
  44. IF BT AND 4 THEN NSI=NSI-1
  45. IF BT AND 8 THEN NSI=NSI+1
  46. IF BT AND 16 THEN CI=CI+1:GOSUB @DISP
  47. IF BT AND 32 THEN CI=CI-1:GOSUB @DISP
  48. NSI=(NSI+NS)%NS
  49. ST[NSI]=(ST[NSI]+49)%49
  50. CI=(CI+70)%70
  51. GOTO @LOOP

  52. @DISP
  53. ACLS
  54. ?"INST: ";CI
  55. FOR I=0 TO 15
  56. ?I,ST[I]
  57. NEXT
  58. 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!


  1. REM DIGITAL KOTO
  2. REM BY HARRY HARDJONO
  3. ACLS:CLEAR:DIM BP[49]
  4. DIM NT$[49]:DIM ST[16]
  5. P=4096/12:T$="CcDdEFfGgAaB"
  6. FOR I=-24 TO 24:J=I+24
  7. BP[J]=P*I
  8. NT$[J]=MID$(T$,(J%12),1):NEXT
  9. ST[0]=14:ST[1]=19:ST[2]=21
  10. ST[3]=22:ST[4]=26:ST[5]=27
  11. ST[6]=31:ST[7]=33:ST[8]=34
  12. ST[9]=38:ST[10]=39:ST[11]=43
  13. ST[12]=45:ST[13]=0:ST[14]=0
  14. @LOOP
  15. NS=13:A=256/NS:B=A/2
  16. VSYNC 1:TX=FLOOR(TCHX*NS/256)
  17. GPAGE 1,1,1:FOR I=0 TO NS-1
  18. GLINE B+I*A,0,B+I*A,192,15
  19. NEXT
  20. GLINE B+TX*A,16,B+TX*A,192,8
  21. SD=BP[ST[TX]]
  22. IF TCHTIME>0 THEN BEEP 16,SD
  23. GOTO @LOOP


No comments:

Post a Comment