-
Notifications
You must be signed in to change notification settings - Fork 0
Dev blake audio #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 10 commits
37b7351
245ceeb
e907031
d88b871
2e81246
1c6904d
300c2d0
7d6ac2a
a80722e
6060a41
d3bc49d
9b99698
bca7cf9
d7c07d2
a01f430
f8a0f44
9aef108
dad4016
440958f
5b251ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,201 @@ | ||
| 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; | ||
| 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; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix odd indentation |
||
| 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 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<byte[]> buffers; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix odd indentation |
||
| private byte[] totalBuffer; | ||
|
|
||
| Context context; | ||
|
|
||
| public AudioRecordThread(Context context) | ||
| { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. put open brace at the end of previous line. Please apply this convention throughout |
||
| this.context = context; | ||
| } | ||
|
|
||
| @Override | ||
| public void run() | ||
| { | ||
| Log.d(LOG_TAG, "Running Audio Thread"); | ||
|
|
||
| buffers = new ArrayList<byte[]>(); | ||
| int N = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,CHANNEL_TYPE,ENCODING_TYPE); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spaces after commas |
||
| Log.d(LOG_TAG, ""+N); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spaces around the + |
||
| try{ | ||
| recorder = new AudioRecord(AUDIO_SOURCE, RECORDER_SAMPLERATE, CHANNEL_TYPE, ENCODING_TYPE, N*10); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. too indented |
||
| } | ||
| catch(Throwable e){ | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. space after paren |
||
| Log.d(LOG_TAG, e.toString()); | ||
| return; | ||
| } | ||
| recorder.startRecording(); | ||
|
|
||
| try{ | ||
| while(!interrupted() && !pollingBuffer) | ||
| { | ||
| buffers.add(new byte[bufferSize]); | ||
| recorder.read(buffers.get(buffers.size()-1),0,bufferSize); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spaces after commas |
||
| } | ||
| mergeBuffers(); | ||
| writeAudioDataToFile(); | ||
| pollingBuffer = false; | ||
| Log.d(LOG_TAG, "Audio Saved"); | ||
| } | ||
| 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(); | ||
| 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; | ||
| } | ||
|
|
||
| private void mergeBuffers(){ | ||
| Log.d(LOG_TAG, "in mergeBuffers()"); | ||
| int i; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix indentation |
||
| int j; | ||
| int ix = 0; | ||
| totalBuffer = new byte[buffers.size() * bufferSize]; | ||
| for(i = 0; i<buffers.size(); i++){ | ||
| for(j = 0; j<bufferSize; j++){ | ||
| totalBuffer[ix] = buffers.get(i)[j]; | ||
| ix++; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private String audioFileName(long millis) { | ||
| return directoryAudio + File.separator + String.valueOf(millis) + ".wav"; | ||
| } | ||
|
|
||
| private void writeAudioDataToFile() { | ||
| int totalAudioLen = buffers.size() * bufferSize; | ||
| int totalDataLen = (totalAudioLen * NUM_CHANNELS * BITS_PER_SAMPLE / 8) + 36; | ||
| //String filePath = audioFileName(); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in a01f430 |
||
| byte header[] = new byte[WAV_HEADER_LENGTH]; | ||
| byte wavFile[] = new byte[totalAudioLen + header.length]; | ||
|
|
||
| FileOutputStream os = null; | ||
| try { | ||
| os = new FileOutputStream(latestFilePath); | ||
| Log.d(LOG_TAG, "file path: " + latestFilePath); | ||
| } catch (FileNotFoundException e) { | ||
| e.printStackTrace(); | ||
| } | ||
|
|
||
| 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) 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); | ||
| header[33] = 0; | ||
| header[34] = 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); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix indentation |
||
| System.arraycopy(totalBuffer, 0, wavFile, header.length, totalBuffer.length); | ||
|
|
||
| try { | ||
| os.write(wavFile, 0, wavFile.length); | ||
| } catch (IOException e) { | ||
| e.printStackTrace(); | ||
| } | ||
|
|
||
| try { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix indentation |
||
| os.close(); | ||
| } catch (IOException e) { | ||
| e.printStackTrace(); | ||
| } | ||
|
|
||
| Intent intent = new Intent("com.wearscript.record.FILE_WRITTEN_AUDIO").putExtra("filepath", latestFilePath); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. consider making "filepath" a static final variable at the top
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in d7c07d2 |
||
| context.sendBroadcast(intent); | ||
| Log.d(LOG_TAG, "Sending broadcast: com.wearscript.record.FILE_WRITTEN_AUDIO"); | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| package com.wearscript.record; | ||
|
|
||
| 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"; | ||
|
|
||
| @Override | ||
| public void onCreate() { | ||
| super.onCreate(); | ||
|
|
||
| Log.d(LOG_TAG, "Service Started"); | ||
| createDirectory(); | ||
|
|
||
| recorder = new AudioRecordThread(this); | ||
| recorder.start(); | ||
| } | ||
|
|
||
| @Override | ||
| public void onDestroy() { | ||
| Log.d(LOG_TAG, "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 createDirectory(){ | ||
| 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("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); | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. uh-oh, why doesn't this say com.wearscript.record?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 9b99698 |
||
|
|
||
| public class RecordActivity extends Activity implements SurfaceHolder.Callback { | ||
| private final static String TAG = "RecordActivity"; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a space after Thread