zoukankan      html  css  js  c++  java
  • C++生成简单WAV文件(三)——根据简谱生成菊花台

    上一次已经可以生成随机的音乐,要从单调的声音变成音乐,最简单的是模仿,那么先根据菊花台的简谱整一个吧。简谱是网上找的。为了简单,乐曲只生成中间一段。

    写头文件没变,依然是: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
Copyright © 2011-2022 走看看