2012-05-22 15 views
6

Quiero encontrar cómo se construyeron las notas. Ejemplo para un instrumento (violín o piano), La nota LA4 (A4) tiene FC de frecuencia principal (o central) a 440 Hz con amplitud específica CA, pero también debe tener otras frecuencias (armónicas?) FH con otras amplitudes AH.Nota Síntesis, Armónicos (Violín, Piano, Guitarra, Bajo), Frecuencias, MIDI

Los armónicos tienen otras frecuencias que dependen de la frecuencia principal con amplitudes (casi) menores que la amplitud de la frecuencia principal.

Formando (edificio) Notas

Quiero saber cómo se forma (establecido) las notas (No hay tiempo se considera).

Ejemplo: A4 = AC (FC) + AH1 (FH1) + AH2 (FH2) + AH3 (FH3) + AH4 (FH4) .... AHn (FHN) Tal vez, FH1 = 2 * FC, FH2 = 3 * FC, FH3 = 4 * FC, y así sucesivamente ....

comparación entre instrumentos (violín y piano)

para piano, la nota LA4 (A4) tiene frecuencia principal FC a 440 Hz y Quizás, FC (Piano) = FC (Violín), FH1 (Piano) = FH1 (Violín), FH2 (Piano) = FH2 (Violín), etc.

Pero, AC (Pian o) = AC (violín), AH1 (Piano) = AH1 (violín), AH2 (Piano) = AH2 (violín), y así sucesivamente ....

Ejemplo de mi pregunta es:!!! http://www.phys.unsw.edu.au/jw/sound.spectrum.html

Quiero reproducir estas notas evitando el formato MIDI, esto puede implementarse en Java/C# (u otra programación de lenguaje) Más tarde, y con más control de mis sonidos.

Gracias.

Ana

Respuesta

3

tengo este ...

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

Este código se utiliza en el instrumento Violín:

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

probar este código, mi sonido no es perfecto, pero es muy similar.

+0

Genial, es muy similar ... – Anita

+0

este código tiene muchas declaraciones faltantes, es nombres de variable ambiguos. no puedo correr pelase declara varibles no declaradas, o eliminarlas del código. Varible no declarado se utiliza en el código sin ser un valor initalizado ... en este momento, el código solo debe inspirarse. –

0

Si he entendido bien, que están tratando de hacer una síntesis de Fourier, con la esperanza de que algo similar a la del instrumento original resultará. Veo las posibilidades de éxito muy escasas:

  • no va a funcionar utilizando MIDI, ya que esto requeriría ondas sinusoidales puras a combinar (que no están disponibles en los instrumentos MIDI estándar GS)
  • uno tiene enorme cantidad de datos difíciles de obtener; nota, que sus coeficientes no son específicos de "piano" por sí solo, sino también variará con el terreno de juego, por lo que "a5 de piano" tiene valores diferentes de "a6 de piano"
    • este modelo asume el estado estable del tono (una objetivo diferente no es posible mediante la adición de ondas sinusoidales); la característica de un instrumento es sin embargo más decidido por su fase de ataque

recomendaría John Pierce, la ciencia del sonido musical para una introducción.

2

Tenga en cuenta que lo que está haciendo es una tarea enorme.Si su objetivo es crear su propio sintetizador que pueda sonar como un piano, violín, etc. agregando armónicos con amplitudes específicas, entonces es increíblemente difícil crear un sonido que sea de alguna manera realista. Los armónicos de un instrumento acústico varían con el tiempo de una manera compleja. Como notas guidot, las partes de ataque y retardo del sonido serán muy diferentes. Si tratas de medir las amplitudes relativas de un instrumento real en varios puntos a lo largo del tiempo y luego sintetizas los sinusoides, entonces lo mejor que lograrás es algo que sonará como el juguete de un niño.

Si eso es lo que quieres hacer, entonces necesitarás analizar el espectro a lo largo del tiempo de los sonidos que deseas emular. La manera más fácil que sugeriría es usar algo como Matlab, Octave o Scipy. Si quieres visualizaciones, prueba Sonic Visualiser o Marsyas.

Sin embargo, si desea crear una reproducción realista, tiene dos opciones. Una es usar Wavetable synthesis, que es la cantidad de sintetizadores baratos (especialmente los que funcionan en las tarjetas de sonido de PC). El otro es mirar en Physical Modelling Synthesis que simula la física de un instrumento para crear sonidos realistas.