用c语言实现作曲与播放教程~,原创哦~ - Sky-J - 博客园
用c语言实现作曲与播放教程~,原创哦~
本程序可以通过输入简谱用windows自带蜂鸣器函数播放出音乐,会编程的你可以借此在朋友面前show一下啦,哈哈
首先,下面这个是样例程序,里面有《国歌》《樱花草》《菊花台》《朋友》《生日快乐》这几首歌曲,以后有时间再做一些
播放直接引用相应函数即可
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<windows.h> 2 #include<stdio.h> 3 void check(); 4 void Birthday(); 5 void JuHuaTai(); 6 void YingHuaCao(); 7 void GuoGe(); 8 void PengYou(); 9 int main() 10 { 11 PengYou(); 12 return 0 ; 13 } 14 void check() 15 { 16 int ff=21; 17 unsigned a[]= 18 { 19 262,294,330,349,392,440,494,523,587,659,698,784,880,988,1046,1175,1318,1397,1568,1760,1976, 20 }; 21 unsigned b[]= 22 { 23 1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000, 24 }; 25 for(int i=0; i<ff; i++) 26 Beep(a[i],b[i]); 27 } 28 void Birthday() 29 30 { 31 unsigned frequency[]= 32 { 33 392,392,440,392,523,494, 34 35 392,392,440,392,587,523, 36 37 392,392,784,659,523,494,440, 38 39 698,698,659,523,587,523 40 } 41 ; 42 unsigned delay[]= 43 { 44 375,125,500,500,500,1000, 45 46 375,125,500,500,500,1000, 47 48 375,125,500,500,500,500,1000, 49 50 375,125,500,500,500,1000, 51 } 52 ; 53 for(int i=0; i<25; i++) 54 { 55 Beep(frequency[i],delay[i]); 56 } 57 } 58 void JuHuaTai() 59 { 60 int LL=182; 61 unsigned frequency[]= 62 { 63 0,0,0,523,587, 64 659,659,784,880,880,1318, 65 1175,1046,1046,880,784, 66 880,784,659,587,523,440,523, 67 587,587,659,587,523,587, 68 659,659,784,880,880,1318, 69 1175,1046,1046,1175,1046, 70 784,784,659,988,1046,523,587, 71 659,587,523, 72 659,659,587,659,0, 73 659,784,659,587,659, 74 523,523,587,659,784,659, 75 587,587,523,587,0, 76 659,784,659,880,784, 77 880,784,784,659,784,784, 78 659,587,659,784,659,587, 79 587,587,523,587, 80 659,659,587,659,0, 81 659,784,659,587,659, 82 523,523,587,659,784,659, 83 587,587,523,587,0, 84 659,784,659,880,784, 85 880,784,784,659,784, 86 659,587,659,784,659,587, 87 587,523,523, 88 0,0,0,523,587, 89 659,659,784,880,880,1318, 90 1175,1046,1046,880,784, 91 880,784,659,587,523,440,523, 92 587,587,523,587,523,587, 93 659,659,784,880,880,1318, 94 1175,1046,1046,1175,1046, 95 784,784,659,988,1046,523,587, 96 659,587, 97 523, 98 99 }; 100 unsigned delay[]= 101 { 102 500,500,500,250,250, 103 500,250,250,500,250,250, 104 250,250,250,250,1000, 105 250,250,250,250,500,250,250, 106 500,250,250,500,250,250, 107 500,250,250,500,250,250, 108 250,250,250,250,1000, 109 500,250,250,250,250,250,250, 110 1000,750,4250, 111 500,250,250,500,500, 112 250,250,250,250,1000, 113 500,250,250,250,250,500, 114 500,250,250,500,500, 115 750,125,125,250,750, 116 250,250,250,250,750,250, 117 500,250,250,500,250,250, 118 500,250,250,1000, 119 500,250,250,500,500, 120 250,250,250,250,1000, 121 500,250,250,250,250,500, 122 500,250,250,500,500, 123 750,125,125,250,750, 124 250,250,250,250,1000, 125 500,250,250,500,250,250, 126 250,250,1500, 127 500,500,500,250,250, 128 500,250,250,500,250,250, 129 250,250,250,250,1000, 130 250,250,250,250,500,250,250, 131 500,250,250,500,250,250, 132 500,250,250,500,250,250, 133 250,250,250,250,1000, 134 500,250,250,250,250,250,250, 135 1000,1000, 136 2000, 137 138 139 }; 140 for(int i=0; i<LL; i++) 141 { 142 Beep(frequency[i],delay[i]); 143 } 144 } 145 void YingHuaCao() 146 { 147 int ff=228; 148 unsigned a[]= 149 { 150 523,659,587,659, 151 523,659,587, 152 523,659,587,659, 153 523, 154 523,659,587,659, 155 784,659,587, 156 523, 157 523,659,587,659, 158 523,659,587, 159 523,659,587,659, 160 523, 161 523,659,587,659, 162 784,659,587, 163 523, 164 659,587, 165 523,392,523,659, 166 587,659,587, 167 523,330,440,523, 168 494,523,494,440,523,440,392,0,523,523, 169 698,659,587,523,659, 170 587,659,587, 171 523,392,523,659, 172 587,659,587, 173 523,330,440,523, 174 494,523,494,440,523,440,392,0,523,523, 175 698,659,587,523,659,587,0,659, 176 523,587,523,0,494,440, 177 392,523,659,698, 178 587,0,659, 179 523,523,587, 180 523,0,494,440, 181 392,523,659,698,587,880,784, 182 659,784,784,659,587,587,880,784, 183 659,784,784,659,587,523,523,587,659, 184 784,659,587,784,659, 185 523,587,659,784,587,880,784, 186 659,784,784,659,587, 187 587,880,784, 188 659,784,784,659,587, 189 523,523,587,659,784,659,587,784,659, 190 523,587,659,784,587,0,659, 191 523, 192 523,659,587,659, 193 523,659,587, 194 523,659,587,659, 195 523, 196 523,659,587,659, 197 784,659,587, 198 523, 199 523,659,587,659, 200 523,659,587, 201 523,659,587,659, 202 523, 203 523,659,587,659, 204 784,659,587, 205 523, 206 }; 207 unsigned b[]= 208 { 209 350,350,350,350, 210 350,350,700, 211 350,350,350,350, 212 1400, 213 350,350,350,350, 214 1050,175,175, 215 2800, 216 350,350,350,350, 217 350,350,700, 218 350,350,350,350, 219 1400, 220 350,350,350,350, 221 1050,175,175, 222 2100, 223 525,175, 224 350,350,350,350, 225 700,525,175, 226 350,350,350,350, 227 700,350,175,875,350,175,875,350,175,175, 228 350,350,350,175,175, 229 700,525,175, 230 350,350,350,350,700,525,175, 231 350,350,350,350,700,350,175,875,350,175,875,350,175,175, 232 350,350,350,175,175, 233 700,350,350, 234 1050,350,700,350,175,175, 235 350,350,350,350,700,350,350, 236 875,175,350, 237 700,350,175,175, 238 350,350,350,350, 239 700,525,175, 240 350,350,350,175,875, 241 525,175, 242 350,350,350,175,175, 243 700,350,175,875,350,175,875,525,175, 244 350,350,350,175,175, 245 700,525,175, 246 350,350,350,175,175, 247 700,525,175, 248 350,350,350,175,175, 249 700,350,175,875,350,175,875,525,175, 250 350,350,350,175,875, 251 350,350, 252 1400, 253 350,350,350,350, 254 350,350,700, 255 350,350,350,350, 256 1400, 257 350,350,350,350, 258 1050,175,175, 259 2800, 260 350,350,350,350, 261 350,350,700, 262 350,350,350,350, 263 1400, 264 350,350,350,350, 265 1050,175,175, 266 2100, 267 }; 268 for(int i=0; i<ff; i++) 269 { 270 printf("第%d个音符\n",i); 271 Beep(a[i],b[i]); 272 } 273 } 274 void GuoGe() 275 { 276 int ff=113; 277 unsigned a[]= 278 { 279 523,659,784,784, 280 880,784, 281 659,523,784,784,784, 282 659,523, 283 392,392,392,392,392,392, 284 523,0,392, 285 523,523,523,523,392,440,494, 286 523,523,0,659,523,587,659, 287 784,784,659,659,523,659, 288 784,659,587,587, 289 880,784,587,659, 290 784,659,0,784, 291 659,587,659,523,659,0, 292 392,440,523,523, 293 659,659,784,784, 294 587,587,587,440, 295 587,392, 296 523,523,659,659,784, 297 523,659,784,784,880,784, 298 659,523,784,784,784, 299 659,0,523,0, 300 392,523,659,523,784,784,784, 301 659,0,523,0, 302 392,523,392,523,392,523,523,0, 303 304 }; 305 unsigned b[]= 306 { 307 350,350,350,350,700,700, 308 525,175,350,350,350, 309 700,700,350,350,350,350,350,350,700, 310 350,350,1050,350,525,175,350,175,175, 311 700,700,350,350,350,175,175, 312 700,700,525,175,525,175, 313 525,175,700,1400, 314 700,700,700,700, 315 350,350,350,350,350,175,175,700, 316 700,700,525,175,350,350, 317 525,175,350,350,350,175,175,700, 318 1050,350, 319 1050,350, 320 1050,350, 321 1400, 322 525,175,350,350, 323 700,700,525,175,350,350,350, 324 350,350,350,350, 325 700,700,525,175,350,350,350, 326 350,350,350,350, 327 700,700,700,700,700,700,700,700, 328 }; 329 for(int i=0; i<ff; i++) 330 { 331 printf("第%d个音符\n",i); 332 Beep(a[i],b[i]); 333 } 334 } 335 void PengYou() 336 { 337 int ff=131; 338 unsigned a[]= 339 { 340 0,587,659,523,587,659,587,659,784, 341 880,784,659,659,587,659,523,587,659,392,587,659, 342 587,440,523, 343 587,659,523,587,659,523,587,659, 344 784,784,880,523,440,523, 345 587,587,523,440,440,523, 346 587,659,587,523,587,587,659,587,523, 347 523,587,587,659,523,587,659, 348 784,784,784,880,523,440,523, 349 587,587,523,440,440,392,440, 350 523,0, 351 659,659,784, 352 784,784,784,880,784,880,988, 353 1046,880,880,784,659,659,587,523, 354 523,880,784,659,587,523, 355 523,440,587,659,659,784, 356 784,784,784,880,784,880,988, 357 1046,880,880,784,659,659,587,523, 358 523,880,784,659,587,523, 359 440,440,523,523, 360 361 }; 362 unsigned b[]= 363 { 364 900,450,450,900,450,450,900,450,450, 365 900,450,450,900,450,450,900,450,450,900,450,450, 366 900,450,4950, 367 450,450,900,450,450,900,450,450,900,450,450,900,450,450, 368 900,450,450,900,450,450, 369 450,450,450,225,225,900,450,225,225, 370 900,450,225,225,900,450,450, 371 900,450,225,225,900,450,450, 372 900,450,225,225,900,450,450, 373 1800,900, 374 450,225,225, 375 450,450,450,225,1125,450,450, 376 450,450,450,225,1125,450,225,1125, 377 450,225,1125,450,225,1125, 378 225,225,1350,450,225,225, 379 450,450,450,225,1125,450,450, 380 450,450,450,225,1125,450,225,1125, 381 450,225,1125,450,225,1125, 382 450,225,675,1350, 383 }; 384 for(int i=0; i<ff; i++) 385 { 386 printf("第%d个音符\n",i); 387 Beep(a[i],b[i]); 388 } 389 }
View Code
有没有运行看看?神奇吧?下面我来教你自己做音乐~
Beep(音调,音长);
这个函数是主角~~
音长以毫秒为单位~
下面这个程序是用来写程序能识别的谱子的,我已经注释的很详细了,接下来会有例子
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #define inandout 2 3 #include <stdio.h> 4 #define one 900 5 int main() 6 { 7 #ifdef inandout 8 freopen("1.in","r",stdin); 9 freopen("1.out","w+",stdout); 10 #endif 11 //******************************************* 12 char a[4]; 13 int b; 14 int a1,b1; 15 int pai; 16 scanf("%d%d",&a1,&b1);//先输入X/X 17 pai=4*one/b1;//定义每拍几毫秒 18 int T=0; 19 printf("本曲谱以%d分音符为一拍每小节%d拍\n",b1,a1); 20 while(scanf("%s",a),a[0]!='@')//输入音符x#高音,xb低音,\回车,@结束输入 21 { 22 if(a[0]=='\\') 23 printf("\n"); 24 else 25 { T++; 26 switch(a[0]) 27 { 28 case '0': 29 printf("0,"); 30 break; 31 case '1': 32 { 33 if(a[1]=='#') 34 printf("%d,",1046); 35 else if(a[1]=='b') 36 printf("%d,",262); 37 else 38 printf("%d,",523); 39 break; 40 } 41 case '2': 42 { 43 if(a[1]=='#') 44 printf("%d,",1175); 45 else if(a[1]=='b') 46 printf("%d,",294); 47 else 48 printf("%d,",587); 49 break; 50 } 51 case '3': 52 { 53 if(a[1]=='#') 54 printf("%d,",1318); 55 else if(a[1]=='b') 56 printf("%d,",330); 57 else 58 printf("%d,",659); 59 break; 60 } 61 case '4': 62 { 63 if(a[1]=='#') 64 printf("%d,",1397); 65 else if(a[1]=='b') 66 printf("%d,",349); 67 else 68 printf("%d,",698); 69 break; 70 } 71 case '5': 72 { 73 if(a[1]=='#') 74 printf("%d,",1568); 75 else if(a[1]=='b') 76 printf("%d,",392); 77 else 78 printf("%d,",784); 79 break; 80 } 81 case '6': 82 { 83 if(a[1]=='#') 84 printf("%d,",1760); 85 else if(a[1]=='b') 86 printf("%d,",440); 87 else 88 printf("%d,",880); 89 break; 90 } 91 case '7': 92 { 93 if(a[1]=='#') 94 printf("%d,",1976); 95 else if(a[1]=='b') 96 printf("%d,",494); 97 else 98 printf("%d,",988); 99 break; 100 } 101 } 102 } 103 104 } 105 printf("\n共音符%d个\n\n",T); 106 T=0; 107 while(scanf("%d",&b)!=EOF)//按顺序输入每个音符拍数 下面每加一杠,数值乘2 如4分音符为1,8分为2,0为回车,若有连音只需按顺序输入音长 5 - -为111 108 { 109 if(b==0) 110 printf("\n"); 111 else 112 { 113 T++; 114 if(b>10) 115 { 116 int sum=0; 117 while(b!=0) 118 { 119 if(b%10!=0) 120 sum+=(pai/(b%10)); 121 b/=10; 122 } 123 printf("%d,",sum); 124 } 125 else 126 printf("%d,",pai/b); 127 } 128 } 129 printf("\n共音长%d个\n\n",T); 130 return 0; 131 }
View Code
想要写谱子,至少需要知道一些基本的乐理,就是每个音符的长度表示(否则你无法输入长度的数据),几分音符,延音占几拍啦之类的,不懂得自行脑补
下面以欢乐颂为例子来写个谱子
1,建立一个1.txt文件在写谱程序的根目录下,就是跟他放一块
2,输入曲谱,格式如下
先输入拍号,欢乐颂为4分音符为一拍,每小节4拍,输入:4 4回车
下面把谱子里的数字打进去(注意!高音为x#,低音为xb),为了方便看,最好每小节回车一次,像这样
记住,\为分小结回车标志,程序会在输入/的地方输出一个回车,主要是方便查错
4 4
3 3 4 5 \
5 4 3 2 \
1 1 2 3 \
3 2 2 \
3 3 4 5 \
5 4 3 2 \
1 1 2 3 \
2 1 1 \
2 3 1\
2 3 4 3 1 \
2 3 4 3 2 \
1 2 5b 3 \
3 3 4 5 \
5 4 3 2 \
1 1 2 3 \
2 1 1 \
@
@为结束标志,在这里我只输入了一次循环,完整的可以自行补上
下面输入音长
格式如下
按顺序输入每个音符拍数 下面每加一杠,数值乘2 如4分音符为1,8分为2,0为回车,若有连音只需按顺序输入音长 5 - -为111 ,附点音符点为音符x音长的一半
不同音符音长一定要用空格隔开,相同的一定要连起来(有时候由乐曲决定),每小节的0是换行,最好输入好查错
4 4
3 3 4 5 \
5 4 3 2 \
1 1 2 3 \
3 2 2 \
3 3 4 5 \
5 4 3 2 \
1 1 2 3 \
2 1 1 \
2 3 1\
2 3 4 3 1 \
2 3 4 3 2 \
1 2 5b 3 \
3 3 4 5 \
5 4 3 2 \
1 1 2 3 \
2 1 1 \
@
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
12 2 11 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
12 2 11 0
12 1 1 0
1 2 2 1 1 0
1 2 2 1 1 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
12 1 11 0
像这样输入完了保存在1.txt里
运行作曲程序
得到1.out,打开后是这样的
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
本曲谱以4分音符为一拍每小节4拍 659,659,698,784, 784,698,659,587, 523,523,587,659, 659,587,587, 659,659,698,784, 784,698,659,587, 523,523,587,659, 587,523,523, 587,659,523,587,659,698,659,523, 587,659,698,659,587, 523,587,392,659, 659,659,698,784, 784,698,659,587, 523,523,587,659, 587,523,523, 共音符62个 900,900,900,900, 900,900,900,900, 900,900,900,900, 1350,450,1800, 900,900,900,900, 900,900,900,900, 900,900,900,900, 1350,450,1800, 1350,900,900, 900,450,450,900,900, 900,450,450,900,900, 900,900,900,900, 900,900,900,900, 900,900,900,900, 900,900,900,900, 1350,900,1800, 共音长62个
View Code
看到音长和音符数值一样,可以笑一下了,但是还没成功呢,得去程序里验证一下,把上面串东西复制到下面的程序标注处并运行
#include<windows.h>
#include<stdio.h>
void check();
int main()
{
check();
return 0 ;
}
void check()
{
int ff=62;//音符个数别忘了写
unsigned a[]=
{
//音符
};
unsigned b[]=
{
//音长
};
for(int i=0; i<ff; i++)
{
printf("第%d个音符\n",i+1);//显示出来好找错
Beep(a[i],b[i]);
}
}
贴好是这样的
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<windows.h> 2 #include<stdio.h> 3 void check(); 4 int main() 5 { 6 check(); 7 return 0 ; 8 } 9 void check() 10 { 11 int ff=62;//音符个数别忘了写 12 unsigned a[]= 13 { 14 659,659,698,784, 15 784,698,659,587, 16 523,523,587,659, 17 659,587,587, 18 659,659,698,784, 19 784,698,659,587, 20 523,523,587,659, 21 587,523,523, 22 587,659,523,587,659,698,659,523, 23 587,659,698,659,587, 24 523,587,392,659, 25 659,659,698,784, 26 784,698,659,587, 27 523,523,587,659, 28 587,523,523, 29 30 //音符 31 }; 32 unsigned b[]= 33 { 34 900,900,900,900, 35 900,900,900,900, 36 900,900,900,900, 37 1350,450,1800, 38 900,900,900,900, 39 900,900,900,900, 40 900,900,900,900, 41 1350,450,1800, 42 1350,900,900, 43 900,450,450,900,900, 44 900,450,450,900,900, 45 900,900,900,900, 46 900,900,900,900, 47 900,900,900,900, 48 900,900,900,900, 49 1350,900,1800, 50 //音长 51 }; 52 for(int i=0; i<ff; i++) 53 { 54 printf("第%d个音符\n",i+1);//显示出来好找错 55 Beep(a[i],b[i]); 56 } 57 }
View Code
但是运行后我们发现,节奏太慢,完全不像欢乐颂啊,不要紧,打开作谱程序
看到开头的#define one 900
这里定义了每个4分音符的时间,单位毫秒,我们改为400,再运行,得到1.out,复制音长粘贴
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#include<windows.h> #include<stdio.h> void check(); int main() { check(); return 0 ; } void check() { int ff=62;//音符个数别忘了写 unsigned a[]= { 659,659,698,784, 784,698,659,587, 523,523,587,659, 659,587,587, 659,659,698,784, 784,698,659,587, 523,523,587,659, 587,523,523, 587,659,523,587,659,698,659,523, 587,659,698,659,587, 523,587,392,659, 659,659,698,784, 784,698,659,587, 523,523,587,659, 587,523,523, //音符 }; unsigned b[]= { 400,400,400,400, 400,400,400,400, 400,400,400,400, 600,200,800, 400,400,400,400, 400,400,400,400, 400,400,400,400, 600,200,800, 600,400,400, 400,200,200,400,400, 400,200,200,400,400, 400,400,400,400, 400,400,400,400, 400,400,400,400, 400,400,400,400, 600,400,800, //音长 }; for(int i=0; i<ff; i++) { printf("第%d个音符\n",i+1);//显示出来好找错 Beep(a[i],b[i]); } }
View Code
这下好多了,大功告成!
希望读者能做出自己的音乐也跟我分享一下,我会把你的贴在这里,另外有什么不懂得可以跟帖,我尽量回复。
程序均为原创,转载请注明出处,谢谢~