Microsoft Windows Logo(MSWLogo)的BEEP组合旋律

不问归期 提交于 2019-12-17 17:38:33

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

Microsoft Windows Logo(下文简称MSWLogo) 的发声依靠SOUND命令实现(类似于C语言里的beep函数),如果要实现拼接成一段旋律,有时还需要用到WAIT命令实现休止符的效果。

1、SOUND命令,播放声音,后接参数为包含两个参数的LIST,第一个参数为频率,第二个参数为发声时长

2、WAIT命令,等待指定长度的时间,后接参数为1/60秒的倍数

一台88键的钢琴,每个键都有自己固定的频率,计算此频率的公式可以参考维基百科条目:

钢琴键的频率:https://en.wikipedia.org/wiki/Piano_key_frequencies

(目前这一条目并还没有被收入汉语维基,所以感兴趣的朋友只能看英文版)

要实现弹琴的效果,可参照如下步骤:

第一步,建立两个全局变量,SOUND_LENGTH是每个音节的默认长度,WAIT_LENGTH是每个休止符的默认长度

MAKE "SOUND_LENGTH 200
MAKE "WAIT_LENGTH 50

第二步,创建两个Procedure,用于播放单个音符

TO PLAY_SOUND :NOTE
  LOCALMAKE "FREQ GET_FREQ :NOTE
  LOCALMAKE "SOUND_PAIR []
  LOCALMAKE "SOUND_PAIR LPUT :FREQ :SOUND_PAIR
  LOCALMAKE "SOUND_PAIR LPUT :SOUND_LENGTH :SOUND_PAIR
  PRINT :SOUND_PAIR
  SOUND :SOUND_PAIR
END

TO PLAY_SOUND_WITH_LEN :NOTE :LENGTH
  LOCALMAKE "FREQ GET_FREQ :NOTE
  LOCALMAKE "SOUND_PAIR []
  LOCALMAKE "SOUND_PAIR LPUT :FREQ :SOUND_PAIR
  LOCALMAKE "SOUND_PAIR LPUT :LENGTH :SOUND_PAIR
  PRINT :SOUND_PAIR
  SOUND :SOUND_PAIR
END

TO GET_FREQ :NOTE
  IF :NOTE = "A         [ OUTPUT 220 ]
  IF :NOTE = "A_SHARP   [ OUTPUT 223 ]
  IF :NOTE = "B         [ OUTPUT 247 ]
  IF :NOTE = "C         [ OUTPUT 262 ]
  IF :NOTE = "C_SHARP   [ OUTPUT 277 ]
  IF :NOTE = "D         [ OUTPUT 294 ]
  IF :NOTE = "D_SHARP   [ OUTPUT 311 ]
  IF :NOTE = "E         [ OUTPUT 330 ]
  IF :NOTE = "F         [ OUTPUT 349 ]
  IF :NOTE = "F_SHARP   [ OUTPUT 370 ]
  IF :NOTE = "G         [ OUTPUT 392 ]
  IF :NOTE = "G_SHARP   [ OUTPUT 415 ]
  IF :NOTE = "A_2       [ OUTPUT 440 ]
  IF :NOTE = "A_SHARP_2 [ OUTPUT 466 ]
  IF :NOTE = "B_2       [ OUTPUT 494 ]
  IF :NOTE = "C_2       [ OUTPUT 523 ]
  IF :NOTE = "C_SHARP_2 [ OUTPUT 554 ]
  IF :NOTE = "D_2       [ OUTPUT 587 ]
  IF :NOTE = "D_SHARP_2 [ OUTPUT 622 ]
  IF :NOTE = "E_2       [ OUTPUT 659 ]
  IF :NOTE = "F_2       [ OUTPUT 698 ]
  IF :NOTE = "F_SHARP_2 [ OUTPUT 740 ]
  IF :NOTE = "G_2       [ OUTPUT 784 ]
  IF :NOTE = "G_SHARP_2 [ OUTPUT 831 ]
END

PLAY_SOUND 使用默认的播放时间播放指定音符;

PLAY_SOUND_WITH_LEN 使用指定长度的时间播放指定音符;

