MML by ノトホホ

再生

 「MML」とは「Music Macro Language」の略。マイコン少年ならPLAY文やMUSIC文で憶えている人も多いかもしれないね。カンタンに言えば、コンピューターで音楽の譜面を表わす記法というところ。
 残念ながらプチコンには付属していないこの機能だけど、プチコンのBEEP命令を使ってMMLを再現したツワモノがいるぞ。
 プログラムをRUNしてみると、自動的に音楽が再生されるだろう。この音楽が実はプログラム内で「MML形式で」書かれているのだ(26~34行目)。もちろんこの部分を書き換えればオリジナルの楽曲も鳴らせるぞ。

作ったのはこの人

ノトホホ
Twitter

実はMML好きで、単なる趣味でWindows用のMMLプログラムを会社のWebサイトにそっと忍ばせているテクノっ子。趣味はジャケ買い。


 CHECK POiNT 

インテリ
MMLといえば、「ドレミ」を「CDE」と書くような構文だね。こういう単純な置き換えの他に、「@~」は音色の指定、「V~」はボリュームの指定、というように後ろに数字を書く指定もあるよ。

博士
さよう。MMLの構文についてもっと詳しくは「MML」でググれ、というところじゃな。プログラムの4~7行目には使えるコマンドが一覧になっておるぞ。

ワンパク
その下には未実装コマンドが残ってるじゃねえか、ガッデム!

神崎
ここには書いてないけど、「.」(付点)にも対応していないみたいだね。まだ未完成ってところなのかな?

博士
うむ。ひとまず音を出すところまではできているから、あとは拡張のできるプログラマー募集、ということなんじゃろうか。

ワンパク
ファック! 丸投げもいいところだぜ!

神崎
リストを順に読んでいけば、どう動作しているのかはだいたい分かるね。オリジナルプログラムにも組み込んでBGMにも使えるんじゃないかな?

