7

ノートがどのように作成されたかを知りたいです。楽器 (バイオリンまたはピアノ) の例では、ノート LA4 (A4) は特定の振幅 AC で 440Hz のメイン (または中心) 周波数 FC を持っていますが、他の周波数 (ハーモニクス?) FH と他の振幅 AH を持っている必要があります。

高調波には、メイン周波数の振幅より (ほぼ) 小さい振幅を持つメイン周波数に依存する他の周波数があります。

フォーミング(建物)の注意事項

ノートがどのように形成(確立)されているか知りたい(時間は考慮しない)。

例: 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 は 440Hz であり、FC(ピアノ) = FC(バイオリン)、FH1(ピアノ) = FH1(バイオリン)、FH2(ピアノ) = FH2(バイオリン)、すぐ....

しかし、AC(ピアノ) != AC(ヴァイオリン)、AH1(ピアノ) != AH1(ヴァイオリン)、AH2(ピアノ) != AH2(ヴァイオリン) など....

私の質問の例: http://www.phys.unsw.edu.au/jw/sound.spectrum.html

私はこのノートを MIDI フォーマットを避けて演奏したいと思っています。これは後で Java/C# (または他の言語プログラミング) で実装でき、サウンドをより細かく制御できます。

ありがとうございました。

アナ

4

3 に答える 3

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);
  }

このコードを試してみてください。私のサウンドは完璧ではありませんが、非常に似ています。

于 2014-12-16T20:26:53.217 に答える
2

あなたが取り組んでいることは巨大な仕事であることに注意してください。特定の振幅を持つハーモニクスを追加することで、ピアノやバイオリンなどのような独自のシンセサイザーを作成することが目標である場合、リアルなサウンドを作成することは非常に困難です。アコースティック楽器のハーモニクスは時間とともに複雑に変化します。guidot が指摘しているように、サウンドのアタック部分とディレイ部分は大きく異なります。実際の楽器の相対的な振幅を時間の経過とともにいくつかの点で測定し、正弦波を合成すると、子供のおもちゃのように聞こえるものが得られます。

それがあなたのやりたいことなら、エミュレートしたい音のスペクトルを時間の経過とともに分析する必要があります。私が提案する最も簡単な方法は、Matlab、Octave、Scipy などを使用することです。ビジュアライゼーションが必要な場合は、Sonic Visualiser または Marsyas を試してください。

ただし、リアルな再生を作成したい場合は、2 つのオプションがあります。1 つは、 Wavetable シンセシスを使用することです。これは、多くの安価なシンセサイザー (特に PC サウンドカードのシンセサイザー) が機能する方法です。もう 1 つは、楽器の物理特性をシミュレートしてリアルなサウンドを作成するPhysical Modeling Synthesisを検討することです。

于 2012-07-23T15:18:43.680 に答える
0

私の理解が正しければ、あなたはフーリエ合成を行おうとしていて、元の楽器に似たものが得られることを期待しています. 成功する可能性は非常に低いと思います。

  • これは純粋な正弦波を組み合わせる必要があるため、MIDI を使用すると機能しません (標準の MIDI GS インストゥルメントでは使用できません)。
  • 手に入れるのが難しい膨大な量のデータが必要です。係数は「ピアノ」だけに固有のものではなく、ピッチによっても異なるため、「ピアノ a5」と「ピアノ a6」の値は異なることに注意してください。
    • このモデルは、トーンの安定状態を想定しています (正弦波を追加しても別の目標は達成できません)。ただし、楽器の特性は、そのアタックフェーズによってより決定されます

入門書として、John Pierce 著 The Science of Music Sound をお勧めします。

于 2012-07-23T14:13:47.833 に答える