马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
事情的起因是因为在研究51单片机的时候找到了能通过蜂鸣器唱歌的程序,但是由于它是通过电磁线圈发生的缘故那个音质有点惨不忍睹。。。而且操作起来也比较反人类(如图)
然后我突发奇想(主要是大晚上没人培我跨年。。。。)想试试直接用c/c++在windows上能不能控制电脑“唱歌”,结果没有花多大力气就找到了Beep()函数
此地址为Beep()函数讲解
但是此帖除了给有关音阶进行了宏定义外想要做到唱歌还是在直接调用Beep()函数,总之我感觉这样做还是很反人类,于是我又在此基础上写了个头文件,除了宏定义外还写了个类,里面定义了一拍、二分之一拍、三分之一拍和四分之一拍的时间(因为在此之前我对于音乐乐理这方面的只是完全是零,突然学习也很不现实所以有关知识我都是硬着头皮查百度的来的,通过百度得知一拍的时间取决于你所定义的一分钟有多少拍,比如说如果定义一分钟是120拍那一拍就是60 / 120 = 0.5s = 500ms),又写了个求拍长的函数:class beat {
public :int beatTime;
public :int halfBeatTime;
public :int quarterBeatTime;
public :int oneThirdBeatTime;
};
int aBeatTime(int beatsPerMinute) {
return (60.0 / beatsPerMinute) * 1000;
}
(虽然字段用public不太好,但是由于是突发奇想我也懒得去get,set。。。)
(二分之一拍的拍长怎么求应该是废话了吧。。。),那么现在如果我想让计算机发出一拍的“do”声音的话只需要先new一个对象bt然后Beep(Do, bt.beatTime);即可(值得一提的是上面帖子的宏定义的"do"与系统默认的宏定义有冲突,所以我在自己的工程中吧do到si的首字母都大写了)
虽然这样看起来没那么抽象了,但是还是有些麻烦,于是我又在头文件里定义了几个函数专门用来代替Beep(),因为那么多宏定义我也不能完全搞明白哪个东西叫什么是干什么的,所以只对Do到Si,do1到si1(高音),qdo到qsi(低音)这些音阶写了函数,拿Do来举例:void ScaleDo(int beat) {
Beep(Do, beat);
}
相比起用Beep我现在想在计算机上发出一拍的“do”只需要ScaleDo(bt.beattTime)即可。然后对于空拍你不能让beep的参数为0所以我用了Sleep()函数来代替,每当需要用到时直接停顿所需拍长的时间即可。那么接下来我们在主函数中在实例化对象后调用函数来进行“创作了”,在工程文件里我用这些函数搞了段badapple(因为这个东西前段时间在B站挺火的),因为一些比较低的声音似乎无法实现(毕竟我懒也没找到),那就只能退而求其次用qdo到qsi了。虽然我找到了简谱但是那些奇奇怪怪的符号和什么重复记号我实在是弄不明白(小学三年级音乐课没好好上实锤了),就只弄了一遍带歌词的部分,代码没技术含量在这里就不放了,总之比起单片机的蜂鸣器效果还是好了很多的(勉勉强强能听出来),最后放一下工程文件,因为是自己乱写的原因没什么注释代码也乱,大家见谅哈
ConsoleApplication1.zip
(211.4 KB, 下载次数: 11)
|