Record .Wav with Android AudioRecorder

I read many pages about Android AudioRecorder. You can see their list below the question.

I am trying to record audio using AudioRecorder, but it does not work well.

public class MainActivity extends Activity { AudioRecord ar = null; int buffsize = 0; int blockSize = 256; boolean isRecording = false; private Thread recordingThread = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void baslat(View v) { // when click to START buffsize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); ar = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, buffsize); ar.startRecording(); isRecording = true; recordingThread = new Thread(new Runnable() { public void run() { writeAudioDataToFile(); } }, "AudioRecorder Thread"); recordingThread.start(); } public void durdur(View v) { // When click to STOP ar.stop(); isRecording = false; } private void writeAudioDataToFile() { // Write the output audio in byte String filePath = "/sdcard/voice8K16bitmono.wav"; short sData[] = new short[buffsize/2]; FileOutputStream os = null; try { os = new FileOutputStream(filePath); } catch (FileNotFoundException e) { e.printStackTrace(); } while (isRecording) { // gets the voice output from microphone to byte format ar.read(sData, 0, buffsize/2); Log.d("eray","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, buffsize); } catch (IOException e) { e.printStackTrace(); } } try { os.close(); } catch (IOException e) { e.printStackTrace(); } } 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; } 

It creates a WAV file, but when I try to listen to it, it does not open. I get a "file not supported" error. I tried to play the file using several applications for media players.

NOTE I need to use AudioRecorder instead of MediaRecorder, because my application will perform a different process while recording (displaying the equalizer).

Here is a list of the pages I read about this topic:

There are many different ways to do this. I tried a lot of them, but nothing works for me. I have been working on this issue for about 6 hours, so I would appreciate a final answer, ideally a sample code.

+8
android audiorecord
source share
4 answers

PCMAudioHelper solved my problem. I will modify this answer and explain it, but first I need to do some tests on this class.

+8
source share

I wrote a simple one (which you should read, not professional standards) to do this yesterday, and it works.

  private class Wave { private final int LONGINT = 4; private final int SMALLINT = 2; private final int INTEGER = 4; private final int ID_STRING_SIZE = 4; private final int WAV_RIFF_SIZE = LONGINT+ID_STRING_SIZE; private final int WAV_FMT_SIZE = (4*SMALLINT)+(INTEGER*2)+LONGINT+ID_STRING_SIZE; private final int WAV_DATA_SIZE = ID_STRING_SIZE+LONGINT; private final int WAV_HDR_SIZE = WAV_RIFF_SIZE+ID_STRING_SIZE+WAV_FMT_SIZE+WAV_DATA_SIZE; private final short PCM = 1; private final int SAMPLE_SIZE = 2; int cursor, nSamples; byte[] output; public Wave(int sampleRate, short nChannels, short[] data, int start, int end) { nSamples=end-start+1; cursor=0; output=new byte[nSamples*SMALLINT+WAV_HDR_SIZE]; buildHeader(sampleRate,nChannels); writeData(data,start,end); } // ------------------------------------------------------------ private void buildHeader(int sampleRate, short nChannels) { write("RIFF"); write(output.length); write("WAVE"); writeFormat(sampleRate, nChannels); } // ------------------------------------------------------------ public void writeFormat(int sampleRate, short nChannels) { write("fmt "); write(WAV_FMT_SIZE-WAV_DATA_SIZE); write(PCM); write(nChannels); write(sampleRate); write(nChannels * sampleRate * SAMPLE_SIZE); write((short)(nChannels * SAMPLE_SIZE)); write((short)16); } // ------------------------------------------------------------ public void writeData(short[] data, int start, int end) { write("data"); write(nSamples*SMALLINT); for(int i=start; i<=end; write(data[i++])); } // ------------------------------------------------------------ private void write(byte b) { output[cursor++]=b; } // ------------------------------------------------------------ private void write(String id) { if(id.length()!=ID_STRING_SIZE) Utils.logError("String "+id+" must have four characters."); else { for(int i=0; i<ID_STRING_SIZE; ++i) write((byte)id.charAt(i)); } } // ------------------------------------------------------------ private void write(int i) { write((byte) (i&0xFF)); i>>=8; write((byte) (i&0xFF)); i>>=8; write((byte) (i&0xFF)); i>>=8; write((byte) (i&0xFF)); } // ------------------------------------------------------------ private void write(short i) { write((byte) (i&0xFF)); i>>=8; write((byte) (i&0xFF)); } // ------------------------------------------------------------ public boolean wroteToFile(String filename) { boolean ok=false; try { File path=new File(getFilesDir(),filename); FileOutputStream outFile = new FileOutputStream(path); outFile.write(output); outFile.close(); ok=true; } catch (FileNotFoundException e) { e.printStackTrace(); ok=false; } catch (IOException e) { ok=false; e.printStackTrace(); } return ok; } } 

Hope this helps

+8
source share

I would add this as a comment, but I don't have enough Stackoverflow rep points yet ...

The Opiatefuchs link allows you sample code that shows the exact formatting of the header needed to create a WAV file. I myself was on this code. Very useful.

0
source share

First you need to know that the wav file has its own format - the header. therefore, you cannot just write clean data to a .wav file.

Secondly, the wav file header includes the length of the file. so you need to write a headline after recording.

My solution: AudioRecorder user writes pcm file.

  byte[] audiodata = new byte[bufferSizeInBytes]; FileOutputStream fos = null; int readsize = 0; try { fos = new FileOutputStream(pcmFileName, true); } catch (FileNotFoundException e) { Log.e("AudioRecorder", e.getMessage()); } status = Status.STATUS_START; while (status == Status.STATUS_START && audioRecord != null) { readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes); if (AudioRecord.ERROR_INVALID_OPERATION != readsize && fos != null) { if (readsize > 0 && readsize <= audiodata.length) fos.write(audiodata, 0, readsize); } catch (IOException e) { Log.e("AudioRecorder", e.getMessage()); } } } try { if (fos != null) { fos.close(); } } catch (IOException e) { Log.e("AudioRecorder", e.getMessage()); } 

then convert it to a wav file.

  byte buffer[] = null; int TOTAL_SIZE = 0; File file = new File(pcmPath); if (!file.exists()) { return false; } TOTAL_SIZE = (int) file.length(); WaveHeader header = new WaveHeader(); header.fileLength = TOTAL_SIZE + (44 - 8); header.FmtHdrLeth = 16; header.BitsPerSample = 16; header.Channels = 1; header.FormatTag = 0x0001; header.SamplesPerSec = 8000; header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8); header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec; header.DataHdrLeth = TOTAL_SIZE; byte[] h = null; try { h = header.getHeader(); } catch (IOException e1) { Log.e("PcmToWav", e1.getMessage()); return false; } if (h.length != 44) return false; File destfile = new File(destinationPath); if (destfile.exists()) destfile.delete(); try { buffer = new byte[1024 * 4]; // Length of All Files, Total Size InputStream inStream = null; OutputStream ouStream = null; ouStream = new BufferedOutputStream(new FileOutputStream( destinationPath)); ouStream.write(h, 0, h.length); inStream = new BufferedInputStream(new FileInputStream(file)); int size = inStream.read(buffer); while (size != -1) { ouStream.write(buffer); size = inStream.read(buffer); } inStream.close(); ouStream.close(); } catch (FileNotFoundException e) { Log.e("PcmToWav", e.getMessage()); return false; } catch (IOException ioe) { Log.e("PcmToWav", ioe.getMessage()); return false; } if (deletePcmFile) { file.delete(); } Log.i("PcmToWav", "makePCMFileToWAVFile success!" + new SimpleDateFormat("yyyy-MM-dd hh:mm").format(new Date())); return true; 
0
source share

All Articles