Metodo para detectar frecuencia microfono.

Hola, muy buenas.

Quería comentar, que estoy haciendo una aplicación libre para la facultad de psicología para tratamiento de niños con hiper-actividad y tengo un problema (por ahora es el único que tengo).

Necesito una librería de java, que me permita obtener la frecuencia en Hz de la entrada de micrófono (a intervalos de tiempo diferentes (1 vez por décima de segundo)).

He mirado funciones del java speech, jmf, javax.sound y no veo nada claro y por eso pido esta gran ayuda por que llevo 2 meses buscando e intentando trastear, y no doy con ello.

Os agradezco de antemano cualquier colaboración.

Un saludo y gracias.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de beto.bateria

Librerias de sonido.

Saludos, me encontre esto en internet:

2.1 Formatos de audio.

Los objetos de la clase AudioFormat definen el formato de una señal de audio, esto es, el número de canales, el número de bits por muestra, frecuencia de muestreo, el tamaño de la trama de voz y su frecuencia, formato de almacenamiento de los datos en memoria (big endian o little endian) y el tipo de codificación (ley a, ley m, PCM). Para guardar el tipo de codificación hay un objeto de la clase AudioFormat.Encoding con esta información. Obteniendo este objeto se puede mirar si es igual (función boolean equals(Object) ) a una de las constantes definidas en la clase AudioFormat.Encoding (ALAW, ULAW, PCM_SIGNED, PCM_UNSIGNED). La clase AudioFormat, aparte del constructor (al que hay que pasarle los parámetros para la iniciación de las variables), tiene los siguientes métodos:

int getChanels(); /* Devuelve el número de canales. */
AudioFormat.Encoding getEncoding(); /* Devuelve objeto con información sobre el tipo de codificación. */
float getFrameRate(); /* Devuelve la frecuencia de trama de la señal. */
int getFrameSize(); /* Devuelve tamaño de la trama en bytes. */
float getSampleRate(); /* Devuelve la frecuencia de muestreo. */
int getSampleSizeInBits(); /* Devuelve el tamaño en bits de cada muestra de sonido. */
boolean isBigEndian(); /* Devuelve true alineamiento big endian y false little endian. */

Estaras buscando algo como:
float getFrameRate(); /* Devuelve la frecuencia de trama de la señal. */

el link es http://cprades.eresmas.com/Tecnica/sonidoenjava.html

Algunas observaciones:
Imaginate que es necesario medir la frecuencia de un lugar en donde se combinan varios sonidos, cada sonido con un rango de frecuencias diferentes, ¿como le haras?, en este caso podrias simular un ecualizador.

Puedes usar Java Native Interface (JNI), para enlazar librerias de otros lenguajes que tienen esa funcionalidad.

Debes de considerar que el sonido que vas a medir este dentro de la frecuencia que puedes manipular en la computadora.

O si sabes electronica puedes hacer un frecuenciometro y solo recibir la informacion por algun puerto:
http://jorgefloresvergaray.blogspot.com/2010/03/frecuencimetro-digital.html

respuesta comentario

Gracias por contestar.

Con este sistema he estado probando, pero no único que consigo con el getFrameRate es obtener el sampleo del formato, por ejemplo 44100 para wav, pero lo que quiero, es no tener que dar formato, es decir, medir la frecuencia de la señal del microfono y no se como hacerlo, estoy muy perdido, miro ejemplos y tal, pero no me vale.

De todas maneras, muchas gracias.

Imagen de ezamudio

Conversión

Tienes que hacer una conversión de números. Lo de 44100 a 16 bits significa que la onda de sonido se convierte en un número de 16 bits, y se toman 44100 muestras del sonido cada segundo. Con esos datos reconstruyes la onda de audio. Si quieres determinar la frecuencia de un sonido, necesitas convertir esos números a algo que tenga sentido en los hertz, o sea contar los ciclos por segundo (puedes contar crestas o valles de la onda de sonido).

En la página de Audacity viene un tutorial bastante informativo y en wikipedia hay una buena explicación de audio digital, eso te puede servir.

Una vez que has logrado decodificar por ejemplo los 44100 números de 16 bits que constituyen un segundo de audio, tienes que encontrar las crestas o los valles de la onda de audio; suponiendo que tienen la misma amplitud, lo único que te queda es contar cuántas crestas o valles encontraste y esa es la frecuencia en Hz.

analisis de las crestas

El problema es que no se como analizar (sacar en claro) la cuenta de las crestas, he visto algunos documentos incompletos que muestra como hacerlo con ficheros de audio, pero desde directamente en tiempo real, desde el micrófono no, y lo que me dices de jugar con los números de 16bits, no lo llego a entender, por que si al menos en java hubiese una función que me devolviese ese numero tantas veces por segundo averiguaría la frecuencia real, ¿no?. llevo meses con esto y atascado me quedo, y no es por no mirar precisamente.

Gracias por la ayuda.

almacenado en array el input stream

Hola buenas, he logrado leer los datos en bytes del AudioInputstream , y al imprimirlos me dar resultados de -127 a 128, ¿tiene que ver con el estado de las crestas de la onda? ¿alguien sabe como debo de manipular esa información? es decir, como se calcula la frecuencia con esos datos y cuantos datos debe contener el array para hacer un buen cálculo.

