2011-03-07 6 views
1

대학 프로젝트 용 나의 교수. 내가 안드로이드 응용 프로그램을 작성하길 원한다면, 내 첫 번째 것이 될 것입니다. Java 경험이 있지만 Android 프로그래밍이 처음이므로 제발 친절하게 대해주십시오.android, AudioRecord.read() -> bufferoverflow, 어떻게 버퍼를 처리 할 수 ​​있습니까?

처음에는 AsyncTask를 시작하는 버튼과 멈추는 버튼이 두 개있는 Activity를 만듭니다. 부울 isRecording을 false로 설정하면 AsyncTask에서 모든 것이 처리됩니다. 소스 코드로 첨부.

꽤 괜찮습니다.하지만 잠시 후에 LogCat에서 몇 가지 bufferoverflow 메시지를 찾을 수 있습니다. 그런 다음 잡히지 않은 예외로 인해 충돌이 발생합니다. 나는 그것이 왜 부서지는 지 알아 냈고 잡히지 않는 예외는 그 질문의 목적이되어서는 안된다. 나는 버퍼 오버플로를 얻을 왜 아무도 말할 수

03-07 11:34:02.474: INFO/buffer 247:(558): 40 
03-07 11:34:02.484: WARN/AudioFlinger(33): RecordThread: buffer overflow 
03-07 11:34:02.484: INFO/MutantAudioRecorder:doInBackground()(558): isRecoding 
03-07 11:34:02.484: INFO/MutantAudioRecorder:doInBackground()(558): isRecoding 
03-07 11:34:02.494: WARN/AudioFlinger(33): RecordThread: buffer overflow 
03-07 11:34:02.494: INFO/buffer 248:(558): -50 
  1. 나는 당신이 볼 수있는 버퍼를 쓸 수 있지만 어떻게 든 제대로 가지 audiorecord를 구성 내가 실수를 생각?

  2. 다음 질문은 어떻게 버퍼를 처리 할 수 ​​있습니까? 내 말은, 그 안에 값을 가지고 있으며, 화면에 그래픽 스펙트로 그램으로 보여주고 싶습니다. 누구든지 그 경험을 가지고 있으며 힌트를 줄 수 있습니까? 어떻게해야합니까?

미리 도움을 주셔서 감사합니다. AsyncTask를의

소스 코드 : 우리는 오디오 데이터를 디코딩하고 간단해야 화면에 표시, 채팅 룸에서 설명하고있는 바와 같이

package nomihodai.audio; 

import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.os.AsyncTask; 
import android.util.Log; 



public class MutantAudioRecorder extends AsyncTask<Void, Void, Void> { 

private boolean isRecording = false; 
public AudioRecord audioRecord = null; 
public int mSamplesRead; 
public int buffersizebytes; 
public int buflen; 
public int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; 
public int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; 
public static short[] buffer; 
public static final int SAMPLESPERSEC = 8000; 


@Override 
protected Void doInBackground(Void... params) { 

    while(isRecording) { 

     audioRecord.startRecording(); 
     mSamplesRead = audioRecord.read(buffer, 0, buffersizebytes); 

     if(!readerT.isAlive()) 
      readerT.start(); 

     Log.i("MutantAudioRecorder:doInBackground()", "isRecoding"); 
    } 

    readerT.stop(); 

    return null; 
} 


Thread readerT = new Thread() { 
    public void run() { 
     for(int i = 0; i < 256; i++){ 
      Log.i("buffer " + i + ": ", Short.toString(buffer[i])); 
     } 
    } 
}; 


@Override 
public void onPostExecute(Void unused) { 
    Log.i("MutantAudioRecorder:onPostExecute()", "try to release the audio hardware"); 

    audioRecord.release(); 

    Log.i("MutantAudioRecorder:onPostExecute()", "released..."); 
} 


public void setRecording(boolean rec) { 
    this.isRecording = rec; 

    Log.i("MutantAudioRecorder:setRecording()", "isRecoding set to " + rec); 
} 


@Override 
protected void onPreExecute() { 

    buffersizebytes = AudioRecord.getMinBufferSize(SAMPLESPERSEC, channelConfiguration, audioEncoding); 
    buffer = new short[buffersizebytes]; 
    buflen = buffersizebytes/2; 

    Log.i("MutantAudioRecorder:onPreExecute()", "buffersizebytes: " + buffersizebytes 
               + ", buffer: " + buffer.length 
               + ", buflen: " + buflen); 

    audioRecord = new AudioRecord(android.media.MediaRecorder.AudioSource.MIC, 
      SAMPLESPERSEC, 
      channelConfiguration, 
      audioEncoding, 
      buffersizebytes); 

    if(audioRecord != null) 
     Log.i("MutantAudioRecorder:onPreExecute()", "audiorecord object created"); 
    else 
     Log.i("MutantAudioRecorder:onPreExecute()", "audiorecord NOT created"); 
} 

}

답변

0

. 오디오 버퍼에는 초당 8000 개의 샘플이 있고 각 샘플은 16 비트이며 모노 오디오입니다.

표시하는 것은 간단해야합니다. 보기에서 각 샘플을 수직 오프셋으로 처리하십시오. 보기의 세로 높이에 -32k에서 + 32k 범위의 범위를 조정해야합니다. 뷰의 왼쪽 가장자리부터 시작하여 열당 하나의 샘플을 그립니다. 오른쪽 가장자리에 도달하면 다시 감싸십시오 (필요한 경우 이전 선을 지우십시오).

이렇게하면 각 샘플이 단일 픽셀로 그려지기 때문에 결과가 좋지 않을 수 있습니다. 인접한 샘플간에 선을 그릴 수도 있습니다. 선 효과를 내기 위해 선 너비, 색상 등으로 놀 수 있습니다.

하나의 마지막 참고 사항 : 초당 8000 회 더 그리기, 이전 샘플을 비우는 데 더 많은 시간을 할애합니다. 프레임 속도가 오디오를 따라갈 수 있는지 확인하려면 몇 가지 단축키가 필요할 수 있습니다. 샘플을 건너 뛰어야 할 수도 있습니다.

4

녹음 된 오디오 바이트를 처리하는 일부 실시간 분석 프로세스입니까?

"버퍼링 버퍼의 크기가 제한되어 있으므로"분석 프로세스 "가 기록 속도보다 느리면 버퍼의 데이터가 멈추지 만 기록 바이트는 항상 버퍼 오버플로가됩니다.

레코딩시 스레드를 사용하고 기록 된 바이트에 다른 프로세스를 사용해보십시오.이 접근법에 대한 오픈 소스 샘플 코드가 있습니다. http://musicg.googlecode.com/files/musicg_android_demo.zip

관련 문제