GET_FREQ 根据输入的按键名返回该键所代表的频率,这里面只实现了一部分琴键的频率,A-G分别代表 do re mi fa so la si 七个音符,SHARP代表音乐中的“♯”符号。(哈哈,这里说个题外话,这里的“♯”注意不要写成“#”,就像有个语言其实叫C♯而不是C#,Sharp符号和井号的区别在于Sharp符号两竖是直的,两横是斜的,而井号中两横是平的,两竖是斜的)

第三步,使用PLAY_SOUND、PLAY_SOUND_WITH_LEN、SOUND命令、WAIT命令就可以写歌了,虽然这种方式写的歌音质实在无法保障~~~

如果想试下音,可以用下面这段代码测试,播放出来就是 do re mi fa so la si

TO MUSIC_TEST_SOUNDS

  PLAY_SOUND "A
  PLAY_SOUND "B
  PLAY_SOUND "C
  PLAY_SOUND "D
  PLAY_SOUND "E
  PLAY_SOUND "F
  PLAY_SOUND "G

END

下面我来秀一下操作 :-P 展示下自己根据简谱翻译的两首歌:

一、贝多芬的《欢乐颂》(乐谱来源于网络)

代码如下:

TO MUSIC_ODE_TO_JOY

  PLAY_SOUND "C_2
  PLAY_SOUND "C_2
  PLAY_SOUND "D_2
  PLAY_SOUND "F_2
  PLAY_SOUND "F_2
  PLAY_SOUND "D_2
  PLAY_SOUND "C_2
  PLAY_SOUND "B_2
  PLAY_SOUND "A_2
  PLAY_SOUND "A_2
  PLAY_SOUND "B_2
  PLAY_SOUND "C_2
  PLAY_SOUND "C_2
  PLAY_SOUND "B_2
  PLAY_SOUND "B_2
  WAIT :WAIT_LENGTH

  PLAY_SOUND "C_2
  PLAY_SOUND "C_2
  PLAY_SOUND "D_2
  PLAY_SOUND "F_2
  PLAY_SOUND "F_2
  PLAY_SOUND "D_2
  PLAY_SOUND "C_2
  PLAY_SOUND "B_2
  PLAY_SOUND "A_2
  PLAY_SOUND "A_2
  PLAY_SOUND "B_2
  PLAY_SOUND "C_2
  PLAY_SOUND "B_2
  PLAY_SOUND "A_2
  PLAY_SOUND "A_2
  WAIT :WAIT_LENGTH

  PLAY_SOUND "B_2
  PLAY_SOUND "B_2
  PLAY_SOUND "C_2
  PLAY_SOUND "A_2
  PLAY_SOUND "B_2
  PLAY_SOUND_WITH_LEN "C_2 :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "D_2 :SOUND_LENGTH / 2
  PLAY_SOUND "C_2
  PLAY_SOUND "A_2
  PLAY_SOUND "B_2
  PLAY_SOUND_WITH_LEN "C_2 :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "D_2 :SOUND_LENGTH / 2
  PLAY_SOUND "C_2
  PLAY_SOUND "B_2
  PLAY_SOUND "A_2
  PLAY_SOUND "B_2
  PLAY_SOUND "E

  PLAY_SOUND "C_2
  PLAY_SOUND "C_2
  PLAY_SOUND "C_2
  PLAY_SOUND "D_2
  PLAY_SOUND "F_2
  PLAY_SOUND "F_2
  PLAY_SOUND "D_2
  PLAY_SOUND "C_2
  PLAY_SOUND_WITH_LEN "D_2 :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "B_2 :SOUND_LENGTH / 2
  PLAY_SOUND "A_2
  PLAY_SOUND "A_2
  PLAY_SOUND "B_2
  PLAY_SOUND "C_2
  PLAY_SOUND "B_2
  PLAY_SOUND_WITH_LEN "A_2 :SOUND_LENGTH / 2
  PLAY_SOUND "A_2
  WAIT :WAIT_LENGTH

END

二、《送别》(乐谱来源于网络)

代码如下:

TO MUSIC_FAREWELL

  PLAY_SOUND "E
  PLAY_SOUND_WITH_LEN "C :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "E :SOUND_LENGTH / 2
  PLAY_SOUND "A_2
  WAIT :WAIT_LENGTH
  PLAY_SOUND "F
  PLAY_SOUND "A_2
  PLAY_SOUND "E
  WAIT :WAIT_LENGTH

  PLAY_SOUND "E
  PLAY_SOUND_WITH_LEN "A :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "B :SOUND_LENGTH / 2
  PLAY_SOUND "C
  PLAY_SOUND_WITH_LEN "B :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "A :SOUND_LENGTH / 2
  PLAY_SOUND "B
  WAIT :WAIT_LENGTH * 3

  PLAY_SOUND "E
  PLAY_SOUND_WITH_LEN "C :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "E :SOUND_LENGTH / 2
  PLAY_SOUND "A_2
  PLAY_SOUND "G
  PLAY_SOUND "F
  PLAY_SOUND "A_2
  PLAY_SOUND "E
  WAIT :WAIT_LENGTH

  PLAY_SOUND "E
  PLAY_SOUND_WITH_LEN "B :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "C :SOUND_LENGTH / 2
  PLAY_SOUND "D
  SOUND [175 200]
  PLAY_SOUND "A
  WAIT :WAIT_LENGTH * 3

  PLAY_SOUND "F
  PLAY_SOUND "A_2
  PLAY_SOUND "A_2
  WAIT :WAIT_LENGTH
  PLAY_SOUND "G
  PLAY_SOUND_WITH_LEN "F :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "G :SOUND_LENGTH / 2
  PLAY_SOUND "A_2
  WAIT :WAIT_LENGTH

  PLAY_SOUND_WITH_LEN "F :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "G :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "A_2 :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "F :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "F :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "E :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "C :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "A :SOUND_LENGTH / 2
  PLAY_SOUND "B
  WAIT :WAIT_LENGTH * 3

  PLAY_SOUND "E
  PLAY_SOUND_WITH_LEN "C :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "E :SOUND_LENGTH / 2
  PLAY_SOUND "A_2
  PLAY_SOUND_WITH_LEN "F :SOUND_LENGTH / 2
  PLAY_SOUND "F
  PLAY_SOUND "A_2
  PLAY_SOUND "E
  WAIT :WAIT_LENGTH

  PLAY_SOUND "E
  PLAY_SOUND_WITH_LEN "B :SOUND_LENGTH / 2
  PLAY_SOUND_WITH_LEN "C :SOUND_LENGTH / 2
  PLAY_SOUND "D
  SOUND [196 200]
  PLAY_SOUND "A

END

END

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!