2012-05-22 17 views
6

Tôi muốn tìm, cách ghi chú được tạo. Ví dụ về một công cụ (Violin hoặc Piano), Note LA4 (A4) có tần số chính (hoặc trung tâm) FC ở 440Hz với AC Amplitude cụ thể, nhưng cũng phải có các tần số khác (sóng hài?) FH với biên độ AH khác.Lưu ý Tổng hợp, Harmonics (Violin, Piano, Guitar, Bass), Tần suất, MIDI

Các sóng hài có tần số khác phụ thuộc vào tần số chính với biên độ (gần) nhỏ hơn biên độ của tần số chính.

Hình thành (xây dựng) Ghi chú

Tôi muốn biết làm thế nào được hình thành (thành lập) các ghi chú (Không có thời gian được xem xét).

Ví dụ: A4 = AC (FC) + AH1 (FH1) + AH2 (FH2) + AH3 (FH3) + AH4 (FH4) .... Ahn (FHn) Có lẽ, FH1 = 2 * FC, FH2 = 3 * FC, FH3 = 4 * FC, và vân vân ....

So sánh giữa công cụ (Violin và Piano)

Đối với Piano, The Note LA4 (A4) có tần số FC chính tại 440Hz và Có thể, FC (Piano) = FC (Violin), FH1 (Piano) = FH1 (Violin), FH2 (Piano) = FH2 (Violin), v.v.

Nhưng, AC (Pian o)! = AC (Violin), AH1 (Piano)! = AH1 (Violin), AH2 (Piano)! = AH2 (Violin), v.v.

Ví dụ về câu hỏi của tôi là: http://www.phys.unsw.edu.au/jw/sound.spectrum.html

Tôi muốn chơi ghi chú này tránh định dạng MIDI, điều này có thể được thực hiện trong Java/C# (hoặc lập trình ngôn ngữ khác) Sau đó, và kiểm soát nhiều hơn âm thanh của tôi.

Cảm ơn bạn.

Ana

Trả lời

3

Tôi có này ...

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

Mã này được sử dụng trong Violin cụ:

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

Hãy thử mã này, âm thanh của tôi là không hoàn hảo nhưng là rất giống nhau.

+0

Tuyệt vời, rất giống nhau ... – Anita

+0

mã này có nhiều khai báo thiếu, là tên biến mơ hồ. không thể chạy. pelase khai báo chênh lệch không khai báo, hoặc loại bỏ chúng khỏi mã. biến thể không khai báo được sử dụng trong mã mà không phải là một giá trị initalized .... ngay bây giờ, mã chỉ được lấy cảm hứng từ. –

0

Nếu tôi hiểu đúng, bạn đang cố gắng để làm một tổng hợp Fourier, hy vọng rằng một cái gì đó tương tự như công cụ ban đầu sẽ cho kết quả. Tôi thấy cơ hội thành công khá mỏng:

  • nó sẽ không làm việc sử dụng midi, vì điều này sẽ đòi hỏi sóng sin thuần túy để kết hợp (mà không có sẵn bằng các công cụ MIDI GS chuẩn)
  • người ta cần khổng lồ lượng dữ liệu khó đi qua; lưu ý, rằng hệ số của bạn không cụ thể với "piano" một mình nhưng cũng thay đổi theo độ cao độ cao, vì vậy "piano a5" có các giá trị khác nhau từ "piano a6"
    • mô hình này giả định trạng thái ổn định của giai điệu mục tiêu khác nhau là không thể đạt được bằng cách thêm sóng sin); các đặc trưng của một công cụ là song ngày càng quyết tâm bởi giai đoạn tấn công của nó

Tôi muốn giới thiệu John Pierce, The Science of Musical Sound cho phần giới thiệu.

2

Lưu ý rằng những gì bạn đang thực hiện là một nhiệm vụ lớn.Nếu mục tiêu của bạn là tạo ra bộ tổng hợp của riêng bạn có thể nghe như piano, violin, vv bằng cách thêm các sóng hài với biên độ cụ thể thì thật khó để tạo ra âm thanh theo bất kỳ cách nào thực tế. Các giai điệu của một nhạc cụ thay đổi theo thời gian trong một thời trang phức tạp. Theo ghi chú của sách hướng dẫn, phần tấn công và trì hoãn các phần âm thanh sẽ rất khác nhau. Nếu bạn cố gắng đo biên độ tương đối của một công cụ thực tại một số điểm theo thời gian và sau đó tổng hợp các sinusoid thì tốt nhất bạn sẽ đạt được là cái gì đó sẽ âm thanh như đồ chơi của trẻ.

Nếu đó là những gì bạn muốn làm thì bạn sẽ cần phải phân tích quang phổ theo thời gian của các âm thanh bạn muốn mô phỏng. Cách dễ nhất tôi sẽ đề nghị là sử dụng một cái gì đó như Matlab, Octave hoặc Scipy. Nếu bạn muốn hình ảnh thì hãy thử Sonic Visualiser hoặc Marsyas.

Nếu bạn muốn tạo phát lại thực tế thì bạn có hai tùy chọn. Một là sử dụng Wavetable synthesis, đó là bao nhiêu tổng hợp giá rẻ (đặc biệt là những người trên card âm thanh máy tính) làm việc. Cách khác là nhìn vào Physical Modelling Synthesis mô phỏng vật lý của một công cụ để tạo ra âm thanh trung thực.