2014-02-06 2 views
1

AudioSource VOICE_UPLINK 및 VOICE_DOWNLINK를 사용하여 성공적으로 녹음 된 통화가 하나 있습니다.VOICE_UPLINK 및 VOICE_DOWNLINK를 사용하는 Android 통화 녹음

나는 그 근원을 사용하여 외침을 기록 할 수있다 그러나 기록한 음성은 명확하지 않다 나는 확고한 음성 같이 들린다는 것을 의미한다.

한 가지 더 질문 : - 작동하지 않을 때 오디오 소스 VOICE_CALL의 용도는 무엇입니까?

감사합니다.

답변

2

사실, VOICE_CALL은 적어도 저에게는 Sony Xperia Z1에서 작동합니다. AudioRecord를 사용하여 일부 임시 파일의 바이트를 저장 한 다음 임시 파일을 WAV 파일로 변환합니다.

나는 뻗어있는 목소리로 똑같은 문제가있었습니다. 문제는 출력 파일의 sampleRates 매개 변수가 기록하는 동안보다 적다는 것입니다. 다음은 완전한 코드입니다.

public class Recorder { 
    private static Recorder mInstance; 
    private AudioRecord mRecorder = null; 

    private Recorder() {} 

    public static Recorder getInstance() { 
     if (mInstance == null) { 
      mInstance = new Recorder(); 
     } 
     return mInstance; 
    } 

    private static final int AUDIO_SOURCE = MediaRecorder.AudioSource.VOICE_CALL; 
    private static final int SAMPLE_RATE = 44100; 
    private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO; 
    private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; 
    private AudioRecord createAudioRecorder() { 
     Log.d(MainActivity.TAG, "Initialize AudioRecord object"); 
     int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT); 
     mRecorder = new AudioRecord(AUDIO_SOURCE, SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, minBufferSize); 

     Log.d(MainActivity.TAG, String.format("SampleRate: %d", mRecorder.getSampleRate())); 

     return mRecorder; 
    } 

    public void startRecording() { 
     Log.d(MainActivity.TAG, "Start recording the conversation..."); 

     mRecorder = createAudioRecorder(); 

     byte[] buffer = new byte[1024]; 
     mRecorder.startRecording(); 

     String tempFileName = UUID.randomUUID().toString() + ".raw"; 
     String wavFileName = UUID.randomUUID().toString() + ".wav"; 
     File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM); 
     File tempFile = new File(path, tempFileName); 
     File wavFile = new File(path, wavFileName); 

     BufferedOutputStream bos = null; 
     try { 
      bos = new BufferedOutputStream(new FileOutputStream(tempFile)); 
      while (mRecorder.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) { 
       int num = mRecorder.read(buffer, 0, buffer.length); 
       bos.write(buffer, 0, num); 
      } 
      mRecorder.release(); 
      mRecorder = null; 
      bos.flush(); 
     } catch (IOException e) { 
      Log.e(MainActivity.TAG, "IOException", e); 
     } finally { 
      try { 
       if (bos != null) { 
        bos.close(); 
       } 
      } catch (IOException e) {} 
     } 
     properWAV(tempFile, wavFile); 
     tempFile.delete(); 
     Log.d(MainActivity.TAG, String.format("Successfully recorded the conversation to %s", wavFile.getPath())); 
    } 

    public void stopRecording() { 
     Log.d(MainActivity.TAG, "Stop recording"); 
     if (mRecorder == null) { 
      Log.d(MainActivity.TAG, "Recorder.stopRecording() mRecorder is NULL"); 
      return; 
     } 

     if (mRecorder.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) 
      mRecorder.stop(); 
    } 

    private void properWAV(File sourceFile, File destinationFile){ 
     try { 
      long mySubChunk1Size = 16; 
      int myBitsPerSample= 16; 
      int myFormat = 1; 
      long myChannels = 1; 
      long mySampleRate = SAMPLE_RATE; //22100; 
      long myByteRate = mySampleRate * myChannels * myBitsPerSample/8; 
      int myBlockAlign = (int) (myChannels * myBitsPerSample/8); 

      byte[] clipData = getBytesFromFile(sourceFile); 

      long myDataSize = clipData.length; 
      long myChunk2Size = myDataSize * myChannels * myBitsPerSample/8; 
      long myChunkSize = 36 + myChunk2Size; 

      OutputStream os; 
      os = new FileOutputStream(destinationFile); 
      BufferedOutputStream bos = new BufferedOutputStream(os); 
      DataOutputStream outFile = new DataOutputStream(bos); 

      outFile.writeBytes("RIFF");          // 00 - RIFF 
      outFile.write(intToByteArray((int)myChunkSize), 0, 4);   // 04 - how big is the rest of this file? 
      outFile.writeBytes("WAVE");          // 08 - WAVE 
      outFile.writeBytes("fmt ");          // 12 - fmt 
      outFile.write(intToByteArray((int)mySubChunk1Size), 0, 4);  // 16 - size of this chunk 
      outFile.write(shortToByteArray((short)myFormat), 0, 2);   // 20 - what is the audio format? 1 for PCM = Pulse Code Modulation 
      outFile.write(shortToByteArray((short)myChannels), 0, 2);  // 22 - mono or stereo? 1 or 2? (or 5 or ???) 
      outFile.write(intToByteArray((int)mySampleRate), 0, 4);   // 24 - samples per second (numbers per second) 
      outFile.write(intToByteArray((int)myByteRate), 0, 4);   // 28 - bytes per second 
      outFile.write(shortToByteArray((short)myBlockAlign), 0, 2);  // 32 - # of bytes in one sample, for all channels 
      outFile.write(shortToByteArray((short)myBitsPerSample), 0, 2); // 34 - how many bits in a sample(number)? usually 16 or 24 
      outFile.writeBytes("data");          // 36 - data 
      outFile.write(intToByteArray((int)myDataSize), 0, 4);   // 40 - how big is this data chunk 
      outFile.write(clipData);          // 44 - the actual data itself - just a long string of numbers 

      outFile.flush(); 
      outFile.close(); 
      bos.close(); 
      os.close(); 
     } catch (IOException e) { 
      Log.e(MainActivity.TAG, "IOException", e); 
     } 

    } 

    private byte[] getBytesFromFile(File file) { 
     int size = (int) file.length(); 
     byte[] bytes = new byte[size]; 
     try { 
      BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file)); 
      buf.read(bytes, 0, bytes.length); 
      buf.close(); 
     } catch (FileNotFoundException e) { 
      Log.e(MainActivity.TAG, "FileNotFoundException", e); 
     } catch (IOException e) { 
      Log.e(MainActivity.TAG, "IOException", e); 
     } 
     return bytes; 
    } 


    private static byte[] intToByteArray(int i) 
    { 
     byte[] b = new byte[4]; 
     b[0] = (byte) (i & 0x00FF); 
     b[1] = (byte) ((i >> 8) & 0x000000FF); 
     b[2] = (byte) ((i >> 16) & 0x000000FF); 
     b[3] = (byte) ((i >> 24) & 0x000000FF); 
     return b; 
    } 

    // convert a short to a byte array 
    public static byte[] shortToByteArray(short data) 
    { 
     /* 
     * NB have also tried: 
     * return new byte[]{(byte)(data & 0xff),(byte)((data >> 8) & 0xff)}; 
     * 
     */ 

     return new byte[]{(byte)(data & 0xff),(byte)((data >>> 8) & 0xff)}; 
    } 
}