上一次已经可以生成随机的音乐,要从单调的声音变成音乐,最简单的是模仿,那么先根据菊花台的简谱整一个吧。简谱是网上找的。为了简单,乐曲只生成中间一段。
写头文件没变,依然是:Head.h,Head.cpp,因为不需要随机产生音符,那么随机数那个就不用了。
Head.h:
#ifndef HEAD_H_
#define HEAD_H_
class Head{
public:
Head();
void setsize(int);
long int getsa();
long int getsize();
~Head();
private:
char RIFF[4];
long int size0;
char WAVE[4];
char FMT[4];
long int size1;
short int fmttag;
short int channel;
long int samplespersec;
long int bytepersec;
short int blockalign;
short int bitpersamples;
char DATA[4];
long int size2;
};
#endif /* HEAD_H_ */
Head.cpp:
#include "Head.h"
#include<iostream>
using namespace std;
Head::Head(){
strcpy(RIFF,"RIFF");
size0=0;
strcpy(WAVE,"WAVE");
strcpy(FMT,"fmt ");
size1=16;
fmttag=1;
channel=1;
samplespersec=11025;
bytepersec=11025;
blockalign=1;
bitpersamples=8;
strcpy(DATA,"data");
size2=0;
cout<<RIFF<<size0<<WAVE<<endl;
}
Head::~Head(){
cout<<123<<endl;
}
void Head::setsize(int size){
Head::size0=size+24;
Head::size2=size;
}
long int Head::getsa(){
return Head::samplespersec;
}
long int Head::getsize(){
return Head::size2;
}
最后是MAIN:其中L[8],N[8],H[8],I[8]存的是不同音的频率。jiepai存的就是数据了。声音波形还是用的正弦波,其中每个节拍里声音轻重也是整了个正弦函数,这个比较简单,实际上不同乐器的差别在每个节拍里的函数肯定是差别很大的。还没细想过。
#include <iostream>
#include<fstream>
#include"Head.h"
#include<math.h>
#include"R.h"
using namespace std;
//L1 131 L2 147 L3 165 L4 175 L5 196 L6 220 L7 247
//N1 262 N2 296 N3 330 N4 349 N5 392 N6 440 N7 494
//H1 523 H2 587 H3 659 H4 698 H5 784 H6 880 H7 988
//I1 1047 I2 1175 I3 1319 I4 1397 I5 1568 I6 1760 I7 1976
int L[8]={0,131,147,165,175,196,220,247};
int N[8]={0,262,296,330,349,392,440,494};
int H[8]={0,523,587,659,698,784,880,988};
int I[8]={0,1047,1175,1319,1397,1568,1760,1979};
int pai=11025/4;
int jiepai[80][2]={{N[3],4},{N[3],2},{N[2],2},{N[3],4},{N[0],4},{N[3],2},{N[5],2},
{N[3],2},{N[2],2},{N[3],8},{N[1],4},{N[1],2},{N[2],2},{N[3],2},
{N[5],2},{N[3],4},{N[2],4},{N[2],2},{N[1],2},{N[2],8},{N[3],6},
{N[5],1},{N[3],1},{N[6],2},{N[5],6},{N[6],2},{N[5],2},{N[5],2},
{N[3],2},{N[5],6},{L[5],5},{N[3],4},{N[2],2},{N[2],2},{N[5],4},
{N[3],2},{N[2],2},{N[2],4},{N[1],4},{N[2],8},{N[3],4},{N[3],2},
{N[2],2},{N[3],8},{N[3],2},{N[5],2},{N[3],2},{N[3],2},{N[3],8},
{N[1],4},{N[1],2},{N[2],2},{N[3],2},{N[5],2},{N[3],4},{N[2],4},
{N[2],2},{N[2],1},{N[2],8},{N[3],6},{N[5],1},{N[3],1},{N[6],1},
{N[5],6},{N[6],2},{N[5],2},{N[5],2},{N[3],2},{N[5],8},{N[0],2},
{N[3],2},{N[2],2},{N[3],2},{N[3],4},{N[5],4},{N[3],2},{N[2],2},
{N[2],2},{N[1],7},{N[0],8}};
void runrun(){
cout<<jiepai[3][1]<<endl;
Head head;
int i,i2,i3;
float a=0;
i3=0;
int size=0;
for(i=0;i<80;i++){
size+=jiepai[i][1];
}
head.setsize(size*pai);//将数据文件大小放进WAV头里面
cout<<head.getsize()<<endl;
char body[head.getsize()];//同时将WAV的数据大小确认
for(i2=0;i2<80;i2++)
{
if(jiepai[i2][0]!=0){
a=(11025/(jiepai[i2][0]));};
for(i=0;i<jiepai[i2][1]*pai;i++){
if(jiepai[i2][0]!=0){
body[i+i3]=(int)(64*sin(6.28/a*i)*(sin(3.14*i/pai/jiepai[i2][1]))+128);}
else{
body[i+i3]=128;
};
}
i3+=jiepai[i2][1]*pai;
cout<<a<<" "<<i3<<endl;
}
ofstream ocout;
ocout.open("1213.wav",ios::out|ios::binary);
ocout.write((char*)&head,sizeof head);
ocout.write((char*)&body,sizeof body);
ocout.close();
// cout <<head.getsize() <<" "<<dou[0]<<endl;
}
int main() {
runrun();
return 0;
}
测试通过,貌似听起来有几个音可能手误写错了,但是总体来说还是挺好玩的。
原文链接: https://www.cnblogs.com/shibuliao/p/3819803.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/136354
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!