文档章节

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

北风其凉
 北风其凉
发布于 2016/07/10 22:14
字数 1195
阅读 58
收藏 0

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

© 著作权归作者所有

共有 人打赏支持
北风其凉

北风其凉

粉丝 118
博文 498
码字总数 463468
作品 4
朝阳
程序员
私信 提问
Microsoft Windows Logo(MSWLogo)中的基础数学函数及补充

今天看了下 Microsoft Windows Logo(下文简称MSWLogo)与数学有关的函数,对比了下.NET4.0提供的基础数学函数库(System.Math,在动态库文件mscorlib.dll内实现),计划写篇文章总结并补充了...

北风其凉
2016/06/29
25
0
解决运行MSWLogo时触发BEX导致崩溃的问题

我使用的操作系统是Win7旗舰版,MSWLogo(Microsoft Windows Logo)程序版本为6.5b 今天在我尝试打开MSWLogo程序时,突然发现程序打不开了,并且会提示崩溃信息: 问题的详细信息描述如下: ...

北风其凉
2016/07/05
77
0
Microsoft Windows Logo(MSWLogo)的颜色设定

今天研究了下 Microsoft Windows Logo(下文简称MSWLogo)中的颜色。 与颜色的设定有关的命令一共有三个: 1、SETPENCOLOR,可简写为SETPC,用于设定画笔颜色 2、SETFLOODCOLOR,可简写为SET...

北风其凉
2016/07/10
66
0
logo语言编程介绍

绘图是LOGO语言中最主要的功能,佩伯特博士就是希望能通过绘图的方式来培养学生学习电脑的兴趣和正确的学习观念。LOGO语言从开始发展到现在,已有Windows版本——MSWLogo,包括Windows 3.X版...

crossmix
2015/10/14
375
0
关于delphi Com+调用C# DLL的一点说明[转]

最近公司进行产品改造,由于存在部分代码是用delphi写的Com+需要调用C#写的Dll方法,经过网上一些搜索和摸索,调用已经OK。但是至于两者之间的事务问题还需要用到的朋友深入研究。 现在来说一...

老朱教授
2017/08/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

day11

architect刘源源
今天
7
0
论学好Linux系统的超级重要性

不知道各位在日常的工作生活中有没有接触过“rm -rf /*”这个命令,因为这个命令搞出来的事情可还不少呢!前段时间就在一个群里看到了有个小伙子,老板让他去维护一下服务器,这小伙也不太懂...

Linux就该这么学
昨天
6
0
git 使用

1,首先在github配置好信息和仓库,然后在本地进行操作 git init git config user.name 'zhangwuer' git config user.email '56789053@qq.com' 2,与远程分支建立连接 git checkout -b test......

天王盖地虎626
昨天
3
0
git checkout 命令详解

在日常的git操作中,git checkout——检出,是我们的常用命令。最为常用的两种情形是创建分支和切换分支。 在下面的命令中,使用了一些简写,在这里说明一下: git st # git statusgit ci ...

shzwork
昨天
11
0
【Nginx】Nginx多级代理,获取客户端真实请求IP以及每级代理IP

Nginx多级代理,获取客户端真实请求IP以及每级代理IP 如图所示,每一级nginx里的location配置里需要加上对应的配置,最后一级nginx是直接到应用,测试时为了方便,直接用echo模块去测试,打印...

薛定谔的旺
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部