2016-11-22 7 views
1

Я новичок в Android. Я разрабатываю приложение, которое использует AudioRecorder и AudioTrack для записи и воспроизведения. В дополнение к этому, я пытаюсь читать и отображать амплитудные значения записанного звука.Аудиодорожка в Android не работает

Вот мой класс

public class MainActivity extends AppCompatActivity { 

private static final String TAG = "RecordSound"; 
private int BufferSize; 
byte[] buffer = new byte[BufferSize]; 

/* AudioRecord and AudioTrack Object */ 
private AudioRecord record = null; 
private AudioTrack track = null; 

/* Audio Configuration */ 
private int sampleRate = 8000; 
private int channelConfig = AudioFormat.CHANNEL_IN_MONO; 
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT; 

private boolean isRecording = true; 
private Thread recordingThread = null; 

private double lastLevel = 0; 
private Thread thread; 
private static final int SAMPLE_DELAY = 75; 
MediaPlayer mediaPlayer; 

RelativeLayout layout; 
private ImageView tankHolder; 
TextView text; 
Button play; 
String filename; 
final Handler mHandler = new Handler(); 


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

    tankHolder = (ImageView)findViewById(R.id.tankHolder); 
    text=(TextView)findViewById(R.id.result_text); 
    layout=(RelativeLayout)findViewById(R.id.linear); 
    play=(Button)findViewById(R.id.btnStartPlay); 

    try { 
     BufferSize = AudioRecord.getMinBufferSize(sampleRate, 
       channelConfig, audioFormat); 
    }catch (Exception e){ 
     e.printStackTrace(); 
    } 


} 

