記得在DOS時代編程使用Turbo C ,在圖書館遇到了樂譜播放程序,於是用C寫了播放音樂的小程序。
現在回憶一下很有意思的事,如果沒有那麼有意思的事可做,編程是很無聊的事。
現在我們學習Nim語言,編寫一個類似的程序。
如果沒有聽說過nim,那麼請連接www.nim-lang.org
nim 語言生成C代碼,可以使用vc,minGW,gcc,c-lang等編譯器編譯.
在舊版本0.12 nim中在windows/windows.nim ,在新版本中被移走(0.16以後)。可以使用nimble 來安裝。
先 nimble refresh ; nimble list ; 再使用nimble install oldwinapi 安裝需要的庫.
然後在 nim.cfg 開始的地方添加 Path=%USERPROFILE%/.nimble/package/windows
下面的代碼在XP下會用PC喇叭播放《小蜜蜂》音樂,在windows7 因爲不支持Beep所以不能播放出聲音。
discard """
使用PC喇叭播放樂譜程序
記得在DOS時代編程使用Turbo C ,在圖書館遇到了樂譜播放程序,於是用C寫了播放音樂的小程序。
現在回憶一下,真是很有趣的事,如果沒有那麼有意思的事可做,編程是很無聊的事。
現在我們學習Nim語言,編寫一個類似的程序。
現在實現:
找到樂譜對應的頻率,
輸入小蜜蜂的樂譜,
輸入節拍,
使用Beep windows API播放。
後續版本實現如下功能
輸入文件:
查找到C,D,E,F,G,A,B等調對應的頻率
1 音符<->頻率對照表
2 樂譜表
3 節拍表
輸出:播放
author:[email protected]
編譯:nim c --cpu:i386 playMusic.nim
"""
import
windows,strutils
type
symbol_frq = tuple[name:string,frq:int]
var
symbol_frq_seq:seq[symbol_frq]
sound_symbol:seq[string]
delay_symbol:seq[int]
discard """
1 262 523 1047
2 294 587 1175
3 330 659 1319
4 349 698 1397
5 392 784 1568
6 440 880 1760
7 494 988 1967
"""
proc MyBeep(frq:int,delay_time:int) =
if Beep(cast[DWORD](frq),cast[DWORD](delay_time)) == 0:
echo "beep failed"
var D_TIME:int = 100
echo "input a delay time:"
D_TIME = parseInt(readline(stdin))
#C調的音符<->頻率對應關係
#後綴 “-” 表示低音
#無後綴 表示中音
#後綴 “+” 表示高音
symbol_frq_seq = @[("0",0),("1-",262),("2-",294),("3-",330),("4-",349),("5-",392),("6-",440),("7-",494),
("1",523),("2",587),("3",659),("4",698),("5",784),("6",880),("7",988),
("1+",1047),("2+",1175),("3+",1319),("4+",1397),("5+",1568),("6+",1760),("7+",1967)]
#小蜜蜂樂譜
sound_symbol= @["5","3","3",
"4","2","2",
"1","2","3","4",
"5","5","5",
"5","3","3",
"4","2","2",
"1","3","5","5","3",
"2","2","2","2",
"2","3","4",
"3","3","3","3",
"3","4","5",
"5","3","3",
"4","2","2",
"1","3","5","5",
"1"]
#節拍表C = 1
delay_symbol =
@[1,1,2,
1,1,2,
1,1,1,1,
1,1,2,
1,1,2,
1,1,2,
1,1,1,1,
8,
1,1,1,1,
1,1,2,
1,1,1,1,
1,1,2,
1,1,2,
1,1,2,
1,1,1,1,
8]
for i in 0..len(sound_symbol)-1:
var fre :int = -1
for s_f in symbol_frq_seq:
if sound_symbol[i] == s_f.name :
fre = s_f.frq
break
if fre == -1:
echo "fre err"
quit(1)
MyBeep(fre,D_TIME*delay_symbol[i])
echo "sym=",sound_symbol[i]," delay=",delay_symbol[i]
#echo symbol_frq_seq
附:小蜜蜂樂譜