3

마이크에서 오디오 데이터를 가져 오려고합니다. 필자는 AudioRecord 클래스를 사용하여 버퍼를 채우는 형식의 short를 사용하여이 작업을 수행했습니다.마이크 입력 처리

결국이 버퍼를 그래프로 표시하여 디스플레이 (실시간 정보)와 같은 오실로스코프를 얻고 싶습니다. 문제는 만약 내가 값을 디스플레이하고 싶다면 (텍스트에서) UI를 업데이트하기 위해 다른 스레드가 필요하다는 것입니다. 현재 나는 AsyncTask을 사용하고 UI를 업데이트하는 것은 AsyncTasks.publishProgress()입니다. 지금까지 나는 아주 성공적이지 않았고, 내가 올바른 길을 가고 있는지 알고 싶습니까? 핸들이 더 좋은 방법인가요? 전에 비슷한 것을 한 사람이 있습니까? 그렇다면 어떤 방법이 효과가 있습니까? 또한 단순히 마이크를 폴링 할 수 있습니까?


여기 내 코드입니다. MIC에서 모든 리드 샘플을 출력하기위한 것입니다. 그것은 수용 가능한 비율로 이것을하는 것처럼 보이지만 때로는 0을 표시합니다. 왜? 여기

package com.ss.audioacquireapp3; 

import android.app.Activity; 
import android.content.Context; 
import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.TextView; 


public class AudioAcquireApp3Activity extends Activity 
{ 
     //Properties (AsyncTask) 
     protected TextView _percentField; 
     protected InitTask _initTask; 

     //Properties (MIC) 
     public AudioRecord audioRecord; 
     public int mSamplesRead; //how many samples read 
     public int recordingState; 
     public int buffersizebytes; 
     public int channelConfiguration = AudioFormat.CHANNEL_IN_MONO; 
     public int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; 
     public static short[] buffer; //+-32767 
     public static final int SAMPPERSEC = 44100; //samp per sec 8000, 11025, 22050 44100 or 48000 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     _percentField = (TextView) findViewById(R.id.percent_field); 

     buffersizebytes = AudioRecord.getMinBufferSize(SAMPPERSEC,channelConfiguration,audioEncoding); //4096 on ion 
     buffer = new short[buffersizebytes]; 
     audioRecord = new AudioRecord(android.media.MediaRecorder.AudioSource.MIC,SAMPPERSEC,channelConfiguration,audioEncoding,buffersizebytes); //constructor 

     _initTask = new InitTask(); 
     _initTask.execute(this); 
    } 

    /** 
    * sub-class of AsyncTask 
    */ 
    protected class InitTask extends AsyncTask<Context, Integer, String> 
    { 
     // -- run intensive processes here 
     // -- notice that the datatype of the first param in the class definition matches the param passed to this method 
     // -- and that the datatype of the last param in the class definition matches the return type of this method 
       @Override 
       protected String doInBackground(Context... params) 
       { 
         //-- on every iteration 
         //-- runs a while loop that causes the thread to sleep for 50 milliseconds 
         //-- publishes the progress - calls the onProgressUpdate handler defined below 
         //-- and increments the counter variable i by one 
         //int i = 0; 

        audioRecord.startRecording(); 

         while(true) 
         { 
           try{ 
             mSamplesRead = audioRecord.read(buffer, 0, buffersizebytes); 

             int amp; 

             for(int i = 0; i < buffersizebytes - 1; i++){ 
              amp = (int)buffer[i]; 
              publishProgress(amp); 
             } 

           } catch(Exception e){       
           } 
         } 
       } 

       // -- gets called just before thread begins 
       @Override 
       protected void onPreExecute() 
       { 
         //Log.i("makemachine", "onPreExecute()"); 
         super.onPreExecute(); 

       } 

       // -- called from the publish progress 
       // -- notice that the datatype of the second param gets passed to this method 
       @Override 
       protected void onProgressUpdate(Integer... values) 
       { 
         super.onProgressUpdate(values); 
         //Log.i("makemachine", "onProgressUpdate(): " + String.valueOf(values[0])); 
         _percentField.setText(String.valueOf(values[0])); 
       } 

       // -- called as soon as doInBackground method completes 
       // -- notice that the third param gets passed to this method 
       @Override 
       protected void onPostExecute(String result) 
       { 
         super.onPostExecute(result); 
         //Log.i("makemachine", "onPostExecute(): " + result); 
       } 


    } 
} 

그리고 당신은 LG 옵티머스 블랙에 AndroidManifest.xml을

<uses-permission android:name="android.permission.RECORD_AUDIO" /> 

내가 이것을 실행하고이를 추가 할 필요가

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:gravity="center_vertical|center_horizontal" 
    > 

<TextView android:id="@+id/percent_field" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:gravity="center_horizontal"/> 

</LinearLayout> 

주 main.xml에 있습니다. 가능한 한이 코드를 효율적으로 만들 수 있도록 도와주세요.

답변

1
  1. 모든 스레드에서 UI 스레드를 업데이트해야 할 경우 항상 Activity.runOnUiThread(Runnable action)을 사용할 수 있습니다. 자세한 내용은 Activity 클래스 javadoc을 참조하십시오.
  2. 나는 정확하게 'simpy poll the microphone'이 무엇을 의미하는지 모르겠다. 내 의견으로는 AudioRecord이 좋은 방법이다. micrphone을 녹음 할 때. 다음은 라이브 녹음 된 주파수를 읽는 예제 구현에 대한 링크입니다. http://www.anddev.org/novice-tutorials-f8/get-frequency-data-from-microphone-in-real-time-t16774.html

희망이 있습니다.

+1

감사합니다. 이것은 많은 도움이됩니다. 필자는 코드 링크를 사용하여 현재 작동하고있는 것을 가지고 있습니다. 불행히도 매우 느리게 실행됩니다. 코드를 도울 수 있습니까? – user893825

+0

글쎄, 실제로 코드를 보지 않고 당신을 도울 수는 없어요. 가장 자주 실행되는 (예 : AsyncTask.run()) 코드를 찾아서 최적화합니다 (예 : 불필요한 디버그 로그 제거, 장기 실행 작업 등). – pkk

+1

내 코드를 게시했습니다. 대답이 아닌 여기에 입력해야 했습니까? 감사 :) – user893825

1

늦은 대답이지만 누군가가 같은 질문에 대한 대답을 필요로 할 수도 있습니다. 여기 오픈 소스 안드로이드 오실로스코프 (OsciPrime) 링크 (http://android.serverbox.ch/?p=268)입니다. 소스 코드는 AsyncTask 대신 Thread를 사용합니다. 소스 코드를 보면, Thread가 Looper와 Handler로 AudioRecord를 처리하는 방법을 알 수 있습니다. 나는 다른 사람들에게 유용하길 바란다 :