Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Ecualizador grafico

Iniciado por Jose134, Julio 31, 2015, 09:11:24 PM

Tema anterior - Siguiente tema
Agosto 05, 2015, 12:59:51 PM #30 Ultima modificación: Agosto 05, 2015, 01:01:21 PM por Jose134
Con el codigo que me has dado no me sale el error pero me puse a hacer una cosilla con el movil y la cancion termino y las barras estaban asiprivate bool ended;

void Update () {
    if(!source.isPlaying && !ended){
   ended = true;
}
if(ended){
   for(int i = 0; i < barsNumber; i++){
      float speed = Time.deltaTime * barSpeed;
      bars.transform.localScale = Vector3.Lerp(bars.transform.localScale,
Vector3.zero, speed);
   }
}
}El problema es que a veces como que "parpadea"

Jajajaja. Pero veo que utilizar el lerp de antes, no el nuevo que parte del scale original al del dato. 
A es que quieres que vayan a zero cuando la canción termine!
Lo que tienes que hacer es jugar con los valores de heightm y el speed en el editor, hasta que encuentres un equilibrio entre suavidad y velocidad. 
De todos modos, hay algo extraño en el código, porqué las barras deberían partir de 0f y las veo nerviosas. No quiero mirar mi código de la app para no hacer trampas. A ver si lo resolvemos.

Agosto 06, 2015, 02:16:22 PM #32 Ultima modificación: Agosto 06, 2015, 02:25:30 PM por Oak Human Flesh
Si quieres ver la app completa que hice con la base de audio que conozco, ve a http://unityspain.com/topic/15839-xqualizer-09a/[/quote] He experimentado bastante, " muchas gracias" http://unityspain.com/profile/27231-irobb/?do=hovercard&referrer=http%253A%252F%252Funityspain.com%252Ftopic%252F15868-ecualizador-grafico%252F%253Fpage%253D2" data-ipshover="">iRobb muy buen ejemplo.Por mi parte no conocía mucho sobre como obtener el espectro de frecuencias de los sonidos en Unity using UnityEngine;
using System.Collections;
[RequireComponent (typeof (AudioListener))]
public class Visualizer : MonoBehaviour
{

public GameObject barrasEqPrefab;
public int cantidadBarrasEq = 64;
public int samples = 4096;
public int longest = 100;
public float height = 7f;
Vector3 outSpectrum;
float[] spectrum;
float sample = 0f;
public float trim = 450;
LineRenderer lr, lrC1, lrC2;
public bool blkmanHarris, hamming, blkMan, rectangular;

void Start()
{
   outSpectrum = new Vector3 ();
   spectrum = new float[samples];
   lr = GameObject.FindWithTag("lr").GetComponent<LineRenderer> ();
   lrC1 = GameObject.FindWithTag("C1").GetComponent<LineRenderer> ();
   lrC2 = GameObject.FindWithTag("C2").GetComponent<LineRenderer> ();
   lr.SetVertexCount (longest-1);
}

void Update()
{
   FFTWindowSelect ();
   LineRendererMainSamplesAnEditorDraw ();
   ControlBarras (8, 9, 10, 11, -25, 48, lrC1);
   ControlBarras (12, 13, 14, 15, -25, 50, lrC2);
}

void FFTWindowSelect ()
{
   //float[] spectrum = audio.GetSpectrumData(8192, 0, FFTWindow.BlackmanHarris);
   if (blkmanHarris) {
      spectrum = AudioListener.GetSpectrumData (spectrum.Length, 0, FFTWindow.BlackmanHarris);
      
   }
   if (hamming) {
      spectrum = AudioListener.GetSpectrumData (spectrum.Length, 0, FFTWindow.Hamming);
      
   }
   if (blkMan) {
      spectrum = AudioListener.GetSpectrumData (spectrum.Length, 0, FFTWindow.Blackman);
      
   }
   if (rectangular) {
      spectrum = AudioListener.GetSpectrumData (spectrum.Length, 0, FFTWindow.Rectangular);
      
   }

}
void LineRendererMainSamplesAnEditorDraw ()
{
   int i = 1;
   while (i < longest-1) {
      outSpectrum = new Vector3(i, Mathf.Log(spectrum) + height, 0);
      //Debug.DrawLine(new Vector3(i - 1, spectrum + 10, 0), new Vector3(i, spectrum[i + 1] + 10, 0), Color.red);
      Debug.DrawLine(new Vector3(i - 1, Mathf.Log(spectrum[i - 1]) + 1, 2), new Vector3(i, Mathf.Log(spectrum) + height, 2), Color.cyan);
      
      lr.SetPosition(i, outSpectrum);
      //Debug.DrawLine(new Vector3(Mathf.Log(i - 1), spectrum[i - 1] - 10, 1), new Vector3(Mathf.Log(i), spectrum - 10, 1), Color.green);
      //Debug.DrawLine(new Vector3(Mathf.Log(i - 1), Mathf.Log(spectrum[i - 1]), 3), new Vector3(Mathf.Log(i), Mathf.Log(spectrum), 3), Color.yellow);
      i++;
   }
}
void ControlBarras (int a, int b, int c, int d, float minPos0, float PosXLineRend1, LineRenderer lRend)
{
   sample = spectrum [a] + spectrum + spectrum [c] + spectrum [d] * trim + minPos0;
   Vector3 c1 = new Vector3 (PosXLineRend1, sample, 0);
   lRend.SetPosition (1, c1);
}
void CreateBars (GameObject inputBarGobj, int cantBarras)
{
   int i = 0;
   while (i < cantBarras) {
      GameObject clon = Instantiate (inputBarGobj, new Vector3 (0, 0, 0), Quaternion.identity) as GameObject;
      clon.gameObject.name = "C" + i;
      clon.GetComponent<LineRenderer>().SetPosition(0, new Vector3(1f * i + i, 0f, 0f));
      clon.GetComponent<LineRenderer>().SetPosition(1, new Vector3(1f * i + i, 5f, 0f));
      i++;
   }
}
void OnGUI ()
{
   if (GUILayout.Button ("CREAR BARRAS")) {
      CreateBars(barrasEqPrefab, cantidadBarrasEq);
   }
}
}en las líneas donde se obtienen los samples (spectrum = AudioListener.GetSpectrumData (spectrum.Length, 0, FFTWindow.xxxx)), arroja un caution que aun no me lo he podido sacar, dice que esta forma de obtener los samples esta obsoleta Oo.
Assets/scripts/Visualizer.cs(53,50): warning CS0618: `UnityEngine.AudioListener.GetSpectrumData(int, int, UnityEngine.FFTWindow)' is obsolete: `GetSpectrumData returning a float[] is deprecated, use GetOutputData and pass a pre allocated array instead.'[/quote]Conoces la forma no obsoleta de obtener los samples????

