700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【小程序】C语言实现简易钢琴-利用sin函数构造不同频率波形模拟各琴键发音

【小程序】C语言实现简易钢琴-利用sin函数构造不同频率波形模拟各琴键发音

时间:2023-11-01 06:18:33

相关推荐

【小程序】C语言实现简易钢琴-利用sin函数构造不同频率波形模拟各琴键发音

根据钢琴音调频率对照表,使用sin函数构造对应频率正弦波数据模拟各琴键声音,实现简易钢琴效果,结果写入wav文件中。

目录

程序效果实现过程样例代码测试用例参考资料

程序效果

截图1:键位图 钢琴键盘结构,包含3组Do Re Mi Fa So La Xi以及空格静音代表的空拍,使用字符'z'结束。

截图2:使用效果-欢乐颂 输入音符后,使用'z'回车即可结束录入,生成的文件位于D盘根目录下,播放即可。

实现过程

截图3:流程图

主要流程如上,需要注意的细节有以下几处:

0.每秒44100采样时,一个音符想要延续0.5秒左右就需要一个长度为22050的数组构造正弦波,不现实,采用s[1000]数组构造正弦波,使用for循环重复至30000左右。

1.使用有限长度数组构造正弦波,由于Π为无理数,在实际计算数值时,很难取到完整周期的分界点。

截图4:不连续现象

分界点选取间隔不大时,人耳听不出明显的噪音。

2.每个音符末尾需要插入一小段短暂静音,否则连续2各相同音会听成一个长音。

截图5:单音末尾静音

3.空拍使用完整静音

截图6:空拍的静音

样例代码

1.共享链接:C语言实现简易钢琴-利用sin函数构造不同频率波形模拟各琴键发音

/download/u013025955/11174606

2.关键代码

//钢琴键盘结构,包含3组Do Re Mi Fa So La Xi以及空格静音代表的空拍struct MusicNote{char noteName; //音符名称int frequence; //音符频率,根据钢琴音高频率对照表定义DWORD noteLength; //在使用sin函数构造正弦波信号的单个音实际字节长度,用于计算总长度,填写在wav文件头部,同时该长度让每个音能延续0.5秒左右,由nearZero*4*2*40算出,可以自定义时长,只要是nearZero的整数倍都行DWORD nearZero; //在使用sin函数构造正弦波信号时,不同频率采样值最接近完整周期的数据点,避免取不到完整周期导致杂音出现}note[NOTENUM] = {{'a', 130, 108800, 680}, {'q', 261, 81600, 170}, {'1', 523, 80960, 253},{'s', 146, 72640, 908}, {'w', 293, 60320, 754}, {'2', 587, 84320, 527},{'d', 164, 86400, 270}, {'e', 329, 75200, 940}, {'3', 659, 69680, 871},{'f', 174, 40460, 508}, {'r', 349, 101280, 633}, {'4', 698, 55680, 696},{'g', 195, 72480, 906}, {'t', 391, 90400, 565}, {'5', 784, 72320, 226},{'h', 220, 64320, 402}, {'y', 440, 64320, 402}, {'6', 880, 68240, 853},{'j', 246, 86240, 539}, {'u', 493, 78800, 985}, {'7', 988, 78720, 492},{' ', 0, 80000, 1000}};//正弦波生成函数void sin_sound(WORD *p, int n, int f){int i;double x, temp1;x = 2*PI*f/44100; //2Πf即可获得对应频率波形,44100为音频文件头定义的采样率,也需要考虑进去for (i=0; i<n; i++) //n的值通过本地测试21次,分别确定的,确定方法为查看正弦函数值从负数变成整数,经过x轴时最接近0的点,即最接近完整周期的点{temp1 = 5000 * sin(x*i);p[i] = (WORD)temp1;}}

测试用例

截图7:测试用例

参考资料

1.利用正弦波产生WAV文件

/download/guo19910426/5697181

2.钢琴的音高与频率对照表

/html//0314/37632175.shtm

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。