From 37b7351d7bfdc84b69af9aee80c24bdc5832effc Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 10 Jun 2014 15:41:14 -0400 Subject: [PATCH 01/20] Add audio recording classes: AudioRecorder (a service) and AudioRecordThread (a thread which gets spawned by AudioRecorder) --- .../wearscript/audio/AudioRecordThread.java | 201 ++++++++++++++++++ .../com/wearscript/audio/AudioRecorder.java | 63 ++++++ 2 files changed, 264 insertions(+) create mode 100644 video/src/main/java/com/wearscript/audio/AudioRecordThread.java create mode 100644 video/src/main/java/com/wearscript/audio/AudioRecorder.java diff --git a/video/src/main/java/com/wearscript/audio/AudioRecordThread.java b/video/src/main/java/com/wearscript/audio/AudioRecordThread.java new file mode 100644 index 0000000..9400a01 --- /dev/null +++ b/video/src/main/java/com/wearscript/audio/AudioRecordThread.java @@ -0,0 +1,201 @@ +package com.wearscript.audio; + +import android.media.AudioFormat; +import android.media.AudioRecord; +import android.media.MediaRecorder.AudioSource; +import android.os.Environment; +import android.util.Log; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +public class AudioRecordThread extends Thread{ + + private static final String LOG_TAG = "Audio"; + + private static final int RECORDER_SAMPLERATE = 8000; + private static final int ENCODING_TYPE = AudioFormat.ENCODING_PCM_16BIT; + private final int CHANNEL_TYPE = AudioFormat.CHANNEL_IN_MONO; + private final int NUM_CHANNELS = 1; + private byte BITS_PER_SAMPLE = 16; + private final int AUDIO_SOURCE = AudioSource.MIC; + private final int BYTE_RATE = RECORDER_SAMPLERATE * NUM_CHANNELS * (BITS_PER_SAMPLE / 8); + private final int RECORDING_SECS = 20; + + public static final String directory = Environment.getExternalStorageDirectory() + File.separator + "wearscript"; + public static final String directoryAudio = directory + File.separator+"audio"; + + private final int bufferSize = 160; //Each buffer holds 1/100th of a second. + private int numBuffers = 100 * RECORDING_SECS; + private boolean pollingBuffer = false; + private String latestFilePath = null; + + AudioRecord recorder = null; + + /** + * Give the thread high priority so that it's not cancelled unexpectedly, and start it + */ + + private ArrayList buffers; + private ArrayList totalBuffer; + + public AudioRecordThread() + { + //Try this at lower priorities. + android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); + } + + @Override + public void run() + { + Log.d(LOG_TAG, "Running Audio Thread"); + + buffers = new ArrayList(); + totalBuffer = new ArrayList(); + int N = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,CHANNEL_TYPE,ENCODING_TYPE); + Log.d(LOG_TAG, ""+N); + try{ + recorder = new AudioRecord(AUDIO_SOURCE, RECORDER_SAMPLERATE, CHANNEL_TYPE, ENCODING_TYPE, N*10); + } + catch(Throwable e){ + Log.d(LOG_TAG, e.toString()); + return; + } + recorder.startRecording(); + + try{ + while(!interrupted()) + { + if (!pollingBuffer){ + buffers.add(new byte[bufferSize]); + recorder.read(buffers.get(buffers.size()-1),0,bufferSize); + } + else{ + pollRingBuffer(0); + writeAudioDataToFile(); + pollingBuffer = false; + Log.d(LOG_TAG, "Audio Saved"); + } + } + Log.d(LOG_TAG, "interrupted"); + } + catch(Throwable x) + { + Log.d(LOG_TAG, "Error reading voice audio", x); + } + /* + * Frees the thread's resources after the loop completes so that it can be run again + */ + finally + { + recorder.stop(); + recorder.release(); + Log.d(LOG_TAG, "Thread Terminated"); + } + } + + public String startPolling(long millis){ + pollingBuffer = true; + latestFilePath = audioFileName(millis); + return latestFilePath; + } + + private void pollRingBuffer(int ix){ + Log.d(LOG_TAG, "in pollRingBuffer()"); + int i; + int j; + for(i = 0; i> 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) NUM_CHANNELS; + header[23] = 0; + header[24] = (byte) (RECORDER_SAMPLERATE & 0xff); + header[25] = (byte) ((RECORDER_SAMPLERATE >> 8) & 0xff); + header[26] = (byte) ((RECORDER_SAMPLERATE >> 16) & 0xff); + header[27] = (byte) ((RECORDER_SAMPLERATE >> 24) & 0xff); + header[28] = (byte) (BYTE_RATE & 0xff); + header[29] = (byte) ((BYTE_RATE >> 8) & 0xff); + header[30] = (byte) ((BYTE_RATE >> 16) & 0xff); + header[31] = (byte) ((BYTE_RATE >> 24) & 0xff); + header[32] = (byte) (NUM_CHANNELS * BITS_PER_SAMPLE / 8);//(2 * 16 / 8); // block align (might be half what it should be) + header[33] = 0; + header[34] = BITS_PER_SAMPLE; // 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); + + System.arraycopy(header, 0, wavFile, 0, header.length); + System.arraycopy(totalBuffer, 0, wavFile, header.length, totalBuffer.size()); + + try { + os.write(wavFile, 0, wavFile.length); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} + diff --git a/video/src/main/java/com/wearscript/audio/AudioRecorder.java b/video/src/main/java/com/wearscript/audio/AudioRecorder.java new file mode 100644 index 0000000..aba298c --- /dev/null +++ b/video/src/main/java/com/wearscript/audio/AudioRecorder.java @@ -0,0 +1,63 @@ +package com.wearscript.audio; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; + +import java.io.File; + +public class AudioRecorder extends Service { + + private final String LOG_TAG = "AudioRecorder"; + + private AudioRecordThread recorder; + public static String MILLIS_EXTRA_KEY = "millis"; + + public AudioRecorder() { + } + + @Override + public void onCreate() { + super.onCreate(); + + Log.d("Memora", "Service Started"); + createMemoraDirectory(); + + recorder = new AudioRecordThread(); + recorder.start(); + } + + @Override + public void onDestroy() { + Log.d("Memora", "Service Destroy"); + recorder.interrupt(); + super.onDestroy(); + } + + @Override + public IBinder onBind(Intent intent) { + // TODO: Return the communication channel to the service. + throw new UnsupportedOperationException("Not yet implemented"); + } + + private void createMemoraDirectory(){ + File directory = new File(AudioRecordThread.directoryAudio); + if (!directory.isDirectory()){ + directory.mkdirs(); + } + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent.getAction() != null && intent.getAction().equals("save_audio_intent")) { + Log.d(LOG_TAG, "Got message"); + long millis = intent.getExtras().getLong(MILLIS_EXTRA_KEY); + Log.d(LOG_TAG, "millis: " + millis); + String filepath = recorder.startPolling(millis); + Log.d(LOG_TAG, "filepath: " + filepath); + } + return 0; + } + +} From 245ceeb9f74a106adf84cdb4724d7206f8c277e9 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 10 Jun 2014 17:40:58 -0400 Subject: [PATCH 02/20] Move audio and video recording to same package --- video/src/main/AndroidManifest.xml | 6 +++--- .../com/wearscript/{audio => record}/AudioRecordThread.java | 2 +- .../com/wearscript/{audio => record}/AudioRecorder.java | 2 +- .../com/wearscript/{video => record}/PlaybackActivity.java | 4 +++- .../com/wearscript/{video => record}/RecordActivity.java | 4 ++-- .../{video => record}/WearScriptBroadcastReceiver.java | 2 +- video/src/main/res/layout/activity_play.xml | 2 +- video/src/main/res/layout/activity_record.xml | 2 +- video/src/main/res/menu/record.xml | 2 +- 9 files changed, 14 insertions(+), 12 deletions(-) rename video/src/main/java/com/wearscript/{audio => record}/AudioRecordThread.java (99%) rename video/src/main/java/com/wearscript/{audio => record}/AudioRecorder.java (98%) rename video/src/main/java/com/wearscript/{video => record}/PlaybackActivity.java (96%) rename video/src/main/java/com/wearscript/{video => record}/RecordActivity.java (99%) rename video/src/main/java/com/wearscript/{video => record}/WearScriptBroadcastReceiver.java (98%) diff --git a/video/src/main/AndroidManifest.xml b/video/src/main/AndroidManifest.xml index 916a9fd..cb02ed5 100644 --- a/video/src/main/AndroidManifest.xml +++ b/video/src/main/AndroidManifest.xml @@ -14,7 +14,7 @@ android:icon="@drawable/ic_launcher" android:label="@string/app_name" > @@ -23,7 +23,7 @@ @@ -34,7 +34,7 @@ - + diff --git a/video/src/main/java/com/wearscript/audio/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java similarity index 99% rename from video/src/main/java/com/wearscript/audio/AudioRecordThread.java rename to video/src/main/java/com/wearscript/record/AudioRecordThread.java index 9400a01..501d780 100644 --- a/video/src/main/java/com/wearscript/audio/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -1,4 +1,4 @@ -package com.wearscript.audio; +package com.wearscript.record; import android.media.AudioFormat; import android.media.AudioRecord; diff --git a/video/src/main/java/com/wearscript/audio/AudioRecorder.java b/video/src/main/java/com/wearscript/record/AudioRecorder.java similarity index 98% rename from video/src/main/java/com/wearscript/audio/AudioRecorder.java rename to video/src/main/java/com/wearscript/record/AudioRecorder.java index aba298c..76d6ee5 100644 --- a/video/src/main/java/com/wearscript/audio/AudioRecorder.java +++ b/video/src/main/java/com/wearscript/record/AudioRecorder.java @@ -1,4 +1,4 @@ -package com.wearscript.audio; +package com.wearscript.record; import android.app.Service; import android.content.Intent; diff --git a/video/src/main/java/com/wearscript/video/PlaybackActivity.java b/video/src/main/java/com/wearscript/record/PlaybackActivity.java similarity index 96% rename from video/src/main/java/com/wearscript/video/PlaybackActivity.java rename to video/src/main/java/com/wearscript/record/PlaybackActivity.java index b94a65e..095827a 100644 --- a/video/src/main/java/com/wearscript/video/PlaybackActivity.java +++ b/video/src/main/java/com/wearscript/record/PlaybackActivity.java @@ -1,4 +1,4 @@ -package com.wearscript.video; +package com.wearscript.record; import android.app.Activity; import android.content.Intent; @@ -8,6 +8,8 @@ import android.util.Log; import android.widget.VideoView; +import com.wearscript.video.R; + import java.io.File; public class PlaybackActivity extends Activity implements MediaPlayer.OnPreparedListener, diff --git a/video/src/main/java/com/wearscript/video/RecordActivity.java b/video/src/main/java/com/wearscript/record/RecordActivity.java similarity index 99% rename from video/src/main/java/com/wearscript/video/RecordActivity.java rename to video/src/main/java/com/wearscript/record/RecordActivity.java index 790432f..c1934ce 100644 --- a/video/src/main/java/com/wearscript/video/RecordActivity.java +++ b/video/src/main/java/com/wearscript/record/RecordActivity.java @@ -1,4 +1,4 @@ -package com.wearscript.video; +package com.wearscript.record; import android.app.Activity; import android.content.Intent; @@ -21,7 +21,7 @@ import java.util.Date; import java.util.List; -import com.wearscript.video.WearScriptBroadcastReceiver; +import com.wearscript.video.R; public class RecordActivity extends Activity implements SurfaceHolder.Callback { private final static String TAG = "RecordActivity"; diff --git a/video/src/main/java/com/wearscript/video/WearScriptBroadcastReceiver.java b/video/src/main/java/com/wearscript/record/WearScriptBroadcastReceiver.java similarity index 98% rename from video/src/main/java/com/wearscript/video/WearScriptBroadcastReceiver.java rename to video/src/main/java/com/wearscript/record/WearScriptBroadcastReceiver.java index 509e730..1baebd5 100644 --- a/video/src/main/java/com/wearscript/video/WearScriptBroadcastReceiver.java +++ b/video/src/main/java/com/wearscript/record/WearScriptBroadcastReceiver.java @@ -1,4 +1,4 @@ -package com.wearscript.video; +package com.wearscript.record; import android.content.BroadcastReceiver; import android.content.Context; diff --git a/video/src/main/res/layout/activity_play.xml b/video/src/main/res/layout/activity_play.xml index 470475b..9b7cd48 100644 --- a/video/src/main/res/layout/activity_play.xml +++ b/video/src/main/res/layout/activity_play.xml @@ -2,7 +2,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" -tools:context="com.wearscript.video.PlaybackActivity"> +tools:context="com.wearscript.record.PlaybackActivity"> + tools:context="com.wearscript.record.RecordActivity"> \ No newline at end of file diff --git a/video/src/main/res/menu/record.xml b/video/src/main/res/menu/record.xml index ae77365..99fac1c 100644 --- a/video/src/main/res/menu/record.xml +++ b/video/src/main/res/menu/record.xml @@ -1,6 +1,6 @@ + tools:context="com.wearscript.record.RecordActivity" > Date: Wed, 11 Jun 2014 18:03:21 -0400 Subject: [PATCH 03/20] Record a continuous amount of audio until interrupted, then send a broadcast with the filename and stop the service --- video/src/main/AndroidManifest.xml | 12 +++++ .../wearscript/record/AudioRecordThread.java | 51 ++++++++++--------- .../com/wearscript/record/AudioRecorder.java | 8 +-- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/video/src/main/AndroidManifest.xml b/video/src/main/AndroidManifest.xml index cb02ed5..f20b721 100644 --- a/video/src/main/AndroidManifest.xml +++ b/video/src/main/AndroidManifest.xml @@ -42,6 +42,18 @@ + + + + + + + + + diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index 501d780..4e8164f 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -1,5 +1,7 @@ package com.wearscript.record; +import android.content.Context; +import android.content.Intent; import android.media.AudioFormat; import android.media.AudioRecord; import android.media.MediaRecorder.AudioSource; @@ -23,13 +25,11 @@ public class AudioRecordThread extends Thread{ private byte BITS_PER_SAMPLE = 16; private final int AUDIO_SOURCE = AudioSource.MIC; private final int BYTE_RATE = RECORDER_SAMPLERATE * NUM_CHANNELS * (BITS_PER_SAMPLE / 8); - private final int RECORDING_SECS = 20; public static final String directory = Environment.getExternalStorageDirectory() + File.separator + "wearscript"; public static final String directoryAudio = directory + File.separator+"audio"; private final int bufferSize = 160; //Each buffer holds 1/100th of a second. - private int numBuffers = 100 * RECORDING_SECS; private boolean pollingBuffer = false; private String latestFilePath = null; @@ -40,12 +40,15 @@ public class AudioRecordThread extends Thread{ */ private ArrayList buffers; - private ArrayList totalBuffer; + private byte[] totalBuffer; + + Context context; - public AudioRecordThread() + public AudioRecordThread(Context context) { //Try this at lower priorities. android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); + this.context = context; } @Override @@ -54,7 +57,6 @@ public void run() Log.d(LOG_TAG, "Running Audio Thread"); buffers = new ArrayList(); - totalBuffer = new ArrayList(); int N = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,CHANNEL_TYPE,ENCODING_TYPE); Log.d(LOG_TAG, ""+N); try{ @@ -67,20 +69,15 @@ public void run() recorder.startRecording(); try{ - while(!interrupted()) - { - if (!pollingBuffer){ - buffers.add(new byte[bufferSize]); - recorder.read(buffers.get(buffers.size()-1),0,bufferSize); - } - else{ - pollRingBuffer(0); - writeAudioDataToFile(); - pollingBuffer = false; - Log.d(LOG_TAG, "Audio Saved"); - } + while(!interrupted() && !pollingBuffer) + { + buffers.add(new byte[bufferSize]); + recorder.read(buffers.get(buffers.size()-1),0,bufferSize); } - Log.d(LOG_TAG, "interrupted"); + pollRingBuffer(); + writeAudioDataToFile(); + pollingBuffer = false; + Log.d(LOG_TAG, "Audio Saved"); } catch(Throwable x) { @@ -93,6 +90,7 @@ public void run() { recorder.stop(); recorder.release(); + context.stopService(new Intent(context, AudioRecorder.class)); Log.d(LOG_TAG, "Thread Terminated"); } } @@ -103,13 +101,16 @@ public String startPolling(long millis){ return latestFilePath; } - private void pollRingBuffer(int ix){ + private void pollRingBuffer(){ Log.d(LOG_TAG, "in pollRingBuffer()"); int i; int j; + int ix = 0; + totalBuffer = new byte[buffers.size() * bufferSize]; for(i = 0; i> 24) & 0xff); System.arraycopy(header, 0, wavFile, 0, header.length); - System.arraycopy(totalBuffer, 0, wavFile, header.length, totalBuffer.size()); + System.arraycopy(totalBuffer, 0, wavFile, header.length, totalBuffer.length); try { os.write(wavFile, 0, wavFile.length); @@ -196,6 +197,10 @@ private void writeAudioDataToFile() { } catch (IOException e) { e.printStackTrace(); } + + Intent intent = new Intent("com.wearscript.record.FILE_WRITTEN_AUDIO").putExtra("filepath", latestFilePath); + context.sendBroadcast(intent); + Log.d(LOG_TAG, "Sending broadcast: com.wearscript.record.FILE_WRITTEN_AUDIO"); } } diff --git a/video/src/main/java/com/wearscript/record/AudioRecorder.java b/video/src/main/java/com/wearscript/record/AudioRecorder.java index 76d6ee5..90e88c6 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecorder.java +++ b/video/src/main/java/com/wearscript/record/AudioRecorder.java @@ -21,16 +21,16 @@ public AudioRecorder() { public void onCreate() { super.onCreate(); - Log.d("Memora", "Service Started"); + Log.d(LOG_TAG, "Service Started"); createMemoraDirectory(); - recorder = new AudioRecordThread(); + recorder = new AudioRecordThread(this); recorder.start(); } @Override public void onDestroy() { - Log.d("Memora", "Service Destroy"); + Log.d(LOG_TAG, "Service Destroy"); recorder.interrupt(); super.onDestroy(); } @@ -50,7 +50,7 @@ private void createMemoraDirectory(){ @Override public int onStartCommand(Intent intent, int flags, int startId) { - if (intent.getAction() != null && intent.getAction().equals("save_audio_intent")) { + if (intent.getAction() != null && intent.getAction().equals("com.wearscript.record.SAVE_AUDIO")) { Log.d(LOG_TAG, "Got message"); long millis = intent.getExtras().getLong(MILLIS_EXTRA_KEY); Log.d(LOG_TAG, "millis: " + millis); From d88b871aab95666cbac16aef7d871d773eadf5be Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 18:39:08 -0400 Subject: [PATCH 04/20] Refactor pollRingBuffer() to mergeBuffers() --- .../main/java/com/wearscript/record/AudioRecordThread.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index 4e8164f..2bf51c0 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -74,7 +74,7 @@ public void run() buffers.add(new byte[bufferSize]); recorder.read(buffers.get(buffers.size()-1),0,bufferSize); } - pollRingBuffer(); + mergeBuffers(); writeAudioDataToFile(); pollingBuffer = false; Log.d(LOG_TAG, "Audio Saved"); @@ -101,8 +101,8 @@ public String startPolling(long millis){ return latestFilePath; } - private void pollRingBuffer(){ - Log.d(LOG_TAG, "in pollRingBuffer()"); + private void mergeBuffers(){ + Log.d(LOG_TAG, "in mergeBuffers()"); int i; int j; int ix = 0; From 2e812465bf31aa1fb79f41f2a3ed3f8671b1728e Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 18:39:42 -0400 Subject: [PATCH 05/20] Remove saveAudio() --- .../main/java/com/wearscript/record/AudioRecordThread.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index 2bf51c0..6e766a3 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -118,10 +118,6 @@ private void mergeBuffers(){ private String audioFileName(long millis) { return directoryAudio + File.separator + String.valueOf(millis) + ".wav"; } - //TODO what does this do and why is this here - public String saveAudio(){ - return "Failed"; - } private void writeAudioDataToFile() { int totalAudioLen = buffers.size() * bufferSize; From 1c6904d737d9490cd4bb6f768131682697453f4f Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 18:46:16 -0400 Subject: [PATCH 06/20] Create constant WAV_HEADER_LENGTH --- .../java/com/wearscript/record/AudioRecordThread.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index 6e766a3..53a1a86 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -15,12 +15,13 @@ import java.util.ArrayList; public class AudioRecordThread extends Thread{ - - private static final String LOG_TAG = "Audio"; + + private static final String LOG_TAG = "Audio"; private static final int RECORDER_SAMPLERATE = 8000; private static final int ENCODING_TYPE = AudioFormat.ENCODING_PCM_16BIT; - private final int CHANNEL_TYPE = AudioFormat.CHANNEL_IN_MONO; + public static final int WAV_HEADER_LENGTH = 44; + private final int CHANNEL_TYPE = AudioFormat.CHANNEL_IN_MONO; private final int NUM_CHANNELS = 1; private byte BITS_PER_SAMPLE = 16; private final int AUDIO_SOURCE = AudioSource.MIC; @@ -123,7 +124,7 @@ private void writeAudioDataToFile() { int totalAudioLen = buffers.size() * bufferSize; int totalDataLen = (totalAudioLen * NUM_CHANNELS * BITS_PER_SAMPLE / 8) + 36; //String filePath = audioFileName(); - byte header[] = new byte[44]; + byte header[] = new byte[WAV_HEADER_LENGTH]; byte wavFile[] = new byte[totalAudioLen + header.length]; FileOutputStream os = null; From 300c2d078b671248e6303f39bd32451914a40d9f Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 18:48:03 -0400 Subject: [PATCH 07/20] Remove comments in WAV header creation --- .../main/java/com/wearscript/record/AudioRecordThread.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index 53a1a86..d7a76bc 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -167,9 +167,9 @@ private void writeAudioDataToFile() { header[29] = (byte) ((BYTE_RATE >> 8) & 0xff); header[30] = (byte) ((BYTE_RATE >> 16) & 0xff); header[31] = (byte) ((BYTE_RATE >> 24) & 0xff); - header[32] = (byte) (NUM_CHANNELS * BITS_PER_SAMPLE / 8);//(2 * 16 / 8); // block align (might be half what it should be) + header[32] = (byte) (NUM_CHANNELS * BITS_PER_SAMPLE / 8); header[33] = 0; - header[34] = BITS_PER_SAMPLE; // bits per sample + header[34] = BITS_PER_SAMPLE; header[35] = 0; header[36] = 'd'; header[37] = 'a'; From 7d6ac2a2cd0ed04cdee904a84c52624f05f5a700 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 18:51:12 -0400 Subject: [PATCH 08/20] Rename createMemoraDirectory() to createDirectory() --- video/src/main/java/com/wearscript/record/AudioRecorder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecorder.java b/video/src/main/java/com/wearscript/record/AudioRecorder.java index 90e88c6..ac90fd9 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecorder.java +++ b/video/src/main/java/com/wearscript/record/AudioRecorder.java @@ -22,7 +22,7 @@ public void onCreate() { super.onCreate(); Log.d(LOG_TAG, "Service Started"); - createMemoraDirectory(); + createDirectory(); recorder = new AudioRecordThread(this); recorder.start(); @@ -41,7 +41,7 @@ public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } - private void createMemoraDirectory(){ + private void createDirectory(){ File directory = new File(AudioRecordThread.directoryAudio); if (!directory.isDirectory()){ directory.mkdirs(); From a80722e04c58f92ea08f3c70e822819dbd8bd9c9 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 19:06:31 -0400 Subject: [PATCH 09/20] Remove empty constructor --- video/src/main/java/com/wearscript/record/AudioRecorder.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecorder.java b/video/src/main/java/com/wearscript/record/AudioRecorder.java index ac90fd9..d495454 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecorder.java +++ b/video/src/main/java/com/wearscript/record/AudioRecorder.java @@ -13,9 +13,6 @@ public class AudioRecorder extends Service { private AudioRecordThread recorder; public static String MILLIS_EXTRA_KEY = "millis"; - - public AudioRecorder() { - } @Override public void onCreate() { From 6060a4172f0c1ce049d935ab760b51e689c9bfb9 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 19:13:26 -0400 Subject: [PATCH 10/20] Remove call to setThreadPriority --- .../main/java/com/wearscript/record/AudioRecordThread.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index d7a76bc..595f8dc 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -46,9 +46,7 @@ public class AudioRecordThread extends Thread{ Context context; public AudioRecordThread(Context context) - { - //Try this at lower priorities. - android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); + { this.context = context; } From d3bc49df24e71aaf5837bcbd5b286105bab9768d Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 19:37:09 -0400 Subject: [PATCH 11/20] Fix code style / indentation issues --- .../wearscript/record/AudioRecordThread.java | 134 +++++++++--------- .../com/wearscript/record/AudioRecorder.java | 2 +- 2 files changed, 66 insertions(+), 70 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index 595f8dc..731e014 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -14,124 +14,120 @@ import java.io.IOException; import java.util.ArrayList; -public class AudioRecordThread extends Thread{ +public class AudioRecordThread extends Thread { private static final String LOG_TAG = "Audio"; - - private static final int RECORDER_SAMPLERATE = 8000; - private static final int ENCODING_TYPE = AudioFormat.ENCODING_PCM_16BIT; + + private static final int RECORDER_SAMPLERATE = 8000; + private static final int ENCODING_TYPE = AudioFormat.ENCODING_PCM_16BIT; public static final int WAV_HEADER_LENGTH = 44; private final int CHANNEL_TYPE = AudioFormat.CHANNEL_IN_MONO; - private final int NUM_CHANNELS = 1; - private byte BITS_PER_SAMPLE = 16; - private final int AUDIO_SOURCE = AudioSource.MIC; + private final int NUM_CHANNELS = 1; + private byte BITS_PER_SAMPLE = 16; + private final int AUDIO_SOURCE = AudioSource.MIC; private final int BYTE_RATE = RECORDER_SAMPLERATE * NUM_CHANNELS * (BITS_PER_SAMPLE / 8); public static final String directory = Environment.getExternalStorageDirectory() + File.separator + "wearscript"; public static final String directoryAudio = directory + File.separator+"audio"; - + private final int bufferSize = 160; //Each buffer holds 1/100th of a second. private boolean pollingBuffer = false; private String latestFilePath = null; - + AudioRecord recorder = null; /** * Give the thread high priority so that it's not cancelled unexpectedly, and start it */ - - private ArrayList buffers; - private byte[] totalBuffer; + + private ArrayList buffers; + private byte[] totalBuffer; Context context; - + public AudioRecordThread(Context context) { this.context = context; } @Override - public void run() - { + public void run() { Log.d(LOG_TAG, "Running Audio Thread"); - + buffers = new ArrayList(); - int N = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,CHANNEL_TYPE,ENCODING_TYPE); - Log.d(LOG_TAG, ""+N); - try{ - recorder = new AudioRecord(AUDIO_SOURCE, RECORDER_SAMPLERATE, CHANNEL_TYPE, ENCODING_TYPE, N*10); + int N = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, CHANNEL_TYPE,ENCODING_TYPE); + Log.d(LOG_TAG, "" + N); + try { + recorder = new AudioRecord(AUDIO_SOURCE, RECORDER_SAMPLERATE, CHANNEL_TYPE, ENCODING_TYPE, N*10); } - catch(Throwable e){ - Log.d(LOG_TAG, e.toString()); - return; + catch (Throwable e) { + Log.d(LOG_TAG, e.toString()); + return; } recorder.startRecording(); - - try{ - while(!interrupted() && !pollingBuffer) - { + + try { + while (!interrupted() && !pollingBuffer) { buffers.add(new byte[bufferSize]); - recorder.read(buffers.get(buffers.size()-1),0,bufferSize); + recorder.read(buffers.get(buffers.size() - 1), 0, bufferSize); } mergeBuffers(); writeAudioDataToFile(); pollingBuffer = false; Log.d(LOG_TAG, "Audio Saved"); } - catch(Throwable x) - { + catch (Throwable x) { Log.d(LOG_TAG, "Error reading voice audio", x); } /* * Frees the thread's resources after the loop completes so that it can be run again */ - finally - { + finally { recorder.stop(); recorder.release(); context.stopService(new Intent(context, AudioRecorder.class)); Log.d(LOG_TAG, "Thread Terminated"); } } - - public String startPolling(long millis){ - pollingBuffer = true; - latestFilePath = audioFileName(millis); - return latestFilePath; + + public String startPolling(long millis) { + pollingBuffer = true; + latestFilePath = audioFileName(millis); + return latestFilePath; } - - private void mergeBuffers(){ + + private void mergeBuffers() { Log.d(LOG_TAG, "in mergeBuffers()"); - int i; - int j; + int i; + int j; int ix = 0; totalBuffer = new byte[buffers.size() * bufferSize]; - for(i = 0; i> 8) & 0xff); header[42] = (byte) ((totalAudioLen >> 16) & 0xff); header[43] = (byte) ((totalAudioLen >> 24) & 0xff); - - System.arraycopy(header, 0, wavFile, 0, header.length); - System.arraycopy(totalBuffer, 0, wavFile, header.length, totalBuffer.length); - + + System.arraycopy(header, 0, wavFile, 0, header.length); + System.arraycopy(totalBuffer, 0, wavFile, header.length, totalBuffer.length); + try { os.write(wavFile, 0, wavFile.length); } catch (IOException e) { e.printStackTrace(); } - - try { - os.close(); - } catch (IOException e) { - e.printStackTrace(); - } + + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } Intent intent = new Intent("com.wearscript.record.FILE_WRITTEN_AUDIO").putExtra("filepath", latestFilePath); context.sendBroadcast(intent); Log.d(LOG_TAG, "Sending broadcast: com.wearscript.record.FILE_WRITTEN_AUDIO"); - } + } } diff --git a/video/src/main/java/com/wearscript/record/AudioRecorder.java b/video/src/main/java/com/wearscript/record/AudioRecorder.java index d495454..22db0d7 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecorder.java +++ b/video/src/main/java/com/wearscript/record/AudioRecorder.java @@ -38,7 +38,7 @@ public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } - private void createDirectory(){ + private void createDirectory() { File directory = new File(AudioRecordThread.directoryAudio); if (!directory.isDirectory()){ directory.mkdirs(); From 9b99698a1b274b4dc3160bd558b3aef8f0452235 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 19:55:57 -0400 Subject: [PATCH 12/20] Convert remaining references to com.wearscript.video into com.wearscript.record --- video/src/main/AndroidManifest.xml | 8 ++++---- .../main/java/com/wearscript/record/RecordActivity.java | 2 -- .../wearscript/record/WearScriptBroadcastReceiver.java | 6 +++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/video/src/main/AndroidManifest.xml b/video/src/main/AndroidManifest.xml index f20b721..b5d3d00 100644 --- a/video/src/main/AndroidManifest.xml +++ b/video/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="com.wearscript.record" > @@ -36,9 +36,9 @@ - - - + + + diff --git a/video/src/main/java/com/wearscript/record/RecordActivity.java b/video/src/main/java/com/wearscript/record/RecordActivity.java index c1934ce..a7bbbda 100644 --- a/video/src/main/java/com/wearscript/record/RecordActivity.java +++ b/video/src/main/java/com/wearscript/record/RecordActivity.java @@ -21,8 +21,6 @@ import java.util.Date; import java.util.List; -import com.wearscript.video.R; - public class RecordActivity extends Activity implements SurfaceHolder.Callback { private final static String TAG = "RecordActivity"; private final static boolean DBG = true; diff --git a/video/src/main/java/com/wearscript/record/WearScriptBroadcastReceiver.java b/video/src/main/java/com/wearscript/record/WearScriptBroadcastReceiver.java index 1baebd5..9d22587 100644 --- a/video/src/main/java/com/wearscript/record/WearScriptBroadcastReceiver.java +++ b/video/src/main/java/com/wearscript/record/WearScriptBroadcastReceiver.java @@ -7,9 +7,9 @@ public class WearScriptBroadcastReceiver extends BroadcastReceiver { - public static final String PLAYBACK_ACTION = "com.wearscript.video.PLAYBACK"; - public static final String RECORD_ACTION = "com.wearscript.video.RECORD"; - public static final String RECORD_RESULT_ACTION = "com.wearscript.video.RECORD_RESULT"; + public static final String PLAYBACK_ACTION = "com.wearscript.record.PLAYBACK"; + public static final String RECORD_ACTION = "com.wearscript.record.RECORD"; + public static final String RECORD_RESULT_ACTION = "com.wearscript.record.RECORD_RESULT"; private static final String TAG = "WearScriptBroadcastReceiver"; private static final boolean DBG = true; From bca7cf96b25915a8fe4f7308908279f3d6cd55d4 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 20:17:34 -0400 Subject: [PATCH 13/20] Remove one more reference to com.wearscript.video --- .../src/main/java/com/wearscript/record/PlaybackActivity.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/PlaybackActivity.java b/video/src/main/java/com/wearscript/record/PlaybackActivity.java index 095827a..83801e0 100644 --- a/video/src/main/java/com/wearscript/record/PlaybackActivity.java +++ b/video/src/main/java/com/wearscript/record/PlaybackActivity.java @@ -7,9 +7,6 @@ import android.os.Bundle; import android.util.Log; import android.widget.VideoView; - -import com.wearscript.video.R; - import java.io.File; public class PlaybackActivity extends Activity implements MediaPlayer.OnPreparedListener, From d7c07d205565b1925dbb4316da0d8056abdd4c96 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 20:17:44 -0400 Subject: [PATCH 14/20] Add constant FILEPATH --- .../src/main/java/com/wearscript/record/AudioRecordThread.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index 731e014..d7823a7 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -21,6 +21,7 @@ public class AudioRecordThread extends Thread { private static final int RECORDER_SAMPLERATE = 8000; private static final int ENCODING_TYPE = AudioFormat.ENCODING_PCM_16BIT; public static final int WAV_HEADER_LENGTH = 44; + public static final String FILEPATH = "filepath"; private final int CHANNEL_TYPE = AudioFormat.CHANNEL_IN_MONO; private final int NUM_CHANNELS = 1; private byte BITS_PER_SAMPLE = 16; @@ -189,7 +190,7 @@ private void writeAudioDataToFile() { e.printStackTrace(); } - Intent intent = new Intent("com.wearscript.record.FILE_WRITTEN_AUDIO").putExtra("filepath", latestFilePath); + Intent intent = new Intent("com.wearscript.record.FILE_WRITTEN_AUDIO").putExtra(FILEPATH, latestFilePath); context.sendBroadcast(intent); Log.d(LOG_TAG, "Sending broadcast: com.wearscript.record.FILE_WRITTEN_AUDIO"); } From a01f430069f7535d82198179c3711a8cf99fcbb0 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Tue, 17 Jun 2014 20:46:53 -0400 Subject: [PATCH 15/20] Remove commented code --- video/src/main/java/com/wearscript/record/AudioRecordThread.java | 1 - 1 file changed, 1 deletion(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index d7823a7..b08eece 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -118,7 +118,6 @@ private String audioFileName(long millis) { private void writeAudioDataToFile() { int totalAudioLen = buffers.size() * bufferSize; int totalDataLen = (totalAudioLen * NUM_CHANNELS * BITS_PER_SAMPLE / 8) + 36; - //String filePath = audioFileName(); byte header[] = new byte[WAV_HEADER_LENGTH]; byte wavFile[] = new byte[totalAudioLen + header.length]; From f8a0f44d72110a72fa90106f7f53cc76120beae8 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Thu, 19 Jun 2014 14:04:39 -0400 Subject: [PATCH 16/20] Move save-file logic inside of while recording loop --- .../com/wearscript/record/AudioRecordThread.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index b08eece..48334ae 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -68,14 +68,18 @@ public void run() { recorder.startRecording(); try { - while (!interrupted() && !pollingBuffer) { + while (!interrupted()) { buffers.add(new byte[bufferSize]); recorder.read(buffers.get(buffers.size() - 1), 0, bufferSize); + if (pollingBuffer) { + mergeBuffers(); + writeAudioDataToFile(); + pollingBuffer = false; + Log.d(LOG_TAG, "Audio Saved"); + break; + } } - mergeBuffers(); - writeAudioDataToFile(); - pollingBuffer = false; - Log.d(LOG_TAG, "Audio Saved"); + } catch (Throwable x) { Log.d(LOG_TAG, "Error reading voice audio", x); From 9aef10841a2684eded305a3b37c5e77d0616d2ee Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Thu, 19 Jun 2014 15:46:16 -0400 Subject: [PATCH 17/20] Save WAV header with long length so that we don't need to edit it when writing more data to the end of the file --- .../main/java/com/wearscript/record/AudioRecordThread.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index 48334ae..e72eb05 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -133,6 +133,11 @@ private void writeAudioDataToFile() { e.printStackTrace(); } + /* Test whether Android media player will play back a WAV file whose header indicates the + * wrong length file! */ + totalAudioLen = Integer.MAX_VALUE - 36; + totalDataLen = Integer.MAX_VALUE; + header[0] = 'R'; // RIFF/WAVE header header[1] = 'I'; header[2] = 'F'; From dad401612c788e90683933cfb4d881586d38f86e Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Thu, 19 Jun 2014 18:03:23 -0400 Subject: [PATCH 18/20] Add ability to save an updated audio file whenever we want to while continuing to record to the same file --- video/src/main/AndroidManifest.xml | 1 + .../wearscript/record/AudioRecordThread.java | 68 ++++++++++--------- .../com/wearscript/record/AudioRecorder.java | 13 ++-- 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/video/src/main/AndroidManifest.xml b/video/src/main/AndroidManifest.xml index b5d3d00..3926733 100644 --- a/video/src/main/AndroidManifest.xml +++ b/video/src/main/AndroidManifest.xml @@ -50,6 +50,7 @@ + diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index e72eb05..d6d3383 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -33,9 +33,10 @@ public class AudioRecordThread extends Thread { private final int bufferSize = 160; //Each buffer holds 1/100th of a second. private boolean pollingBuffer = false; - private String latestFilePath = null; AudioRecord recorder = null; + FileOutputStream os = null; + String filePath; /** * Give the thread high priority so that it's not cancelled unexpectedly, and start it @@ -66,20 +67,13 @@ public void run() { return; } recorder.startRecording(); + writeWavHeader(System.currentTimeMillis()); try { while (!interrupted()) { buffers.add(new byte[bufferSize]); recorder.read(buffers.get(buffers.size() - 1), 0, bufferSize); - if (pollingBuffer) { - mergeBuffers(); - writeAudioDataToFile(); - pollingBuffer = false; - Log.d(LOG_TAG, "Audio Saved"); - break; - } } - } catch (Throwable x) { Log.d(LOG_TAG, "Error reading voice audio", x); @@ -95,21 +89,20 @@ public void run() { } } - public String startPolling(long millis) { - pollingBuffer = true; - latestFilePath = audioFileName(millis); - return latestFilePath; - } - private void mergeBuffers() { Log.d(LOG_TAG, "in mergeBuffers()"); int i; int j; int ix = 0; - totalBuffer = new byte[buffers.size() * bufferSize]; - for (i = 0; i < buffers.size(); i++) { + + ArrayList copy = (ArrayList) buffers.clone(); + buffers = new ArrayList(); + + totalBuffer = new byte[copy.size() * bufferSize]; + for (i = 0; i < copy.size(); i++) { for(j = 0; j> 16) & 0xff); header[43] = (byte) ((totalAudioLen >> 24) & 0xff); - System.arraycopy(header, 0, wavFile, 0, header.length); - System.arraycopy(totalBuffer, 0, wavFile, header.length, totalBuffer.length); - try { - os.write(wavFile, 0, wavFile.length); + os.write(header, 0, header.length); } catch (IOException e) { e.printStackTrace(); } + } + + public void stopRecording() { + Log.d(LOG_TAG, "in stopRecording()"); + writeAudioDataToFile(); try { os.close(); @@ -198,7 +190,19 @@ private void writeAudioDataToFile() { e.printStackTrace(); } - Intent intent = new Intent("com.wearscript.record.FILE_WRITTEN_AUDIO").putExtra(FILEPATH, latestFilePath); + interrupt(); + } + + public void writeAudioDataToFile() { + mergeBuffers(); + + try { + os.write(totalBuffer, 0, totalBuffer.length); + } catch (IOException e) { + e.printStackTrace(); + } + + Intent intent = new Intent("com.wearscript.record.FILE_WRITTEN_AUDIO").putExtra(FILEPATH, filePath); context.sendBroadcast(intent); Log.d(LOG_TAG, "Sending broadcast: com.wearscript.record.FILE_WRITTEN_AUDIO"); } diff --git a/video/src/main/java/com/wearscript/record/AudioRecorder.java b/video/src/main/java/com/wearscript/record/AudioRecorder.java index 22db0d7..9b484b6 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecorder.java +++ b/video/src/main/java/com/wearscript/record/AudioRecorder.java @@ -47,12 +47,13 @@ private void createDirectory() { @Override public int onStartCommand(Intent intent, int flags, int startId) { - if (intent.getAction() != null && intent.getAction().equals("com.wearscript.record.SAVE_AUDIO")) { - Log.d(LOG_TAG, "Got message"); - long millis = intent.getExtras().getLong(MILLIS_EXTRA_KEY); - Log.d(LOG_TAG, "millis: " + millis); - String filepath = recorder.startPolling(millis); - Log.d(LOG_TAG, "filepath: " + filepath); + if (intent.getAction() != null) { + if (intent.getAction().equals("com.wearscript.record.SAVE_AUDIO")) { + recorder.writeAudioDataToFile(); + } else if (intent.getAction().equals("com.wearscript.record.STOP_AUDIO")) { + recorder.stopRecording(); + stopSelf(); + } } return 0; } From 440958fa4ad25cb8c06136a340843b251aced1c8 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Thu, 19 Jun 2014 18:34:11 -0400 Subject: [PATCH 19/20] Accept audio file name passed in when recording is started --- .../com/wearscript/record/AudioRecordThread.java | 12 ++++++------ .../java/com/wearscript/record/AudioRecorder.java | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index d6d3383..ce20901 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -47,9 +47,10 @@ public class AudioRecordThread extends Thread { Context context; - public AudioRecordThread(Context context) + public AudioRecordThread(Context context, String fileName) { this.context = context; + writeWavHeader(fileName); } @Override @@ -67,7 +68,6 @@ public void run() { return; } recorder.startRecording(); - writeWavHeader(System.currentTimeMillis()); try { while (!interrupted()) { @@ -108,15 +108,15 @@ private void mergeBuffers() { } } - private String audioFileName(long millis) { - return directoryAudio + File.separator + String.valueOf(millis) + ".wav"; + private String audioFileName(String fileName) { + return directoryAudio + File.separator + fileName + ".wav"; } - private void writeWavHeader(long millis) { + private void writeWavHeader(String fileName) { byte header[] = new byte[WAV_HEADER_LENGTH]; try { - filePath = audioFileName(millis); + filePath = audioFileName(fileName); os = new FileOutputStream(filePath); Log.d(LOG_TAG, "file path: " + filePath); } catch (FileNotFoundException e) { diff --git a/video/src/main/java/com/wearscript/record/AudioRecorder.java b/video/src/main/java/com/wearscript/record/AudioRecorder.java index 9b484b6..3ac7821 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecorder.java +++ b/video/src/main/java/com/wearscript/record/AudioRecorder.java @@ -20,9 +20,6 @@ public void onCreate() { Log.d(LOG_TAG, "Service Started"); createDirectory(); - - recorder = new AudioRecordThread(this); - recorder.start(); } @Override @@ -48,7 +45,10 @@ private void createDirectory() { @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent.getAction() != null) { - if (intent.getAction().equals("com.wearscript.record.SAVE_AUDIO")) { + if (intent.getAction().equals("com.wearscript.record.RECORD_AUDIO")) { + recorder = new AudioRecordThread(this, intent.getStringExtra("fileName")); + recorder.start(); + } else if (intent.getAction().equals("com.wearscript.record.SAVE_AUDIO")) { recorder.writeAudioDataToFile(); } else if (intent.getAction().equals("com.wearscript.record.STOP_AUDIO")) { recorder.stopRecording(); From 5b251eab5c21c10b61f5b12608ccfcf633aeac87 Mon Sep 17 00:00:00 2001 From: Blake Elias Date: Fri, 20 Jun 2014 16:36:01 -0400 Subject: [PATCH 20/20] Have AudioRecordThread accept filePath instead of fileName --- .../java/com/wearscript/record/AudioRecordThread.java | 8 ++++---- .../main/java/com/wearscript/record/AudioRecorder.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/video/src/main/java/com/wearscript/record/AudioRecordThread.java b/video/src/main/java/com/wearscript/record/AudioRecordThread.java index ce20901..6ae441d 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecordThread.java +++ b/video/src/main/java/com/wearscript/record/AudioRecordThread.java @@ -47,10 +47,10 @@ public class AudioRecordThread extends Thread { Context context; - public AudioRecordThread(Context context, String fileName) + public AudioRecordThread(Context context, String filePath) { this.context = context; - writeWavHeader(fileName); + writeWavHeader(filePath); } @Override @@ -112,11 +112,11 @@ private String audioFileName(String fileName) { return directoryAudio + File.separator + fileName + ".wav"; } - private void writeWavHeader(String fileName) { + private void writeWavHeader(String filePath) { byte header[] = new byte[WAV_HEADER_LENGTH]; try { - filePath = audioFileName(fileName); + this.filePath = filePath; os = new FileOutputStream(filePath); Log.d(LOG_TAG, "file path: " + filePath); } catch (FileNotFoundException e) { diff --git a/video/src/main/java/com/wearscript/record/AudioRecorder.java b/video/src/main/java/com/wearscript/record/AudioRecorder.java index 3ac7821..e2305a8 100644 --- a/video/src/main/java/com/wearscript/record/AudioRecorder.java +++ b/video/src/main/java/com/wearscript/record/AudioRecorder.java @@ -46,7 +46,7 @@ private void createDirectory() { public int onStartCommand(Intent intent, int flags, int startId) { if (intent.getAction() != null) { if (intent.getAction().equals("com.wearscript.record.RECORD_AUDIO")) { - recorder = new AudioRecordThread(this, intent.getStringExtra("fileName")); + recorder = new AudioRecordThread(this, intent.getStringExtra("filePath")); recorder.start(); } else if (intent.getAction().equals("com.wearscript.record.SAVE_AUDIO")) { recorder.writeAudioDataToFile();