Yo había supuesto que cuando me da un dato cualquiera por ejemplo -15 , 20, -5, 10. Yo imaginaba que eso serían 2 hercios ya que hace efecto de onda bajando y subiendo su posición 2 veces.

Ojala alguien me pueda ayudar.

P.D.: hay una cosa que me ha extrañado mucho, y es que incluso sin haberalgo emitiendo por la entrada ni del microfono ni por el puerto line-in de la tarjeta de sonido, siempre me devuelve datos. No veo la cosa clara.

Gracias

Se finaliza asunto

Por fin he logrado averiguar mediante pruebas si mi manejo con los datos era correcto y si, es correcto.
Para que los resultados fuesen los más parecidos a la realidad tuve que diseñar un filtro para que ignorara datos contaminantes los cuales me hacía incrementar el número de herciios de forma desastrosa.

Muchas gracias a todos, y un saludo.

Imagen de JaimeItlzc

Que bien

Que bien que ya tengas mas avances a tu proyecto, espero puedas platicarnos despues en tu blog acerca de tu proyecto y como lograste este analisis seria de gran aporte tu publicacion para los miembros que puedan tener algun proyecto parecido al tuyo.

Saludos.

Proyecto

Yo tengo que hacer un proyecto de este tipo.
Si hay alguien que maneje java y la forma de medir los decibelios de sonido a través de un micrófono estaré eternamente agradecido.

Pueden ponerse en contacto conmigo a través de correo electrónico: rafa_carneros@hotmail.com

Si hay alguien que entienda de esto le explicaré en que consiste el proyecto y si me puede ayudar sería fantastico.

Un saludo!

Imagen de ezamudio

hardware

Para poder medir dB estás un poco supeditado al hardware con el que cuentes, porque se necesita un micrófono con muy buena sensibilidad y los que traen las computadoras por lo general son bastante simples y no están hechos para eso.

La manera más simple (y la única que se me ocurre) que podrías "medir" los dB es tener un sonómetro a la mano, generar un ruido, y capturar lo que dice el sonómetro y a la vez capturar el nivel de audio que capta el micrófono de la computadora; con eso lo vas calibrando (sabes que el nivel de audio que capturaste en la compu corresponde a los dB que indica el sonómetro). Haces eso con distintos niveles de ruido y con eso tienes ya puntos de datos, con eso luego puedes ya aplicar bien la fórmula de los dB y calibrarla para que coincida con los puntos de datos que tienes (recuerda que la medición de dB no es lineal sino logarítmica).

hardware

En el caso de tener algún microfono en condiciones, ¿Como lo hago?

Imagen de juanfranc520

Ayuda e ideas

Te comento a modo personal , la verdad no he realizado la prueba con JAVA, pero si creo que debes tener en cuentas varioas factores, las frecuencias son un poco complejas de capturar debido a que es son señales senosoidales muy cambiantes en ordenes de tiempo muy cortos, por lo que es muy complejo que un programa lo realice de manera eficiente, debes tener en cuenta que esas variables no es constante, es mas asi no utilices el microfono existira un señal senosoidal de frecuencias muy pequeña debido al ruido, entonces te aconsejaria realizar la medicion de manera electronica y de esa manera obtener un dato (variable) la cual puedes enviar al PC (aplicacion) y de esa manera medirla, y creeme que asi intentes medir en un 100% la señal no lo podras hacer debido a la velocidad, un metodo podria ser con un PIC (Microcontrolador) y ese te permite enviar conexion serial al PC, otra opcion es convertir la señal en Hz a una señal DC que muy complicado o sino, ademas te recomiendo hacerle un "Filtro Pasa Alta" para que no te afecte el ruido, y si es posible debes realizar la prueba con la ayuda de un Osciloscopio Digital.

Julian Franco.
Cali - Colombia

Imagen de ezamudio

Afinadores

Y sin embargo vemos que hay varios afinadores de instrumentos por software, que no son otra cosa que analizadores de frecuencias, que te dicen la frecuencia que detectan cuando tocas una nota de un instrumento, y tienen una tabla para decirte la nota a la que corresponde esa frecuencia y si está muy arriba o muy abajo de donde debe ser la frecuencia exacta para dicha nota.

Incluso hay para Android, donde sabemos que tiene que estar hecho en Java el software, no hay manera de que tengan acceso más directo al micrófono del celular (que además no es de muy buena calidad) y sin embargo el afinar un instrumento con software como este, funciona lo suficientemente bien.

Imagen de beto.bateria

Para Cafar1990 - Dacs

Ahi te va informacion:

http://es.wikipedia.org/wiki/Decibelio
http://es.wikipedia.org/wiki/Conversi%C3%B3n_digital-anal%C3%B3gica

Considerando que recibes un 00000000 al manejar un DAC, quiere decir que hay silencio, si recibes un 11111111, quiere decir que recibiste un ruido con muchos decibelios.

Esto se aplica a la libreria de java mencionada arriba.

Solamente tendrias que calibrar el software.