├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── drawable-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_switch.jpg │ │ │ ├── drawable-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── drawable-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── values-sw600dp │ │ │ │ └── dimens.xml │ │ │ ├── values │ │ │ │ ├── dimens.xml │ │ │ │ ├── styles.xml │ │ │ │ └── strings.xml │ │ │ ├── values-sw720dp-land │ │ │ │ └── dimens.xml │ │ │ ├── values-v11 │ │ │ │ └── styles.xml │ │ │ ├── values-v14 │ │ │ │ └── styles.xml │ │ │ └── layout │ │ │ │ ├── main.xml │ │ │ │ ├── video_play.xml │ │ │ │ ├── audio_play.xml │ │ │ │ ├── audio_rec.xml │ │ │ │ └── video_rec.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── hwangjr │ │ │ │ └── recordhelper │ │ │ │ └── app │ │ │ │ ├── utils │ │ │ │ ├── NotificationUtils.java │ │ │ │ └── StorageUtils.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── SizeAdapter.java │ │ │ │ ├── VideoPlaybackActivity.java │ │ │ │ ├── AudioPlaybackActivity.java │ │ │ │ ├── AudioRecordingActivity.java │ │ │ │ └── VideoRecordingActivity.java │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── hwangjr │ │ │ └── recordhelper │ │ │ └── app │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── hwangjr │ │ └── recordhelper │ │ └── app │ │ └── ApplicationTest.java ├── proguard-rules.pro └── build.gradle ├── jhelper ├── .gitignore ├── docs │ ├── ProjectHome.md │ ├── Files.md │ ├── SimpleTextWriter.md │ ├── SimpleTextReader.md │ ├── Strings.md │ └── IOs.md ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── hwangjr │ │ │ └── jhelper │ │ │ ├── Filter.java │ │ │ ├── IterableLineReader.java │ │ │ ├── Dumper.java │ │ │ ├── MultiFileLineIterator.java │ │ │ ├── KeyValueReader.java │ │ │ ├── StringFilters.java │ │ │ ├── LineIterator.java │ │ │ └── Doubles.java │ └── test │ │ └── java │ │ └── com │ │ └── hwangjr │ │ └── jhelper │ │ ├── IOTest.java │ │ ├── TestSystems.java │ │ ├── TestUtil.java │ │ ├── CountingSetTest.java │ │ ├── KeyValueReaderTest.java │ │ ├── FilesTest.java │ │ ├── SimpleTextWriterTest.java │ │ └── SimpleTextReaderTest.java ├── build.gradle └── README.md ├── soundhelper ├── .gitignore ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── hwangjr │ │ └── soundhelper │ │ ├── dsp │ │ ├── DoubleVectorProcessor.java │ │ ├── Complex.java │ │ ├── DoubleVectorProcessingPipeline.java │ │ ├── MutableComplex.java │ │ ├── DoubleVector.java │ │ ├── WindowerFactory.java │ │ ├── NormalizedFrameIterator.java │ │ └── DoubleVectorFrameSource.java │ │ ├── pcm │ │ ├── PcmMonoOutputStream.java │ │ ├── WavAudioFormat.java │ │ ├── WavFileWriter.java │ │ ├── MonoWavFileReader.java │ │ ├── PcmAudioHelper.java │ │ ├── JavaAudioFormatBuilder.java │ │ ├── PcmAudioFormat.java │ │ ├── RiffHeaderData.java │ │ └── PcmMonoInputStream.java │ │ └── system │ │ └── WavPlayer.java │ └── test │ └── java │ └── com │ └── hwangjr │ └── soundhelper │ └── pcm │ ├── PcmAudioInputStreamTests.java │ ├── WavAuidoFormatTests.java │ ├── PcmAudioFormatTest.java │ └── IterableFrameReaderTest.java ├── recordhelper ├── .gitignore ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── hwangjr │ │ │ └── recordhelper │ │ │ ├── video │ │ │ ├── PlaybackHandler.java │ │ │ ├── VideoRecordingHandler.java │ │ │ ├── MediaPlayerManager.java │ │ │ ├── MediaRecorderManager.java │ │ │ ├── VideoRecordingManager.java │ │ │ ├── CameraManager.java │ │ │ ├── CameraHelper.java │ │ │ ├── AdaptiveSurfaceView.java │ │ │ └── VideoPlaybackManager.java │ │ │ ├── audio │ │ │ ├── AudioRecordingHandler.java │ │ │ ├── AudioPlaybackManager.java │ │ │ └── AudioRecordingThread.java │ │ │ ├── visualizer │ │ │ ├── AudioData.java │ │ │ ├── FFTData.java │ │ │ ├── renderer │ │ │ │ ├── BarGraphRenderer.java │ │ │ │ └── Renderer.java │ │ │ └── VisualizerView.java │ │ │ └── fft │ │ │ ├── Complex.java │ │ │ └── FFT.java │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── hwangjr │ │ │ └── recordhepler │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── hwangjr │ │ └── recordhepler │ │ └── ApplicationTest.java ├── build.gradle └── proguard-rules.pro ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── gradle.properties ├── gradlew.bat ├── gradlew └── README.md /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /jhelper/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /soundhelper/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /recordhelper/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':recordhelper', ':soundhelper', ':jhelper' 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndroidKnife/RecordHelper/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /jhelper/docs/ProjectHome.md: -------------------------------------------------------------------------------- 1 | Simple but useful Java helper library which contains classes for File, String, IO and text read-write operations. -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndroidKnife/RecordHelper/HEAD/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_switch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndroidKnife/RecordHelper/HEAD/app/src/main/res/drawable-hdpi/ic_switch.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndroidKnife/RecordHelper/HEAD/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /recordhelper/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndroidKnife/RecordHelper/HEAD/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /jhelper/src/main/java/com/hwangjr/jhelper/Filter.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.jhelper; 2 | 3 | interface Filter { 4 | boolean canPass(T t); 5 | } 6 | -------------------------------------------------------------------------------- /jhelper/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | dependencies { 4 | compile fileTree(dir: 'libs', include: ['*.jar']) 5 | 6 | // test 7 | testCompile 'junit:junit:4.12' 8 | } -------------------------------------------------------------------------------- /recordhelper/src/main/java/com/hwangjr/recordhelper/video/PlaybackHandler.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.video; 2 | 3 | public interface PlaybackHandler { 4 | public void onPreparePlayback(); 5 | } 6 | -------------------------------------------------------------------------------- /soundhelper/README.md: -------------------------------------------------------------------------------- 1 | SoundHelper 2 | ------ 3 | Clone from [simplesound](https://code.google.com/p/simplesound/source/browse/). 4 | 5 | # Introduction 6 | Simple raw-wav audio I/O and processing helper tool for java. -------------------------------------------------------------------------------- /soundhelper/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | dependencies { 4 | compile fileTree(dir: 'libs', include: ['*.jar']) 5 | compile project(':jhelper') 6 | 7 | // test 8 | testCompile 'junit:junit:4.12' 9 | } -------------------------------------------------------------------------------- /jhelper/README.md: -------------------------------------------------------------------------------- 1 | JHelper 2 | ------ 3 | Clone from [jcaki](https://code.google.com/p/jcaki/). 4 | 5 | # Introduction 6 | Simple but useful Java helper library which contains classes for File, String, IO and text read-write operations. -------------------------------------------------------------------------------- /app/src/main/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Oct 21 11:34:03 PDT 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip 7 | -------------------------------------------------------------------------------- /soundhelper/src/main/java/com/hwangjr/soundhelper/dsp/DoubleVectorProcessor.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.soundhelper.dsp; 2 | 3 | public interface DoubleVectorProcessor { 4 | 5 | DoubleVector process(DoubleVector input); 6 | 7 | void processInPlace(DoubleVector input); 8 | } 9 | -------------------------------------------------------------------------------- /soundhelper/src/test/java/com/hwangjr/soundhelper/pcm/PcmAudioInputStreamTests.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.soundhelper.pcm; 2 | 3 | import org.junit.Test; 4 | 5 | public class PcmAudioInputStreamTests { 6 | 7 | @Test 8 | public void testReadInt() { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/res/values-sw720dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 128dp 8 | 9 | 10 | -------------------------------------------------------------------------------- /recordhelper/src/main/java/com/hwangjr/recordhelper/video/VideoRecordingHandler.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.video; 2 | 3 | import android.hardware.Camera.Size; 4 | 5 | public interface VideoRecordingHandler { 6 | public boolean onPrepareRecording(); 7 | 8 | public Size getVideoSize(); 9 | 10 | public int getDisplayRotation(); 11 | } 12 | -------------------------------------------------------------------------------- /recordhelper/src/main/java/com/hwangjr/recordhelper/audio/AudioRecordingHandler.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.audio; 2 | 3 | public interface AudioRecordingHandler { 4 | public void onFftDataCapture(byte[] bytes); 5 | 6 | public void onRecordSuccess(); 7 | 8 | public void onRecordingError(); 9 | 10 | public void onRecordSaveError(); 11 | } 12 | -------------------------------------------------------------------------------- /soundhelper/src/main/java/com/hwangjr/soundhelper/dsp/Complex.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.soundhelper.dsp; 2 | 3 | public final class Complex { 4 | 5 | public final double real; 6 | public final double imaginary; 7 | 8 | public Complex(double real, double imaginary) { 9 | this.real = real; 10 | this.imaginary = imaginary; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/hwangjr/recordhelper/app/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.app; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /recordhelper/src/test/java/com/hwangjr/recordhepler/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhepler; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/hwangjr/recordhelper/app/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.app; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /recordhelper/src/androidTest/java/com/hwangjr/recordhepler/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhepler; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /recordhelper/src/main/java/com/hwangjr/recordhelper/visualizer/AudioData.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.visualizer; 2 | 3 | // Data class to explicitly indicate that these bytes are raw audio data 4 | public class AudioData { 5 | public AudioData() { 6 | } 7 | 8 | private byte[] bytes; 9 | 10 | public byte[] getBytes() { 11 | return bytes; 12 | } 13 | 14 | public void setBytes(byte[] bytes) { 15 | this.bytes = bytes; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /recordhelper/src/main/java/com/hwangjr/recordhelper/visualizer/FFTData.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.visualizer; 2 | 3 | // Data class to explicitly indicate that these bytes are the FFT of audio data 4 | public class FFTData { 5 | public FFTData() { 6 | } 7 | 8 | private byte[] bytes; 9 | 10 | public byte[] getBytes() { 11 | return bytes; 12 | } 13 | 14 | public void setBytes(byte[] bytes) { 15 | this.bytes = bytes; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/video_play.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | /*/build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | *.iml 30 | /.idea 31 | /.idea/workspace.xml 32 | /.idea/libraries 33 | .DS_Store 34 | /captures 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/audio_play.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /jhelper/src/test/java/com/hwangjr/jhelper/IOTest.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.jhelper; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | 6 | import java.io.FileOutputStream; 7 | import java.io.IOException; 8 | import java.net.URL; 9 | 10 | 11 | public class IOTest { 12 | 13 | @Ignore("Not a unit test") 14 | @Test 15 | public void readURI() throws IOException { 16 | URL url = new URL("http://www.google.com"); 17 | IOs.copy(url.openStream(), new FileOutputStream("blah.txt")); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /jhelper/src/test/java/com/hwangjr/jhelper/TestSystems.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.jhelper; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Map; 6 | 7 | public class TestSystems { 8 | 9 | @Test 10 | public void testHome() { 11 | System.out.println(Systems.getUserHome()); 12 | } 13 | 14 | public static void main(String[] args) { 15 | Map p = System.getenv(); 16 | for (String s : p.keySet()) { 17 | System.out.println(s + " : " + p.get(s)); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /jhelper/src/test/java/com/hwangjr/jhelper/TestUtil.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.jhelper; 2 | 3 | import java.util.Map; 4 | 5 | public class TestUtil { 6 | 7 | public static boolean containsAllKeys(Map map, T... keys) { 8 | for (T key : keys) { 9 | if (!map.containsKey(key)) return false; 10 | } 11 | return true; 12 | } 13 | 14 | public static boolean containsAllValues(Map map, V... values) { 15 | for (V value : values) { 16 | if (!map.containsValue(value)) return false; 17 | } 18 | return true; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /soundhelper/src/main/java/com/hwangjr/soundhelper/dsp/DoubleVectorProcessingPipeline.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.soundhelper.dsp; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | public class DoubleVectorProcessingPipeline { 7 | 8 | List processors; 9 | Iterator vectorSource; 10 | 11 | public DoubleVectorProcessingPipeline(Iterator vectorSource, 12 | List processors) { 13 | this.vectorSource = vectorSource; 14 | this.processors = processors; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /jhelper/src/test/java/com/hwangjr/jhelper/CountingSetTest.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.jhelper; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.Test; 6 | 7 | public class CountingSetTest { 8 | 9 | @Test 10 | public void testGenerate() { 11 | CountingSet histogram = new CountingSet(); 12 | histogram.add("Apple", "Pear", "Plum", "Apple", "Apple", "Grape", "Pear"); 13 | Assert.assertEquals(3, histogram.getCount("Apple")); 14 | Assert.assertEquals(2, histogram.getCount("Pear")); 15 | Assert.assertEquals(1, histogram.getCount("Plum")); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /recordhelper/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | minSdkVersion 9 9 | targetSdkVersion 23 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(dir: 'libs', include: ['*.jar']) 23 | compile project(':soundhelper') 24 | } 25 | -------------------------------------------------------------------------------- /soundhelper/src/main/java/com/hwangjr/soundhelper/dsp/MutableComplex.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.soundhelper.dsp; 2 | 3 | public class MutableComplex { 4 | public double real; 5 | public double imaginary; 6 | 7 | public MutableComplex(double real, double imaginary) { 8 | this.real = real; 9 | this.imaginary = imaginary; 10 | } 11 | 12 | public MutableComplex(Complex complex) { 13 | this.real = complex.real; 14 | this.imaginary = complex.imaginary; 15 | } 16 | 17 | public Complex getImmutableComplex() { 18 | return new Complex(real, imaginary); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/android-sdk-linux/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /recordhelper/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/android-sdk-linux/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /jhelper/src/test/java/com/hwangjr/jhelper/KeyValueReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.jhelper; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.Map; 9 | 10 | public class KeyValueReaderTest { 11 | 12 | @Test 13 | public void testReader() throws IOException { 14 | Map map = new KeyValueReader(":") 15 | .loadFromFile(new File("test/key-value-colon-separator.txt")); 16 | Assert.assertEquals(map.size(), 4); 17 | Assert.assertTrue(TestUtil.containsAllKeys(map, "1", "2", "3", "4")); 18 | Assert.assertTrue(TestUtil.containsAllValues(map, "bir", "iki", "uc", "dort")); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /soundhelper/src/main/java/com/hwangjr/soundhelper/dsp/DoubleVector.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.soundhelper.dsp; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * a vector containing a double numbers. 7 | */ 8 | public class DoubleVector { 9 | 10 | final double[] data; 11 | 12 | public DoubleVector(double[] data) { 13 | if (data == null) 14 | throw new IllegalArgumentException("Data cannot be null!"); 15 | this.data = data; 16 | } 17 | 18 | public int size() { 19 | return data.length; 20 | } 21 | 22 | public double[] getData() { 23 | return data; 24 | } 25 | 26 | 27 | @Override 28 | public String toString() { 29 | return Arrays.toString(data); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.hwangjr.recordhelper.app" 9 | minSdkVersion 9 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:23.1.1' 25 | compile project(':recordhelper') 26 | 27 | // test 28 | testCompile 'junit:junit:4.12' 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/hwangjr/recordhelper/app/utils/NotificationUtils.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.app.utils; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | import android.content.DialogInterface; 6 | import android.content.DialogInterface.OnClickListener; 7 | 8 | public class NotificationUtils { 9 | public static void showInfoDialog(Context ctx, String msg) { 10 | AlertDialog.Builder builder = new AlertDialog.Builder(ctx); 11 | builder.setMessage(msg); 12 | builder.setPositiveButton(ctx.getString(android.R.string.ok), new OnClickListener() { 13 | public void onClick(DialogInterface dialog, int arg1) { 14 | dialog.cancel(); 15 | } 16 | }); 17 | AlertDialog alert = builder.create(); 18 | alert.show(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/hwangjr/recordhelper/app/utils/StorageUtils.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.app.utils; 2 | 3 | import android.os.Environment; 4 | 5 | public class StorageUtils { 6 | private static final String AUDIO_FILE_NAME = "audiorecordtest.wav"; 7 | private static final String VIDEO_FILE_NAME = "videorecordtest.3gp"; 8 | 9 | public static boolean checkExternalStorageAvailable() { 10 | String state = Environment.getExternalStorageState(); 11 | if (Environment.MEDIA_MOUNTED.equals(state)) { 12 | return true; 13 | } 14 | else { 15 | return false; 16 | } 17 | } 18 | 19 | public static String getFileName(boolean isAudio) { 20 | String storageDir = Environment.getExternalStorageDirectory().getAbsolutePath(); 21 | return String.format("%s/%s", storageDir, (isAudio) ? AUDIO_FILE_NAME : VIDEO_FILE_NAME); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Android Recording 5 | Audio Recording 6 | Video Recording 7 | Playback 8 | 9 | 10 | @string/audioActivity 11 | @string/videoActivity 12 | 13 | 14 | Record 15 | Stop 16 | Play 17 | 18 | External storage is unavailable 19 | Error recording audio 20 | Error saving audio record 21 | Recording video failed 22 | 23 | -------------------------------------------------------------------------------- /jhelper/src/test/java/com/hwangjr/jhelper/FilesTest.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.jhelper; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | public class FilesTest { 12 | @Test 13 | public void MD5CalculationTest() throws IOException { 14 | assertEquals("873362e429c261e3596ad1d387ad152e", 15 | Bytes.toHex(Files.calculateMD5(new File("test/file_for_md5.txt")))); 16 | } 17 | 18 | @Ignore("Not a unit test") 19 | @Test 20 | public void fileAppendTest() throws IOException { 21 | Files.appendFiles(new File("apended.txt"), new File("test/file_for_md5.txt"), new File("test/multi_line_text_file.txt")); 22 | } 23 | 24 | @Ignore("Not a unit test") 25 | @Test 26 | public void testHexDump() throws IOException { 27 | Files.hexDump(new File("test/multi_line_text_file.txt"), -1); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /jhelper/docs/Files.md: -------------------------------------------------------------------------------- 1 | # Introduction # 2 | 3 | Files class has static methods for File related operations. 4 | 5 | # Details # 6 | 7 | ``` 8 | void deleteFiles(File... files) 9 | ``` 10 | deletes an arbitrary number of files. It only deletes files, not Directories. 11 | 12 | ``` 13 | void deleteFilesAndDirs(File... files) 14 | ``` 15 | Deletes all files and directories. 16 | 17 | ``` 18 | byte[] calculateMD5(File file) 19 | ``` 20 | Calculates MD5 value of a file. 21 | 22 | ``` 23 | void copy(File src, File dst) 24 | ``` 25 | Copies a file. 26 | 27 | ``` 28 | void copyDirectory(File srcDir, File dstDir) 29 | ``` 30 | copies content of a directory to another directory. if target directory does not exist, it creates target directory. 31 | 32 | ``` 33 | boolean contentEquals(File file1, File file2) 34 | ``` 35 | checks if two files content are exactly equal. 36 | 37 | ``` 38 | boolean containsUTF8Bom(File file) 39 | ``` 40 | checks if File contains UTF-8 BOM information. 41 | 42 | ``` 43 | void appendFiles(File target, File... filesToAppend) 44 | ``` 45 | appends several files to a file. if the target file does not exist, it creates it. if it exists, it appends the source files. 46 | 47 | ``` 48 | void hexDump(File f, long amount) 49 | ``` 50 | Usually used for debugging. it dumps a Files content as hex values to Console. 51 | 52 | ``` 53 | void hexDump(File f, File out, long amount) 54 | ``` 55 | same as above but values are saved to file this time. -------------------------------------------------------------------------------- /jhelper/src/main/java/com/hwangjr/jhelper/IterableLineReader.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.jhelper; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.Closeable; 5 | import java.io.Reader; 6 | import java.util.Iterator; 7 | 8 | /** 9 | * This class wraps a LineIterator. It is useful to use this in an enhanced for loop. 10 | */ 11 | public class IterableLineReader implements Iterable, Closeable { 12 | 13 | private final BufferedReader bufferedReader; 14 | private boolean trim; 15 | private Filter filters[] = new Filter[0]; 16 | 17 | public IterableLineReader(Reader reader) { 18 | if (reader instanceof BufferedReader) 19 | this.bufferedReader = (BufferedReader) reader; 20 | else 21 | this.bufferedReader = new BufferedReader(reader); 22 | 23 | } 24 | 25 | public IterableLineReader(Reader reader, boolean trim, Filter[] filters) { 26 | if (reader instanceof BufferedReader) 27 | this.bufferedReader = (BufferedReader) reader; 28 | else 29 | this.bufferedReader = new BufferedReader(reader); 30 | this.filters = filters; 31 | this.trim = trim; 32 | 33 | } 34 | 35 | public void close() { 36 | IOs.closeSilently(bufferedReader); 37 | } 38 | 39 | public Iterator iterator() { 40 | return new LineIterator(bufferedReader, trim, filters); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /soundhelper/src/main/java/com/hwangjr/soundhelper/pcm/PcmMonoOutputStream.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.soundhelper.pcm; 2 | 3 | import com.hwangjr.jhelper.Bytes; 4 | import com.hwangjr.jhelper.IOs; 5 | 6 | import java.io.Closeable; 7 | import java.io.DataOutputStream; 8 | import java.io.File; 9 | import java.io.FileOutputStream; 10 | import java.io.IOException; 11 | import java.io.OutputStream; 12 | 13 | public class PcmMonoOutputStream extends OutputStream implements Closeable { 14 | 15 | final PcmAudioFormat format; 16 | final DataOutputStream dos; 17 | 18 | public PcmMonoOutputStream(PcmAudioFormat format, DataOutputStream dos) { 19 | this.format = format; 20 | this.dos = dos; 21 | } 22 | 23 | public PcmMonoOutputStream(PcmAudioFormat format, File file) throws IOException { 24 | this.format = format; 25 | this.dos = new DataOutputStream(new FileOutputStream(file)); 26 | } 27 | 28 | public void write(int b) throws IOException { 29 | dos.write(b); 30 | } 31 | 32 | public void write(short[] shorts) throws IOException { 33 | dos.write(Bytes.toByteArray(shorts, shorts.length, format.isBigEndian())); 34 | } 35 | 36 | public void write(int[] ints) throws IOException { 37 | dos.write(Bytes.toByteArray(ints, ints.length, format.getBytePerSample(), format.isBigEndian())); 38 | } 39 | 40 | public void close() { 41 | IOs.closeSilently(dos); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/hwangjr/recordhelper/app/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.hwangjr.recordhelper.app; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.AdapterView; 8 | import android.widget.AdapterView.OnItemClickListener; 9 | import android.widget.ArrayAdapter; 10 | import android.widget.ListView; 11 | 12 | public class MainActivity extends Activity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.main); 18 | 19 | ListView list = (ListView) findViewById(android.R.id.list); 20 | ArrayAdapter listAdapter = new ArrayAdapter(getApplicationContext(), 21 | android.R.layout.simple_list_item_1, 22 | getResources().getStringArray(R.array.activities)); 23 | list.setAdapter(listAdapter); 24 | list.setOnItemClickListener(new OnItemClickListener() { 25 | @Override 26 | public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { 27 | launchDemo(arg2); 28 | } 29 | }); 30 | } 31 | 32 | private void launchDemo(int position) { 33 | switch (position) { 34 | case 0: default: { 35 | Intent i = new Intent(MainActivity.this, AudioRecordingActivity.class); 36 | startActivity(i); 37 | break; 38 | } 39 | case 1: { 40 | Intent i = new Intent(MainActivity.this, VideoRecordingActivity.class); 41 | startActivity(i); 42 | break; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/audio_rec.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 |