2013-06-09 3 views
5

Следующий код должен записывать аудио и хранить его на SD-карте в формате PCM. код работает со мной, но файл PCM не играет !!!!Как я могу воспроизвести файл pcm

Я получил этот код из этой ссылки .... Android : recording audio using audiorecord class play as fast forwarded

Мне нужно, чтобы воспроизвести файл PCM Как я могу сделать это ??????

public class Audio_Record extends Activity { 
private static final int RECORDER_SAMPLERATE = 8000; 
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO; 
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 
private AudioRecord recorder = null; 
private Thread recordingThread = null; 
private boolean isRecording = false; 

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

setButtonHandlers(); 
enableButtons(false); 

int bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, 
     RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); 

System.out.println("BUFFER SIZE VALUE IS " + bufferSize); 

} 

     private void setButtonHandlers() { 
((Button) findViewById(R.id.btnStart)).setOnClickListener(btnClick); 
((Button) findViewById(R.id.btnStop)).setOnClickListener(btnClick); 
    } 

    private void enableButton(int id, boolean isEnable) { 
((Button) findViewById(id)).setEnabled(isEnable); 
    } 

private void enableButtons(boolean isRecording) { 
enableButton(R.id.btnStart, !isRecording); 
enableButton(R.id.btnStop, isRecording); 
    } 

    int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we 
          // use only 1024 
    int BytesPerElement = 2; // 2 bytes in 16bit format 

    private void startRecording() { 

recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
     RECORDER_SAMPLERATE, RECORDER_CHANNELS, 
     RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement); 

recorder.startRecording(); 
isRecording = true; 

recordingThread = new Thread(new Runnable() { 

     public void run() { 

     writeAudioDataToFile(); 

    } 
}, "AudioRecorder Thread"); 
recordingThread.start(); 
    } 