Bye Bye



Me voy a mirar tu código esta tarde que lo veo muy interesante. Respecto al obsolete, lo llevo viendo desde la 4.6. Lo intenté con esa función que menciona pero no ví que devolviera el mismo nivel de detalle. Ah y lo del cambio de tipo fft parece muy interesante.

He exportado el proyecto y lo he subido para que puedas analizar mejor, esta en la ultima version de Unity 5 Pppppppppersoooonal Lol
http://unityspain.com/applications/core/interface/file/attachment.php?id=8264">EqGraph.unitypackage

Bye Bye



Ahora voy a por él 
Oye quedan muy bien las barras. Por otro lado, para los canales right/left, yo hice otra implementación aparte de la fft. Te interesa?

Agosto 06, 2015, 09:11:20 PM #36 Ultima modificación: Agosto 06, 2015, 09:13:59 PM por Oak Human Flesh

Bye Bye



Ok! Mira:        float rawValue = 0f;        AudioListener.GetOutputData(audioData, channel);        for (int x = 0; x < audioData.Length; x++) {
            // -1 to 1 = 0 to 1
            rawValue += audioData
  • * audioData
  • ;
        } Donde channel es left = 0 y right = 1 y lo empaquetas en una matriz de float también. Como los valores son entre -1 y 1, los elevamos al cuadrado para dejarlos entre 0 y 1 y eliminar los negativos. Y luego para el RMS (seguro que algo de audio sabes :D) aplicas la siguiente fórmula:        //RMS = squareroot(avg(sum(audioData
  • ^2)))Y para el valor en Db's:       float value = 20f * Mathf.Log10(rmsValue / rmsRefValue);       if (value < -160f) value = -160f;Donde rmsValue = rawValue de antes y rmsRefValue = 0.1f. Lo limitamos a -160 db's para que no se dispare.  

Whoaa!, a penas pueda lo pruebo,  muy bueno el ejercicio, muchas gracias 

Bye Bye



Jajajaja ya me suponía que eso de obtener el valor RMS era mucho más que solo tratar de obtener el valor de peak y luego multiplicarlo por .707 

Bye Bye