プログラムリスト

  1. ’┌───────────────────┐
  2. ’│MML v1.0           │
  3. ’├───────────────────┤
  4. ’│C,D,E,F,G,A,B,C#―A#│
  5. ’│L1,L2,L4,L8,L16,L32│
  6. ’│O0―4,<,>,@0―127    │
  7. ’│P0―127,V0―V127     │
  8. ’├───────────────────┤
  9. ’│ミシ゛ッソウ             │
  10. ’│Tempo,Loop,[],Key  │
  11. ’└───────────────────┘
  12. VISIBLE 1,1,0,0,0,0
  13. CLS
  14. CLEAR
  15. PRINT”┌───────────────┐”
  16. PRINT”│MML PLAYER v1.0│”
  17. PRINT”└───────────────┘”
  18. ’---8マテ゛(オオキイトテンホ゜オチル)
  19. MMLTR=8
  20. PRINT”1)MMLシステムショキカ”
  21. GOSUB @MMLRESET
  22. ’---エンソウテ゛-タ
  23. @BGM1
  24. DATA”@16CDEFGAB<C>”
  25. DATA”@18V50P127CRCRGRGR”
  26. DATA”@30P32GFDBGFCA”
  27. DATA”@19L16C<C>C<C>C<C>C<C>”
  28. ’---
  29. DATA”@31L16CRRRRRRRCRRRRRRR”
  30. DATA”@53L16RRRRCRRRRRRRCRRC”
  31. DATA”V30@54L16RCCCRCCCRCCCRCCR”
  32. DATA”@48L16RRRRRRRRRRRRRRCC”
  33. ’---
  34. PRINT”2)BGMテ゛-タセッテイ”
  35. RESTORE @BGM1
  36. GOSUB @MMLSET
  37. FOR T=0 TO MMLTR-1
  38.  PRINT ” ”;T;”:”;MML$(T)
  39. NEXT
  40. ’┌───────┐
  41. ’│メインル-フ゜│
  42. ’└───────┘
  43. PRINT”3)BGMエンソウチュウ”
  44. STY=CSRY
  45. ’MLOOP=FALSE
  46. ’---
  47. @LOOP
  48. ’ GOSUB @PUTSTAT
  49.  GOSUB @MMLPLAY
  50.  VSYNC 1
  51. GOTO @LOOP
  52. END
  53. ’---トラックスウカ゛オオイトキハツカワナイコト
  54. @PUTSTAT
  55. LOCATE 0,STY
  56. FOR T=0 TO MMLTR-1
  57.  PRINT ” ”;T;”=”;
  58.  PRINT CH(T,_MI);”  ”
  59. NEXT
  60. RETURN
  61. ’┌───────┐
  62. ’│MMLエンソウ│
  63. ’└───────┘
  64. @MMLPLAY
  65. FOR T=0 TO MMLTR-1
  66.  GOSUB @MMLSUB
  67. NEXT
  68. RETURN
  69. ’---1トラックコ゛トエンソウ
  70. @MMLSUB
  71. IF CH(T,_MS)==0 THEN RETURN
  72. ’---ナカ゛サカクニン
  73. L=CH(T,_MLC)-1
  74. CH(T,_MLC)=L
  75. IF L>0 THEN RETURN
  76. ’---ノ-トマテ゛クリカエス
  77. @CMDLOOP
  78. GOSUB @MMLGET
  79. IF C$==”” THEN RETURN
  80. ’---コマント゛コ゛トノショリヘ
  81. IF C$==”L” THEN @MCLEN
  82. IF C$==”O” THEN @MCOCT
  83. IF C$==”V” THEN @MCVOL
  84. IF C$==”P” THEN @MCPAN
  85. IF C$==”@” THEN @MCVCE
  86. IF C$==”R” THEN @MCRR
  87. IF C$==”<” THEN @MCOUP
  88. IF C$==”>” THEN @MCODW
  89. ’---オンテイセッテイ
  90. NT=ASC(C$)-ASC(”A”)
  91. IF NT<0 OR NT>7 THEN @MCERR
  92. NT=MNOTE(NT)
  93. ’---ツキ゛ハ#カ?
  94. GOSUB @MMLCHK
  95. IF C$!=”#” THEN @MNOTE
  96. NT=NT+1
  97. GOSUB @MMLNEXT
  98. ’---
  99. @MNOTE
  100. CH(T,_MN)=NT
  101. ’---オクタ-フ゛コウリョ
  102. OC=CH(T,_MO)-2
  103. NT=NT+(OC*12)
  104. ’---オトヲナラス
  105. VC=CH(T,_MX)
  106. VL=CH(T,_MV)
  107. PN=CH(T,_MP)
  108. NT=NT*MPLEN
  109. BEEP VC,NT,VL,PN
  110. ’---ナカ゛サヲイレテヌケル
  111. @MCRR
  112. CH(T,_MLC)=CH(T,_ML)
  113. RETURN
  114. ’---エラ-
  115. @MCERR
  116. PRINT”オカシナMMLテ゛ス(”;C$;”)”
  117. END
  118. ’---ナカ゛サヘンカ
  119. @MCLEN
  120. GOSUB @MNGET
  121. I=_L32:IF N==32 THEN @MCLSET
  122. I=_L16:IF N==16 THEN @MCLSET
  123. I=_L8:IF N==8 THEN @MCLSET
  124. I=_L4:IF N==4 THEN @MCLSET
  125. I=_L2:IF N==2 THEN @MCLSET
  126. I=_L1:IF N==1 THEN @MCLSET
  127. GOTO @MCERR
  128. ’---
  129. @MCLSET
  130. CH(T,_ML)=MLEN(I)
  131. GOTO @CMDLOOP
  132. ’---オクタ-フ゛ヘンカ
  133. @MCOCT
  134. GOSUB @MNGET
  135. CH(T,_MO)=N
  136. GOTO @CMDLOOP
  137. @MCOUP
  138. CH(T,_MO)=CH(T,_MO)+1
  139. GOTO @CMDLOOP
  140. @MCODW
  141. CH(T,_MO)=CH(T,_MO)-1
  142. GOTO @CMDLOOP
  143. ’---オンリョウヘンカ
  144. @MCVOL
  145. GOSUB @MNGET
  146. CH(T,_MV)=N
  147. GOTO @CMDLOOP
  148. ’---ハ゜ンホ゜ットヘンカ
  149. @MCPAN
  150. GOSUB @MNGET
  151. CH(T,_MP)=N
  152. GOTO @CMDLOOP
  153. ’---オンショクヘンカ
  154. @MCVCE
  155. GOSUB @MNGET
  156. CH(T,_MX)=N
  157. GOTO @CMDLOOP
  158. ’---ツキ゛ノコマント゛サキヨミ
  159. @MMLCHK
  160. I=CH(T,_MI)
  161. C$=MID$(MML$(T),I,1)
  162. RETURN
  163. ’---ヨミコミイチヘンコウ
  164. @MMLNEXT
  165. I=I+1
  166. IF I>=CH(T,_MS) THEN I=0
  167. CH(T,_MI)=I
  168. RETURN
  169. ’---コマント゛シュトク
  170. @MMLGET
  171. I=CH(T,_MI)
  172. IF I==CH(T,_MS) THEN @MCHKLOOP
  173. ’---コマント゛
  174. CH(T,_MI)=I+1
  175. C$=MID$(MML$(T),I,1)
  176. RETURN
  177. ’---キョクセ゛ンタイル-フ゜?
  178. @MCHKLOOP
  179. IF MLOOP==FALSE THEN @MMLTEND
  180. CH(T,_MI)=0
  181. GOTO @MMLGET
  182. ’---トラックオワリ
  183. @MMLTEND
  184. C$=””:CH(T,_MS)=0
  185. RETURN
  186. ’---スウシ゛シュトク
  187. @MNGET
  188. N=0:NC=0
  189. ’---
  190. @MNLOOP
  191. GOSUB @MNCHK
  192. IF R==FALSE THEN @MNEXIT
  193. N=N*10+(C-ASC(”0”))
  194. ’---ツキ゛ヘススメル
  195. I=I+1
  196. IF I!=CH(T,_MS) THEN @MNSKIP
  197. IF MLOOP==FALSE THEN RETURN
  198. I=0
  199. @MNSKIP
  200. CH(T,_MI)=I
  201. NC=NC+1
  202. GOTO @MNLOOP
  203. ’---
  204. @MNEXIT
  205. IF NC THEN RETURN
  206. C$=”NUM”
  207. GOTO @MCERR
  208. ’---ツキ゛ハスウシ゛カ?
  209. @MNCHK
  210. I=CH(T,_MI)
  211. C=ASC(MID$(MML$(T),I,1))
  212. R=C>=ASC(”0”) AND C<=ASC(”9”)
  213. RETURN
  214. ’┌───────┐
  215. ’│MMLショキカ│
  216. ’└───────┘
  217. @MMLRESET
  218. RESTORE @MMLRESET
  219. IF TRMAX>8 THEN TRMAX=8
  220. ’---ナカ゛サ(32,16,8,4,2,1)
  221. DIM MLEN(6)
  222. L=3
  223. FOR I=0 TO 5
  224.  MLEN(I)=L
  225.  L=L*2
  226. NEXT
  227. _L32=0
  228. _L16=1
  229. _L8=2
  230. _L4=3
  231. _L2=4
  232. _L1=5
  233. ’---ハンオンノナカ゛サ
  234. MPLEN=FLOOR(4096/12)
  235. ’---セ゛ンタイノヨウソ
  236. MLOOP=TRUE
  237. MTEMPO=120
  238. MTMPCNT=0
  239. ’---ノ-トヨウ(ABCDEFG)
  240. DIM MNOTE(7)
  241. DATA 9,11,0,2,4,5,7
  242. FOR I=0 TO 6
  243.  READ MNOTE(I)
  244. NEXT
  245. ’---エンソウヨウノワ-クテイキ゛
  246. _ML=0:’ナカ゛サ
  247. _MO=1:’オクタ-フ゛
  248. _MN=2:’オンテイ
  249. _MK=3:’キ-
  250. _MV=4:’ホ゛リュ-ム
  251. _MP=5:’ハ゜ンホ゜ット
  252. _MS=6:’サイス゛
  253. _MX=7:’オンショク
  254. _MLC=8:’ナカ゛サカウンタ
  255. _MI=9:’オフセット
  256. _MMAX=10
  257. DIM MML$(MMLTR)
  258. DIM CH(MMLTR,_MMAX)
  259. ’---ワ-クリセット
  260. FOR T=0 TO TR-1
  261.  CH(T,_MS)=0
  262. NEXT
  263. RETURN
  264. ’┌───────┐
  265. ’│MMLセッテイ│
  266. ’└───────┘
  267. @MMLSET
  268. FOR T=0 TO MMLTR-1
  269.  READ MML$(T)
  270.  CH(T,_MS)=LEN(MML$(T))
  271.  CH(T,_ML)=MLEN(_L4)
  272.  CH(T,_MLC)=0
  273.  CH(T,_MO)=2
  274.  CH(T,_MN)=0
  275.  CH(T,_MK)=0
  276.  CH(T,_MV)=100
  277.  CH(T,_MP)=64
  278.  CH(T,_MX)=16+T
  279. NEXT
  280. RETURN