有一段wave,如何编程改变它的音调呢?另:有无现成的源码? ^_*

解决方案 »

  1.   

    在CSDN论坛中搜一下“音量”。        //CD音量
    case 169:   //音量减小
     volumesize =  GetVolume(3);
     volumesize -= 4;
     if( volumesize < 0)
     volumesize = 0;
     SetVolume(3,volumesize);
      break;
     case 183:     //音量增加
     volumesize =  GetVolume(3);
     SetVolume(3,volumesize+6);
      break;////////////////////////////////////////////////////////////////////
    bool GetVolumeControl(HMIXER hmixer ,long componentType,long ctrlType,MIXERCONTROL* mxc)
    {
    MIXERLINECONTROLS mxlc;
    MIXERLINE mxl;
    mxl.cbStruct = sizeof(mxl);
    mxl.dwComponentType = componentType;
    if(!mixerGetLineInfo((HMIXEROBJ)hmixer, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE))
    {
    mxlc.cbStruct = sizeof(mxlc);
    mxlc.dwLineID = mxl.dwLineID;
    mxlc.dwControlType = ctrlType;
    mxlc.cControls = 1;
    mxlc.cbmxctrl = sizeof(MIXERCONTROL);
    mxlc.pamxctrl = mxc;
    if(mixerGetLineControls((HMIXEROBJ)hmixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE))
    return 0;
    else
    return 1;
    }
    return 0;
    }
    //---------------------------------------------------------------------------
    long GetMuteValue(HMIXER hmixer ,MIXERCONTROL *mxc)
    {
    MIXERCONTROLDETAILS mxcd;
    MIXERCONTROLDETAILS_BOOLEAN mxcdMute;
    mxcd.hwndOwner = 0;
    mxcd.cbStruct = sizeof(mxcd);
    mxcd.dwControlID = mxc->dwControlID;
    mxcd.cbDetails = sizeof(mxcdMute);
    mxcd.paDetails = &mxcdMute;
    mxcd.cChannels = 1;
    mxcd.cMultipleItems = 0;
    if (mixerGetControlDetails((HMIXEROBJ)hmixer, &mxcd,MIXER_OBJECTF_HMIXER|MIXER_GETCONTROLDETAILSF_VALUE))
    return -1;
    return mxcdMute.fValue;
    }//---------------------------------------------------------------------------
    unsigned GetVolumeValue(HMIXER hmixer ,MIXERCONTROL *mxc)
    {
    MIXERCONTROLDETAILS mxcd;
    MIXERCONTROLDETAILS_UNSIGNED vol; vol.dwValue=0;
    mxcd.hwndOwner = 0;
    mxcd.cbStruct = sizeof(mxcd);
    mxcd.dwControlID = mxc->dwControlID;
    mxcd.cbDetails = sizeof(vol);
    mxcd.paDetails = &vol;
    mxcd.cChannels = 1;
    if(mixerGetControlDetails((HMIXEROBJ)hmixer, &mxcd, MIXER_OBJECTF_HMIXER|MIXER_GETCONTROLDETAILSF_VALUE))
    return -1;
    return vol.dwValue;
    }//---------------------------------------------------------------------------
    bool SetMuteValue(HMIXER hmixer ,MIXERCONTROL *mxc, bool mute)
    {
    MIXERCONTROLDETAILS mxcd;
    MIXERCONTROLDETAILS_BOOLEAN mxcdMute;mxcdMute.fValue=mute;
    mxcd.hwndOwner = 0;
    mxcd.dwControlID = mxc->dwControlID;
    mxcd.cbStruct = sizeof(mxcd);
    mxcd.cbDetails = sizeof(mxcdMute);
    mxcd.paDetails = &mxcdMute;
    mxcd.cChannels = 1;
    mxcd.cMultipleItems = 0;
    if (mixerSetControlDetails((HMIXEROBJ)hmixer, &mxcd, MIXER_OBJECTF_HMIXER|MIXER_SETCONTROLDETAILSF_VALUE))
    return 0;
    return 1;
    }//---------------------------------------------------------------------------bool SetVolumeValue(HMIXER hmixer ,MIXERCONTROL *mxc, long volume)
    {
    MIXERCONTROLDETAILS mxcd;
    MIXERCONTROLDETAILS_UNSIGNED vol;vol.dwValue = volume;
    mxcd.hwndOwner = 0;
    mxcd.dwControlID = mxc->dwControlID;
    mxcd.cbStruct = sizeof(mxcd);
    mxcd.cbDetails = sizeof(vol);
    mxcd.paDetails = &vol;
    mxcd.cChannels = 1;
    if(mixerSetControlDetails((HMIXEROBJ)hmixer, &mxcd, MIXER_OBJECTF_HMIXER|MIXER_SETCONTROLDETAILSF_VALUE))
    return 0;
    return 1;
    }
    //---------------------------------------------------------------------------
    unsigned WINAPI GetVolume(int dev)//得到设备的音量dev=0主音量,1WAVE ,2MIDI ,3 LINE IN
    {long device;unsigned rt=0;
    MIXERCONTROL volCtrl;
    HMIXER hmixer;
      switch (dev)
       {
        case 1:
               device=MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; 
       break;
        case 2:
                device=MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER; 
    break;
        case 3:
              //  device=MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC; break;  // cd 音量
              //  device=MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE; break;   //麦克风音量
              //  device=MIXERLINE_COMPONENTTYPE_SRC_LINE; break;         //PC 扬声器音量
                device=MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC; 
    break;    //default:
                //device=MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
       }if(mixerOpen(&hmixer, 0, 0, 0, 0)) return 0;
    if(!GetVolumeControl(hmixer,device,MIXERCONTROL_CONTROLTYPE_VOLUME,&volCtrl))
    return 0;
    rt=GetVolumeValue(hmixer,&volCtrl)*100/volCtrl.Bounds.lMaximum;
    mixerClose(hmixer);
    return rt;}//---------------------------------------------------------------------------bool WINAPI SetVolume(long dev,unsigned vol)//设置设备的音量
    {
    // dev =0,1,2   分别表示主音量,波形,MIDI ,LINE IN
    // vol=0-100    表示音量的大小 , 设置与返回音量的值用的是百分比,即音量从0 - 100,而不是设备的绝对值
    // retrun false 表示设置音量的大小的操作不成功
    // retrun true  表示设置音量的大小的操作成功long device;
    bool rc=false;
    MIXERCONTROL volCtrl;
    HMIXER hmixer;
    switch (dev)
     {
      case 1:
               device=MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; 
       break;
      case 2:
               device=MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER; 
       break;
      case 3:
               device=MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC; 
       break;  //default:
               //device=MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
     }if(mixerOpen(&hmixer, 0, 0, 0, 0)) return 0;if(GetVolumeControl(hmixer,device,MIXERCONTROL_CONTROLTYPE_VOLUME,&volCtrl))
      {
      vol=vol*volCtrl.Bounds.lMaximum/100;
      if(SetVolumeValue(hmixer,&volCtrl,vol))
      rc=true;
      }
    mixerClose(hmixer);
    return rc;
    }//---------------------------------------------------------------------------
      

  2.   

    音量是很容易改变的。
    音调就没有那么简单了。
    如果你要是想是的音调变得很奇怪。
    只要读wav。然后各几个点复制一个就可以了。
    要是想精确的控制音调的话。那太困难了。首先要切出辅音元音分界。
    然后调整元音周期。很麻烦的。呵呵。建议用prata调节。
      

  3.   

    http://ncsp.forum.nokia.com/downloads/nokia/documents/CH_BriefIntroductiontoMMAPIv1_0.pdf
      

  4.   

    本世纪70年代初,美国普林斯顿大学的生态学家R·May在研究昆虫群体繁殖规律时提出一个著名的模型: χ[n+1]=k*χ[n]*(1-χ[n])
      其中χ[n]表示第n代群体的数目。当给定一个初始的χ[0]值,然后不停地迭代,人们发现随着k值的不同,得到的序列χn 有许多有趣的现象。当k值介于0与1之间时,χ[n]经过一定次数的迭代后都趋于0。当k值介于1和3之间时趋于1/k,当k值大于3时,经过一定次数的迭代后χ[n]在2个值之间交替变化,k值增加到3.449附近时,交替变化值又变为4个。继续增加k值,χ[n]交替变化的值的个数依4→8→16→32的次序迅速加倍,终于一片混沌。但当k值在3.835附近时,经过一定次数的迭代后,χ[n]非常简单地在3个值之间交替变化,接着又迅速依3→6→12的次序迅速增长。如此反复,在简单的方程中隐藏着令人惊奇的复杂性。χ[n]随k的变化情况如下图所示:
      为了体现这种复杂之中的无穷奥妙,下面这个用TC2.0编写的小程序用χ[n]大小来控制PC喇叭的发音频率,设定不同的k值,我们就可以聆听到混沌的声音。
      #include <dos.h>
      #include <stdio.h>
      main(){
      int fMin=20,fMax=16000; /*fMin代表最低频率,fMax代表最高频率*/
      int fDis,i,j; /*fDis代表最高频率和最低频率之间的差值*/
      /*i,j用于循环记数*/
      float x=0.1,k; /*x代表x[n]的大小,设定其初始值为0.1,即x[0]=0.1*/
      fDis=fMax-fMin;
      for(j=1;;j++){
      printf("Please input The value of k(1-4.0)\n"); /*输入k值*/
      printf("If you want to quit,Please input:0\n"); /*如果k=0退出*/
      scanf("%f",&k);
      if (k==0) break;
      for(i=1;i<100;i++) /*去除开始的100个点*/
      x=k*x*(1-x);
      for (i=1;i<100;i++){
      x=k*x*(1-x); /*计算x的值*/
      sound(x*fDis+20); /*用x的值控制PC喇叭的发音频率*/
      delay(1000); }
      nosound(); }}
      执行上面的小程序时,k值就相当于一个“调音旋钮”。当将k值设定在1与3之间时,喇叭里传出的只有一个音调,重复又烦人。当k值稍稍大于3时,便开始有了韵律:so-mi-so-mi…。k值增加到3.449时,变成了so-fa-la-mi-so-fa-la-mi…,再增加k值,韵律更加复杂,终于成了现代抽象派作曲家的音乐作品。但是韵律并不是随着k值的增加无限地复杂下去。在k值增加到3.835时,音调又变成了mi-so-ti-mi-so-ti…,再增加k值又迅速地变得更加复杂。
    不停地改变k值,仔细聆听,会听到混沌中的无限奥妙。
      

  5.   

    你说的问题就是一个变频的问题。
    可别以为这是一个简单的问题。
    我想他非常复杂。
    所以连微软的 DirectX SDK 里附带变频例子程序的变频结果都同时导致时间相应伸缩。
    要做到发音时间不变而频率改变。那必然涉及到语音数学模型的课题。
    基本理论是:无论多么复杂的泛音波形都是由有限个不同频率的正弦波合成。
    基本思想是:把声音流还原成波形函数->分解出n个主要的正弦波->分别变频后重新合成。
    这仅仅是数学理论,按照这个思想去做一定能成功,但是做出来得程序不仅大而且慢那是肯定的。商业程序可不能是这样的。别人的商业程序里有什么技巧,那是人家的企业秘密,一般不公开的。
      

  6.   

    to icansaymyabc, 有没有现成的代码呢? 因为工程时间比较紧
      

  7.   

    这个是工程上的一个代码。要pay money的。
    不是随便就能用的。
    就我看到的一个调整时长的函数来说,呵呵。
    可是我这边的公司的一个项目啊。哪里能这么容易就得到。
    大概有10000行代码。