private byte[] short2byte(short[] sData) { 
int shortArrsize = sData.length; 
byte[] bytes = new byte[shortArrsize * 2]; 

for (int i = 0; i < shortArrsize; i++) { 
    bytes[i * 2] = (byte) (sData[i] & 0x00FF); 
    bytes[(i * 2) + 1] = (byte) (sData[i] >> 8); 
    sData[i] = 0; 
} 
return bytes; 

    } 

    private void writeAudioDataToFile() { 
// Write the output audio in byte 

String filePath = "/sdcard/voice8K16bitmono.pcm"; 
short sData[] = new short[BufferElements2Rec]; 

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

while (isRecording) { 
    // gets the voice output from microphone to byte format 

    recorder.read(sData, 0, BufferElements2Rec); 
    System.out.println("Short wirting to file" + sData.toString()); 
    try { 
     // // writes the data to file from buffer 
     // // stores the voice buffer 

     byte bData[] = short2byte(sData); 

     os.write(bData, 0, BufferElements2Rec * BytesPerElement); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

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

private void stopRecording() { 
// stops the recording activity 
if (null != recorder) { 
    isRecording = false; 

    recorder.stop(); 
    recorder.release(); 

    recorder = null; 
    recordingThread = null; 
} 
} 

private View.OnClickListener btnClick = new View.OnClickListener() { 
public void onClick(View v) { 
    switch (v.getId()) { 
    case R.id.btnStart: { 
     enableButtons(true); 
     startRecording(); 
     break; 
    } 
    case R.id.btnStop: { 
     enableButtons(false); 
     stopRecording(); 
     break; 
    } 
    } 
} 
}; 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 

if (keyCode == KeyEvent.KEYCODE_BACK) { 

    finish(); 
} 
return super.onKeyDown(keyCode, event); 
} 
} 
+0

Пожалуйста Смотрите мой вопрос @TechEnd –

+0

Как вы тестирования, играет ли он или нет? –

+0

Я пошел на путь, где он был сохранен, и когда я попытался открыть его, он сказал: «Невозможно найти приложение для выполнения этого действия» @Ken Wolf –

ответ

4

Медиаплеер для Android по умолчанию не воспроизводит файлы PCM. Либо

  1. Скопируйте его из SD-карты на компьютер и играть там
  2. Написать свой собственный плеер с помощью AudioTrack
  3. Установите приложение, которое играет PCM

Вот учебник о том, как играть в PCM, используя AudioTrack класс: (http://jongladwin.blogspot.co.uk/2010/03/android-play-pcmwav-audio-buffer-using.html)

Windows Media Player должен иметь возможность играть в PCM, некоторые альтернативы упомянутый здесь: (http://www.makeuseof.com/answers/play-pcm-file-pc/)

Я полагаю, что большинство приложений для большого музыкального плеера на Android будет поддерживать PCM.

+0

Я скопировал его на свой компьютер, но он не работал. "не удается отобразить этот файл" –

+0

Трудно диагностировать здесь, но попробуйте перейти на .wav и открыть в Windows Media Player (при условии, что вы используете окна) –

+0

Я загрузил программу ,, Audacity, и он открыл файл PCM , но это не звук того, что я записал, его как быстрая перемотка вперед, как скрипучий звук! Я не знаю, в чем проблема ?! @Ken Wolf –

3

Я также использовал ваш код, но моя запись была похожа на запись «zzzzz». Поэтому я немного изменил код, и теперь я могу без проблем слушать и искажать записи как на смартфоне, так и на ПК (в данном случае с Audacity). Это мой код:

public class VoiceActivity extends Activity { 
private static final String TAG = "VoiceRecord"; 

private static final int RECORDER_SAMPLERATE = 8000;  
private static final int RECORDER_CHANNELS_IN = AudioFormat.CHANNEL_IN_MONO; 
private static final int RECORDER_CHANNELS_OUT = AudioFormat.CHANNEL_OUT_MONO; 
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 

private static final int AUDIO_SOURCE = MediaRecorder.AudioSource.MIC; 

// Initialize minimum buffer size in bytes. 
private int bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS_IN, RECORDER_AUDIO_ENCODING); 

private AudioRecord recorder = null; 
private Thread recordingThread = null; 
private boolean isRecording = false; 

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

    ((Button) findViewById(R.id.start_button)).setOnClickListener(btnClick); 
    ((Button) findViewById(R.id.stop_button)).setOnClickListener(btnClick); 
    enableButtons(false); 
} 

private void enableButton(int id, boolean isEnable) { 
    ((Button) findViewById(id)).setEnabled(isEnable); 
} 

private void enableButtons(boolean isRecording) { 
    enableButton(R.id.start_button, !isRecording); 
    enableButton(R.id.stop_button, isRecording); 
} 

private void startRecording() { 
    if(bufferSize == AudioRecord.ERROR_BAD_VALUE) 
     Log.e(TAG, "Bad Value for \"bufferSize\", recording parameters are not supported by the hardware"); 

    if(bufferSize == AudioRecord.ERROR) 
     Log.e(TAG, "Bad Value for \"bufferSize\", implementation was unable to query the hardware for its output properties"); 

    Log.e(TAG, "\"bufferSize\"="+bufferSize); 

    // Initialize Audio Recorder.  
    recorder = new AudioRecord(AUDIO_SOURCE, RECORDER_SAMPLERATE, RECORDER_CHANNELS_IN, RECORDER_AUDIO_ENCODING, bufferSize); 
    // Starts recording from the AudioRecord instance. 
    recorder.startRecording(); 

    isRecording = true; 

    recordingThread = new Thread(new Runnable() { 
     public void run() { 
      writeAudioDataToFile(); 
     } 
    }, "AudioRecorder Thread"); 
    recordingThread.start(); 
} 

private void writeAudioDataToFile() { 
    //Write the output audio in byte 
    String filePath = "/sdcard/8k16bitMono.pcm"; 
    byte saudioBuffer[] = new byte[bufferSize]; 

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

    while (isRecording) { 
     // gets the voice output from microphone to byte format 
     recorder.read(saudioBuffer, 0, bufferSize); 
     try { 
      // writes the data to file from buffer stores the voice buffer 
      os.write(saudioBuffer, 0, bufferSize); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    try { 
     os.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void stopRecording() throws IOException { 
    // stops the recording activity 
    if (null != recorder) { 
     isRecording = false; 
     recorder.stop(); 
     recorder.release(); 
     recorder = null; 
     recordingThread = null; 
     PlayShortAudioFileViaAudioTrack("/sdcard/8k16bitMono.pcm"); 
    } 
} 

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(RECORDER_SAMPLERATE, RECORDER_CHANNELS_OUT, RECORDER_AUDIO_ENCODING); 
    Log.d(TAG, intSize+""); 

    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, RECORDER_SAMPLERATE, RECORDER_CHANNELS_OUT, RECORDER_AUDIO_ENCODING, intSize, AudioTrack.MODE_STREAM); 
    if (at!=null) { 
     at.play(); 
     // Write the byte array to the track 
     at.write(byteData, 0, byteData.length); 
     at.stop(); 
     at.release(); 
    } 
    else 
     Log.d(TAG, "audio track is not initialised "); 

} 

private View.OnClickListener btnClick = new View.OnClickListener() { 
    public void onClick(View v) { 
     switch (v.getId()) { 
     case R.id.start_button: { 
      enableButtons(true); 
      startRecording(); 
      break; 
     } 
     case R.id.stop_button: { 
      enableButtons(false); 
      try { 
       stopRecording(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      break; 
     } 
     } 
    } 
}; 

    // onClick of backbutton finishes the activity. 
@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     finish(); 
    } 
    return super.onKeyDown(keyCode, event); 
} 
} 
+0

Спасибо за изменение ! У меня была аналогичная проблема с искажением записанного звука, ваше решение решило искажение. Исходный код усекал запись, поэтому происходит искажение. Должен использовать размер буфера, возвращаемый «AudioRecord».getMinBufferSize ". –

+0

Как получить доступ к исходным звуковым данным (может быть в целом) с помощью' byteData' в функции 'PlayShortAudioFileViaAudioTrack'? Когда я пытаюсь напечатать' byteData', я получаю все нули, однако, когда я открываю файл .pcm, используя sublime редактор Я вижу шестнадцатеричные значения. – mio

0

частная пустота startRecording() { если (BufferSize == AudioRecord.ERROR_BAD_VALUE) Log.e (TAG, "Bad Значение для \" BufferSize \», регистрирующие параметры не являются поддерживается аппаратными средствами ");

if(bufferSize == AudioRecord.ERROR) 
    Log.e(TAG, "Bad Value for \"bufferSize\", implementation was unable to query the hardware for its output properties"); 

Log.e(TAG, "\"bufferSize\"="+bufferSize); 

// Initialize Audio Recorder.  
recorder = new AudioRecord(AUDIO_SOURCE, RECORDER_SAMPLERATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, RECORDER_AUDIO_ENCODING, bufferSize); 
// Starts recording from the AudioRecord instance. 
recorder.startRecording(); 

isRecording = true; 

recordingThread = new Thread(new Runnable() { 
    public void run() { 
     writeAudioDataToFile(); 
    } 
}, "AudioRecorder Thread"); 
recordingThread.start(); 

}

Заменить код записи ...

0

это мое решение

public class AudioTrackPlayer { 
    private String pathAudio; 
    private AudioTrack audioPlayer; 
    private Thread mThread; 
    private int bytesread = 0, ret = 0; 
    private int size; 
    private FileInputStream in = null; 
    private byte[] byteData = null; 
    private int count = 512 * 1024; // 512 kb 
    private boolean isPlay = true; 
    private boolean isLooping = false; 
    private static Handler mHandler; 

    public AudioTrackPlayer() { 

    } 

    public void prepare(String pathAudio){ 
     this.pathAudio = pathAudio; 
     mHandler = new Handler(); 
    } 

    public void play(){ 
     stop(); 

     isPlay = true; 
     bytesread = 0; 
     ret = 0; 
     if (pathAudio == null) 
      return; 

     audioPlayer = createAudioPlayer(); 
     if (audioPlayer == null) return; 
     audioPlayer.play(); 

     mThread = new Thread(new PlayerProcess()); 
     mThread.start(); 
    } 

    private final Runnable mLopingRunnable = new Runnable() { 
     @Override 
     public void run() { 
      play(); 
     } 
    }; 

    private AudioTrack createAudioPlayer(){ 
     int intSize = android.media.AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
       AudioFormat.ENCODING_PCM_16BIT); 
     AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
       AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM); 
     if (audioTrack == null) { 
      Log.d("TCAudio", "audio track is not initialised "); 
      return null; 
     } 

     File file = null; 
     file = new File(pathAudio); 

     byteData = new byte[(int) count]; 
     try { 
      in = new FileInputStream(file); 

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

     size = (int) file.length(); 
     return audioTrack; 
    } 

    private class PlayerProcess implements Runnable{ 

     @Override 
     public void run() { 
      while (bytesread < size && isPlay) { 
       if (Thread.currentThread().isInterrupted()) { 
        break; 
       } 
       try { 
        ret = in.read(byteData, 0, count); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       if (ret != -1) { // Write the byte array to the track 
        audioPlayer.write(byteData,0, ret); 
        bytesread += ret; 
       } else break; 
      } 
      try { 
       in.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      if (audioPlayer!=null){ 
       if (audioPlayer.getState()!=AudioTrack.PLAYSTATE_STOPPED){ 
        audioPlayer.stop(); 
        audioPlayer.release(); 
        mThread = null; 
       } 
      } 
      if (isLooping && isPlay) mHandler.postDelayed(mLopingRunnable,100); 
     } 
    } 

    public void setLooping(){ 
     isLooping = !isLooping; 
    } 

    public void pause(){ 

    } 

    public void stop(){ 
     isPlay = false; 
     if (mThread != null) { 
      mThread.interrupt(); 
      mThread = null; 
     } 
     if (audioPlayer != null) { 
      audioPlayer.stop(); 
      audioPlayer.release(); 
      audioPlayer = null; 
     } 
    } 

    public void reset(){ 

    } 
} 
+0

Я улучшил отступы кода для вас. Вы также можете улучшить свой ответ, объяснив свой код немного, в том числе о том, почему и как он исправляет проблему (проблемы) вопроса. – mmgross

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