2012-05-22 261 views
6

我想找到,音符是如何構建的。 (小提琴或鋼琴)的例子,註釋LA4(A4)具有440Hz的主(或中)頻率FC和特定振幅AC,但也必須具有其他頻率(諧波?)FH和其他振幅AH。筆記綜合,諧波(小提琴,鋼琴,吉他,貝斯),頻率,MIDI

諧波具有其他頻率,主頻依賴於振幅(幾乎)小於主頻振幅。

成型(建築)注意

我想知道的是如何形成(建立)的注意事項(沒有時間考慮)。

示例: A4 = AC(FC)+ AH1(FH1)+ AH2(FH2)+ AH3(FH3)+ AH4(FH4).... AHN(FHN) 也許,FH1 = 2 * FC, FH2 = 3 * FC,FH3 = 4 * FC,等等....

儀器(小提琴與鋼琴)

對於鋼琴之間比較,該注LA4(A4)具有主頻率FC (鋼琴)= FC(小提琴),FH1(鋼琴)= FH1(小提琴),FH2(鋼琴)= FH2(小提琴),等等......

但是, AC(篇O)= AC(小提琴),AH1(鋼琴)= AH1(小提琴),AH2(鋼琴)= AH2(小提琴),等等....我的問題的

例子是:!!! http://www.phys.unsw.edu.au/jw/sound.spectrum.html

我想播放這個避免MIDI格式的音符,這可以在Java/C#(或其他語言編程)中實現,稍後,我可以更多地控制我的聲音。

謝謝。

安娜

回答

3

我有這個...

