2017-02-11 2 views
0

내가 내 음성을 동시에 여기원시 오디오 녹음에서 주파수를 얻는 방법?

기록에서 주파수를 얻고 싶은 것은 내 코드입니다 :

내 SoundProcessing의 된 .java와 메인 클래스

public class SoundProcessing extends Activity { 

private WaveformView mRealtimeWaveformView; 
private RecordingThread mRecordingThread; 
private PlaybackThread mPlaybackThread; 
private static final int REQUEST_RECORD_AUDIO = 13; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_tab_sound_processing); 

    mRealtimeWaveformView = (WaveformView) findViewById(R.id.waveformView); 
    mRecordingThread = new RecordingThread(new AudioDataReceivedListener() { 
     @Override 
     public void onAudioDataReceived(short[] data) { 
      mRealtimeWaveformView.setSamples(data); 
     } 
    }); 
    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      if (!mRecordingThread.recording()) { 
       startAudioRecordingSafe(); 
      } else { 
       mRecordingThread.stopRecording(); 
      } 
     } 
    }); 
} 

내 RecordingThread.java :

,

공용 클래스 RecordingThread {

private static final String LOG_TAG = RecordingThread.class.getSimpleName(); 
private static final int SAMPLE_RATE = 44100; 

public RecordingThread(AudioDataReceivedListener listener) { 
    mListener = listener; 
} 

private boolean mShouldContinue; 
private AudioDataReceivedListener mListener; 
private Thread mThread; 

public boolean recording() { 
    return mThread != null; 
} 

public void startRecording() { 
    if (mThread != null) 
     return; 

    mShouldContinue = true; 
    mThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      record(); 
     } 
    }); 
    mThread.start(); 
} 

public void stopRecording() { 
    if (mThread == null) 
     return; 

    mShouldContinue = false; 
    mThread = null; 
} 

private void record() { 
    Log.v(LOG_TAG, "Start"); 
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO); 

    // buffer size in bytes 
    int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, 
      AudioFormat.CHANNEL_IN_MONO, 
      AudioFormat.ENCODING_PCM_16BIT); 

    if (bufferSize == AudioRecord.ERROR || bufferSize == AudioRecord.ERROR_BAD_VALUE) { 
     bufferSize = SAMPLE_RATE * 2; 
    } 

    short[] audioBuffer = new short[bufferSize/2]; 

    AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, 
      SAMPLE_RATE, 
      AudioFormat.CHANNEL_IN_MONO, 
      AudioFormat.ENCODING_PCM_16BIT, 
      bufferSize); 

    if (record.getState() != AudioRecord.STATE_INITIALIZED) { 
     Log.e(LOG_TAG, "Audio Record can't initialize!"); 
     return; 
    } 
    record.startRecording(); 

    Log.v(LOG_TAG, "Start recording"); 

    long shortsRead = 0; 
    while (mShouldContinue) { 
     int numberOfShort = record.read(audioBuffer, 0, audioBuffer.length); 
     shortsRead += numberOfShort; 

     // Notify waveform 
     mListener.onAudioDataReceived(audioBuffer); 
    } 

    record.stop(); 
    record.release(); 

    Log.v(LOG_TAG, String.format("Recording stopped. Samples read: %d", shortsRead)); 
} 
} 

및 푸리에 변환으로, 예를 들어 그것을 분석 할 필요가 신호의 주파수를 얻기 위하여 내 AudioDataReceivedListener.java

public interface AudioDataReceivedListener { 

    void onAudioDataReceived(short[] data); 
} 

답변

1

. 기술적 인 어플리케이션에서는 Fast/Discrete Fourier Transformation (FFT)을 사용합니다. 원시 오디오는 시간이 지남에 따라 기록 된 신호입니다. FFT를 사용하면 신호에 포함 된 주파수를 볼 수 있습니다.

귀하의 경우에는 audioBuffer에 FFT를 적용해야한다는 의미입니다. Java 클래스와 C/C++ 코드 (NDK 포함)가 있습니다. 실시간 응용 프로그램의 경우 C/C++가 더 빨라야합니다.

관련 문제