2011-02-28 5 views
13

Hej, 현재 AudioRecord를 작동 시키려고합니다. 왜냐하면 나는 더 큰 프로젝트에서 그것을 필요로하기 때문이다. 그러나 그것은 많이 엉망진창 같다. 나는 많은 것들을 시도해 왔기 때문에이 버그를 추적했을 때 나는 기본으로 돌아갔다. 디버깅 장치로 삼성 Galaxy S를 사용하고 있습니다.Android AudioRecord - 두 번째로 초기화하지 않습니다.

제 문제는 장치를 처음 재부팅 한 후 처음으로 문제없이 만들 수있는 AudioRecord 개체를 초기화 할 수 있다는 것입니다. 하지만 두 번째 실행하면 AudioRecord 객체가 초기화되지 않습니다. 여러 주파수를 시도했습니다. 여기

내 코드입니다. 내가 "를 가지 audiorecord에 기본 보류를 해제하는 것이 이벤트

02-28 10:46:37.048: DEBUG/dalvikvm(4477): GC_EXPLICIT freed 1801 objects/98944 bytes in 97ms 
02-28 10:46:37.048: VERBOSE/AudioRecord(4477): stop 

에게 발견 로그 캣 정보를 통해보고 몇 시간 후

package android.audiorecordtest; 

import android.app.Activity; 
import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 

public class AudioRecordTest extends Activity { 

    int frequency; 
    AudioRecord audRec; 
    TextView txtVw; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     txtVw = (TextView) findViewById(R.id.txtVw); 


     frequency=8000; 
     int bufferSize=(AudioRecord.getMinBufferSize(frequency, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT))*2; 
     if (bufferSize>0) { 
      audRec = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); 
       int status = audRec.getState(); 
     if (status == AudioRecord.STATE_INITIALIZED) { 
      txtVw.setText("Initialized" + frequency); 
     } else { 
      txtVw.setText("Not Initialized i=" + frequency); 
     } 
     } 

그래서 나는 내 Audiorecord object.release()로 마무리 오버라이드를 시도했다.이 비록 작동하지 않습니다 .. 누구나 어떤 생각이있어?

+0

내가 아무도 어떤 답이없는 이유를 정말 너희들이 문제를 재현 할 수 없기 때문에 그 것이다, 궁금 해서요, 또는 사람들은 방해 할 수 없기 때문에 도움을하거나 다음과 같이 당신은 그것을 사용할 수 있습니다 ? –

+0

이것에 걸림돌이되는 사람은 기록 허가를 받았는지 확인하십시오! – NateS

+1

@NateS 만약 당신이 레코드 권한을 가지고 있지 않다면 심지어 처음에는 내 질문에 제목이 명확하게 나와있는 것처럼 초기화되지 않을 것입니다. 그렇지만 누군가가 첫 번째 초기화 시도에 문제가있는 경우 AndroidManifest.xml에서 권한을 확인해야합니다. –

답변

11

(삼성 전화에서) 문제를 재현 할 수있었습니다. I 레코드 해제들의 OnDestroy() 메소드 덧붙여이 가하여

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    System.out.println("OnDestroy"); 
    audRec.release(); 
} 

을 상기 가지 audiorecord 올바르게 작업이 시작될 때마다 초기화 같다.

+1

+1 저에게있어서, AsyncTask의 onCancelled() 메소드가 필요했습니다. 그러나 이것없이 문제의 바닥에 어떻게 도달했는지 모르겠습니다. 감사. :) – Mikaveli

0

당신은 시도해야합니다 o 자원을 해제하려면 audRec.stop()을 호출하십시오.

+0

정지는 실행중인 녹음을 중지하기위한 것입니다. 하지만 Release는 멈추지 않고 리소스를 해제하고 있지만 Stop을 호출하는 try-catch도 있습니다. 내가 수업을 들여다 보았던 한. 고마워. –

1

내 자신의 질문에 대답하려면 AudioRecord를 사용할 수있는 유일한 방법은 전역 변수로 사용하지 않는 것입니다. 그 이유는 모르겠지만 인스턴스의 리소스를 해제 할 수는없는 것 같습니다. 당신이 그렇게한다면.

