2015-01-05 3 views
-1

마이크에서 오디오를 녹음하는 동안 생성 된 PCM 파일을 재생하려고합니다.Android : PCM 파일 재생 중 오류가 발생했습니다.

마이크로 녹음 된 사운드의 주파수를 분석하려고하기 때문에 AudioRecord를 사용하고 있습니다.

PCM 파일을 재생하는 코드 스 니펫은 다음과 같습니다. 그러나 파일을 재생하려고 할 때 재생되는 소리가 심합니다.

FileInputStream fis=null; 
    File l=null; 
    l=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/f1.pcm"); 

    byte[] buffer=new byte[(int)l.length()]; 

    try { 
     fis = new FileInputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Notate/f1.pcm"); 
     fis.read(buffer); 
    } 
    catch(Exception e) 
    { 

    } 
    int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, 
      AudioFormat.ENCODING_PCM_16BIT); 
    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO, 
      AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM); 
    if (at!=null) { 
     at.play(); 
     at.write(buffer, 0, buffer.length); 
     at.stop(); 
     at.release(); 
    } 

PCM 파일을 저장하는 데 사용되는 코드는 아래와 같다. AudioTrack 아마도 샘플 리틀 엔디안 (최하위 바이트) 것으로 기대하면서

private class RecordAudio extends AsyncTask<Void, Double, Void> { 
    FileOutputStream os = null; 
    BufferedOutputStream bos =null; 
    DataOutputStream dos = null; 
    @Override 
    protected Void doInBackground(Void... params) { 
     int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioEncoding);    // Gets the minimum buffer needed 
     AudioRecord audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioEncoding, bufferSize); // The RAW PCM sample recording 
     File f=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/"); 
     if(!f.isDirectory()) { 
      File newDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Notate/"); 
      newDirectory.mkdirs(); 
     } 
     String filepath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/f1.pcm"; 
     short[] buffer = new short[blockSize];   // Save the raw PCM samples as short bytes 
     try{ 
      os=new FileOutputStream(filepath); 
     } 
     catch(FileNotFoundException e) 
     { 

     } 
     bos = new BufferedOutputStream(os); 
     dos = new DataOutputStream(bos); 
     try { 
      audioRecord.startRecording(); //Start 
     } catch (Throwable t) { 
     } 
     while (started) { 
      int length=audioRecord.read(buffer, 0, blockSize); 

      Yin alpha = new Yin(44100, 1024, 0.2); 
      float[] floaters = new float[buffer.length]; 
      for (int i = 0; i < buffer.length; i++) { 
       floaters[i] = buffer[i]; 
      } 
      for(int k=0;k<length;k++) { 
       try { 
        dos.writeShort(buffer[k]); 


       } catch (IOException e) { 

       } 
      } 
      float result = alpha.getPitch(floaters); 
      publishProgress((double) result); 

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

     return null; 
    } 

답변

0

writeShort는 빅 엔디안 레이아웃, 즉 제 최상위 바이트의 값을 기록한다.

녹음 할 때 short[] 대신 byte[]을 사용하면 더 쉽게 만들 수 있습니다. 그런 다음 DataOutputStreamdos.write(buffer, 0, length);으로 간단하게 쓸 수 있습니다. 부동 소수점 값으로의 변환은이 경우 약간 수정해야합니다.

for (int i = 0; i < length; i += 2) { 
    floaters[i] = (short)(buffer[i] | (buffer[i+1] << 8)); 
} 
+0

감사합니다! 이 일했다! – shivram

관련 문제