Skip to content

Instantly share code, notes, and snippets.

@Capotasto
Created December 24, 2017 20:31
Show Gist options
  • Save Capotasto/c258e68b976b8025cfe51dc091c22c1c to your computer and use it in GitHub Desktop.
Save Capotasto/c258e68b976b8025cfe51dc091c22c1c to your computer and use it in GitHub Desktop.
package com.funckyhacker.util;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.SystemClock;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import rx.Single;
import rx.SingleSubscriber;
public class AudioRecordUtils {
private static final int AUDIO_SOURCE = MediaRecorder.AudioSource.MIC;
private static final int SAMPLE_RATE = 16000; // Hz
private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private static final int CHANNEL_MASK = AudioFormat.CHANNEL_IN_MONO;
private static final int BUFFER_SIZE = 2 * AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_MASK, ENCODING);
private File mWavFile;
private boolean isRecording;
public void startRecording() {
isRecording = true;
}
public void stopRecording() {
isRecording = false;
}
public File getRecordedFile() {
return mWavFile;
}
public boolean isRecording() {
return isRecording;
}
public Single<Long[]> doRecordAudio() {
return Single.create((SingleSubscriber<? super Long[]> singleSubscriber) -> {
final File file = getNewRecordingFile();
AudioRecord audioRecord = null;
FileOutputStream wavOut = null;
long startTime = 0;
long endTime = 0;
try {
// Open our two resources
audioRecord = new AudioRecord(AUDIO_SOURCE, SAMPLE_RATE, CHANNEL_MASK, ENCODING, BUFFER_SIZE);
wavOut = new FileOutputStream(file);
// Write out the wav file header
FileUtils.writeWavHeader(wavOut, CHANNEL_MASK, SAMPLE_RATE, ENCODING);
// Avoiding loop allocations
byte[] buffer = new byte[BUFFER_SIZE];
boolean run = true;
int read;
long total = 0;
// Let's go
startTime = SystemClock.elapsedRealtime();
audioRecord.startRecording();
while (run && isRecording) {
read = audioRecord.read(buffer, 0, buffer.length);
// WAVs cannot be > 4 GB due to the use of 32 bit unsigned integers.
if (total + read > 4294967295L) {
// Write as many bytes as we can before hitting the max size
for (int i = 0; i < read && total <= 4294967295L; i++, total++) {
wavOut.write(buffer[i]);
}
run = false;
} else {
// Write out the entire read buffer
wavOut.write(buffer, 0, read);
total += read;
}
}
} catch (IOException ex) {
singleSubscriber.onError(ex);
} finally {
if (audioRecord != null) {
try {
if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
audioRecord.stop();
endTime = SystemClock.elapsedRealtime();
}
} catch (IllegalStateException ex) {
singleSubscriber.onError(ex);
}
if (audioRecord.getState() == AudioRecord.STATE_INITIALIZED) {
audioRecord.release();
}
}
if (wavOut != null) {
try {
wavOut.close();
} catch (IOException ex) {
singleSubscriber.onError(ex);
}
}
}
try {
// This is not put in the try/catch/finally above since it needs to run
// after we close the FileOutputStream
FileUtils.updateWavHeader(file);
} catch (IOException ex) {
singleSubscriber.onError(ex);
}
singleSubscriber.onSuccess(new Long[]{file.length(), endTime - startTime});
});
}
private File getNewRecordingFile() {
mWavFile = new File(Environment.getExternalStorageDirectory().getPath(),
"recording_" + System.currentTimeMillis() / 1000 + ".wav");
return mWavFile;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment