diff --git a/.idea/misc.xml b/.idea/misc.xml
index 49d53af..53130d8 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -13,6 +13,7 @@
+
diff --git a/app/build.gradle b/app/build.gradle
index a6e64a6..84fb6b8 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -31,7 +31,9 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
+
implementation 'com.agrawalsuneet.androidlibs:dotsloader:1.4'
+
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 41144ec..dffb699 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,7 +6,8 @@
-
+
+
{
+ recordTask = new RecordAudio();
+ recordTask.start();
+ recordTask.execute();
+ }, 250);
+ }
+
+ public void stopRecording() {
+ /*
+ mediaRecorder.stop();
+ mediaRecorder.reset();
+ mediaRecorder.release();*/
+
+ recordTask.stop();
+ recordTask.cancel(true);
+
+ //byteArrayOutputStream.toByteArray();
+ }
+
+ public void onClickMicrophone(View view) {
view.setVisibility(View.INVISIBLE);
View dots = findViewById(R.id.dots);
dots.setVisibility(View.VISIBLE);
+ //recordAudio(5);
+
+ startRecording();
+
+
}
- public void stopRecording(View view) {
+
+ public void onClickRecordingDots(View view) {
view.setVisibility(View.INVISIBLE);
View dots = findViewById(R.id.microphone);
dots.setVisibility(View.VISIBLE);
+
+ stopRecording();
}
}
\ No newline at end of file
diff --git a/app/src/main/java/ch/mathieubroillet/jarvis/android/RecordAudio.java b/app/src/main/java/ch/mathieubroillet/jarvis/android/RecordAudio.java
new file mode 100644
index 0000000..109d7c9
--- /dev/null
+++ b/app/src/main/java/ch/mathieubroillet/jarvis/android/RecordAudio.java
@@ -0,0 +1,263 @@
+package ch.mathieubroillet.jarvis.android;
+
+import android.annotation.SuppressLint;
+import android.media.AudioFormat;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class RecordAudio extends AsyncTask {
+
+ private static final String TAG = MainActivity.class.getSimpleName();
+
+ private static final int RECORDER_BPP = 16;
+ private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
+ private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
+ private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
+ private boolean started = false;
+
+ private int bufferSize;
+ private final int frequency = 44100;;
+
+ private FileOutputStream os = null;
+
+ public void start(){
+ started = true;
+ }
+
+ public void stop(){
+ started = false;
+ }
+
+ @Override
+ protected Void doInBackground(Void... voids) {
+ Log.w(TAG, "doInBackground");
+ try {
+
+ String filename = getTempFilename();
+
+ try {
+ os = new FileOutputStream(filename);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+
+
+ int channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
+ int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
+ bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
+
+ @SuppressLint("MissingPermission")
+ AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, channelConfiguration, audioEncoding, bufferSize);
+
+ short[] buffer = new short[bufferSize];
+
+ audioRecord.startRecording();
+
+ while (started) {
+ int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
+ if (AudioRecord.ERROR_INVALID_OPERATION != bufferReadResult) {
+ //check signal
+ //put a threshold
+ short threshold = 15000;
+ int foundPeak = searchThreshold(buffer, threshold);
+ if (foundPeak > -1) { //found signal
+ //record signal
+ byte[] byteBuffer = shortToByte(buffer, bufferReadResult);
+ try {
+ os.write(byteBuffer);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {//count the time
+ //don't save signal
+ }
+
+
+ //show results
+ //here, with publichProgress function, if you calculate the total saved samples,
+ //you can optionally show the recorded file length in seconds: publishProgress(elsapsedTime,0);
+
+
+ }
+ }
+
+ audioRecord.stop();
+
+ //close file
+ try {
+ os.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ copyWaveFile(getTempFilename(), getFilename());
+ deleteTempFile();
+
+
+ } catch (Throwable t) {
+ t.printStackTrace();
+ Log.e("AudioRecord", "Recording Failed");
+ }
+ return null;
+
+ }
+
+ byte[] shortToByte(short[] input, int elements) {
+ int short_index, byte_index;
+ byte[] buffer = new byte[elements * 2];
+
+ short_index = byte_index = 0;
+
+ while (short_index != elements) {
+ buffer[byte_index] = (byte) (input[short_index] & 0x00FF);
+ buffer[byte_index + 1] = (byte) ((input[short_index] & 0xFF00) >> 8);
+
+ ++short_index;
+ byte_index += 2;
+ }
+
+ return buffer;
+ }
+
+
+ int searchThreshold(short[] arr, short thr) {
+ int peakIndex;
+ int arrLen = arr.length;
+ for (peakIndex = 0; peakIndex < arrLen; peakIndex++) {
+ if ((arr[peakIndex] >= thr) || (arr[peakIndex] <= -thr)) {
+ return peakIndex;
+ }
+ }
+ return -1;
+ }
+
+ private String getFilename() {
+ String filepath = Environment.getExternalStorageDirectory().getPath();
+ File file = new File(filepath, AUDIO_RECORDER_FOLDER);
+
+ if (!file.exists()) {
+ file.mkdirs();
+ }
+
+ return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + AUDIO_RECORDER_FILE_EXT_WAV);
+ }
+
+
+ private String getTempFilename() {
+ String filepath = Environment.getExternalStorageDirectory().getPath();
+ File file = new File(filepath, AUDIO_RECORDER_FOLDER);
+
+ if (!file.exists()) {
+ file.mkdirs();
+ }
+
+ File tempFile = new File(filepath, AUDIO_RECORDER_TEMP_FILE);
+
+ if (tempFile.exists())
+ tempFile.delete();
+
+ return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
+ }
+
+
+ private void deleteTempFile() {
+ File file = new File(getTempFilename());
+
+ file.delete();
+ }
+
+ private void copyWaveFile(String inFilename, String outFilename) {
+ FileInputStream in;
+ FileOutputStream out;
+ long totalAudioLen;
+ long totalDataLen;
+ long longSampleRate = frequency;
+ int channels = 1;
+ long byteRate = (long) RECORDER_BPP * frequency * channels / 8;
+
+ byte[] data = new byte[bufferSize];
+
+ try {
+ in = new FileInputStream(inFilename);
+ out = new FileOutputStream(outFilename);
+ totalAudioLen = in.getChannel().size();
+ totalDataLen = totalAudioLen + 36;
+
+
+ writeWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate);
+
+ while (in.read(data) != -1) {
+ out.write(data);
+ }
+
+ in.close();
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void writeWaveFileHeader(
+ FileOutputStream out, long totalAudioLen,
+ long totalDataLen, long longSampleRate, int channels,
+ long byteRate) throws IOException {
+
+ byte[] header = new byte[44];
+
+ header[0] = 'R'; // RIFF/WAVE header
+ header[1] = 'I';
+ header[2] = 'F';
+ header[3] = 'F';
+ header[4] = (byte) (totalDataLen & 0xff);
+ header[5] = (byte) ((totalDataLen >> 8) & 0xff);
+ header[6] = (byte) ((totalDataLen >> 16) & 0xff);
+ header[7] = (byte) ((totalDataLen >> 24) & 0xff);
+ header[8] = 'W';
+ header[9] = 'A';
+ header[10] = 'V';
+ header[11] = 'E';
+ header[12] = 'f'; // 'fmt ' chunk
+ header[13] = 'm';
+ header[14] = 't';
+ header[15] = ' ';
+ header[16] = 16; // 4 bytes: size of 'fmt ' chunk
+ header[17] = 0;
+ header[18] = 0;
+ header[19] = 0;
+ header[20] = 1; // format = 1
+ header[21] = 0;
+ header[22] = (byte) channels;
+ header[23] = 0;
+ header[24] = (byte) (longSampleRate & 0xff);
+ header[25] = (byte) ((longSampleRate >> 8) & 0xff);
+ header[26] = (byte) ((longSampleRate >> 16) & 0xff);
+ header[27] = (byte) ((longSampleRate >> 24) & 0xff);
+ header[28] = (byte) (byteRate & 0xff);
+ header[29] = (byte) ((byteRate >> 8) & 0xff);
+ header[30] = (byte) ((byteRate >> 16) & 0xff);
+ header[31] = (byte) ((byteRate >> 24) & 0xff);
+ header[32] = (byte) (channels * 16 / 8); // block align
+ header[33] = 0;
+ header[34] = RECORDER_BPP; // bits per sample
+ header[35] = 0;
+ header[36] = 'd';
+ header[37] = 'a';
+ header[38] = 't';
+ header[39] = 'a';
+ header[40] = (byte) (totalAudioLen & 0xff);
+ header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
+ header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
+ header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
+
+ out.write(header, 0, 44);
+ }
+}
diff --git a/app/src/main/res/layout/dialog_listening.xml b/app/src/main/res/layout/dialog_listening.xml
index 012f999..098538f 100644
--- a/app/src/main/res/layout/dialog_listening.xml
+++ b/app/src/main/res/layout/dialog_listening.xml
@@ -84,7 +84,7 @@
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="223dp"
- android:onClick="stopRecording"
+ android:onClick="onClickRecordingDots"
android:visibility="invisible"
app:loader_animDur="250"
app:loader_circleRadius="10dp"
@@ -104,7 +104,7 @@
android:layout_centerHorizontal="true"
android:layout_marginTop="205dp"
android:contentDescription="microphone"
- android:onClick="startRecording"
+ android:onClick="onClickMicrophone"
app:srcCompat="@drawable/microphone"
tools:ignore="OnClick" />