2011-01-16 4 views
4

나는 안드로이드 API의 AudioRecord 기능을 뒤적 거리며 이상한 행동을 발견했다.Android AudioRecord에 대한 질문이 있으십니까?

배경 정보 : 휴대 전화는 HTC Incredible입니다. 에뮬레이터와 함께 Android 개발 용 Eclipse 플러그인을 사용하고 있습니다. 대상 플랫폼 또는 OS는 2.2 ... 내 전화기가 사용하는 것이기 때문에.

일부 코드 :

bufferSize = AudioRecord.getMinBufferSize(FREQUENCY, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); 
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); 

이 내가 함께 가지 audiorecord의 API 설정에 사용하는 코드입니다. 이제 에뮬레이터의 경우 FREQUENCY가 작동하려면 8000으로 설정하는 것이 좋습니다. 버퍼 크기 640으로 돌아옵니다. 44100을 사용하는 전화의 경우 하나의 문제는 파도에 대한 결과 PCM 데이터가 8 비트 부호있는 웨이브처럼 보입니다. 나는 값을 -127에서 128로 얻는다. 나는 값 AudioFormat.ENCODING_PCM_16BIT이 뭔가 다른 것을 생산할 것이라고 생각했다.

난 스레드와 오디오

public void run() { 
    while(isRecording) { 
    audioRecord.startRecording(); 
    byte[] data = new byte[bufferSize]; 
    audioRecord.read(data, 0, bufferSize); 
    listener.setData(data); 
    handleData(data); 
    } 
    audioRecord.release(); 
} 

내가 SurfaceView를 그래픽을 이용하여 실시간으로 전파 대응하는 표시 방법이 처리. MIC에서 많은 소음이 오는 것 같습니다. 나는 에뮬레이터와 전화에서이 잡음을 얻는다. 일종의 필터를 통해 데이터를 실행해야합니까? 이 데이터를 사용하여 재미있는 FFT를 계산하고 웨이브를 가지고 놀고 싶습니다. 그러나 어떻게 든 잡음을 줄여야합니다.

이 경험이있는 사람이 있습니까? 누구든지 해결책이 있습니까?

나는 당신의 시간과 응답, 덕분에, 나는 조금의 도움을받을 수 있습니다 DK

답변

3

감사. 그러나, 나는 너와 같은 상황에 처해있다. 그래서 나는 너에게 나의 경험에 대해서만 말할 수있다.

나는 당신과 같이 장치의 선호 sampleRate을 얻을 수 있다고 생각 :

int sampleRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_SYSTEM); 

16 비트 인코딩 모드가 가지 audiorecord에서만 작동하는 것입니다. 나는 8Bit을 출력과 같이 얻는 이유를 확신 할 수 없다. 어쩌면 누군가는 알고 있습니다.

검색된 바이트에서 진폭을 가져 오는 방법을 확신 할 수 없습니까? 내가 대답뿐만 아니라 자신의 답을 알고 싶지 않을 수 있습니다 여기에 두 개의 큰 질문이 있습니다

int sampleRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_SYSTEM); 
int channelMode = AudioFormat.CHANNEL_IN_MONO; 
int encodingMode = AudioFormat.ENCODING_PCM_16BIT; 
int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelMode, encodingMode); 

AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channelMode, encodingMode, bufferSize); 

recorder.setPositionNotificationPeriod(intervalFrames); 
recorder.setRecordPositionUpdateListener(recordListener); 
recorder.startRecording(); 

private RecordListener recordListener = new RecordListener(); 
private class RecordListener implements AudioRecord.OnRecordPositionUpdateListener { 
    public void onMarkerReached(AudioRecord recorder) { 
     Log.v("MicInfoService", "onMarkedReached CALL"); 
    } 

    public void onPeriodicNotification(AudioRecord recorder) { 
     Log.v("MicInfoService", "onPeriodicNotification CALL"); 
    } 
} 

: 마지막으로

, 난 당신이,주기 리스너 함수를 사용과 같이 할 생각

  1. intervalFrames로 설정해야하는 항목은 무엇입니까?
  2. 리스너 메소드가 호출되지 않는 이유는 무엇입니까?

더 도움이 되었으면합니다.

+0

일부 FFT 기술을 사용하여 노이즈를 줄였으며 몇 가지 코드 예제가 있습니다. 나는 지금 여행 중이지만 내가 돌아 왔을 때 토론을 계속하고 싶다. 귀하의 의견을 보내 주셔서 감사합니다. – dakira

+3

intervalFrames는 통보 받고자하는 샘플 수입니다. 8000에서 샘플링하는 경우 intervalFrames = 4000은 알림 청취자에게 1/(8000/4000) = 0.5 초마다 호출합니다. 리스너 함수가 호출되도록 읽기를 시작해야하며, 또한 읽기 버퍼 크기가> = intervalFrames인지 확인해야합니다. –

+1

+1 getNativeOutputSampleRate(); 어떻게 당신 문제를 해결 했나요? 비슷한 문제로 고민 중입니까? http://stackoverflow.com/questions/9413998/live-audio-recording-and-playing-in-android – aProgrammer

9

이 질문이 제기 된 지 오래되었으므로 더 이상 답변이 필요한지 여부는 알 수 없습니다.

-127에서 128까지의 값을 가져 오는 이유는 각각 8 비트 숫자가있는 바이트 배열을 읽는 것입니다. 16 비트 오디오의 경우 단락 배열을 읽습니다.

나는 소음 문제를 해결할 수 없다.

+4

라고 불릴 것입니다. Peter가 각 샘플의 하위 바이트를 사용하고 있다면, 더 큰 진폭 정보가 8 바이트 이상 있다고 가정하면이 값은 매우 시끄 럽습니다. 이 정보는보다 일관성이 있습니다. 나는 '짧은'조정이 소음 문제도 해결했다고 가정하고있다. –

+0

@mike, 비슷한 문제가 있습니다. http : //stackoverflow.com/questions/9413998/live-audio-recording-and-playing-in-android#comment12005651_9413998 .... help !!! – aProgrammer

12

"AudioFormat.ENCODING_PCM_16BIT"스트림에서 바이트를 읽으면 실제로 각 샘플의 상위 바이트와 하위 바이트를 2 순차 바이트로 제공합니다. 이것은 각 바이트가 샘플이되도록 (실제로는 반 샘플 대신) 가져 오는 것이 매우 시끄러운 것처럼 보일뿐 아니라 서명이 첫 번째 바이트에 대해 잘못 될 것입니다 (little endian 순서로되어 있음).

스트림에서 의미있는 데이터를 가져 오려면 다음과 같은 단락을 통해 읽습니다.

https://github.com/gast-lib/gast-lib

그것은 그것은이있는 AsyncTask

있습니다

public void run() { 
    while(isRecording) { 
    audioRecord.startRecording(); 
    short[] data = new short[bufferSize/2]; 
    audioRecord.read(data, 0, bufferSize/2); 
    listener.setData(data); 
    handleData(data); 
    } 
    audioRecord.release(); 
} 
+0

이 경우 청취자는 무엇을합니까 ....? 나는 또한 비슷한 질문을 내 질문에 참조하십시오 http://stackoverflow.com/questions/9413998/live-audio-recording-and-playing-in-android#comment12005651_9413998 – aProgrammer