+0

요르단이했던 방식대로 시도해야합니다. 나는 그것을 좋아한다. 그리고 그것은 단지 잘된다. ... – ThaMe90

+0

그가 그것을 재현하고, 그것을 해결하면, 그래, 그에게 정확한 답을주기에 충분하다. 내 관심. –

+0

나는 그것을 null로 설정하는 것이 맨 위에 조금있다, 당신이 release()를 호출 한 후, GC는 당신을 위해 얼마 동안 자동적으로 그것을 정리해야하므로 다시 초기화 할 수있다. – ThaMe90

5

동일한 문제가 있었지만 일반적으로 audRec.release()가 실제로 도움이되었습니다. 그러나 여러 번 중지하고 시작해야하는 경우 다음 코드가 더욱 강력합니다. 게다가, 나는 기록이 별도의 스레드에서 발생했고 오랜 시간 동안 실행될 때 Android가 스레드를 죽이는 문제가있었습니다. 따라서이 코드를 살펴, 그것은 다른 스레드가 정지) (죽은 다음 audRec.start에있을 때 녹음도 개최됩니다 확인합니다 해제 : 다음

import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.media.MediaRecorder; 

public class RecorderSingleton { 

    private static final int FREQUENCY = 16000; 

    public static RecorderSingleton instance = new RecorderSingleton(); 
    private AudioRecord recordInstance = null; 
    private int bufferSize; 

    private RecorderSingleton() { 
     bufferSize = AudioRecord.getMinBufferSize(FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); 
    } 

    public boolean init() { 
     recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); 
     if (recordInstance.getState() == AudioRecord.STATE_UNINITIALIZED) { 
      return false; 
     } 
     return true; 
    } 

    public int getBufferSize() { 
     return bufferSize; 
    } 
    public boolean start() { 
     if (recordInstance != null && recordInstance.getState() != AudioRecord.STATE_UNINITIALIZED) { 
      if (recordInstance.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED) { 
       recordInstance.stop(); 
      } 
      recordInstance.release(); 
     } 
     if (!init()) { 
      return false; 
     } 
     recordInstance.startRecording(); 
     return true; 
    } 

    public int read(short[] tempBuffer) { 
     if (recordInstance == null) { 
      return AudioRecord.ERROR_INVALID_OPERATION; 
     } 
     int ret = recordInstance.read(tempBuffer, 0, bufferSize); 
     return ret; 
    } 

    public void stop() { 
     if (recordInstance == null) { 
      return; 
     } 
     recordInstance.stop(); 
     recordInstance.release(); 
    } 
} 

당신은 레코더 스레드가있는 경우

import android.media.AudioRecord; 

public class Recorder implements Runnable { 
    private int requiredSamples; 
    private int takenSamples = 0; 
    private boolean cancelled = false; 

    public void run() { 

     // We're important... 
     android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 

     int bufferRead = 0; 
     int bufferSize = RecorderSingleton.instance.getBufferSize(); 
     short[] tempBuffer = new short[bufferSize]; 
     if (!RecorderSingleton.instance.start()) { 
      return; 
     } 
     try { 
      Log.d(RoomieConstants.LOG_TAG, "Recorder Started"); 
      while (takenSamples < requiredSamples && !cancelled) { 
       bufferRead = RecorderSingleton.instance.read(tempBuffer); 
       if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) { 
        throw new IllegalStateException("read() returned AudioRecord.ERROR_INVALID_OPERATION"); 
       } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) { 
        throw new IllegalStateException("read() returned AudioRecord.ERROR_BAD_VALUE"); 
       } 
       takenSamples += bufferRead; 
       // do something with the samples ... 
       // ... 
       // ... 
      } 
     } finally { 
      // Close resources... 
      stop(); 
     } 
    } 

    public void stop() { 
     RecorderSingleton.instance.stop(); 
    } 

    public void cancel() { 
     cancelled = true; 
    } 
} 
+0

특별한 경우에 required 샘플을주는 가치는 어느 것입니까? – Josh