Cómo ajustar la sensibilidad del micrófono mientras graba audio en android
Estoy trabajando en una aplicación de grabación de voz. En app tengo un Seekbar para cambiar la ganancia de voz de entrada. No pude encontrar ninguna forma de ajustar la ganancia de voz de entrada.
Estoy usando la clase AudioRecord para grabar voz.
- Reutilización de tareas asíncronas de Android
- Cómo transferir una lista ArrayList
- Binarizar imagen en Android
- ¿Cómo puedo instalar un apk en varios dispositivos conectados?
- Android - Tabs, MapView, actividades dentro de las pestañas
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, bufferSize); recorder.startRecording();
He visto una aplicación también en la tienda de juego que están utilizando esta funcionalidad.
Https://play.google.com/store/apps/details?id=com.grace.microphone
- ¿Cómo comprobar con gracia si un recurso bruto no existe?
- Cómo hacer una copia de un archivo en android?
- No se puede inicializar AudioEffect (LoudnessEnhancer) en MediaPlayer (API 19)
- org.xml.sax.SAXParseException: Token inesperado al analizar XML
- Error: Android Pre Dex: Android SDK no está especificado
- Luz de flash no detectada
- ¿Cómo interpreta Android la palabra clave @null en los diseños?
- "Error al resolver: com.android.support:support-v4:26.0.0" y otros errores similares en la sincronización de Gradle
Como he entendido que no desea ningún ajuste automático, sólo manual de la interfaz de usuario. No hay funcionalidad incorporada para esto en Android, en cambio tienes que modificar tus datos manualmente.
Suponga que usted utiliza read (short [] audioData, int offsetInShorts, int sizeInShorts) para leer el flujo. Así que deberías hacer algo como esto:
float gain = getGain(); // taken from the UI control, perhaps in range from 0.0 to 2.0 int numRead = read(audioData, 0, SIZE); if (numRead > 0) { for (int i = 0; i < numRead; ++i) { audioData[i] = (short)Math.min((int)(audioData[i] * gain), (int)Short.MAX_VALUE); } }
Math.min
se utiliza para evitar el desbordamiento si la gain
es mayor que 1.
La sensibilidad dinámica del micrófono no es algo que el hardware o el sistema operativo sea capaz, ya que requiere análisis en el sonido grabado. Debe implementar su propio algoritmo para analizar el sonido grabado y ajustar (amplificar o disminuir) el nivel de sonido por su cuenta.
Puede comenzar analizando los últimos segundos y encontrar un multiplicador que va a "equilibrar" la amplitud promedio. El multiplicador debe ser inversamente proporcional a la amplitud media para equilibrarla.
PS: Si todavía quieres hacerlo, los niveles de micrófono son accesibles cuando tienes un acceso root, pero todavía no estoy seguro -y no creo que sea posible- si puedes cambiar la configuración mientras grabas. Sugerencia: "/ system / etc / snd_soc_msm" archivo.
Esta es la implementación de trabajo basada en ByteBuffer
para 16 bits de audio. Es importante sujetar el valor incrementado de ambos lados desde que se firma el corto. También es importante establecer el orden de bytes nativos en ByteBuffer
ya que audioRecord.read()
devuelve bytes de endian nativos.
También puede realizar audioRecord.read()
y el código siguiente en un bucle, llamando a data.clear()
después de cada iteración.
double gain = 2.0; ByteBuffer data = ByteBuffer.allocateDirect(SAMPLES_PER_FRAME).order(ByteOrder.nativeOrder()); int audioInputLengthBytes = audioRecord.read(data, SAMPLES_PER_FRAME); ShortBuffer shortBuffer = data.asShortBuffer(); for (int i = 0; i < audioInputLengthBytes / 2; i++) { // /2 because we need the length in shorts short s = shortBuffer.get(i); int increased = (int) (s * gain); s = (short) Math.min(Math.max(increased, Short.MIN_VALUE), Short.MAX_VALUE); shortBuffer.put(i, s); }
Solución por OP.
Lo he hecho usando
final int USHORT_MASK = (1 << 16) - 1; final ByteBuffer buf = ByteBuffer.wrap(data).order( ByteOrder.LITTLE_ENDIAN); final ByteBuffer newBuf = ByteBuffer.allocate( data.length).order(ByteOrder.LITTLE_ENDIAN); int sample; while (buf.hasRemaining()) { sample = (int) buf.getShort() & USHORT_MASK; sample *= db_value_global; newBuf.putShort((short) (sample & USHORT_MASK)); } data = newBuf.array(); os.write(data);
- ¿Cómo habilitar / deshabilitar una aplicación Widgets en Android basado en la versión sdk?
- ExpandableList getChildView ejecutándose dos veces por niño