java audio speech-recognition javasound

java - Detecta silencio al grabar



audio speech-recognition (2)

¿Cómo puedo detectar el silencio cuando la operación de grabación se inicia en Java? ¿Qué son los datos de PCM? ¿Cómo puedo calcular datos de PCM en Java?

Encontré la solución:

package bemukan.voiceRecognition.speechToText; import javax.sound.sampled.*; import java.io.*; public class RecordAudio { private File audioFile; protected boolean running; private ByteArrayOutputStream out; private AudioInputStream inputStream; final static float MAX_8_BITS_SIGNED = Byte.MAX_VALUE; final static float MAX_8_BITS_UNSIGNED = 0xff; final static float MAX_16_BITS_SIGNED = Short.MAX_VALUE; final static float MAX_16_BITS_UNSIGNED = 0xffff; private AudioFormat format; private float level; private int frameSize; public RecordAudio(){ getFormat(); } private AudioFormat getFormat() { File file = new File("src/Facebook/1.wav"); AudioInputStream stream; try { stream = AudioSystem.getAudioInputStream(file); format=stream.getFormat(); frameSize=stream.getFormat().getFrameSize(); return stream.getFormat(); } catch (UnsupportedAudioFileException e) { } catch (IOException e) { } return null; } public void stopAudio() { running = false; } public void recordAudio() { try { final AudioFormat format = getFormat(); DataLine.Info info = new DataLine.Info( TargetDataLine.class, format); final TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info); line.open(format); line.start(); Runnable runner = new Runnable() { int bufferSize = (int) format.getSampleRate() * format.getFrameSize(); byte buffer[] = new byte[bufferSize]; public void run() { int readPoint = 0; out = new ByteArrayOutputStream(); running = true; int sum=0; while (running) { int count = line.read(buffer, 0, buffer.length); calculateLevel(buffer,0,0); System.out.println(level); if (count > 0) { out.write(buffer, 0, count); } } line.stop(); } }; Thread captureThread = new Thread(runner); captureThread.start(); } catch (LineUnavailableException e) { System.err.println("Line unavailable: " + e); System.exit(-2); } } public File getAudioFile() { byte[] audio = out.toByteArray(); InputStream input = new ByteArrayInputStream(audio); try { final AudioFormat format = getFormat(); final AudioInputStream ais = new AudioInputStream(input, format, audio.length / format.getFrameSize()); AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File("temp.wav")); input.close(); System.out.println("New file created!"); } catch (IOException e) { System.out.println(e.getMessage()); } return new File("temp.wav"); } private void calculateLevel (byte[] buffer, int readPoint, int leftOver) { int max = 0; boolean use16Bit = (format.getSampleSizeInBits() == 16); boolean signed = (format.getEncoding() == AudioFormat.Encoding.PCM_SIGNED); boolean bigEndian = (format.isBigEndian()); if (use16Bit) { for (int i=readPoint; i<buffer.length-leftOver; i+=2) { int value = 0; // deal with endianness int hiByte = (bigEndian ? buffer[i] : buffer[i+1]); int loByte = (bigEndian ? buffer[i+1] : buffer [i]); if (signed) { short shortVal = (short) hiByte; shortVal = (short) ((shortVal << 8) | (byte) loByte); value = shortVal; } else { value = (hiByte << 8) | loByte; } max = Math.max(max, value); } // for } else { // 8 bit - no endianness issues, just sign for (int i=readPoint; i<buffer.length-leftOver; i++) { int value = 0; if (signed) { value = buffer [i]; } else { short shortVal = 0; shortVal = (short) (shortVal | buffer [i]); value = shortVal; } max = Math.max (max, value); } // for } // 8 bit // express max as float of 0.0 to 1.0 of max value // of 8 or 16 bits (signed or unsigned) if (signed) { if (use16Bit) { level = (float) max / MAX_16_BITS_SIGNED; } else { level = (float) max / MAX_8_BITS_SIGNED; } } else { if (use16Bit) { level = (float) max / MAX_16_BITS_UNSIGNED; } else { level = (float) max / MAX_8_BITS_UNSIGNED; } } } // calculateLevel }


¿Cómo puedo detectar el silencio cuando la operación de grabación se inicia en Java?

Calcule el valor dB o RMS para un grupo de marcos de sonido y decida a qué nivel se considera ''silencio''.

¿Qué son los datos de PCM?

Datos que están en formato de modulación de código Pulse .

¿Cómo puedo calcular datos de PCM en Java?

No entiendo esa pregunta. Pero supongo que tiene algo que ver con la etiqueta de speech-recognition . Tengo algunas malas noticias. Esto teóricamente podría hacerse usando la API de Java Speech . Pero aparentemente no hay implementaciones de "voz a texto" disponibles para la API (solo ''texto a voz'').

Tengo que calcular rms para el proyecto de reconocimiento de voz. Pero no sé cómo puedo calcular en Java.

Para un solo canal que está representado por tamaños de señal en un double va de -1 a 1, puede usar este método.

/** Computes the RMS volume of a group of signal sizes ranging from -1 to 1. */ public double volumeRMS(double[] raw) { double sum = 0d; if (raw.length==0) { return sum; } else { for (int ii=0; ii<raw.length; ii++) { sum += raw[ii]; } } double average = sum/raw.length; double sumMeanSquare = 0d; for (int ii=0; ii<raw.length; ii++) { sumMeanSquare += Math.pow(raw[ii]-average,2d); } double averageMeanSquare = sumMeanSquare/raw.length; double rootMeanSquare = Math.sqrt(averageMeanSquare); return rootMeanSquare; }

Hay un búfer de bytes para guardar los valores de entrada de la línea, y lo que debería hacer con este búfer?

Si usa el volumeRMS(double[]) , convierta los valores de byte en una matriz de valores double que van de -1 a 1.;)


Necesita capturar el valor como un silencio de número es cero o cerca

Por favor, adapte su código a su requerimiento! En este caso, una variable llamada UMBRAL (Umbral en español) ...

Supongamos que tiene acceso al archivo WAV como byteHeader de bytes ...

private Integer Byte2PosIntBig(byte Byte24, byte Byte16, byte Byte08, byte Byte00) { return new Integer ( ((Byte24) << 24)| ((Byte16 & 0xFF) << 16)| ((Byte08 & 0xFF) << 8)| ((Byte00 & 0xFF) << 0)); }

Antes de ....

RandomAccessFile RAFSource = new RandomAccessFile("your old file wav", "r");

Comienza aquí ...

int PSData = 44; byte[] Bytes = new byte[4]; byte[] ByteHeader = new byte[44]; RAFSource.seek(0); RAFSource.read(ByteHeader); int WavSize = Byte2PosIntBig(ByteHeader[43],ByteHeader[42],ByteHeader[41],ByteHeader[40]); int NumBits = Byte2PosIntBig(ByteHeader[35],ByteHeader[34]); int NumByte = NumBits/8; for (int i = PSData;i < PSData+WavSize;i+=NumByte) { int WavSample = 0; int WavResultI =0; int WavResultO = 0; if (NumByte == 2) { RAFSource.seek(i); Bytes[0] = RAFSource.readByte(); Bytes[1] = RAFSource.readByte(); WavSample = (int)(((Bytes[1]) << 8)|((Bytes[0] & 0xFF) << 0)); if (Math.abs(WavSample) < UMBRAL) { //SILENCE DETECTED!!! } } else { RAFSource.seek(i); WavSample = (short)(RAFSource.readByte() & 0xFF); short sSamT = (short)WavSample; sSamT += 128; double dSamD = (double)sSamT*Multiplier; if ((double)sSamT < UMBRAL) { //SILENCE DETECTED!!! } }