@Override 
protected void onResume() { 
    super.onResume(); 
    //calling MediaPlayer for alarmtone when the tank is almost full 
    mediaPlayer = MediaPlayer.create(this, R.raw.tone); 

    startRecording(); 

    play.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      try { 
       stopRecording(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

private void stopRecording() throws IOException{ 
    if (null != record) { 
     isRecording = false; 
     record.stop(); 
     record.release(); 
     record = null; 
     recordingThread = null; 
     mHandler.post(runRecord); 
     mediaPlayer.stop(); 
     mediaPlayer.release(); 
    } 
} 

final Runnable runRecord=new Runnable() { 
    @Override 
    public void run() { 
     text.setText("working"); 
     try { 
      PlayShortAudioFileViaAudioTrack("/sdcard/recorded.pcm"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

private void PlayShortAudioFileViaAudioTrack(String filePath) throws IOException{ 
    // We keep temporarily filePath globally as we have only two sample sounds now.. 
    if (filePath==null) 
     return; 

    //Reading the file.. 
    File file = new File(filePath); // for ex. path= "/sdcard/samplesound.pcm" or "/sdcard/samplesound.wav" 
    byte[] byteData = new byte[(int) file.length()]; 
    Log.d(TAG, (int) file.length()+""); 

    FileInputStream in = null; 
    try { 
     in = new FileInputStream(file); 
     in.read(byteData); 
     in.close(); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    // Set and push to audio track.. 
    int intSize = android.media.AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); 
    Log.d(TAG, intSize+""); 

    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM); 
    at.play(); 
    // Write the byte array to the track 
    at.write(byteData, 0, byteData.length); 
    at.stop(); 
    at.release(); 

} 


private void startRecording() 
{ 
    record = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, 
      channelConfig, audioFormat, BufferSize); 
    if (AudioRecord.STATE_INITIALIZED == record.getState()) 
     record.startRecording(); 

    isRecording = true; 

/* Run a thread for Recording */ 
    recordingThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      writeAudioDataToFile(); 
     } 
    },"AudioRecorder Thread"); 
    recordingThread.start(); 

    thread = new Thread(new Runnable() { 
     public void run() { 

      while(thread != null && !thread.isInterrupted()){ 
       //Let's make the thread sleep for a the approximate sampling time 
       try{ 
        Thread.sleep(SAMPLE_DELAY);}catch(InterruptedException ie){ie.printStackTrace();} 
       readAudioBuffer();//After this call we can get the last value assigned to the lastLevel variable 

       runOnUiThread(new Runnable() { 

        @Override 
        public void run() { 

         if(lastLevel >= 7 && lastLevel <= 15){ 
          text.setTextColor(getResources().getColor(R.color.Blue)); 
          layout.setBackgroundColor(Color.RED); 
          tankHolder.setImageResource(R.drawable.ftank); 
          if (!mediaPlayer.isPlaying()){ 
           mediaPlayer.start(); 
          } 
          text.setText(String.valueOf(lastLevel)); 

         }else 
         if(lastLevel > 50 && lastLevel <= 100){ 
          text.setText(String.valueOf(lastLevel)); 
          text.setTextColor(getResources().getColor(R.color.Orange)); 
          layout.setBackgroundColor(Color.WHITE); 
          tankHolder.setImageResource(R.drawable.htank); 
          if (mediaPlayer.isPlaying()){ 
           mediaPlayer.pause(); 
          } 
         }else 
         if(lastLevel > 100 && lastLevel <= 170){ 
          text.setText(String.valueOf(lastLevel)); 
          text.setTextColor(getResources().getColor(R.color.Yellow)); 
          layout.setBackgroundColor(Color.WHITE); 
          tankHolder.setImageResource(R.drawable.qtank); 
          if (mediaPlayer.isPlaying()){ 
           mediaPlayer.pause(); 
          } 
         } 
         if(lastLevel > 170){ 
          text.setText(String.valueOf(lastLevel)); 
          text.setTextColor(getResources().getColor(R.color.Blue)); 
          layout.setBackgroundColor(Color.WHITE); 
          tankHolder.setImageResource(R.drawable.qtank); 
          if (mediaPlayer.isPlaying()){ 
           mediaPlayer.pause(); 
          } 
         } 
        } 
       }); 
      } 
     } 
    },"AudioRecorder Thread"); 
    thread.start(); 

} 

private void writeAudioDataToFile() 
{ 
    byte data[] = new byte[BufferSize]; 

/* Record audio to following file */ 

    String filePath = "/sdcard/recorded.pcm"; 
    filename = Environment.getExternalStorageDirectory().getAbsolutePath(); 
    filename +="/audiofile.pcm"; 
    FileOutputStream os = null; 

    try { 
     os = new FileOutputStream(filePath); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 

    int read_bytes = 0; 

    if(null != os){ 
     while(isRecording) 
     { 
      read_bytes = record.read(data, 0, BufferSize); 

      if(AudioRecord.ERROR_INVALID_OPERATION != read_bytes){ 
       try { 
        os.write(data); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     try { 
      os.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

private void readAudioBuffer() { 

    try { 
     short[] buffer = new short[BufferSize]; 

     int bufferReadResult = 1; 

     if (record != null) { 

      // Sense the voice... 
      bufferReadResult = record.read(buffer, 0, BufferSize); 
      double sumLevel = 0; 
      for (int i = 0; i < bufferReadResult; i++) { 
       sumLevel += buffer[i]; 
      } 
      lastLevel = Math.abs((sumLevel/bufferReadResult)); 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
} 

Если я бегу, мой runOnUiThread(new Runnable() { работает и воспроизведения нажатием кнопки, записанный звук не воспроизводится. Если я удалю runOnUiThread(new Runnable() {, тогда нажмите кнопку воспроизведения, записанный звук будет воспроизводиться без проблем. Итак, я думаю, что проблема связана с потоками, и я попытался реализовать класс обработчика, но я его не получаю.

ответ

0

См. Это, http://www.java2s.com/Code/Android/Media/UsingAudioRecord.htm для записи звука. Если вы не удовлетворены, https://www.tutorialspoint.com/android/android_audio_capture.htm для получения более подробного объяснения

+0

Я могу записать звук и воспроизвести его, если я не буду использовать runOnUiThread (новый Runnable() {thread.) Так что я хочу, чтобы ответ включал этот поток. –

 Смежные вопросы

  • Нет связанных вопросов^_^