int iTone = 40; //Tone to be interpreted 
    iSmplRate = 32000; //Sample Rate 
    int NumBytesPerSample = 16; // 8 or 16 
    int NumChannels = 2; //1 Mono, 2 Stereo 
    double Duration = 6.5; //Seconds performing 
    Short sAmplit = 1200; 
    int iNumSmpl = (int)(SampleRate*Duration); 
    NumTotalBytes = (int)(SampleRate*Duration*NumBytesPerSample*NumChannels); 
    ByteBuffer bbWav = ByteBuffer.allocate(NumTotalBytes); 


    double dMaxInstr = (double)Short.MIN_VALUE; 
    double dMinInstr = (double)Short.MAX_VALUE; 


    //Amplitude for violin's armonics 
    double[] violAmps = {1.0, 0.286699025, 0.150079537, 0.042909002, 
         0.203797365, 0.229228698, 0.156931925, 
         0.115470898, 0.0, 0.097401803, 0.087653465, 
         0.052331036, 0.052922462, 0.038850593, 
         0.053554676, 0.053697434, 0.022270261, 
         0.013072562, 0.008585879, 0.005771505, 
         0.004343925, 0.002141371, 0.005343231, 
         0.000530244, 0.004711017, 0.009014153}; 

    //Amplitude for piano's armonics 
    double[] pianAmps = {1.0, 0.399064778, 0.229404484, 0.151836061, 
         0.196754229, 0.093742264, 0.060871957, 
         0.138605419, 0.010535002, 0.071021868, 
         0.029954614, 0.051299684, 0.055948288, 
         0.066208224, 0.010067391, 0.00753679, 
         0.008196947, 0.012955577, 0.007316738, 
         0.006216476, 0.005116215, 0.006243983, 
         0.002860679, 0.002558108, 0.0, 0.001650392}; 
    double[] operator = {1.0}; 
    if (instrument.equals("violin")) { 
     operator = violAmps; 
    } 
    if (instrument.equals("piano")) { 
     operator = pianAmps; 
    } 
    double dFreq = 440.0*Math.pow(2.0, (iTone-69)/12.0; 

    double dFreqRel = iSmplRate/dFreq; 
    Integer iSampleInstrument = null; 
    double PI2 = 2*Math.PI; 

    int[] iSamplesInstr = new int[iNumSmpl]; 
    for (int i = 0;i < iNumSmpl; i++) { 
     Double Angle = i*PI2/dFreqRel; 
     Double dInstrument = 0.0; 
     for (int a = 1; a <=operator.length; a++) { 
     dInstrument += operator[a-1]*Math.sin((double)a*Angle); 
     } 

     dMaxInstr = (dInstrument>dMaxInstr)?dInstrument:dMaxInstr; 
     dMinInstr = (dInstrument<dMinInstr)?dInstrument:dMinInstr; 

     iSampleInstrument = (int)(sAmplit*dInstrument); 

     if (instrument.equals("violin")) { 
     double FreqEnvV = iSmplRate/6.0; 
     double FracEnvV = 35.0; 
     double dEnvViolin = sAmplit*DStepperExt(Math.sin(1.0*i*PI2/FreqEnvV),4)/FracEnvV; 
     iSampleInstrument = (int)(iSampleInstrument+dEnvViolin); 
     } 
     if (instrument.equals("piano")) { 
     double FracEnvP = 8.0/10.0; 
     double AngP = (double)i/(iSmplRate*FracEnvP); 
     double EnvPiano = 1.0/Math.exp(AngP); 
     iSampleInstrument = (int)(iSampleInstrument*EnvPiano); 
     } 
     dMxSmplInstr = (iSampleInstrument>dMxSmplInstr)?iSampleInstrument:dMxSmplInstr; 
     dMnSmplInstr = (iSampleInstrument<dMnSmplInstr)?iSampleInstrument:dMnSmplInstr; 
     iSamplesInstr[i] = iSampleInstrument; 
    } 

    double dMaxAbs = 
      (Math.abs(dMaxInstr)>Math.abs(dMinInstr))?Math.abs(dMaxInstr):Math.abs(dMinInstr); 
    double dMxAbsSmpl = 
      (Math.abs(dMxSmplInstr)>Math.abs(dMnSmplInstr))?Math.abs(dMxSmplInstr):Math.abs(dMnSmplInstr); 
    double dNormal = 1.0; 
    if (dMxAbsSmpl > 32768.0) { 
     dNormal = 32768.0/dMxAbsSmpl; 
    } 

    for (int i = 0;i < iNumSmpl; i++) { 
     short sSampleInst = (short)(iSamplesInstr[i]*dNormal); 
     try { 
     if (iNumByteSmpl == 2) { 
      bbWav.put((byte)((sSampleInst >> 0) & 0xFF)); 
      bbWav.put((byte)((sSampleInst >> 8) & 0xFF)); 
      if (iNumChnnls == 2) { 
      bbWav.put((byte)((sSampleInst >> 0) & 0xFF)); 
      bbWav.put((byte)((sSampleInst >> 8) & 0xFF)); 
      } 
     } else { 
      byte ByteSample = (byte)((sSampleInst >> 8) & 0xFF); 
      short ShrtSample = (short)(ByteSample & 0xFF); 
      ShrtSample += 128; 
      bbWav.put((byte)(ShrtSample & 0xFF)); 
      if (iNumChnnls == 2) { 
      bbWav.put((byte)(ShrtSample & 0xFF)); 
      } 
     } 
     } catch (Exception e) { 
     System.out.println(e.getMessage()); 
     } 

此代碼是在小提琴儀器使用:

private Double DStepperExt(Double Val, Integer Steps) { 
    //Return a value inside in range defined by step 
    //Divide [-1.0,1.0]/(Steps-1), retorning the value according to the range 
    //The value must be between 0.0 and 1.0 
    if (Steps <= 0.0) { 
     return 0.0; 
    } 
    if (Val != -1.0 && Val != 1.0) { 
     Val = Val - Val.intValue(); 
    } 
    Double sDouble = new Double(Steps-1); 
    Double bdStep = 2.0/sDouble; 
    Double bdRef = bdStep/2.0; 
    bdRef = bdRef - 1.0; 
    Double bdInit = -1.0; 

    Double bdRet = null; 
    for (int c = 0; c<=sDouble;c++) { 
     if (Val < bdRef) { 
     bdRet = bdInit; 
     break; 
     } else { 
     bdInit = bdInit+bdStep; 
     bdRef = bdRef+bdStep; 
     } 
    } 
    return Math.min(bdRet.doubleValue(),1.0); 
    } 

試試這個代碼,我的聲音是不完美的,但非常相似。

+0

很好,非常相似...... – Anita

+0

這段代碼有很多遺漏的聲明,是不明確的變量名。不能跑。 pelase聲明未聲明的變量,或從代碼中刪除它們。未聲明的變量在代碼中使用,而不是一個價值initalized ....現在,代碼只是受到啓發。 –

0

如果我理解正確,你正在嘗試做的傅立葉合成,希望類似原始工具的東西會導致。我看到了成功的機會相當渺茫:

  • 將無法​​正常工作使用MIDI,因爲這需要純正弦波到 結合(這是不是標準的MIDI樂器GS提供)
  • 一個需要巨大難以獲得的數據量;注意, 您係數不具體到「鋼琴」單獨也與 的間距各不相同,因此「鋼琴A5」已經從「鋼琴A6」
    • 該模型假設語氣的穩定狀態不同的值(一不同的目標是通過添加正弦波不可實現 );儀器的特點然而更加堅定 其攻擊階段

我建議約翰·皮爾斯,音樂聲科學的介紹。

2

請注意,您正在從事的是一個巨大的任務。如果您的目標是通過將具有特定振幅的諧波加在一起來創建自己的合成器,該合成器可以聽起來像鋼琴,小提琴等,那麼創建任何真實感的聲音難以想象。聲學儀器的諧波隨着時間的推移以複雜的方式變化。正如guidot筆記,聲音的攻擊和延遲部分將會非常不同。如果你試圖在一段時間內測量一個實際儀器的相對幅度,然後合成這些正弦曲線,那麼你將獲得的最好結果就像是一個孩子的玩具。

如果這是你想要做的,那麼你將需要分析你想要模擬的聲音的時間譜。我建議的最簡單的方法是使用Matlab,Octave或Scipy之類的東西。如果你想要可視化,然後嘗試聲波Visualiser或Marsyas。

如果您想要創建逼真的播放,那麼您有兩個選項。一種是使用Wavetable synthesis,這是多少便宜的合成器(特別是PC聲卡上的合成器)的工作。另一種是研究Physical Modelling Synthesis,它模擬樂器的物理特性來創造逼真的聲音。