diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a307a61 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Built application files +/*/build/ + +# Crashlytics configuations +com_crashlytics_export_strings.xml + +# Local configuration file (sdk path, etc) +local.properties + +# Gradle generated files +.gradle/ + +# Signing files +.signing/ + +# User-specific configurations +.idea/libraries/ +.idea/workspace.xml +.idea/tasks.xml +.idea/.name +.idea/compiler.xml +.idea/copyright/profiles_settings.xml +.idea/encodings.xml +.idea/misc.xml +.idea/modules.xml +.idea/scopes/scope_settings.xml +.idea/vcs.xml +*.iml + +# OS-specific files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..36ff7ab --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..ddf3d67 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..3b31283 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..1588c87 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.2" + + defaultConfig { + applicationId "com.lixissimus.thedrummersapp" + minSdkVersion 21 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + testCompile 'junit:junit:4.12' + compile 'com.android.support:appcompat-v7:23.2.0' + compile 'com.google.android.gms:play-services-appindexing:8.1.0' +} diff --git a/app/libs/TarsosDSP-Android-latest.jar b/app/libs/TarsosDSP-Android-latest.jar new file mode 100644 index 0000000..6958bc3 Binary files /dev/null and b/app/libs/TarsosDSP-Android-latest.jar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..03cbe3d --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\Users\Felix\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/lixissimus/thedrummersapp/ApplicationTest.java b/app/src/androidTest/java/com/lixissimus/thedrummersapp/ApplicationTest.java new file mode 100644 index 0000000..38e1201 --- /dev/null +++ b/app/src/androidTest/java/com/lixissimus/thedrummersapp/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.lixissimus.thedrummersapp; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ff3ac4b --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/lixissimus/thedrummersapp/MainActivity.java b/app/src/main/java/com/lixissimus/thedrummersapp/MainActivity.java new file mode 100644 index 0000000..58760a4 --- /dev/null +++ b/app/src/main/java/com/lixissimus/thedrummersapp/MainActivity.java @@ -0,0 +1,194 @@ +package com.lixissimus.thedrummersapp; + +import android.media.AudioFormat; +import android.media.AudioRecord; +import android.media.MediaRecorder; +import android.net.Uri; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import com.google.android.gms.appindexing.Action; +import com.google.android.gms.appindexing.AppIndex; +import com.google.android.gms.common.api.GoogleApiClient; + +import be.tarsos.dsp.pitch.PitchDetectionResult; +import be.tarsos.dsp.pitch.Yin; + +public class MainActivity extends AppCompatActivity { + + private static final String TAG = "DrummersApp"; + + final int SAMPLING_RATE = 8000; + + private boolean recording = false; + /** + * ATTENTION: This was auto-generated to implement the App Indexing API. + * See https://g.co/AppIndexing/AndroidStudio for more information. + */ + private GoogleApiClient client; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + Button startButton = (Button) findViewById(R.id.startButton); + Button stopButton = (Button) findViewById(R.id.stopButton); + + startButton.setOnClickListener( + new Button.OnClickListener() { + public void onClick(View v) { + startRecording(); + } + } + ); + + stopButton.setOnClickListener( + new Button.OnClickListener() { + public void onClick(View v) { + stopRecording(); + } + } + ); + // ATTENTION: This was auto-generated to implement the App Indexing API. + // See https://g.co/AppIndexing/AndroidStudio for more information. + client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build(); + } + + private void startRecording() { + if (recording) { + return; + } + Log.i(TAG, "Start recording"); + recording = true; + + new Thread( + new Runnable() { + @Override + public void run() { + Log.i(TAG, "micThread started..."); + + final int CHANNEL = AudioFormat.CHANNEL_IN_MONO; + final int FORMAT = AudioFormat.ENCODING_PCM_16BIT; + final int BUFFER_SIZE = AudioRecord.getMinBufferSize( + SAMPLING_RATE, CHANNEL, FORMAT); + + short[] buffer = new short[BUFFER_SIZE]; + + Log.d(TAG, "Creating the AudioRecord"); + AudioRecord recorder = new AudioRecord( + MediaRecorder.AudioSource.MIC, + SAMPLING_RATE, + CHANNEL, + FORMAT, + BUFFER_SIZE * 10 + ); + + Log.d(TAG, "AudioRecord recording..."); + recorder.startRecording(); + + while (recording) { + int read = recorder.read(buffer, 0, buffer.length); + + onNewBufferRead(buffer, read); + + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + recorder.stop(); + recorder.release(); + } + } + ).start(); + } + + private void stopRecording() { + if (!recording) { + return; + } + Log.i(TAG, "Stop Recording"); + recording = false; + } + + private void onNewBufferRead(short[] buffer, int size) { + Yin pitchDetector = new Yin(SAMPLING_RATE, size); + + final PitchDetectionResult result = pitchDetector.getPitch(shortBufferToFloat(buffer)); + float freq = result.getPitch(); + final float roundedFreq = Math.round(freq * 10) / 10.0f; + + + if (freq < 0) { + return; + } + + final TextView textField = (TextView) findViewById(R.id.textViewFrequency); + + textField.post(new Runnable() { + @Override + public void run() { + textField.setText(String.format("%.1f", roundedFreq)); + } + }); + } + + private float[] shortBufferToFloat(short[] sBuffer) { + float[] fBuffer = new float[sBuffer.length]; + int i = 0; + for (short b : sBuffer) { + fBuffer[i] = ((float) b) / (float) Math.pow(2, 15); + i++; + } + + return fBuffer; + } + + @Override + public void onStart() { + super.onStart(); + + // ATTENTION: This was auto-generated to implement the App Indexing API. + // See https://g.co/AppIndexing/AndroidStudio for more information. + client.connect(); + Action viewAction = Action.newAction( + Action.TYPE_VIEW, // TODO: choose an action type. + "Main Page", // TODO: Define a title for the content shown. + // TODO: If you have web page content that matches this app activity's content, + // make sure this auto-generated web page URL is correct. + // Otherwise, set the URL to null. + Uri.parse("http://host/path"), + // TODO: Make sure this auto-generated app deep link URI is correct. + Uri.parse("android-app://com.lixissimus.thedrummersapp/http/host/path") + ); + AppIndex.AppIndexApi.start(client, viewAction); + } + + @Override + public void onStop() { + super.onStop(); + + // ATTENTION: This was auto-generated to implement the App Indexing API. + // See https://g.co/AppIndexing/AndroidStudio for more information. + Action viewAction = Action.newAction( + Action.TYPE_VIEW, // TODO: choose an action type. + "Main Page", // TODO: Define a title for the content shown. + // TODO: If you have web page content that matches this app activity's content, + // make sure this auto-generated web page URL is correct. + // Otherwise, set the URL to null. + Uri.parse(null), + // TODO: Make sure this auto-generated app deep link URI is correct. + Uri.parse("android-app://com.lixissimus.thedrummersapp/http/host/path") + ); + AppIndex.AppIndexApi.end(client, viewAction); + client.disconnect(); + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..6ac0730 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,56 @@ + + + + + +