Agosto 09, 2015, 07:16:32 PM #40 Ultima modificación: Agosto 09, 2015, 07:18:30 PM por Oak Human Flesh
 
Y luego para el RMS (seguro que algo de audio sabes :D) aplicas la siguiente fórmula://RMS = squareroot(avg(sum(audioData
  • ^2)))[/quote]Jajajaja rmsValue = Mathf.Sqrt(Mathf.Abs(audioData
  • + audioData
  • * audioData
  • ));luego mis estudios de audio no están completos, pues mis estudios son de electricidad, por lo cual cuando se habla de un valor RMS, se viene a mi mente el recuerdo para una clase sobre onda senosoidal de corriente alterna ... según mi maestro... el valor RMS se obtiene fácilmente luego de obtener el valor peak dividiéndolo por la raíz cuadrada de 2, luego se deduce que también se puede obtener el factor de multiplicación para obtener el valor RMS de 0.7071068, esto luego de descomponer esta  desagradable formula:  var qSamples: int = 1024;  // array size
     var refValue: float = 0.1; // RMS value for 0 dB
     var threshold = 0.02;      // minimum amplitude to extract pitch
     var rmsValue: float;   // sound level - RMS
     var dbValue: float;    // sound level - dB
     var pitchValue: float; // sound pitch - Hz
     
     private var samples: float[]; // audio samples
     private var spectrum: float[]; // audio spectrum
     private var fSample: float;
     
     function Start () {
         samples = new float[qSamples];
         spectrum = new float[qSamples];
         fSample = AudioSettings.outputSampleRate;
     }
     
     function AnalyzeSound(){
         audio.GetOutputData(samples, 0); // fill array with samples
         var i: int;
         var sum: float = 0;
         for (i=0; i < qSamples; i++){
             sum += samples*samples; // sum squared samples
         }
         rmsValue = Mathf.Sqrt(sum/qSamples); // rms = square root of average
         dbValue = 20*Mathf.Log10(rmsValue/refValue); // calculate dB
         if (dbValue < -160) dbValue = -160; // clamp it to -160dB min
         // get sound spectrum
         audio.GetSpectrumData(spectrum, 0, FFTWindow.BlackmanHarris);
         var maxV: float = 0;
         var maxN: int = 0;
         for (i=0; i < qSamples; i++){ // find max
             if (spectrum > maxV && spectrum > threshold){
                 maxV = spectrum;
                 maxN = i; // maxN is the index of max
             }
         }
         var freqN: float = maxN; // pass the index to a float variable
         if (maxN > 0 && maxN < qSamples-1){ // interpolate index using neighbours
             var dL = spectrum[maxN-1]/spectrum[maxN];
             var dR = spectrum[maxN+1]/spectrum[maxN];
             freqN += 0.5*(dR*dR - dL*dL);
         }
         pitchValue = freqN*(fSample/2)/qSamples; // convert index to frequency
     }
     
     var display: GUIText; // drag a GUIText here to show results
     
     function Update () {
         if (Input.GetKeyDown("p")){
             audio.Play();
         }
         AnalyzeSound();
         if (display){
             display.text = "RMS: "+rmsValue.ToString("F2")+
             " ("+dbValue.ToString("F1")+" dB)\n"+
             "Pitch: "+pitchValue.ToString("F0")+" Hz";
         }
     }

    del cual alimente mi proyecto con la línea:
    rmsValue = Mathf.Sqrt(sum/qSamples); // rms = square root of average
    ya que la forma de obtener el espectro es idéntica a la que estaba usando gracias a Ustedes void ControlBarras (int channel, float PosXLineRend1, LineRenderer lRend)
    {
       float rawValue = 0f;
       
       AudioListener.GetOutputData(audioData, channel);
       
       for (int x = 0; x < audioData.Length; x++) {
          rawValue += audioData
    • * audioData
    • ;
       }
       rmsValue = Mathf.Sqrt(rawValue/audioData.Length);// rms = square root of average
       Db = 20f * Mathf.Log10(rmsValue / rmsRefValue);
       if (Db < -160f) Db = -160f;
       Vector3 c1 = new Vector3 (PosXLineRend1, Mathf.Clamp(Db * trim, minYEq, maxYEq), 0);
       lRend.SetPosition (1, c1);

    }y funciona EqGraph1.unitypackage

Bye Bye



Pues yo creo que ya tienes todas las piezas del puzzle. Y añado:Si sustituyes AudioListener por un AudioSource que contenga el audioclip ya no será deprecated.

Etiquetas: