Skip to content

Instantly share code, notes, and snippets.

@MensObscura
Created December 6, 2017 12:39
Show Gist options
  • Save MensObscura/8e08f1b80ce3f1350f4aa19e1de7c9ec to your computer and use it in GitHub Desktop.
Save MensObscura/8e08f1b80ce3f1350f4aa19e1de7c9ec to your computer and use it in GitHub Desktop.
AudioRecorder
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.util.Log;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* See: http://stackoverflow.com/questions/5774104/android-audio-fft-to-retrieve-specific-frequency-magnitude-using-audiorecord
* Created from https://github.com/synaptik-/SoundWave/blob/master/app/src/main/java/com/synaptik/soundwave/AudioMonitor.java
*/
public class AudioRecorder implements Runnable {
private static final String TAG = AudioRecorder.class.getSimpleName();
private int mBufferSize;
private byte[] bufferByte;
private short[] bufferShort;
private AudioTrack at;
public boolean done = false;
private AudioRecord mAudio;
private OnUpdateListener mListener;
private static final int REQUIRED_FREQUENCY = 16000;
private static final int REQUIRED_CHANNEL = AudioFormat.CHANNEL_IN_MONO;
private static final int REQUIRED_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
public AudioRecorder(OnUpdateListener listener) {
this.mListener = listener;
this.initialize();
}
private void initialize() {
mBufferSize = AudioRecord.getMinBufferSize(REQUIRED_FREQUENCY, REQUIRED_CHANNEL, REQUIRED_FORMAT) * 2;
Log.d(TAG, "Recommended bufferSize: " + mBufferSize);
if (mBufferSize > 0) {
bufferShort = new short[mBufferSize / 2];
bufferByte = new byte[mBufferSize];
mAudio = new AudioRecord(MediaRecorder.AudioSource.MIC, REQUIRED_FREQUENCY, REQUIRED_CHANNEL, REQUIRED_FORMAT, mBufferSize);
if (mAudio.getState() == AudioRecord.STATE_UNINITIALIZED) {
Log.d(TAG, "Unable to initializeAudioMonitor AudioRecord. Ensure nothing else is using the microphone.");
if (mListener != null) {
this.mListener.quit(OnUpdateListener.ERROR_CODE_MICROPHONE_LOCKED);
}
mAudio = null;
}
}
}
public boolean isInitialized() {
return this.mAudio != null;
}
@Override
public void run() {
Log.d(TAG, "run");
if (mAudio != null) {
mAudio.startRecording();
while (!done) {
int count = mAudio.read(bufferByte, 0, mBufferSize);
int j =0;
for (int i = 0; i < bufferShort.length; i++) {
ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(bufferByte[j]);
bb.put(bufferByte[j+1]);
short shortVal = bb.getShort(0);
bufferShort[i] = shortVal;
j+=2;
}
if (count > 0) {
if (mListener != null) {
float sampleLength = 1.0f / ((float) REQUIRED_FREQUENCY / (float) count);
mListener.update(bufferByte, bufferShort, count, sampleLength);
}
} else {
done = true;
}
}
mAudio.stop();
mAudio.release();
Log.d(TAG, "released");
mAudio = null;
} else {
Log.d(TAG, "mAudio was null!");
}
}
public void setListener(OnUpdateListener listener) {
mListener = listener;
}
}
public class MyFragment extends Fragment implements OnUpdateListener {
AudioRecorder mAudioRecorder;
Thread mAudioThread;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Don't forget to ask permission Manifest.permission.RECORD_AUDIO;
mAudioRecorder = new AudioRecorder(this);
if (mAudioRecorder.isInitialized()) {
mAudioThread = new Thread(mAudioRecorder);
mAudioThread.start();
}
}
public void stopRecording() {
if (mAudioRecorder != null && mAudioRecorder.isInitialized()) {
mAudioRecorder.setListener(null);
mAudioRecorder.done = true;
}
}
// region AUDIO_MONITOR
@Override
public void update(final byte[] bytes, final short[] bufferShort, final int length, final float sampleLength) {
//Do you stuff
}
@Override
Public void quit(int errorCode) {
if (errorCode == OnUpdateListener.ERROR_CODE_MICROPHONE_LOCKED) {
new AlertDialog.Builder(getContext())
.setTitle("ERROR")
.setMessage("Can't use microphone")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
onBackPressed();
}
})
.show();
}
}
}
public interface OnUpdateListener {
int ERROR_CODE_MICROPHONE_LOCKED = 1;
void update(byte[] bytes, short[] bufferShort, int length, float sampleLength);
void quit(int errorCode);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment