Espectro malo de la salida FFT de Android (Visualiser)?

Tengo algún tipo de pregunta sobre FFT (En realidad creo que es más acerca de Androids FFT-Salida de Visualizer.getFFT ()).

He creado un reproductor de música con función de biblioteca propia para Android, incluyendo lotes de cosas (como géneros, listas de reproducción dinámicas y visualizaciones). Actualmente tengo algunos problemas con las visualizaciones que crear cuando se trata de hacer un espectro de la AudioStream actual.

Ya leí las siguientes preguntas (y respuestas) para obtener una idea de Androids FFT:

¿Qué tipo de salida debo ver de getFft?

Android 2.3 Visualizer – Problemas para entender getFft ()

Ahora a mi problema: El espectro que consigo de los coeficientes de los getFFTs parece ser algo "impar". Noto que el espectro que hago parece mostrar mucho "ruido" cuando toco una canción así que intenté usar algunos sonidos de prueba. Uno de ellos es un simple sonido de 8khz que debería dar como resultado sólo un pico en el gráfico. Desafortunadamente, el resultado es similar al siguiente:

Http://img4.imageshack.us/img4/4181/spectrum8khz.png

El ruido que aparece en la parte inferior está parpadeando por todo el ancho de la gráfica. Las barras altas permanecen en posición sólo parpadeando ligeramente en magnitud.

Cuando uso un sonido de prueba moviéndose lentamente de 1kHz a 20kHz, parece que lo siguiente (a unos 2-3kHz):

Http://img846.imageshack.us/img846/7373/spectrum3khz1khz20khz.png

Los picos se mueven de izquierda a derecha y cada uno es un poco más rápido, así que con el tiempo la distancia entre los picos crece. Lo que no es visible es que los picos vuelven y van de derecha a izquierda una vez que salen de la pantalla a la derecha (pero con menor magnitud). También todos los picos se unen a un gran pico en un poco más de 0,5 de la pantalla.

Aquí está el código que utilizo para recuperar los datos:

for (int i = 1; i < n / 2; i++) { byte rfk = mRawSpecData[2*i]; byte ifk = mRawSpecData[2*i+1]; float magnitude = (float)Math.sqrt(rfk * rfk + ifk * ifk); mFormattedSpecData[i-1] = magnitude / 128f; } 

En el código anterior mRawSpecData es el resultado de la función de los visores getFFT (). La longitud de los datos capturados es 1024. Actualmente la pendiente comienza en 1 porque mRawSpecData [0] contiene la DC y mRawSpecData [1] contiene n / 2.

Para solucionar mi problema también traté de jugar con la DC y la fase de la frecuencia-bin. Quizás tuve que aplicar algún cálculo sobre las magnitudes para "limpiar" el gráfico. Pero no tuve éxito (Tal vez porque no he conseguido lo que es goind con DC / fase en absoluto!).

Me pasé dos semanas buscando google por las noches y probar diferentes cálculos pero nada realmente ayudó.

Entonces, ¿cuál es el trato? ¿Estoy haciendo algo mal o dejando algo fuera? Después de eso otra pregunta que me molesta es cómo escalar las magnitudes correctamente. Mi objetivo es obtener valores entre 0f y 1f.

Muchas gracias

alboroto

PS: Capturas de pantalla tomadas a través de eclipse desde un teléfono con Android 2.3.

PPS: También he comprobado los sonidos con varios otros jugadores (como winamp) y allí veo el comportamiento correcto del espectro.

Tengo buen resultado usando cálculos siguientes, para obtener un visualizador como esta imagen. Estoy utilizando cerca de 19 imágenes para mostrar como this.Thats están respondiendo por las entradas de método getFFT (). Y asegúrese de habilitar tanto el ecualizador y el visualizador, de lo contrario da valores altos y fft valores se responde al volumen del dispositivo.Actualmente no soy capaz Para dar la explicación del código debido a mi código pasado de english.so i aquí.

VisualizerView:

 public class VisualizerView extends View { private byte[] mBytes; private float[] mPoints; Paint mForePaint = new Paint(); // private int width;// height; private Paint mPaint; Bitmap mBmpArray[]; int wTilesize; int hTilesize; int no_of_colomuns; private Bitmap peakBitmap; private float changeFromTop, changeFromLeft; private int images_drawn_starting_point ; int magnitudePoints[]; int max[] = new int[34]; int temp[]=new int[32]; private final int[][] images = { { R.drawable.blue_fade_1, R.drawable.blue_fade_2, R.drawable.blue_fade_3, R.drawable.blue_fade_4, R.drawable.blue_fade_5, R.drawable.blue_fade_6, R.drawable.blue_fade_7, R.drawable.blue_fade_8, R.drawable.blue_fade_9, R.drawable.blue_fade_10, R.drawable.blue_fade_11, R.drawable.blue_fade_12, R.drawable.blue_fade_13, R.drawable.blue_fade_14, R.drawable.blue_fade_15, R.drawable.blue_fade_16, R.drawable.blue_fade_17, R.drawable.blue_fade_18, R.drawable.blue_fade_19 }}; private final int IMAGES_LENTH = 19; public VisualizerView(Context context) { super(context); mBmpArray = new Bitmap[20]; init(); } public VisualizerView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public VisualizerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); images_drawn_starting_point = h; int temp; wTilesize = w / 34; // hTilesize = h / 30; temp = h - ((IMAGES_LENTH - 1) ); hTilesize = temp / (IMAGES_LENTH ); no_of_colomuns = ( w / (wTilesize)); magnitudePoints = new int[no_of_colomuns]; changeFromLeft = wTilesize + 3f;//For spacing left changeFromTop = hTilesize + 2.5f;//For spacing Right } public void init() { mPaint = new Paint(); mPaint.setColor(Color.BLACK); mPaint.setStrokeWidth(5f); } @Override public void draw(Canvas canvas) { super.draw(canvas); int h = canvas.getHeight(); int w = canvas.getWidth(); canvas.drawRect(new Rect(0, 0, w, h), mPaint); if (mBytes == null) { return; } if (mPoints == null || mPoints.length < mBytes.length * 4) { mPoints = new float[mBytes.length * 4]; } double magnitude; //VisualizerActivity.THEME_COLOR=0 for (int j = 0; j < IMAGES_LENTH; j++) loadTile(j,getResources().getDrawable(images[VisualizerActivity.THEME_COLOR][j])); for (int i = 0; i < no_of_colomuns; i++) { byte rfk = mBytes[2 * i]; byte ifk = mBytes[2 * i + 1]; magnitude = ((rfk * rfk + ifk * ifk)); int dbValue = (int) (10 * Math.log10(magnitude)); magnitude = Math.round(dbValue * 8); try { magnitudePoints[i] = (int) magnitude; } catch (Exception e) { e.printStackTrace(); } } int left; int top; int index; try { index = 0; left = 0; int m = 1; if (VisualizerActivity.THEME_STYLE == 0) { // common for (int i = 0; i < no_of_colomuns; i++) { top = images_drawn_starting_point; index = 18; for (int j = 0; j < IMAGES_LENTH; j++) { if (j > magnitudePoints[m] / IMAGES_LENTH) { canvas.drawBitmap(mBmpArray[0], left, top, mPaint); index++; } else { canvas.drawBitmap(mBmpArray[index--], left, top, mPaint); } top -= changeFromTop;// hTilesize+1.5; } m++; left += changeFromLeft;// wTilesize+2.5; } } } catch (Exception e) { e.getMessage(); } } public void loadTile(int key, Drawable tile) { try { Bitmap bitmap = Bitmap.createBitmap(wTilesize, hTilesize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); tile.setBounds(0, 0, wTilesize, hTilesize); tile.draw(canvas); mBmpArray[key] = bitmap; } catch (Exception e) { e.printStackTrace(); } } public void updateVisualizerWithFft(byte[] bytes) { if (AudioPlayer.player != null) { if (AudioPlayer.player.isPlaying()) { mBytes = bytes; } } invalidate(); } } 

En VisualizerActivity.java:

 AudioPlayer.mVisualizer.setCaptureSize(Visualizer .getCaptureSizeRange()[1]); AudioPlayer.mVisualizer.setDataCaptureListener( new Visualizer.OnDataCaptureListener() { public void onWaveFormDataCapture( Visualizer visualizer, byte[] bytes, int samplingRate) { // mVisualizerView.updateVisualizer(bytes); } public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) { mVisualizerView.updateVisualizerWithFft(bytes); } }, Visualizer.getMaxCaptureRate() / 2, false, true); 
  • Android Visualizador FFT / onda afectada por el volumen del dispositivo?
  • Obtener ultrasonido de android usando frecuencia
  • Entendiendo jtransform
  • Técnica subyacente de FaceDetector de Android
  • ¿Cómo puedo obtener datos de frecuencia de PCM usando FFT
  • Transformada de Fourier en Android
  • Android FFT de audio para mostrar la frecuencia fundamental
  • FFT de audio Android para recuperar la magnitud de frecuencia específica mediante audiorecord
  • Encuentra el tono de voz en Android
  • JTransforms FFT en Android de datos de PCM
  • Interpretación FFT
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.