2012-01-03 3 views
1

마이크의 오디오 입력에서 음성 입력 주파수를 계산하는 데 문제가 있습니다. 아무도 이것으로 나를 도울 수 있습니까?자바에서 실시간 오디오 주파수를 계산 중

마이크에서 오디오 입력을 받고 빈도를 계산해야합니다.

이것은 내가 한 일을 보여주기위한 코드입니다. 누구든지 결함있는 구현을 식별 할 수있는 경우

package STLMA; 

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 


/** 
* 
* @author CATE GABRIELLE 
*/ 

import java.io.*; 
import javax.sound.sampled.*; 

public class SpeechDetection { 
boolean stopCapture = false; 
ByteArrayOutputStream byteArrayOutputStream; 
TargetDataLine targetDataLine; // This is the object that acquires data from 
           // the microphone and delivers it to the program 

// the declaration of three instance variables used to create a SourceDataLine 
// object that feeds data to the speakers on playback 
AudioFormat audioFormat;  
AudioInputStream audioInputStream; 
SourceDataLine sourceDataLine;  

double voiceFreq = 0;  

FileOutputStream fout; 
AudioFileFormat.Type fileType; 
public static String closestSpeaker; 

public SpeechDetection(){ 
    captureAudio(); 
}  

private void captureAudio(){ 
    try{ 
     audioFormat = getAudioFormat(); 
     DataLine.Info dataLineInfo = new 
     DataLine.Info(TargetDataLine.class,audioFormat); 
     // object that describes the data line that we need to handle the acquisition 
     // of the audio data from the microphone. The first parameter makes the audio 
     // data readable 
     targetDataLine = (TargetDataLine)AudioSystem.getLine(dataLineInfo); 
     // object to handle data acquisition 
     targetDataLine.open(audioFormat);     
      //from the microphone that matches 
     targetDataLine.start();        
     // the information encapsulated in the DataLine.Info object 
     Thread captureThread = new Thread(new CaptureThread()); 
     captureThread.start(); 
    } catch (Exception e) { 
    System.out.println(e); 
    System.exit(0); 
    } 
}  

private AudioFormat getAudioFormat(){ 
    float sampleRate = 8000.0F; // The number of samples that will be acquired 
    //8000,11025,16000,22050,44100 each second for each channel of audio data. 
    int sampleSizeInBits = 16; //The number of bits that will be used to 
    //8,16      describe the value of each audio sample. 
    int channels = 1;   // Two channels for stereo, and one channel for mono. 
    //1,2 
    boolean signed = true;  // Whether the description of each audio sample 
    //true,false   
    //consists of both positive and negative values, or positive values only.   
    boolean bigEndian = false; 
    //true,false 
    return new AudioFormat(sampleRate,sampleSizeInBits,channels,signed,bigEndian);   
} 

//Inner class to capture data from microphone 
class CaptureThread extends Thread { 
    byte tempBuffer[] = new byte[8000]; 
    // byte buffer variable to contain the raw audio data 
    int countzero;      
    // counter variable to count the number of zero's    
    short convert[] = new short[tempBuffer.length]; 
    // short variable that is appropriate to 

    // collect the audio input for porcessing 

    //  public void start(){ 
    //   Thread voices = new Thread(this); 
    //   voices.start(); 
    //  } 

    @Override 
    public void run(){    
    // a continuous thread to process the continuous audio input 
     byteArrayOutputStream = new ByteArrayOutputStream(); // the object to write the 

    // raw audio input to the byte buffer variable 
     stopCapture = false; 
     try{ 
      while(!stopCapture){      
       int cnt = targetDataLine.read(tempBuffer,0,tempBuffer.length); 
      // reads the raw audio input 

      // and returns the number of bytes actually read 
       byteArrayOutputStream.write(tempBuffer, 0, cnt); 
      // writing the number of bytes read to the 
                   // container     
       try{ 
        countzero = 0; 

        for(int i=0; i < tempBuffer.length; i++){ 
       // the loop that stores the whole audio data           
         convert[i] = tempBuffer[i];  
       // to the convert variable which is a short data type, 
         if(convert[i] == 0){countzero++;}  
       // then counts the number of zero's 
        } 
        voiceFreq = (countzero/2)+1;    
       // calculates the number of frequency and 
            // stores to the voiceFreq variable 
        if(voiceFreq>=80 && voiceFreq<=350) 
         System.out.println("Voice"+voiceFreq); 
        else 
         System.out.println("Unvoice"+voiceFreq); 
       }catch(StringIndexOutOfBoundsException e) 
       {System.out.println(e.getMessage());}                      
        Thread.sleep(0);           
      } 
     byteArrayOutputStream.close(); 
     }catch (Exception e) { 
      System.out.println(e); 
      System.exit(0); 
     } 
    } 
}   

public static void main(String [] args){ 
    SpeechDetection voiceDetector1 = new SpeechDetection();   
    //  voiceDetector1.setSize(300,100); 
    //  voiceDetector1.setDefaultCloseOperation(EXIT_ON_CLOSE); 
    //  voiceDetector1.setVisible(true); 
} 



} 

그런데 "voiceFreq"는 음성 주파수를 나타냅니다. 여기 내 목표는 입력이 음성인지 잡음인지를 확인하는 것입니다. 누군가 내 문제를 도울 수 있기를 바랍니다. 고맙습니다. 그리고 새해 복 많이 받으십시오.

답변

3

잠재적 인 목소리인지 잡음인지를 감지하기 위해서는 데이터 섹션에서 FFT를 수행하고 주파수 구성 요소가 "정상적인 목소리"의 범위 내에 있는지 확인해야합니다.

일부 FFT 정보의 경우 Reliable and fast FFT in Java이 표시 될 수 있습니다.

+0

예 FFT를 고려해 보았지만 FFT를 이해하고 작동하는 방법을 이해하고 코드와 함께 구현하는 데 어려움을 겪고 있습니다. 아직도 그것에 종사하고있는 Im. 이 일을하는 다른 사람이 있습니까? – jpeter723

+0

+1 : 순수한 음색에 대해 계수 빈도가 작동합니다. 봉우리 사이의 샘플 수를 계산하면됩니다. 녹음 된 오디오에는 주파수가 혼합되어 있으며 FFT는 모든 주파수 (또는 주파수의 버킷)의 강도를 제공합니다. 변환에서 가장 강한 것을 선택하거나 가중 평균 또는 다른 접근 방식을 취할 수 있습니다. FFT를 사용하면 노이즈와 인프라 사운드를 제거 할 수 있습니다 (주파수는 무시할 수 있음). –

+0

FFT를 사용하여 구현하려면 FFT에서 코드의 어느 부분을 사용해야합니까? 왜냐하면 FFT에서 이해 한대로 3 개의 입력이 필요하기 때문에 X, Y 및 Z가 필요합니다.이 변수가 무엇을 의미하는지 알지 못합니다. – jpeter723

관련 문제