plectrum

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit a41db25305c71f518fcac730291efce2adbd5722
parent 16b9e1cd227217538ecea6bac0a01715d97306e1
Author: gstraube <gstraube@users.noreply.github.com>
Date:   Sun,  3 Feb 2019 15:50:38 +0100

Merge pull request #24 from TacoTheDank/master

Lots of changes
Diffstat:
M.gitignore | 37+++++--------------------------------
D.idea/gradle.xml | 19-------------------
D.idea/runConfigurations.xml | 13-------------
M.travis.yml | 22++++++++++++++--------
MREADME.md | 16+++++++++-------
Dapp/.gitignore | 1-
Mapp/build.gradle | 47++++++++++++++++++++++-------------------------
Dapp/proguard-rules.pro | 25-------------------------
Mapp/src/androidTest/java/com/github/cythara/TunerViewTest.java | 20+++++++-------------
Mapp/src/main/AndroidManifest.xml | 6++----
Mapp/src/main/java/be/tarsos/dsp/AudioEvent.java | 6+++---
Mapp/src/main/java/be/tarsos/dsp/AudioGenerator.java | 16++++++++--------
Mapp/src/main/java/be/tarsos/dsp/AutoCorrelation.java | 4++--
Mapp/src/main/java/be/tarsos/dsp/ConstantQ.java | 10++++++----
Mapp/src/main/java/be/tarsos/dsp/FadeOut.java | 6+++++-
Mapp/src/main/java/be/tarsos/dsp/SilenceDetector.java | 10+++++++---
Mapp/src/main/java/be/tarsos/dsp/SpectralPeakProcessor.java | 126++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mapp/src/main/java/be/tarsos/dsp/WaveformSimilarityBasedOverlapAdd.java | 15++++++++-------
Mapp/src/main/java/be/tarsos/dsp/beatroot/Agent.java | 16++++++++--------
Mapp/src/main/java/be/tarsos/dsp/beatroot/AgentList.java | 8++++----
Mapp/src/main/java/be/tarsos/dsp/beatroot/BeatRootOnsetEventHandler.java | 8++++----
Mapp/src/main/java/be/tarsos/dsp/io/PipeDecoder.java | 3++-
Mapp/src/main/java/be/tarsos/dsp/pitch/McLeodPitchMethod.java | 6+++---
Mapp/src/main/java/be/tarsos/dsp/resample/RateTransposer.java | 2++
Mapp/src/main/java/be/tarsos/dsp/util/AudioResourceUtils.java | 3++-
Mapp/src/main/java/be/tarsos/dsp/util/ConcurrencyUtils.java | 51++++++++++++++++++++++++++-------------------------
Mapp/src/main/java/be/tarsos/dsp/util/CubicSplineFast.java | 15++++++++-------
Mapp/src/main/java/be/tarsos/dsp/util/FFMPEGDownloader.java | 10+++++-----
Mapp/src/main/java/be/tarsos/dsp/util/PeakPicker.java | 26+++++++++++++++-----------
Mapp/src/main/java/be/tarsos/dsp/util/PitchConverter.java | 8++++----
Mapp/src/main/java/be/tarsos/dsp/util/fft/FFT.java | 2+-
Mapp/src/main/java/be/tarsos/dsp/wavelet/HaarWaveletDecoder.java | 2++
Mapp/src/main/java/be/tarsos/dsp/wavelet/HaarWaveletTransform.java | 5++++-
Mapp/src/main/java/be/tarsos/dsp/writer/WaveHeader.java | 7+++++--
Mapp/src/main/java/be/tarsos/dsp/writer/WriterProcessor.java | 1+
Mapp/src/main/java/com/github/cythara/CanvasPainter.java | 61+++++++++++++++++++++++++++++++------------------------------
Mapp/src/main/java/com/github/cythara/ListenerFragment.java | 31+++++++++++++------------------
Mapp/src/main/java/com/github/cythara/MainActivity.java | 45++++++++++++++++++++++++---------------------
Mapp/src/main/java/com/github/cythara/Note.java | 3+++
Mapp/src/main/java/com/github/cythara/NumberPickerDialog.java | 10+++++++---
Mapp/src/main/java/com/github/cythara/PitchDifference.java | 24+++++++++++-------------
Mapp/src/main/java/com/github/cythara/Sampler.java | 4++--
Mapp/src/main/java/com/github/cythara/tuning/BassTuning.java | 25+++++++++++++------------
Mapp/src/main/java/com/github/cythara/tuning/CelloTuning.java | 12+++++-------
Mapp/src/main/java/com/github/cythara/tuning/ChromaticTuning.java | 22+++++++++++-----------
Mapp/src/main/java/com/github/cythara/tuning/DropCGuitarTuning.java | 25+++++++++++++------------
Mapp/src/main/java/com/github/cythara/tuning/DropCSharpGuitarTuning.java | 25+++++++++++++------------
Mapp/src/main/java/com/github/cythara/tuning/DropDGuitarTuning.java | 25+++++++++++++------------
Mapp/src/main/java/com/github/cythara/tuning/GuitarTuning.java | 25+++++++++++++------------
Mapp/src/main/java/com/github/cythara/tuning/OpenGGuitarTuning.java | 25+++++++++++++------------
Mapp/src/main/java/com/github/cythara/tuning/UkuleleDTuning.java | 24++++++++++++------------
Mapp/src/main/java/com/github/cythara/tuning/UkuleleTuning.java | 22+++++++++++-----------
Mapp/src/main/java/com/github/cythara/tuning/ViolinTuning.java | 25+++++++++++++------------
Mapp/src/main/res/drawable-nodpi/ic_line_style_icons_mic.xml | 16++++++++--------
Mapp/src/main/res/drawable-nodpi/ic_line_style_icons_mic_active.xml | 16++++++++--------
Mapp/src/main/res/drawable/ic_logo.xml | 233+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Mapp/src/main/res/layout/activity_main.xml | 7+++----
Mapp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml | 7+++----
Mapp/src/main/res/values-de-rDE/strings.xml | 10++++++++--
Mapp/src/main/res/values-eu/strings.xml | 6++++--
Mapp/src/main/res/values-pt-rBR/strings.xml | 61+++++++++++++++++++++++++++++++++----------------------------
Mapp/src/main/res/values/strings.xml | 12++++++++++--
Mapp/src/main/res/values/styles.xml | 2+-
Mapp/src/test/java/com/github/cythara/PitchComparatorTest.java | 8++------
Mapp/src/test/java/com/github/cythara/SamplerTest.java | 3+--
Mbuild.gradle | 7+++----
Mfastlane/Fastfile | 14+++++++-------
Mgradle.properties | 2++
Mgradle/wrapper/gradle-wrapper.jar | 0
Mgradle/wrapper/gradle-wrapper.properties | 2+-
Mgradlew | 2+-
Mgradlew.bat | 2+-
72 files changed, 749 insertions(+), 666 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -20,8 +20,6 @@ out/ # Gradle files .gradle -.gradle/ -build/ # Signing files .signing/ @@ -36,13 +34,10 @@ proguard/ *.log # Android Studio -/*/build/ -/*/local.properties -/*/out -/*/*/build -/*/*/production -captures/ -.navigation/ +build +production +captures +.navigation *.ipr *~ *.swp @@ -59,29 +54,9 @@ obj/ # IntelliJ IDEA *.iml *.iws -/out/ # User-specific configurations -.idea/caches/ -.idea/libraries/ -.idea/shelf/ -.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/dictionaries -.idea/vcs.xml -.idea/jsLibraryMappings.xml -.idea/datasources.xml -.idea/dataSources.ids -.idea/sqlDataSources.xml -.idea/dynamic.xml -.idea/uiDesigner.xml +.idea/ # OS-specific files .DS_Store @@ -99,6 +74,4 @@ Thumbs.db ### AndroidStudio Patch ### -!/gradle/wrapper/gradle-wrapper.jar - # End of https://www.gitignore.io/api/androidstudio diff --git a/.idea/gradle.xml b/.idea/gradle.xml @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="GradleSettings"> - <option name="linkedExternalProjectsSettings"> - <GradleProjectSettings> - <option name="distributionType" value="DEFAULT_WRAPPED" /> - <option name="externalProjectPath" value="$PROJECT_DIR$" /> - <option name="modules"> - <set> - <option value="$PROJECT_DIR$" /> - <option value="$PROJECT_DIR$/app" /> - </set> - </option> - <option name="resolveModulePerSourceSet" value="false" /> - </GradleProjectSettings> - </option> - </component> -</project> -\ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="RunConfigurationProducerService"> - <option name="ignoredProducers"> - <set> - <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" /> - <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" /> - <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" /> - </set> - </option> - </component> -</project> -\ No newline at end of file diff --git a/.travis.yml b/.travis.yml @@ -1,21 +1,27 @@ language: android + jdk: oraclejdk8 + android: components: - tools - platform-tools - tools - - build-tools-28.0.2 + - build-tools-28.0.3 - android-28 - extra-android-support + + licenses: + - 'android-sdk-license-.+' + - 'android-sdk-preview-license-.+' + - '.+' + before_install: - mkdir "$ANDROID_HOME/licenses" || true - echo -e "8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e" > "$ANDROID_HOME/licenses/android-sdk-license" - echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license" -script: ./gradlew test -licenses: - - android-sdk-license-.+ - - android-sdk-preview-license-.+ - - '.+' -+notifications: -+ email: false + +script: ./gradlew build + +notifications: + email: false diff --git a/README.md b/README.md @@ -1,11 +1,11 @@ [![Build Status](https://travis-ci.org/gstraube/cythara.svg?branch=master)](https://travis-ci.org/gstraube/cythara) # Cythara -A musical instrument tuner for Android +A musical instrument tuner for Android. -[<img src="https://f-droid.org/badge/get-it-on.png" +[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" - height="80">](https://f-droid.org/app/com.github.cythara) + height="80">](https://f-droid.org/packages/com.github.cythara/) [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" alt="Get it on Google Play" height="80">](https://play.google.com/store/apps/details?id=com.github.cythara) @@ -27,19 +27,21 @@ can be run using `./gradlew connectedCheck`. The reference images are generated The Tarsos DSP library (https://github.com/JorenSix/TarsosDSP) is used for pitch detection. +Current library version: commit [c26e500](https://github.com/JorenSix/TarsosDSP/tree/c26e5004e203ee79be1ec25c2603b1f11b69d276) + ## License -Cythara is licensed under the GPL, version 3. A copy of the license is included in LICENSE.txt. +Cythara is licensed under GPLv3. A copy of the license is included in LICENSE.txt. # Contributors In chronological order: -* [mtbu](https://github.com/mtbu) added the violing tuning +* [mtbu](https://github.com/mtbu) added the violin tuning * [afmachado](https://github.com/afmachado) provided the translation to Brazilian Portuguese * [tebriz159](https://github.com/tebriz159) created the logo * [toXel](https://github.com/toXel) provided the translation to German -* [TacoTheDank](https://github.com/TacoTheDank) enabled the installation on external storage, upgraded the language level and updated dependencies -* [thim](https://github.com/thim) added the cello tuning, fixed issues and updated library versions +* [TacoTheDank](https://github.com/TacoTheDank) enabled the installation on external storage, upgraded the language level, and updated dependencies +* [thim](https://github.com/thim) added the cello tuning, fixed issues, and updated library versions * [obibon](https://github.com/obibon) provided the translation to Basque Thank you all! diff --git a/app/.gitignore b/app/.gitignore @@ -1 +0,0 @@ -/build diff --git a/app/build.gradle b/app/build.gradle @@ -1,17 +1,17 @@ apply plugin: 'com.android.application' -apply plugin: 'findbugs' - android { compileSdkVersion 28 buildToolsVersion '28.0.3' + defaultConfig { applicationId "com.github.cythara" minSdkVersion 15 targetSdkVersion 28 versionCode 20 versionName "2.9" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -26,35 +26,32 @@ android { } compileOptions { + encoding = 'UTF-8' sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } packagingOptions { - exclude 'META-INF/proguard/androidx-annotations.pro' + exclude 'META-INF/*' } } dependencies { - androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - - androidTestImplementation('com.android.support.test:runner:1.0.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - - androidTestImplementation('com.android.support.test:rules:1.0.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.jaredrummler:material-spinner:1.3.0' - implementation 'com.shawnlin:number-picker:2.4.6' - - testImplementation 'junit:junit:4.12' - testImplementation 'org.hamcrest:hamcrest-all:1.3' - testImplementation 'org.robolectric:robolectric:3.8' - testImplementation 'org.powermock:powermock-api-mockito2:1.7.4' - testImplementation 'org.powermock:powermock-module-junit4:1.7.4' + // Support libraries + implementation 'androidx.annotation:annotation:1.1.0-alpha01' + implementation 'androidx.appcompat:appcompat:1.1.0-alpha01' + implementation 'androidx.core:core:1.1.0-alpha04' + implementation 'androidx.fragment:fragment:1.1.0-alpha03' + + // Other + implementation 'com.jaredrummler:material-spinner:1.3.1' + implementation 'com.shawnlin:number-picker:2.4.7' + + // Testing libraries + testImplementation 'junit:junit:4.13-beta-1' + testImplementation 'org.hamcrest:hamcrest:2.1' + testImplementation 'org.powermock:powermock-api-mockito2:2.0.0' + testImplementation 'org.powermock:powermock-module-junit4:2.0.0' + androidTestImplementation 'androidx.test:rules:1.1.2-alpha01' + androidTestImplementation 'androidx.test:runner:1.1.2-alpha01' } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro @@ -1,25 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /home/gst/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 *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/app/src/androidTest/java/com/github/cythara/TunerViewTest.java b/app/src/androidTest/java/com/github/cythara/TunerViewTest.java @@ -5,9 +5,6 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.os.Environment; -import android.support.test.rule.ActivityTestRule; -import android.support.test.rule.GrantPermissionRule; -import android.support.test.runner.AndroidJUnit4; import org.junit.Assert; import org.junit.Rule; @@ -21,7 +18,11 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; -import static android.support.test.rule.GrantPermissionRule.grant; +import androidx.test.rule.ActivityTestRule; +import androidx.test.rule.GrantPermissionRule; +import androidx.test.runner.AndroidJUnit4; + +import static androidx.test.rule.GrantPermissionRule.grant; import static com.github.cythara.tuning.GuitarTuning.Pitch.*; import static java.lang.String.format; @@ -134,16 +135,10 @@ public class TunerViewTest { private void writeToFile(Bitmap bitmap, String name) throws IOException { File sdCard = Environment.getExternalStorageDirectory(); - FileOutputStream out = null; - try { - out = new FileOutputStream(sdCard.getAbsolutePath() + "/" + name); + try (FileOutputStream out = new FileOutputStream(sdCard.getAbsolutePath() + "/" + name)) { bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); } catch (FileNotFoundException e) { e.printStackTrace(); - } finally { - if (out != null) { - out.close(); - } } } @@ -156,4 +151,4 @@ public class TunerViewTest { this.name = name; } } -} -\ No newline at end of file +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml @@ -8,9 +8,9 @@ <application android:allowBackup="false" android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:label="@string/app_name" android:theme="@style/Theme.AppCompat.Light.NoActionBar"> <activity android:name=".MainActivity"> <intent-filter> @@ -19,5 +19,4 @@ </intent-filter> </activity> </application> - -</manifest> -\ No newline at end of file +</manifest> diff --git a/app/src/main/java/be/tarsos/dsp/AudioEvent.java b/app/src/main/java/be/tarsos/dsp/AudioEvent.java @@ -184,10 +184,10 @@ public class AudioEvent { */ public static double calculateRMS(float[] floatBuffer){ double rms = 0.0; - for (float aFloatBuffer : floatBuffer) { - rms += aFloatBuffer * aFloatBuffer; + for (int i = 0; i < floatBuffer.length; i++) { + rms += floatBuffer[i] * floatBuffer[i]; } - rms = rms / (double) floatBuffer.length; + rms = rms / Double.valueOf(floatBuffer.length); rms = Math.sqrt(rms); return rms; } diff --git a/app/src/main/java/be/tarsos/dsp/AudioGenerator.java b/app/src/main/java/be/tarsos/dsp/AudioGenerator.java @@ -99,8 +99,8 @@ public class AudioGenerator implements Runnable { } public AudioGenerator(final int audioBufferSize, final int bufferOverlap,final int samplerate){ - - audioProcessors = new CopyOnWriteArrayList<>(); + + audioProcessors = new CopyOnWriteArrayList<AudioProcessor>(); format = getTargetAudioFormat(samplerate); @@ -126,12 +126,12 @@ public class AudioGenerator implements Runnable { * @return The audio format after conversion. */ private TarsosDSPAudioFormat getTargetAudioFormat(int targetSampleRate) { - TarsosDSPAudioFormat audioFormat = new TarsosDSPAudioFormat(TarsosDSPAudioFormat.Encoding.PCM_SIGNED, - targetSampleRate, - 2 * 8, - 1, - 2, - targetSampleRate, + TarsosDSPAudioFormat audioFormat = new TarsosDSPAudioFormat(TarsosDSPAudioFormat.Encoding.PCM_SIGNED, + targetSampleRate, + 2 * 8, + 1, + 2 * 1, + targetSampleRate, ByteOrder.BIG_ENDIAN.equals(ByteOrder.nativeOrder())); return audioFormat; } diff --git a/app/src/main/java/be/tarsos/dsp/AutoCorrelation.java b/app/src/main/java/be/tarsos/dsp/AutoCorrelation.java @@ -36,8 +36,8 @@ public class AutoCorrelation implements AudioProcessor { result = 0; - for (float anAudioFloatbuffer : audioFloatbuffer) { - result += Math.abs(anAudioFloatbuffer) / (float) audioFloatbuffer.length; + for (int i=0; i<audioFloatbuffer.length; i++){ + result += ((float)Math.abs(audioFloatbuffer[i]))/(float)audioFloatbuffer.length; } return true; } diff --git a/app/src/main/java/be/tarsos/dsp/ConstantQ.java b/app/src/main/java/be/tarsos/dsp/ConstantQ.java @@ -214,8 +214,8 @@ public class ConstantQ implements AudioProcessor { int len = (int)Math.min(Math.ceil( q * sampleRate / frequencies[i]), fftLength); for (int j = 0; j < len; j++) { - - double window = -.5 * Math.cos(2. * Math.PI * (double) j / (double) len) + .5;// Hanning Window + + double window = -.5*Math.cos(2.*Math.PI*(double)j/(double)len)+.5;; // Hanning Window // double window = -.46*Math.cos(2.*Math.PI*(double)j/(double)len)+.54; // Hamming Window window /= len; @@ -252,8 +252,10 @@ public class ConstantQ implements AudioProcessor { sKernel = new float[k * 2]; int[] indexes = new int[k]; - System.arraycopy(cKernel, 0, sKernel, 0, k * 2); - System.arraycopy(cindexes, 0, indexes, 0, k); + for (int j = 0; j < k * 2; j++) + sKernel[j] = cKernel[j]; + for (int j = 0; j < k; j++) + indexes[j] = cindexes[j]; // Normalize fft output for (int j = 0; j < sKernel.length; j++) diff --git a/app/src/main/java/be/tarsos/dsp/FadeOut.java b/app/src/main/java/be/tarsos/dsp/FadeOut.java @@ -1,5 +1,9 @@ package be.tarsos.dsp; +import be.tarsos.dsp.AudioEvent; +import be.tarsos.dsp.AudioProcessor; +import be.tarsos.dsp.GainProcessor; + public class FadeOut implements AudioProcessor { // VARIABLES @@ -27,7 +31,7 @@ public class FadeOut implements AudioProcessor public boolean process(AudioEvent audioEvent) { // Don't do anything before the beginning of Fade Out - if (isFadeOut) + if(isFadeOut==true) { if(firstTime==-1) firstTime=audioEvent.getTimeStamp(); diff --git a/app/src/main/java/be/tarsos/dsp/SilenceDetector.java b/app/src/main/java/be/tarsos/dsp/SilenceDetector.java @@ -124,9 +124,13 @@ public class SilenceDetector implements AudioProcessor { public boolean process(AudioEvent audioEvent) { boolean isSilence = isSilence(audioEvent.getFloatBuffer()); //break processing chain on silence? - //break if silent - return !breakProcessingQueueOnSilence || !isSilence; -//never break the chain + if(breakProcessingQueueOnSilence){ + //break if silent + return !isSilence; + }else{ + //never break the chain + return true; + } } diff --git a/app/src/main/java/be/tarsos/dsp/SpectralPeakProcessor.java b/app/src/main/java/be/tarsos/dsp/SpectralPeakProcessor.java @@ -124,11 +124,11 @@ public class SpectralPeakProcessor implements AudioProcessor { frequencyEstimates = new float[bufferSize / 2]; dt = (bufferSize - overlap) / (double) sampleRate; - cbin = dt * sampleRate / (double) bufferSize; + cbin = (double) (dt * sampleRate / (double) bufferSize); - inv_2pi = 1.0 / (2.0 * Math.PI); - inv_deltat = 1.0 / dt; - inv_2pideltat = inv_deltat * inv_2pi; + inv_2pi = (double) (1.0 / (2.0 * Math.PI)); + inv_deltat = (double) (1.0 / dt); + inv_2pideltat = (double) (inv_deltat * inv_2pi); this.sampleRate = sampleRate; @@ -140,49 +140,18 @@ public class SpectralPeakProcessor implements AudioProcessor { // Extract the power and phase data fft.powerPhaseFFT(fftData, magnitudes, currentPhaseOffsets); } - - /** - * Calculate a noise floor for an array of magnitudes. - * - * @param magnitudes The magnitudes of the current frame. - * @param medianFilterLength The length of the median filter used to determine the noise floor. - * @param noiseFloorFactor The noise floor is multiplied with this factor to determine if the - * information is either noise or an interesting spectral peak. - * @return a float array representing the noise floor. - */ - public static float[] calculateNoiseFloor(float[] magnitudes, int medianFilterLength, float noiseFloorFactor) { - double[] noiseFloorBuffer; - float[] noisefloor = new float[magnitudes.length]; - - float median = (float) median(magnitudes.clone()); - - // Naive median filter implementation. - // For each element take a median of surrounding values (noiseFloorBuffer) - // Store the median as the noise floor. - for (int i = 0; i < magnitudes.length; i++) { - noiseFloorBuffer = new double[medianFilterLength]; - int index = 0; - for (int j = i - medianFilterLength / 2; j <= i + medianFilterLength / 2 && index < noiseFloorBuffer.length; j++) { - if (j >= 0 && j < magnitudes.length) { - noiseFloorBuffer[index] = magnitudes[j]; - } else { - noiseFloorBuffer[index] = median; - } - index++; - } - // calculate the noise floor value. - noisefloor[i] = median(noiseFloorBuffer) * (noiseFloorFactor); - } - - float rampLength = 12.0f; - for (int i = 0; i <= rampLength; i++) { - //ramp - float ramp = 1.0f; - ramp = (float) (-1 * (Math.log(i / rampLength))) + 1.0f; - noisefloor[i] = ramp * noisefloor[i]; - } - - return noisefloor; + + private void normalizeMagintudes(){ + float maxMagnitude = (float) -1e6; + for(int i = 0;i<magnitudes.length;i++){ + maxMagnitude = Math.max(maxMagnitude, magnitudes[i]); + } + + //log10 of the normalized value + //adding 75 makes sure the value is above zero, a bit ugly though... + for(int i = 1;i<magnitudes.length;i++){ + magnitudes[i] = (float) (10 * Math.log10(magnitudes[i]/maxMagnitude)) + 75; + } } @Override @@ -254,21 +223,51 @@ public class SpectralPeakProcessor implements AudioProcessor { frequencyInHertz = (float) (inv_2pideltat * phaseDelta + inv_deltat * k); } else { frequencyInHertz = (float) fft.binToHz(binIndex, sampleRate); - } - return frequencyInHertz; - } - - private void normalizeMagintudes() { - float maxMagnitude = (float) -1e6; - for (float magnitude : magnitudes) { - maxMagnitude = Math.max(maxMagnitude, magnitude); - } - - //log10 of the normalized value - //adding 75 makes sure the value is above zero, a bit ugly though... - for (int i = 1; i < magnitudes.length; i++) { - magnitudes[i] = (float) (10 * Math.log10(magnitudes[i]/maxMagnitude)) + 75; } + return frequencyInHertz; + } + + /** + * Calculate a noise floor for an array of magnitudes. + * @param magnitudes The magnitudes of the current frame. + * @param medianFilterLength The length of the median filter used to determine the noise floor. + * @param noiseFloorFactor The noise floor is multiplied with this factor to determine if the + * information is either noise or an interesting spectral peak. + * @return a float array representing the noise floor. + */ + public static float[] calculateNoiseFloor(float[] magnitudes, int medianFilterLength, float noiseFloorFactor) { + double[] noiseFloorBuffer; + float[] noisefloor = new float[magnitudes.length]; + + float median = (float) median(magnitudes.clone()); + + // Naive median filter implementation. + // For each element take a median of surrounding values (noiseFloorBuffer) + // Store the median as the noise floor. + for (int i = 0; i < magnitudes.length; i++) { + noiseFloorBuffer = new double[medianFilterLength]; + int index = 0; + for (int j = i - medianFilterLength/2; j <= i + medianFilterLength/2 && index < noiseFloorBuffer.length; j++) { + if(j >= 0 && j < magnitudes.length){ + noiseFloorBuffer[index] = magnitudes[j]; + } else{ + noiseFloorBuffer[index] = median; + } + index++; + } + // calculate the noise floor value. + noisefloor[i] = (float) (median(noiseFloorBuffer) * (noiseFloorFactor)) ; + } + + float rampLength = 12.0f; + for(int i = 0 ; i <= rampLength ; i++){ + //ramp + float ramp = 1.0f; + ramp = (float) (-1 * (Math.log(i/rampLength))) + 1.0f; + noisefloor[i] = ramp * noisefloor[i]; + } + + return noisefloor; } /** @@ -420,7 +419,8 @@ public class SpectralPeakProcessor implements AudioProcessor { return (m[middle-1] + m[middle]) / 2.0; } } - + + public static class SpectralPeak{ private final float frequencyInHertz; private final float magnitude; @@ -473,4 +473,6 @@ public class SpectralPeakProcessor implements AudioProcessor { return bin; } } + + } diff --git a/app/src/main/java/be/tarsos/dsp/WaveformSimilarityBasedOverlapAdd.java b/app/src/main/java/be/tarsos/dsp/WaveformSimilarityBasedOverlapAdd.java @@ -136,10 +136,10 @@ public class WaveformSimilarityBasedOverlapAdd implements AudioProcessor { * @param output The output buffer. * @param input The input buffer. */ - private void overlap(final float[] output, float[] input, int inputOffset) { + private void overlap(final float[] output, int outputOffset, float[] input,int inputOffset){ for(int i = 0 ; i < overlapLength ; i++){ int itemp = overlapLength - i; - output[i + 0] = (input[i + inputOffset] * i + pMidBuffer[i] * itemp) / overlapLength; + output[i + outputOffset] = (input[i + inputOffset] * i + pMidBuffer[i] * itemp ) / overlapLength; } } @@ -152,9 +152,10 @@ public class WaveformSimilarityBasedOverlapAdd implements AudioProcessor { * cross-correlation value over the overlapping period * * @param inputBuffer The input buffer + * @param postion The position where to start the seek operation, in the input buffer. * @return The best position. */ - private int seekBestOverlapPosition(float[] inputBuffer) { + private int seekBestOverlapPosition(float[] inputBuffer, int postion) { int bestOffset; double bestCorrelation, currentCorrelation; int tempOffset; @@ -172,12 +173,12 @@ public class WaveformSimilarityBasedOverlapAdd implements AudioProcessor { // over the permitted range. for (tempOffset = 0; tempOffset < seekLength; tempOffset++) { - comparePosition = tempOffset; + comparePosition = postion + tempOffset; // Calculates correlation value for the mixing position // corresponding // to 'tempOffset' - currentCorrelation = calcCrossCorr(pRefMidBuffer, inputBuffer, comparePosition); + currentCorrelation = (double) calcCrossCorr(pRefMidBuffer, inputBuffer,comparePosition); // heuristic rule to slightly favor values close to mid of the // range double tmp = (double) (2 * tempOffset - seekLength) / seekLength; @@ -228,13 +229,13 @@ public class WaveformSimilarityBasedOverlapAdd implements AudioProcessor { assert audioFloatBuffer.length == getInputBufferSize(); //Search for the best overlapping position. - int offset = seekBestOverlapPosition(audioFloatBuffer); + int offset = seekBestOverlapPosition(audioFloatBuffer,0); // Mix the samples in the 'inputBuffer' at position of 'offset' with the // samples in 'midBuffer' using sliding overlapping // ... first partially overlap with the end of the previous sequence // (that's in 'midBuffer') - overlap(outputFloatBuffer, audioFloatBuffer, offset); + overlap(outputFloatBuffer,0,audioFloatBuffer,offset); //copy sequence samples from input to output int sequenceLength = seekWindowLength - 2 * overlapLength; diff --git a/app/src/main/java/be/tarsos/dsp/beatroot/Agent.java b/app/src/main/java/be/tarsos/dsp/beatroot/Agent.java @@ -61,18 +61,18 @@ public class Agent { /** The maximum amount by which a beat can be earlier than the predicted beat time, * expressed as a fraction of the beat period. */ public static double PRE_MARGIN_FACTOR = 0.15; - - /** The default value of innerMargin, which is the maximum time (in seconds) that a + + /** The default value of innerMargin, which is the maximum time (in seconds) that a * beat can deviate from the predicted beat time without a fork occurring. */ public static final double INNER_MARGIN = 0.040; - - /** The maximum allowed deviation from the initial tempo, expressed as a fraction of the initial beat period. */ + + /** The maximum allowed deviation from the initial tempo, expressed as a fraction of the initial beat period. */ public static double MAX_CHANGE = 0.2; - - /** The slope of the penalty function for onsets which do not coincide precisely with predicted beat times. */ + + /** The slope of the penalty function for onsets which do not coincide precisely with predicted beat times. */ public static double CONF_FACTOR = 0.5; - - /** The reactiveness/inertia balance, i.e. degree of change in the tempo, is controlled by the correctionFactor + + /** The reactiveness/inertia balance, i.e. degree of change in the tempo, is controlled by the correctionFactor * variable. This constant defines its default value, which currently is not subsequently changed. The * beat period is updated by the reciprocal of the correctionFactor multiplied by the difference between the * predicted beat time and matching onset. */ diff --git a/app/src/main/java/be/tarsos/dsp/beatroot/AgentList.java b/app/src/main/java/be/tarsos/dsp/beatroot/AgentList.java @@ -53,11 +53,11 @@ public class AgentList { /** Flag for choice between sum and average beat salience values for Agent scores. * The use of summed saliences favours faster tempi or lower metrical levels. */ public static boolean useAverageSalience = false; - - /** Flag for printing debugging output. */ + + /** Flag for printing debugging output. */ public static boolean debug = false; - - /** For the purpose of removing duplicate agents, the default JND of IBI */ + + /** For the purpose of removing duplicate agents, the default JND of IBI */ public static final double DEFAULT_BI = 0.02; /** For the purpose of removing duplicate agents, the default JND of phase */ diff --git a/app/src/main/java/be/tarsos/dsp/beatroot/BeatRootOnsetEventHandler.java b/app/src/main/java/be/tarsos/dsp/beatroot/BeatRootOnsetEventHandler.java @@ -47,9 +47,9 @@ public class BeatRootOnsetEventHandler implements OnsetHandler { e.salience = salience; onsetList.add(e); } - - - /** + + + /** * Creates a new Event object representing an onset or beat. * * @param time @@ -70,7 +70,7 @@ public class BeatRootOnsetEventHandler implements OnsetHandler { * the beat is not calculated: -1 is returned. */ public void trackBeats(OnsetHandler beatHandler){ - AgentList agents = null; + AgentList agents = null; // tempo not given; use tempo induction agents = Induction.beatInduction(onsetList); agents.beatTrack(onsetList, -1); diff --git a/app/src/main/java/be/tarsos/dsp/io/PipeDecoder.java b/app/src/main/java/be/tarsos/dsp/io/PipeDecoder.java @@ -210,7 +210,8 @@ public class PipeDecoder { public double getDuration(final String resource) { double duration = -1; try { - String command = "ffmpeg -i '%resource%'"; + //use " for windows compatibility! + String command = "ffmpeg -i \"%resource%\""; command = command.replace("%resource%", resource); diff --git a/app/src/main/java/be/tarsos/dsp/pitch/McLeodPitchMethod.java b/app/src/main/java/be/tarsos/dsp/pitch/McLeodPitchMethod.java @@ -33,7 +33,7 @@ import java.util.List; * <p> * Implementation of The McLeod Pitch Method (MPM). It is described in the * article <a href= - * "http://miracle.otago.ac.nz/postgrads/tartini/papers/A_Smarter_Way_to_Find_Pitch.pdf" + * "http://miracle.otago.ac.nz/tartini/papers/A_Smarter_Way_to_Find_Pitch.pdf" * >A Smarter Way to Find Pitch</a>. According to the article: * </p> * <blockquote> <bufferCount> @@ -223,7 +223,7 @@ public final class McLeodPitchMethod implements PitchDetector { if (nsdf[tau] > SMALL_CUTOFF) { // calculates turningPointX and Y - prabolicInterpolation(tau); + parabolicInterpolation(tau); // store the turning points ampEstimates.add(turningPointY); periodEstimates.add(turningPointX); @@ -300,7 +300,7 @@ public final class McLeodPitchMethod implements PitchDetector { * @param tau * The delay tau, b value in the drawing is the tau value. */ - private void prabolicInterpolation(final int tau) { + private void parabolicInterpolation(final int tau) { final float nsdfa = nsdf[tau - 1]; final float nsdfb = nsdf[tau]; final float nsdfc = nsdf[tau + 1]; diff --git a/app/src/main/java/be/tarsos/dsp/resample/RateTransposer.java b/app/src/main/java/be/tarsos/dsp/resample/RateTransposer.java @@ -72,6 +72,8 @@ public class RateTransposer implements AudioProcessor { r.process(factor, src, 0, src.length, false, out, 0, out.length); //The size of the output buffer changes (according to factor). audioEvent.setFloatBuffer(out); + //Update overlap offset to match new buffer size + audioEvent.setOverlap((int) (audioEvent.getOverlap() * factor)); return true; } diff --git a/app/src/main/java/be/tarsos/dsp/util/AudioResourceUtils.java b/app/src/main/java/be/tarsos/dsp/util/AudioResourceUtils.java @@ -152,7 +152,7 @@ public class AudioResourceUtils { * @return The contents of the file. */ public static String readTextFromUrl(URL url) { - StringBuilder fubber = new StringBuilder(); + StringBuffer fubber = new StringBuffer(); try { BufferedReader in = new BufferedReader(new InputStreamReader( url.openStream())); @@ -166,4 +166,5 @@ public class AudioResourceUtils { } return fubber.toString(); } + } diff --git a/app/src/main/java/be/tarsos/dsp/util/ConcurrencyUtils.java b/app/src/main/java/be/tarsos/dsp/util/ConcurrencyUtils.java @@ -57,8 +57,6 @@ * ***** END LICENSE BLOCK ***** */ package be.tarsos.dsp.util; -import android.support.annotation.NonNull; - import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -97,15 +95,21 @@ public class ConcurrencyUtils { } - /** - * Checks if x is a power-of-two number. - * - * @param x - * @return true if x is a power-of-two number - */ - public static boolean isPowerOf2(int x) { - return x > 0 && (x & (x - 1)) == 0; - } + private static class CustomThreadFactory implements ThreadFactory { + private static final ThreadFactory defaultFactory = Executors.defaultThreadFactory(); + + private final Thread.UncaughtExceptionHandler handler; + + CustomThreadFactory(Thread.UncaughtExceptionHandler handler) { + this.handler = handler; + } + + public Thread newThread(Runnable r) { + Thread t = defaultFactory.newThread(r); + t.setUncaughtExceptionHandler(handler); + return t; + } + }; /** * Returns the number of available processors. @@ -269,20 +273,17 @@ public class ConcurrencyUtils { return (int) Math.pow(2, Math.floor(Math.log(x) / Math.log(2))); } - private static class CustomThreadFactory implements ThreadFactory { - private static final ThreadFactory defaultFactory = Executors.defaultThreadFactory(); - - private final Thread.UncaughtExceptionHandler handler; - - CustomThreadFactory(Thread.UncaughtExceptionHandler handler) { - this.handler = handler; - } - - public Thread newThread(@NonNull Runnable r) { - Thread t = defaultFactory.newThread(r); - t.setUncaughtExceptionHandler(handler); - return t; - } + /** + * Checks if x is a power-of-two number. + * + * @param x + * @return true if x is a power-of-two number + */ + public static boolean isPowerOf2(int x) { + if (x <= 0) + return false; + else + return (x & (x - 1)) == 0; } /** diff --git a/app/src/main/java/be/tarsos/dsp/util/CubicSplineFast.java b/app/src/main/java/be/tarsos/dsp/util/CubicSplineFast.java @@ -69,9 +69,9 @@ package be.tarsos.dsp.util; public class CubicSplineFast{ private int nPoints = 0; // no. of tabulated points - private double[] y; // y=f(x) tabulated function - private double[] x; // x in tabulated function f(x) - private double[] d2ydx2; // second derivatives of y + private double[] y = null; // y=f(x) tabulated function + private double[] x = null; // x in tabulated function f(x) + private double[] d2ydx2 = null; // second derivatives of y // Constructors // Constructor with data arrays initialised to arrays x and y @@ -110,7 +110,8 @@ public class CubicSplineFast{ // Primarily for use in BiCubicSplineFast public static CubicSplineFast zero(int n){ if(n<3)throw new IllegalArgumentException("A minimum of three data points is needed"); - return new CubicSplineFast(n); + CubicSplineFast aa = new CubicSplineFast(n); + return aa; } // Create a one dimensional array of cubic spline objects of length n each of array length m @@ -128,7 +129,7 @@ public class CubicSplineFast{ // for use by the cubic spline interpolation method (.interpolate) // This method follows the procedure in Numerical Methods C language procedure for calculating second derivatives public void calcDeriv(){ - double p, qn, sig, un; + double p=0.0D,qn=0.0D,sig=0.0D,un=0.0D; double[] u = new double[nPoints]; d2ydx2[0]=u[0]=0.0; @@ -154,8 +155,8 @@ public class CubicSplineFast{ // then stored for use on all subsequent calls public double interpolate(double xx){ - double h, b, a, yy; - int k; + double h=0.0D,b=0.0D,a=0.0D, yy=0.0D; + int k=0; int klo=0; int khi=this.nPoints-1; while (khi-klo > 1){ diff --git a/app/src/main/java/be/tarsos/dsp/util/FFMPEGDownloader.java b/app/src/main/java/be/tarsos/dsp/util/FFMPEGDownloader.java @@ -24,7 +24,7 @@ import java.util.logging.Logger; */ public class FFMPEGDownloader { - private static String url = "http://0110.be/releases/TarsosDSP/TarsosDSP-static-ffmpeg/"; + private static String url = "https://0110.be/releases/TarsosDSP/TarsosDSP-static-ffmpeg/"; private final String ffmpegBinary; @@ -84,9 +84,9 @@ public class FFMPEGDownloader { String operatingSystem = System.getProperty("os.name").toLowerCase(); if(operatingSystem.indexOf("indows") > 0 ){ name = "windows"; - } else if (operatingSystem.contains("nux")) { + }else if(operatingSystem.indexOf("nux") >= 0){ name="linux"; - } else if (operatingSystem.contains("mac")) { + }else if(operatingSystem.indexOf("mac") >= 0){ name="mac_os_x"; }else{ name = null; @@ -95,11 +95,11 @@ public class FFMPEGDownloader { } private String processorArchitecture(){ - boolean is64bit; + boolean is64bit = false; if (System.getProperty("os.name").contains("Windows")) { is64bit = (System.getenv("ProgramFiles(x86)") != null); } else { - is64bit = (System.getProperty("os.arch").contains("64")); + is64bit = (System.getProperty("os.arch").indexOf("64") != -1); } if(is64bit){ return "64_bits"; diff --git a/app/src/main/java/be/tarsos/dsp/util/PeakPicker.java b/app/src/main/java/be/tarsos/dsp/util/PeakPicker.java @@ -99,8 +99,8 @@ public class PeakPicker { * @return True if a peak is detected, false otherwise. **/ public boolean pickPeak(float onset) { - float mean; - float median; + float mean = 0.f; + float median = 0.f; int length = win_post + win_pre + 1; @@ -116,7 +116,7 @@ public class PeakPicker { onset_proc[length-1] = onset; /* filter onset_proc */ - /* \bug filtfilt calculated post+pre times, should be only once !? */ + /** \bug filtfilt calculated post+pre times, should be only once !? */ biquad.doFiltering(onset_proc,scratch); /* calculate mean and median for onset_proc */ @@ -129,14 +129,16 @@ public class PeakPicker { } Arrays.sort(scratch); median = scratch[scratch.length/2]; - mean = sum / (float) length; + mean = sum/Float.valueOf(length); /* shift peek array */ - System.arraycopy(onset_peek, 1, onset_peek, 0, 3 - 1); + for (int j=0;j<3-1;j++){ + onset_peek[j] = onset_peek[j+1]; + } /* calculate new peek value */ onset_peek[2] = (float) (onset_proc[win_post] - median - mean * threshold); - - boolean isPeak = isPeak(); + + boolean isPeak = isPeak(1); lastPeekValue = onset; return isPeak; @@ -153,11 +155,13 @@ public class PeakPicker { /** * Returns true if the onset is a peak. * + * @param index + * the index in onset_peak to check. * @return True if the onset is a peak, false otherwise. */ - private boolean isPeak() { - return (onset_peek[1] > onset_peek[0] && - onset_peek[1] > onset_peek[1 + 1] && - onset_peek[1] > 0.); + private boolean isPeak(int index) { + return ( onset_peek[index] > onset_peek[index - 1] && + onset_peek[index] > onset_peek[index + 1] && + onset_peek[index] > 0.); } } diff --git a/app/src/main/java/be/tarsos/dsp/util/PitchConverter.java b/app/src/main/java/be/tarsos/dsp/util/PitchConverter.java @@ -109,10 +109,10 @@ public final class PitchConverter { return absoluteCentValue % 1200.0; } - /* - This method is not really practical. Maybe I will need it someday. - - @param relativeCent + /** + * This method is not really practical. Maybe I will need it someday. + * + * @param relativeCent * @return public static double relativeCentToHertz(double relativeCent){ if * (relativeCent < 0 || relativeCent >= 1200) throw new * IllegalArgumentException diff --git a/app/src/main/java/be/tarsos/dsp/util/fft/FFT.java b/app/src/main/java/be/tarsos/dsp/util/fft/FFT.java @@ -32,7 +32,7 @@ package be.tarsos.dsp.util.fft; * * @author Joren Six */ -public final class FFT { +public class FFT { /** * Forward FFT. diff --git a/app/src/main/java/be/tarsos/dsp/wavelet/HaarWaveletDecoder.java b/app/src/main/java/be/tarsos/dsp/wavelet/HaarWaveletDecoder.java @@ -43,5 +43,7 @@ public class HaarWaveletDecoder implements AudioProcessor{ @Override public void processingFinished() { + } + } diff --git a/app/src/main/java/be/tarsos/dsp/wavelet/HaarWaveletTransform.java b/app/src/main/java/be/tarsos/dsp/wavelet/HaarWaveletTransform.java @@ -111,7 +111,10 @@ public class HaarWaveletTransform { if (number <= 0) { throw new IllegalArgumentException("number: " + number); } - return (number & -number) == number; + if ((number & -number) == number) { + return true; + } + return false; } /** diff --git a/app/src/main/java/be/tarsos/dsp/writer/WaveHeader.java b/app/src/main/java/be/tarsos/dsp/writer/WaveHeader.java @@ -5,6 +5,9 @@ import java.io.InputStream; import java.io.OutputStream; /** + * this source code is copied from : https://android.googlesource.com/platform/frameworks/base.git/+/android-4.3_r2/core/java/android/speech/srec/WaveHeader.java + */ +/** * This class represents the header of a WAVE format audio file, which usually * have a .wav suffix. The following integer valued fields are contained: * <ul> @@ -237,14 +240,14 @@ public class WaveHeader { } private static void writeInt(OutputStream out, int val) throws IOException { - out.write(val); + out.write(val >> 0); out.write(val >> 8); out.write(val >> 16); out.write(val >> 24); } private static void writeShort(OutputStream out, short val) throws IOException { - out.write(val); + out.write(val >> 0); out.write(val >> 8); } diff --git a/app/src/main/java/be/tarsos/dsp/writer/WriterProcessor.java b/app/src/main/java/be/tarsos/dsp/writer/WriterProcessor.java @@ -1,5 +1,6 @@ package be.tarsos.dsp.writer; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.RandomAccessFile; diff --git a/app/src/main/java/com/github/cythara/CanvasPainter.java b/app/src/main/java/com/github/cythara/CanvasPainter.java @@ -8,19 +8,14 @@ import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.drawable.Drawable; -import android.support.v4.content.ContextCompat; import android.text.TextPaint; import java.util.Locale; import java.util.Objects; -import static android.content.Context.MODE_PRIVATE; -import static com.github.cythara.ListenerFragment.IS_RECORDING; -import static com.github.cythara.MainActivity.PREFS_FILE; -import static com.github.cythara.MainActivity.REFERENCE_PITCH; -import static com.github.cythara.MainActivity.USE_SCIENTIFIC_NOTATION; -import static com.github.cythara.NoteName.A; -import static java.lang.String.valueOf; +import androidx.core.content.ContextCompat; + +import static android.graphics.Paint.ANTI_ALIAS_FLAG; class CanvasPainter { @@ -31,10 +26,10 @@ class CanvasPainter { private Canvas canvas; - private TextPaint textPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); - private TextPaint numbersPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); - private Paint gaugePaint = new Paint(Paint.ANTI_ALIAS_FLAG); - private Paint symbolPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + private TextPaint textPaint = new TextPaint(ANTI_ALIAS_FLAG); + private TextPaint numbersPaint = new TextPaint(ANTI_ALIAS_FLAG); + private Paint gaugePaint = new Paint(ANTI_ALIAS_FLAG); + private Paint symbolPaint = new TextPaint(ANTI_ALIAS_FLAG); private int redBackground; private int greenBackground; @@ -48,14 +43,14 @@ class CanvasPainter { private boolean useScientificNotation; private int referencePitch; - static CanvasPainter with(Context context) { - return new CanvasPainter(context); - } - private CanvasPainter(Context context) { this.context = context; } + static CanvasPainter with(Context context) { + return new CanvasPainter(context); + } + CanvasPainter paint(PitchDifference pitchDifference) { this.pitchDifference = pitchDifference; @@ -63,9 +58,14 @@ class CanvasPainter { } void on(Canvas canvas) { - SharedPreferences preferences = context.getSharedPreferences(PREFS_FILE, MODE_PRIVATE); - useScientificNotation = preferences.getBoolean(USE_SCIENTIFIC_NOTATION, true); - referencePitch = preferences.getInt(REFERENCE_PITCH, 440); + SharedPreferences preferences = context.getSharedPreferences( + MainActivity.PREFS_FILE, Context.MODE_PRIVATE); + + useScientificNotation = preferences.getBoolean( + MainActivity.USE_SCIENTIFIC_NOTATION, true); + + referencePitch = preferences.getInt( + MainActivity.REFERENCE_PITCH, 440); this.canvas = canvas; @@ -139,7 +139,7 @@ class CanvasPainter { Note note = new Note() { @Override public NoteName getName() { - return A; + return NoteName.A; } @Override @@ -158,12 +158,12 @@ class CanvasPainter { } }; - TextPaint paint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + TextPaint paint = new TextPaint(ANTI_ALIAS_FLAG); paint.setColor(textColor); int size = (int) (textPaint.getTextSize() / 2); paint.setTextSize(size); - float offset = paint.measureText(getNote(note.getName()) + valueOf(getOctave(4))) * 0.75f; + float offset = paint.measureText(getNote(note.getName()) + String.valueOf(getOctave(4))) * 0.75f; drawText(x - gaugeWidth, y, note, paint); canvas.drawText(String.format(Locale.ENGLISH, "= %d Hz", referencePitch), @@ -173,7 +173,7 @@ class CanvasPainter { private void drawListeningIndicator() { int resourceId = R.drawable.ic_line_style_icons_mic; - if (IS_RECORDING) { + if (ListenerFragment.IS_RECORDING) { resourceId = R.drawable.ic_line_style_icons_mic_active; } @@ -184,8 +184,10 @@ class CanvasPainter { int width = Objects.requireNonNull(drawable).getIntrinsicWidth() * 2; int height = drawable.getIntrinsicHeight() * 2; - drawable.setBounds(x - width / 2, y, - x + width / 2, y + height); + drawable.setBounds( + x - width / 2, y, + x + width / 2, + y + height); drawable.draw(canvas); @@ -235,7 +237,7 @@ class CanvasPainter { if (mark > 0) { prefix = "+"; } - String text = prefix + valueOf(mark); + String text = prefix + String.valueOf(mark); int yOffset = (int) (numbersPaint.getTextSize() / 6); if (mark % 10 == 0) { @@ -255,9 +257,9 @@ class CanvasPainter { float offset = textPaint.measureText(noteText) / 2F; String sign = note.getSign(); - String octave = valueOf(getOctave(note.getOctave())); + String octave = String.valueOf(getOctave(note.getOctave())); - TextPaint paint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + TextPaint paint = new TextPaint(ANTI_ALIAS_FLAG); paint.setColor(textColor); int textSize = (int) (textPaint.getTextSize() / 2); paint.setTextSize(textSize); @@ -314,4 +316,4 @@ class CanvasPainter { return Math.round(rounded / 10f) * 10; } -} -\ No newline at end of file +} diff --git a/app/src/main/java/com/github/cythara/ListenerFragment.java b/app/src/main/java/com/github/cythara/ListenerFragment.java @@ -1,7 +1,6 @@ package com.github.cythara; import android.app.Activity; -import android.app.Fragment; import android.content.Context; import android.os.AsyncTask; import android.os.Build; @@ -10,32 +9,23 @@ import android.os.Bundle; import java.util.ArrayList; import java.util.List; +import androidx.fragment.app.Fragment; import be.tarsos.dsp.AudioDispatcher; +import be.tarsos.dsp.io.android.AudioDispatcherFactory; import be.tarsos.dsp.pitch.PitchDetectionHandler; import be.tarsos.dsp.pitch.PitchProcessor; - -import static be.tarsos.dsp.io.android.AudioDispatcherFactory.fromDefaultMicrophone; -import static be.tarsos.dsp.pitch.PitchProcessor.PitchEstimationAlgorithm.FFT_YIN; -import static com.github.cythara.PitchComparator.retrieveNote; +import be.tarsos.dsp.pitch.PitchProcessor.PitchEstimationAlgorithm; public class ListenerFragment extends Fragment { - interface TaskCallbacks { - - void onProgressUpdate(PitchDifference percent); - } - - static boolean IS_RECORDING; - private static final int SAMPLE_RATE = 44100; - private static final int BUFFER_SIZE = 1024 * 4; private static final int OVERLAP = 768 * 4; private static final int MIN_ITEMS_COUNT = 15; + static boolean IS_RECORDING; private static List<PitchDifference> pitchDifferences = new ArrayList<>(); - - private PitchListener pitchListener; private static TaskCallbacks taskCallbacks; + private PitchListener pitchListener; @Override public void onAttach(Context context) { @@ -89,6 +79,11 @@ public class ListenerFragment extends Fragment { } } + interface TaskCallbacks { + + void onProgressUpdate(PitchDifference percent); + } + private static class PitchListener extends AsyncTask<Void, PitchDifference, Void> { private AudioDispatcher audioDispatcher; @@ -111,7 +106,7 @@ public class ListenerFragment extends Fragment { if (pitch != -1) { float adjustedPitch = MainActivity.adjustPitch(pitch); - PitchDifference pitchDifference = retrieveNote(adjustedPitch); + PitchDifference pitchDifference = PitchComparator.retrieveNote(adjustedPitch); pitchDifferences.add(pitchDifference); @@ -126,10 +121,10 @@ public class ListenerFragment extends Fragment { } }; - PitchProcessor pitchProcessor = new PitchProcessor(FFT_YIN, SAMPLE_RATE, + PitchProcessor pitchProcessor = new PitchProcessor(PitchEstimationAlgorithm.FFT_YIN, SAMPLE_RATE, BUFFER_SIZE, pitchDetectionHandler); - audioDispatcher = fromDefaultMicrophone(SAMPLE_RATE, + audioDispatcher = AudioDispatcherFactory.fromDefaultMicrophone(SAMPLE_RATE, BUFFER_SIZE, OVERLAP); audioDispatcher.addAudioProcessor(pitchProcessor); diff --git a/app/src/main/java/com/github/cythara/MainActivity.java b/app/src/main/java/com/github/cythara/MainActivity.java @@ -1,35 +1,38 @@ package com.github.cythara; import android.Manifest; -import android.app.AlertDialog; -import android.app.FragmentManager; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.app.AppCompatDelegate; -import android.support.v7.widget.Toolbar; import android.view.ContextThemeWrapper; import android.view.Menu; import android.view.MenuItem; -import android.view.WindowManager; +import android.view.WindowManager.LayoutParams; +import com.github.cythara.ListenerFragment.TaskCallbacks; import com.jaredrummler.materialspinner.MaterialSpinner; +import com.jaredrummler.materialspinner.MaterialSpinner.OnItemSelectedListener; import com.jaredrummler.materialspinner.MaterialSpinnerAdapter; import com.shawnlin.numberpicker.NumberPicker; +import com.shawnlin.numberpicker.NumberPicker.OnValueChangeListener; import java.util.Arrays; -import static com.github.cythara.TuningMapper.getTuningFromPosition; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AlertDialog.Builder; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.Toolbar; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentManager; -public class MainActivity extends AppCompatActivity implements ListenerFragment.TaskCallbacks, - MaterialSpinner.OnItemSelectedListener, NumberPicker.OnValueChangeListener { +public class MainActivity extends AppCompatActivity implements TaskCallbacks, + OnItemSelectedListener, OnValueChangeListener { public static final int RECORD_AUDIO_PERMISSION = 0; public static final String PREFS_FILE = "prefs_file"; @@ -43,7 +46,7 @@ public class MainActivity extends AppCompatActivity implements ListenerFragment. private static PitchAdjuster pitchAdjuster; public static Tuning getCurrentTuning() { - return getTuningFromPosition(tuningPosition); + return TuningMapper.getTuningFromPosition(tuningPosition); } public static boolean isDarkModeEnabled() { @@ -74,7 +77,7 @@ public class MainActivity extends AppCompatActivity implements ListenerFragment. setTuning(); setPitchAdjuster(); - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON); Toolbar myToolbar = findViewById(R.id.my_toolbar); myToolbar.setTitle(R.string.app_name); @@ -93,7 +96,7 @@ public class MainActivity extends AppCompatActivity implements ListenerFragment. switch (item.getItemId()) { case R.id.show_privacy_policy: { Intent browserIntent = new Intent(Intent.ACTION_VIEW, - Uri.parse("https://gstraube.github.io/privacy_policy.html")); + Uri.parse(getString(R.string.privacy_policy_link))); startActivity(browserIntent); break; @@ -106,7 +109,7 @@ public class MainActivity extends AppCompatActivity implements ListenerFragment. int checkedItem = useScientificNotation ? 0 : 1; - AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(this, + Builder builder = new Builder(new ContextThemeWrapper(this, R.style.AppTheme)); builder.setTitle(R.string.choose_notation); builder.setSingleChoiceItems(R.array.notations, checkedItem, @@ -149,7 +152,7 @@ public class MainActivity extends AppCompatActivity implements ListenerFragment. dialog.setArguments(bundle); dialog.setValueChangeListener(this); - dialog.show(getFragmentManager(), "number_picker"); + dialog.show(getSupportFragmentManager(), "number_picker"); break; } @@ -180,10 +183,10 @@ public class MainActivity extends AppCompatActivity implements ListenerFragment. && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startRecording(); } else { - AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create(); + AlertDialog alertDialog = new Builder(MainActivity.this).create(); alertDialog.setTitle(R.string.permission_required); - alertDialog.setMessage("Microphone permission is required. App will be closed"); - alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK", + alertDialog.setMessage(getString(R.string.microphone_permission_required)); + alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, getString(R.string.ok), (dialog, which) -> { dialog.dismiss(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { @@ -226,7 +229,7 @@ public class MainActivity extends AppCompatActivity implements ListenerFragment. } private void startRecording() { - FragmentManager fragmentManager = getFragmentManager(); + FragmentManager fragmentManager = getSupportFragmentManager(); ListenerFragment listenerFragment = (ListenerFragment) fragmentManager.findFragmentByTag(TAG_LISTENER_FRAGMENT); diff --git a/app/src/main/java/com/github/cythara/Note.java b/app/src/main/java/com/github/cythara/Note.java @@ -3,7 +3,10 @@ package com.github.cythara; public interface Note { NoteName getName(); + int getOctave(); + String getSign(); + float getFrequency(); } diff --git a/app/src/main/java/com/github/cythara/NumberPickerDialog.java b/app/src/main/java/com/github/cythara/NumberPickerDialog.java @@ -1,7 +1,5 @@ package com.github.cythara; - -import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.os.Bundle; @@ -9,6 +7,9 @@ import android.view.ContextThemeWrapper; import com.shawnlin.numberpicker.NumberPicker; +import androidx.appcompat.app.AlertDialog.Builder; +import androidx.fragment.app.FragmentManager; + public class NumberPickerDialog extends DialogFragment { private NumberPicker.OnValueChangeListener valueChangeListener; @@ -31,7 +32,7 @@ public class NumberPickerDialog extends DialogFragment { numberPicker.setSelectedTextColor(color); } - AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), + Builder builder = new Builder(new ContextThemeWrapper(getActivity(), R.style.AppTheme)); builder.setMessage(R.string.choose_a_frequency); @@ -55,4 +56,7 @@ public class NumberPickerDialog extends DialogFragment { public void setValueChangeListener(NumberPicker.OnValueChangeListener valueChangeListener) { this.valueChangeListener = valueChangeListener; } + + public void show(FragmentManager supportFragmentManager, String number_picker) { + } } diff --git a/app/src/main/java/com/github/cythara/PitchDifference.java b/app/src/main/java/com/github/cythara/PitchDifference.java @@ -5,6 +5,16 @@ import android.os.Parcelable; class PitchDifference implements Parcelable { + public static final Creator<PitchDifference> CREATOR = new Creator<PitchDifference>() { + public PitchDifference createFromParcel(Parcel in) { + return new PitchDifference(in); + } + + public PitchDifference[] newArray(int size) { + return new PitchDifference[size]; + } + }; + final Note closest; final double deviation; @@ -29,15 +39,4 @@ class PitchDifference implements Parcelable { dest.writeString(closest.getName().name()); dest.writeDouble(deviation); } - - public static final Parcelable.Creator<PitchDifference> CREATOR - = new Parcelable.Creator<PitchDifference>() { - public PitchDifference createFromParcel(Parcel in) { - return new PitchDifference(in); - } - - public PitchDifference[] newArray(int size) { - return new PitchDifference[size]; - } - }; -} -\ No newline at end of file +} diff --git a/app/src/main/java/com/github/cythara/Sampler.java b/app/src/main/java/com/github/cythara/Sampler.java @@ -14,8 +14,8 @@ class Sampler { double deviationSum = 0; int sameNoteCount = 0; for (PitchDifference pitchDifference : filteredSamples) { - deviationSum += pitchDifference.deviation; - sameNoteCount++; + deviationSum += pitchDifference.deviation; + sameNoteCount++; } if (sameNoteCount > 0) { diff --git a/app/src/main/java/com/github/cythara/tuning/BassTuning.java b/app/src/main/java/com/github/cythara/tuning/BassTuning.java @@ -1,5 +1,6 @@ package com.github.cythara.tuning; +import com.github.cythara.Note; import com.github.cythara.NoteName; import com.github.cythara.Tuning; @@ -7,17 +8,27 @@ import static com.github.cythara.NoteName.*; public class BassTuning implements Tuning { - private enum Pitch implements com.github.cythara.Note { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + + private enum Pitch implements Note { E1(E, 1, 41.204f), A1(A, 1, 55f), D2(D, 2, 73.416f), G2(G, 2, 97.999f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, float frequency) { this.name = name; @@ -44,14 +55,4 @@ public class BassTuning implements Tuning { return sign; } } - - @Override - public com.github.cythara.Note[] getNotes() { - return Pitch.values(); - } - - @Override - public com.github.cythara.Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/java/com/github/cythara/tuning/CelloTuning.java b/app/src/main/java/com/github/cythara/tuning/CelloTuning.java @@ -1,26 +1,24 @@ package com.github.cythara.tuning; +import com.github.cythara.Note; import com.github.cythara.NoteName; import com.github.cythara.Tuning; -import static com.github.cythara.NoteName.A; -import static com.github.cythara.NoteName.C; -import static com.github.cythara.NoteName.D; -import static com.github.cythara.NoteName.G; +import static com.github.cythara.NoteName.*; public class CelloTuning implements Tuning { @Override - public com.github.cythara.Note[] getNotes() { + public Note[] getNotes() { return Pitch.values(); } @Override - public com.github.cythara.Note findNote(String name) { + public Note findNote(String name) { return Pitch.valueOf(name); } - private enum Pitch implements com.github.cythara.Note { + private enum Pitch implements Note { C2(C, 2, 65.4f), G2(G, 2, 98f), diff --git a/app/src/main/java/com/github/cythara/tuning/ChromaticTuning.java b/app/src/main/java/com/github/cythara/tuning/ChromaticTuning.java @@ -8,6 +8,16 @@ import static com.github.cythara.NoteName.*; public class ChromaticTuning implements Tuning { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + private enum Pitch implements Note { C_MINUS_1(C, -1, 8.176f), @@ -149,10 +159,10 @@ public class ChromaticTuning implements Tuning { F9_SHARP(F, 9, "#", 11839.8f), G9(G, 9, 12543.9f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, String sign, float frequency) { this.name = name; @@ -186,14 +196,4 @@ public class ChromaticTuning implements Tuning { return sign; } } - - @Override - public Note[] getNotes() { - return Pitch.values(); - } - - @Override - public Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/java/com/github/cythara/tuning/DropCGuitarTuning.java b/app/src/main/java/com/github/cythara/tuning/DropCGuitarTuning.java @@ -1,5 +1,6 @@ package com.github.cythara.tuning; +import com.github.cythara.Note; import com.github.cythara.NoteName; import com.github.cythara.Tuning; @@ -7,7 +8,17 @@ import static com.github.cythara.NoteName.*; public class DropCGuitarTuning implements Tuning { - private enum Pitch implements com.github.cythara.Note { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + + private enum Pitch implements Note { C2(C, 2, 65.406f), G2(G, 2, 97.999f), @@ -16,10 +27,10 @@ public class DropCGuitarTuning implements Tuning { A3(A, 3, 220f), D4(D, 4, 293.665f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, float frequency) { this.name = name; @@ -46,14 +57,4 @@ public class DropCGuitarTuning implements Tuning { return sign; } } - - @Override - public com.github.cythara.Note[] getNotes() { - return Pitch.values(); - } - - @Override - public com.github.cythara.Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/java/com/github/cythara/tuning/DropCSharpGuitarTuning.java b/app/src/main/java/com/github/cythara/tuning/DropCSharpGuitarTuning.java @@ -1,5 +1,6 @@ package com.github.cythara.tuning; +import com.github.cythara.Note; import com.github.cythara.NoteName; import com.github.cythara.Tuning; @@ -7,7 +8,17 @@ import static com.github.cythara.NoteName.*; public class DropCSharpGuitarTuning implements Tuning { - private enum Pitch implements com.github.cythara.Note { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + + private enum Pitch implements Note { C2_SHARP(C, 2, "#", 69.30f), A2(A, 2, 110f), @@ -16,10 +27,10 @@ public class DropCSharpGuitarTuning implements Tuning { B3(B, 3, 246.942f), E4(E, 4, 329.628f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, String sign, float frequency) { this.name = name; @@ -53,14 +64,4 @@ public class DropCSharpGuitarTuning implements Tuning { return sign; } } - - @Override - public com.github.cythara.Note[] getNotes() { - return Pitch.values(); - } - - @Override - public com.github.cythara.Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/java/com/github/cythara/tuning/DropDGuitarTuning.java b/app/src/main/java/com/github/cythara/tuning/DropDGuitarTuning.java @@ -1,5 +1,6 @@ package com.github.cythara.tuning; +import com.github.cythara.Note; import com.github.cythara.NoteName; import com.github.cythara.Tuning; @@ -7,7 +8,17 @@ import static com.github.cythara.NoteName.*; public class DropDGuitarTuning implements Tuning { - private enum Pitch implements com.github.cythara.Note { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + + private enum Pitch implements Note { D2(D, 2, 73.416f), A2(A, 2, 110f), @@ -16,10 +27,10 @@ public class DropDGuitarTuning implements Tuning { B3(B, 3, 246.942f), E4(E, 4, 329.628f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, float frequency) { this.name = name; @@ -46,14 +57,4 @@ public class DropDGuitarTuning implements Tuning { return sign; } } - - @Override - public com.github.cythara.Note[] getNotes() { - return Pitch.values(); - } - - @Override - public com.github.cythara.Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/java/com/github/cythara/tuning/GuitarTuning.java b/app/src/main/java/com/github/cythara/tuning/GuitarTuning.java @@ -1,5 +1,6 @@ package com.github.cythara.tuning; +import com.github.cythara.Note; import com.github.cythara.NoteName; import com.github.cythara.Tuning; @@ -7,7 +8,17 @@ import static com.github.cythara.NoteName.*; public class GuitarTuning implements Tuning { - public enum Pitch implements com.github.cythara.Note { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + + public enum Pitch implements Note { E2(E, 2, 82.407f), A2(A, 2, 110f), @@ -16,10 +27,10 @@ public class GuitarTuning implements Tuning { B3(B, 3, 246.942f), E4(E, 4, 329.628f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, float frequency) { this.name = name; @@ -46,14 +57,4 @@ public class GuitarTuning implements Tuning { return sign; } } - - @Override - public com.github.cythara.Note[] getNotes() { - return Pitch.values(); - } - - @Override - public com.github.cythara.Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/java/com/github/cythara/tuning/OpenGGuitarTuning.java b/app/src/main/java/com/github/cythara/tuning/OpenGGuitarTuning.java @@ -1,5 +1,6 @@ package com.github.cythara.tuning; +import com.github.cythara.Note; import com.github.cythara.NoteName; import com.github.cythara.Tuning; @@ -7,7 +8,17 @@ import static com.github.cythara.NoteName.*; public class OpenGGuitarTuning implements Tuning { - private enum Pitch implements com.github.cythara.Note { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + + private enum Pitch implements Note { D2(D, 2, 73.416f), G2(G, 2, 97.999f), @@ -16,10 +27,10 @@ public class OpenGGuitarTuning implements Tuning { B3(B, 3, 246.942f), D4(D, 4, 293.665f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, float frequency) { this.name = name; @@ -46,14 +57,4 @@ public class OpenGGuitarTuning implements Tuning { return sign; } } - - @Override - public com.github.cythara.Note[] getNotes() { - return Pitch.values(); - } - - @Override - public com.github.cythara.Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/java/com/github/cythara/tuning/UkuleleDTuning.java b/app/src/main/java/com/github/cythara/tuning/UkuleleDTuning.java @@ -8,17 +8,27 @@ import static com.github.cythara.NoteName.*; public class UkuleleDTuning implements Tuning { - private enum Pitch implements com.github.cythara.Note { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + + private enum Pitch implements Note { A4(A, 4, 440f), D4(D, 4, 293.665f), F3_SHARP(F, 3, "#", 369.99f), B4(B, 4, 493.88f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, String sign, float frequency) { this.name = name; @@ -52,14 +62,4 @@ public class UkuleleDTuning implements Tuning { return sign; } } - - @Override - public Note[] getNotes() { - return Pitch.values(); - } - - @Override - public Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/java/com/github/cythara/tuning/UkuleleTuning.java b/app/src/main/java/com/github/cythara/tuning/UkuleleTuning.java @@ -8,6 +8,16 @@ import static com.github.cythara.NoteName.*; public class UkuleleTuning implements Tuning { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + private enum Pitch implements Note { G4(G, 4, 391.995f), @@ -15,10 +25,10 @@ public class UkuleleTuning implements Tuning { E4(E, 4, 329.628f), A4(A, 4, 440f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, float frequency) { this.name = name; @@ -45,14 +55,4 @@ public class UkuleleTuning implements Tuning { return sign; } } - - @Override - public Note[] getNotes() { - return Pitch.values(); - } - - @Override - public Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/java/com/github/cythara/tuning/ViolinTuning.java b/app/src/main/java/com/github/cythara/tuning/ViolinTuning.java @@ -1,5 +1,6 @@ package com.github.cythara.tuning; +import com.github.cythara.Note; import com.github.cythara.NoteName; import com.github.cythara.Tuning; @@ -7,17 +8,27 @@ import static com.github.cythara.NoteName.*; public class ViolinTuning implements Tuning { - private enum Pitch implements com.github.cythara.Note { + @Override + public Note[] getNotes() { + return Pitch.values(); + } + + @Override + public Note findNote(String name) { + return Pitch.valueOf(name); + } + + private enum Pitch implements Note { G3(G, 3, 196f), D4(D, 4, 293.66f), A4(A, 4, 440f), E5(E, 5, 659.26f); - private NoteName name; private final String sign; private final int octave; private final float frequency; + private NoteName name; Pitch(NoteName name, int octave, float frequency) { this.name = name; @@ -44,14 +55,4 @@ public class ViolinTuning implements Tuning { return sign; } } - - @Override - public com.github.cythara.Note[] getNotes() { - return Pitch.values(); - } - - @Override - public com.github.cythara.Note findNote(String name) { - return Pitch.valueOf(name); - } } diff --git a/app/src/main/res/drawable-nodpi/ic_line_style_icons_mic.xml b/app/src/main/res/drawable-nodpi/ic_line_style_icons_mic.xml @@ -1,12 +1,12 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="15dp" - android:height="32dp" - android:viewportWidth="15.0" - android:viewportHeight="32.0"> + android:width="15dp" + android:height="32dp" + android:viewportWidth="15.0" + android:viewportHeight="32.0"> <path - android:pathData="M7,24.007V28H4.034c-1.141,0 -2,0.859 -2,2v1.5c0,0.276 0.224,0.5 0.5,0.5h10c0.276,0 0.5,-0.224 0.5,-0.5v-1.425c0,-1.164 -0.879,-2.075 -2,-2.075H8v-3.993c3.973,-0.278 7.068,-3.56 7.068,-7.564v-1.887c0,-0.295 -0.239,-0.534 -0.534,-0.534S14,14.262 14,14.557v1.887c0,3.597 -2.9,6.522 -6.466,6.522s-6.466,-2.926 -6.466,-6.522v-1.887c0,-0.295 -0.239,-0.534 -0.534,-0.534S0,14.262 0,14.557v1.887C0,20.447 3.095,23.729 7,24.007zM12.034,30.075V31h-9v-1c0,-0.589 0.411,-1 1,-1h7C11.604,29 12.034,29.462 12.034,30.075z" - android:fillColor="#80e10000"/> + android:fillColor="#80e10000" + android:pathData="M7,24.007V28H4.034c-1.141,0 -2,0.859 -2,2v1.5c0,0.276 0.224,0.5 0.5,0.5h10c0.276,0 0.5,-0.224 0.5,-0.5v-1.425c0,-1.164 -0.879,-2.075 -2,-2.075H8v-3.993c3.973,-0.278 7.068,-3.56 7.068,-7.564v-1.887c0,-0.295 -0.239,-0.534 -0.534,-0.534S14,14.262 14,14.557v1.887c0,3.597 -2.9,6.522 -6.466,6.522s-6.466,-2.926 -6.466,-6.522v-1.887c0,-0.295 -0.239,-0.534 -0.534,-0.534S0,14.262 0,14.557v1.887C0,20.447 3.095,23.729 7,24.007zM12.034,30.075V31h-9v-1c0,-0.589 0.411,-1 1,-1h7C11.604,29 12.034,29.462 12.034,30.075z" /> <path - android:pathData="M7.534,-0.034C5.034,-0.034 3,2.025 3,4.557v11.887c0,2.531 2.034,4.591 4.534,4.591s4.534,-2.06 4.466,-4.591V4.557C12.068,2.025 10.034,-0.034 7.534,-0.034zM11,16.443c0,1.942 -1.555,3.522 -3.466,3.522S4,18.386 4,16.443V4.557c0,-1.942 1.623,-3.522 3.534,-3.522S11,2.614 11,4.557V16.443z" - android:fillColor="#80e10000"/> + android:fillColor="#80e10000" + android:pathData="M7.534,-0.034C5.034,-0.034 3,2.025 3,4.557v11.887c0,2.531 2.034,4.591 4.534,4.591s4.534,-2.06 4.466,-4.591V4.557C12.068,2.025 10.034,-0.034 7.534,-0.034zM11,16.443c0,1.942 -1.555,3.522 -3.466,3.522S4,18.386 4,16.443V4.557c0,-1.942 1.623,-3.522 3.534,-3.522S11,2.614 11,4.557V16.443z" /> </vector> diff --git a/app/src/main/res/drawable-nodpi/ic_line_style_icons_mic_active.xml b/app/src/main/res/drawable-nodpi/ic_line_style_icons_mic_active.xml @@ -1,12 +1,12 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="15dp" - android:height="32dp" - android:viewportWidth="15.0" - android:viewportHeight="32.0"> + android:width="15dp" + android:height="32dp" + android:viewportWidth="15.0" + android:viewportHeight="32.0"> <path - android:pathData="M7,24.007V28H4.034c-1.141,0 -2,0.859 -2,2v1.5c0,0.276 0.224,0.5 0.5,0.5h10c0.276,0 0.5,-0.224 0.5,-0.5v-1.425c0,-1.164 -0.879,-2.075 -2,-2.075H8v-3.993c3.973,-0.278 7.068,-3.56 7.068,-7.564v-1.887c0,-0.295 -0.239,-0.534 -0.534,-0.534S14,14.262 14,14.557v1.887c0,3.597 -2.9,6.522 -6.466,6.522s-6.466,-2.926 -6.466,-6.522v-1.887c0,-0.295 -0.239,-0.534 -0.534,-0.534S0,14.262 0,14.557v1.887C0,20.447 3.095,23.729 7,24.007zM12.034,30.075V31h-9v-1c0,-0.589 0.411,-1 1,-1h7C11.604,29 12.034,29.462 12.034,30.075z" - android:fillColor="#8000ff00"/> + android:fillColor="#8000ff00" + android:pathData="M7,24.007V28H4.034c-1.141,0 -2,0.859 -2,2v1.5c0,0.276 0.224,0.5 0.5,0.5h10c0.276,0 0.5,-0.224 0.5,-0.5v-1.425c0,-1.164 -0.879,-2.075 -2,-2.075H8v-3.993c3.973,-0.278 7.068,-3.56 7.068,-7.564v-1.887c0,-0.295 -0.239,-0.534 -0.534,-0.534S14,14.262 14,14.557v1.887c0,3.597 -2.9,6.522 -6.466,6.522s-6.466,-2.926 -6.466,-6.522v-1.887c0,-0.295 -0.239,-0.534 -0.534,-0.534S0,14.262 0,14.557v1.887C0,20.447 3.095,23.729 7,24.007zM12.034,30.075V31h-9v-1c0,-0.589 0.411,-1 1,-1h7C11.604,29 12.034,29.462 12.034,30.075z" /> <path - android:pathData="M7.534,-0.034C5.034,-0.034 3,2.025 3,4.557v11.887c0,2.531 2.034,4.591 4.534,4.591s4.534,-2.06 4.466,-4.591V4.557C12.068,2.025 10.034,-0.034 7.534,-0.034zM11,16.443c0,1.942 -1.555,3.522 -3.466,3.522S4,18.386 4,16.443V4.557c0,-1.942 1.623,-3.522 3.534,-3.522S11,2.614 11,4.557V16.443z" - android:fillColor="#8000ff00"/> + android:fillColor="#8000ff00" + android:pathData="M7.534,-0.034C5.034,-0.034 3,2.025 3,4.557v11.887c0,2.531 2.034,4.591 4.534,4.591s4.534,-2.06 4.466,-4.591V4.557C12.068,2.025 10.034,-0.034 7.534,-0.034zM11,16.443c0,1.942 -1.555,3.522 -3.466,3.522S4,18.386 4,16.443V4.557c0,-1.942 1.623,-3.522 3.534,-3.522S11,2.614 11,4.557V16.443z" /> </vector> diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml @@ -1,94 +1,209 @@ -<vector android:height="24dp" android:viewportHeight="254.00002" - android:viewportWidth="253.99998" android:width="24dp" - xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android"> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:aapt="http://schemas.android.com/aapt" + android:width="24dp" + android:height="24dp" + android:viewportWidth="253.99998" + android:viewportHeight="254.00002"> <path android:pathData="m201.355,83.745 l-41.8,-39.9 -20.4,-18.4c-1.1,-1.3 -2.7,-2.1 -4.6,-2.1 -3.2,0 -5.9,2.4 -5.9,5.3v125.7c-4.1,-2.4 -9,-3.9 -14.3,-3.9 -14.4,0 -26,10.5 -26,23.5 0,13 11.6,23.5 26,23.5 14.4,0 26,-10.5 26,-23.5 0,-0.1 0,-0.3 0,-0.4 0,-0.1 0,-0.1 0,-0.2L140.355,59.745l15.2,5.6z"> <aapt:attr name="android:fillColor"> - <gradient android:endX="125.15384" android:endY="224.94815" - android:startX="151.94794" android:startY="92.93785" android:type="linear"> - <item android:color="#FFFF1577" android:offset="0"/> - <item android:color="#FFFE116E" android:offset="0.05213103"/> - <item android:color="#FFFC075B" android:offset="0.193"/> - <item android:color="#FFFA0250" android:offset="0.3381"/> - <item android:color="#FFFA004C" android:offset="0.4927"/> - <item android:color="#FFF70D70" android:offset="1"/> + <gradient + android:endX="125.15384" + android:endY="224.94815" + android:startX="151.94794" + android:startY="92.93785" + android:type="linear"> + <item + android:color="#FFFF1577" + android:offset="0" /> + <item + android:color="#FFFE116E" + android:offset="0.05213103" /> + <item + android:color="#FFFC075B" + android:offset="0.193" /> + <item + android:color="#FFFA0250" + android:offset="0.3381" /> + <item + android:color="#FFFA004C" + android:offset="0.4927" /> + <item + android:color="#FFF70D70" + android:offset="1" /> </gradient> </aapt:attr> </path> <path android:pathData="m65.155,166.245c0.8,0 1.5,-0.6 1.6,-1.5 1.1,-10.3 5.6,-20.3 13.5,-28.2 7.9,-7.9 17.9,-12.4 28.2,-13.5 0.8,-0.1 1.5,-0.8 1.5,-1.6v0c0,-1 -0.8,-1.7 -1.8,-1.6 -11,1.2 -21.7,6 -30.2,14.4 -8.4,8.4 -13.2,19.2 -14.4,30.2 -0.2,0.9 0.6,1.8 1.6,1.8z"> <aapt:attr name="android:fillColor"> - <gradient android:endX="72.13724" android:endY="214.18735" - android:startX="98.931335" android:startY="82.17705" android:type="linear"> - <item android:color="#FFFF1577" android:offset="0"/> - <item android:color="#FFFE116E" android:offset="0.05213103"/> - <item android:color="#FFFC075B" android:offset="0.193"/> - <item android:color="#FFFA0250" android:offset="0.3381"/> - <item android:color="#FFFA004C" android:offset="0.4927"/> - <item android:color="#FFF70D70" android:offset="1"/> + <gradient + android:endX="72.13724" + android:endY="214.18735" + android:startX="98.931335" + android:startY="82.17705" + android:type="linear"> + <item + android:color="#FFFF1577" + android:offset="0" /> + <item + android:color="#FFFE116E" + android:offset="0.05213103" /> + <item + android:color="#FFFC075B" + android:offset="0.193" /> + <item + android:color="#FFFA0250" + android:offset="0.3381" /> + <item + android:color="#FFFA004C" + android:offset="0.4927" /> + <item + android:color="#FFF70D70" + android:offset="1" /> </gradient> </aapt:attr> </path> <path android:pathData="m109.955,218.145c0,-0.8 -0.6,-1.5 -1.5,-1.6 -10.3,-1.1 -20.3,-5.6 -28.2,-13.5 -7.9,-7.9 -12.4,-17.9 -13.5,-28.2 -0.1,-0.8 -0.8,-1.5 -1.6,-1.5v0c-1,0 -1.7,0.8 -1.6,1.8 1.2,11 6,21.7 14.4,30.2 8.4,8.5 19.2,13.2 30.2,14.4 0.9,0.2 1.8,-0.6 1.8,-1.6z"> <aapt:attr name="android:fillColor"> - <gradient android:endX="82.690155" android:endY="216.32925" - android:startX="109.484245" android:startY="84.31904" android:type="linear"> - <item android:color="#FFFF1577" android:offset="0"/> - <item android:color="#FFFE116E" android:offset="0.05213103"/> - <item android:color="#FFFC075B" android:offset="0.193"/> - <item android:color="#FFFA0250" android:offset="0.3381"/> - <item android:color="#FFFA004C" android:offset="0.4927"/> - <item android:color="#FFF70D70" android:offset="1"/> + <gradient + android:endX="82.690155" + android:endY="216.32925" + android:startX="109.484245" + android:startY="84.31904" + android:type="linear"> + <item + android:color="#FFFF1577" + android:offset="0" /> + <item + android:color="#FFFE116E" + android:offset="0.05213103" /> + <item + android:color="#FFFC075B" + android:offset="0.193" /> + <item + android:color="#FFFA0250" + android:offset="0.3381" /> + <item + android:color="#FFFA004C" + android:offset="0.4927" /> + <item + android:color="#FFF70D70" + android:offset="1" /> </gradient> </aapt:attr> </path> <path android:pathData="m161.855,173.345c-0.8,0 -1.5,0.6 -1.6,1.5 -1.1,10.3 -5.6,20.3 -13.5,28.2 -7.9,7.9 -17.9,12.4 -28.2,13.5 -0.8,0.1 -1.5,0.8 -1.5,1.6v0c0,1 0.8,1.7 1.8,1.6 11,-1.2 21.7,-6 30.2,-14.4 8.4,-8.4 13.2,-19.2 14.4,-30.2 0.1,-0.9 -0.6,-1.8 -1.6,-1.8z"> <aapt:attr name="android:fillColor"> - <gradient android:endX="134.26495" android:endY="226.79745" - android:startX="161.05914" android:startY="94.787155" android:type="linear"> - <item android:color="#FFFF1577" android:offset="0"/> - <item android:color="#FFFE116E" android:offset="0.05213103"/> - <item android:color="#FFFC075B" android:offset="0.193"/> - <item android:color="#FFFA0250" android:offset="0.3381"/> - <item android:color="#FFFA004C" android:offset="0.4927"/> - <item android:color="#FFF70D70" android:offset="1"/> + <gradient + android:endX="134.26495" + android:endY="226.79745" + android:startX="161.05914" + android:startY="94.787155" + android:type="linear"> + <item + android:color="#FFFF1577" + android:offset="0" /> + <item + android:color="#FFFE116E" + android:offset="0.05213103" /> + <item + android:color="#FFFC075B" + android:offset="0.193" /> + <item + android:color="#FFFA0250" + android:offset="0.3381" /> + <item + android:color="#FFFA004C" + android:offset="0.4927" /> + <item + android:color="#FFF70D70" + android:offset="1" /> </gradient> </aapt:attr> </path> <path android:pathData="m54.955,165.845c0.8,0 1.5,-0.6 1.6,-1.5 1.3,-12.6 6.7,-24.8 16.3,-34.4 9.6,-9.6 21.8,-15.1 34.4,-16.3 0.8,-0.1 1.5,-0.8 1.5,-1.6v-0.7c0,-1 -0.8,-1.7 -1.8,-1.6 -13.5,1.4 -26.5,7.2 -36.8,17.5 -10.3,10.3 -16.1,23.4 -17.5,36.8 -0.1,1 0.6,1.8 1.6,1.8z"> <aapt:attr name="android:fillColor"> - <gradient android:endX="65.41165" android:endY="212.82227" - android:startX="92.20584" android:startY="80.81195" android:type="linear"> - <item android:color="#FFFF1577" android:offset="0"/> - <item android:color="#FFFE116E" android:offset="0.05213103"/> - <item android:color="#FFFC075B" android:offset="0.193"/> - <item android:color="#FFFA0250" android:offset="0.3381"/> - <item android:color="#FFFA004C" android:offset="0.4927"/> - <item android:color="#FFF70D70" android:offset="1"/> + <gradient + android:endX="65.41165" + android:endY="212.82227" + android:startX="92.20584" + android:startY="80.81195" + android:type="linear"> + <item + android:color="#FFFF1577" + android:offset="0" /> + <item + android:color="#FFFE116E" + android:offset="0.05213103" /> + <item + android:color="#FFFC075B" + android:offset="0.193" /> + <item + android:color="#FFFA0250" + android:offset="0.3381" /> + <item + android:color="#FFFA004C" + android:offset="0.4927" /> + <item + android:color="#FFF70D70" + android:offset="1" /> </gradient> </aapt:attr> </path> <path android:pathData="m108.855,228.345c0,-0.8 -0.6,-1.5 -1.5,-1.6 -12.6,-1.3 -24.8,-6.7 -34.4,-16.3 -9.6,-9.6 -15.1,-21.8 -16.3,-34.4 -0.1,-0.8 -0.8,-1.5 -1.6,-1.5h-0.7c-1,0 -1.7,0.8 -1.6,1.8 1.4,13.5 7.2,26.5 17.5,36.8 10.3,10.3 23.4,16.1 36.8,17.5 1,0.1 1.8,-0.6 1.8,-1.6z"> <aapt:attr name="android:fillColor"> - <gradient android:endX="78.12726" android:endY="215.40314" - android:startX="104.92145" android:startY="83.39285" android:type="linear"> - <item android:color="#FFFF1577" android:offset="0"/> - <item android:color="#FFFE116E" android:offset="0.05213103"/> - <item android:color="#FFFC075B" android:offset="0.193"/> - <item android:color="#FFFA0250" android:offset="0.3381"/> - <item android:color="#FFFA004C" android:offset="0.4927"/> - <item android:color="#FFF70D70" android:offset="1"/> + <gradient + android:endX="78.12726" + android:endY="215.40314" + android:startX="104.92145" + android:startY="83.39285" + android:type="linear"> + <item + android:color="#FFFF1577" + android:offset="0" /> + <item + android:color="#FFFE116E" + android:offset="0.05213103" /> + <item + android:color="#FFFC075B" + android:offset="0.193" /> + <item + android:color="#FFFA0250" + android:offset="0.3381" /> + <item + android:color="#FFFA004C" + android:offset="0.4927" /> + <item + android:color="#FFF70D70" + android:offset="1" /> </gradient> </aapt:attr> </path> <path android:pathData="m171.255,174.445c-0.8,0 -1.5,0.6 -1.6,1.5 -1.3,12.6 -6.7,24.8 -16.3,34.4 -9.6,9.6 -21.8,15.1 -34.4,16.3 -0.8,0.1 -1.5,0.8 -1.5,1.6v0.7c0,1 0.8,1.7 1.8,1.6 13.5,-1.4 26.5,-7.2 36.8,-17.5 10.3,-10.3 16.1,-23.4 17.5,-36.8 0.1,-1 -0.6,-1.8 -1.6,-1.8z"> <aapt:attr name="android:fillColor"> - <gradient android:endX="140.45316" android:endY="228.05344" - android:startX="167.24734" android:startY="96.04315" android:type="linear"> - <item android:color="#FFFF1577" android:offset="0"/> - <item android:color="#FFFE116E" android:offset="0.05213103"/> - <item android:color="#FFFC075B" android:offset="0.193"/> - <item android:color="#FFFA0250" android:offset="0.3381"/> - <item android:color="#FFFA004C" android:offset="0.4927"/> - <item android:color="#FFF70D70" android:offset="1"/> + <gradient + android:endX="140.45316" + android:endY="228.05344" + android:startX="167.24734" + android:startY="96.04315" + android:type="linear"> + <item + android:color="#FFFF1577" + android:offset="0" /> + <item + android:color="#FFFE116E" + android:offset="0.05213103" /> + <item + android:color="#FFFC075B" + android:offset="0.193" /> + <item + android:color="#FFFA0250" + android:offset="0.3381" /> + <item + android:color="#FFFA004C" + android:offset="0.4927" /> + <item + android:color="#FFF70D70" + android:offset="1" /> </gradient> </aapt:attr> </path> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml @@ -7,7 +7,7 @@ android:orientation="vertical" tools:context="com.github.cythara.MainActivity"> - <android.support.v7.widget.Toolbar + <androidx.appcompat.widget.Toolbar android:id="@+id/my_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" @@ -25,6 +25,6 @@ android:id="@+id/pitch" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:theme="@style/AppTheme"/> + android:theme="@style/AppTheme" /> -</LinearLayout> -\ No newline at end of file +</LinearLayout> diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> - <background android:drawable="@drawable/ic_launcher_background"/> - <foreground android:drawable="@mipmap/ic_launcher_foreground"/> -</adaptive-icon> -\ No newline at end of file + <background android:drawable="@drawable/ic_launcher_background" /> + <foreground android:drawable="@mipmap/ic_launcher_foreground" /> +</adaptive-icon> diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml @@ -1,12 +1,18 @@ <resources> <string name="app_name">Cythara</string> + <string name="privacy_policy">Datenschutzrichtlinie anzeigen</string> <string name="set_notation">Notation wählen</string> - <string name="toggle_dark_mode">Dunkelmodus umschalten</string> <string name="choose_notation">Wähle die Notation</string> - <string name="permission_required">Berechtigungen erforderlich</string> + <string name="toggle_dark_mode">Dunkelmodus umschalten</string> <string name="set_reference_pitch">Referenztonhöhe einstellen</string> <string name="choose_a_frequency">Wähle eine Frequenz:</string> + <string name="permission_required">Berechtigungen erforderlich</string> + <string name="microphone_permission_required"> + Eine Mikrofongenehmigung ist erforderlich. App wird geschlossen. + </string> + <string name="ok">OK</string> + <string-array name="tunings"> <item>Chromatisch</item> <item>Gitarre (Standard)</item> diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml @@ -2,9 +2,11 @@ <string name="app_name">Cythara</string> <string name="privacy_policy">Erakutsi pribatutasun politika</string> <string name="set_notation">Ezarri notazioa</string> - <string name="toggle_dark_mode">(Des)aktibatu modu iluna</string> <string name="choose_notation">Hautatu notazioa</string> - <string name="permission_required">Baimena behar da</string> + <string name="toggle_dark_mode">(Des)aktibatu modu iluna</string> <string name="set_reference_pitch">Ezarri erreferentzia-tonua</string> <string name="choose_a_frequency">Maiztasun bat hautatu:</string> + <string name="permission_required">Baimena behar da</string> + <string name="microphone_permission_required">Mikrofonoa baimena behar da. Aplikazioa itxi egingo da.</string> + <string name="ok">Ados</string> </resources> diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml @@ -1,27 +1,33 @@ -<resources> - <string name="app_name">Cythara</string> - <string name="privacy_policy">Exibir políticas de privacidade</string> - <string name="set_notation">Definir notação</string> - <string name="choose_notation">Escolher notação</string> - <string name="permission_required">Permissão necessária</string> - <string-array name="tunings"> - <item>Cromático</item> - <item>Violão (padrão)</item> - <item>Violão (Drop D)</item> - <item>Violão (Drop C)</item> - <item>Violão (Drop C#)</item> - <item>Violão (Open G)</item> - <item>Bass (padrão)</item> - <item>Ukulele (padrão)</item> - <item>Ukulele (D tuning)</item> - <item>Violino (padrão)</item> - <item>Cello (padrão)</item> - </string-array> - <string-array name="notations"> - <item name="scientific">Notação científica</item> - <item name="sol">Solfejo</item> - </string-array> - <string name="toggle_dark_mode">Alternar modo escuro</string> - <string name="set_reference_pitch">Definir o passo de referência</string> - <string name="choose_a_frequency">Escolha uma frequência:</string> -</resources> -\ No newline at end of file +<resources> + <string name="app_name">Cythara</string> + + <string name="privacy_policy">Exibir políticas de privacidade</string> + <string name="set_notation">Definir notação</string> + <string name="choose_notation">Escolher notação</string> + <string name="toggle_dark_mode">Alternar modo escuro</string> + <string name="set_reference_pitch">Definir o passo de referência</string> + <string name="choose_a_frequency">Escolha uma frequência:</string> + <string name="permission_required">Permissão necessária</string> + <string name="microphone_permission_required"> + A permissão do microfone é necessária. App será fechado. + </string> + <string name="ok">OK</string> + + <string-array name="tunings"> + <item>Cromático</item> + <item>Violão (padrão)</item> + <item>Violão (Drop D)</item> + <item>Violão (Drop C)</item> + <item>Violão (Drop C#)</item> + <item>Violão (Open G)</item> + <item>Bass (padrão)</item> + <item>Ukulele (padrão)</item> + <item>Ukulele (D tuning)</item> + <item>Violino (padrão)</item> + <item>Cello (padrão)</item> + </string-array> + <string-array name="notations"> + <item name="scientific">Notação científica</item> + <item name="sol">Solfejo</item> + </string-array> +</resources> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml @@ -1,12 +1,20 @@ <resources> <string name="app_name">Cythara</string> + <string name="privacy_policy">Show privacy policy</string> + <string name="privacy_policy_link" translatable="false"> + https://gstraube.github.io/privacy_policy.html + </string> + <string name="set_notation">Set notation</string> - <string name="toggle_dark_mode">Toggle dark mode</string> <string name="choose_notation">Choose notation</string> - <string name="permission_required">Permission required</string> + <string name="toggle_dark_mode">Toggle dark mode</string> <string name="set_reference_pitch">Set reference pitch</string> <string name="choose_a_frequency">Choose a frequency:</string> + <string name="permission_required">Permission required</string> + <string name="microphone_permission_required">Microphone permission is required. App will close.</string> + <string name="ok">OK</string> + <string-array name="tunings"> <item>Chromatic</item> <item>Guitar (standard)</item> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml @@ -1,6 +1,6 @@ <resources> <!-- Base application theme. --> - <style name="AppTheme" parent="Theme.AppCompat.DayNight"/> + <style name="AppTheme" parent="Theme.AppCompat.DayNight" /> </resources> diff --git a/app/src/test/java/com/github/cythara/PitchComparatorTest.java b/app/src/test/java/com/github/cythara/PitchComparatorTest.java @@ -12,14 +12,10 @@ import org.powermock.modules.junit4.PowerMockRunner; import java.util.HashMap; import java.util.Map; -import static com.github.cythara.tuning.GuitarTuning.Pitch.D3; -import static com.github.cythara.tuning.GuitarTuning.Pitch.E2; -import static com.github.cythara.tuning.GuitarTuning.Pitch.E4; -import static com.github.cythara.tuning.GuitarTuning.Pitch.G3; +import static com.github.cythara.tuning.GuitarTuning.Pitch.*; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.closeTo; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.*; @RunWith(PowerMockRunner.class) @PrepareForTest(MainActivity.class) diff --git a/app/src/test/java/com/github/cythara/SamplerTest.java b/app/src/test/java/com/github/cythara/SamplerTest.java @@ -83,4 +83,4 @@ public class SamplerTest { assertThat(note.getName(), either(is(E2.getName())).or(is(B3.getName()))); } -} -\ No newline at end of file +} diff --git a/build.gradle b/build.gradle @@ -2,12 +2,12 @@ buildscript { repositories { - jcenter() google() + jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -16,9 +16,8 @@ buildscript { allprojects { repositories { - jcenter() google() - maven { url "https://maven.google.com" } + jcenter() } } diff --git a/fastlane/Fastfile b/fastlane/Fastfile @@ -1,6 +1,6 @@ # Customize this file, documentation can be found here: # https://docs.fastlane.tools/actions/ -# All available actions: https://docs.fastlane.tools/actions +# All available actions: https://docs.fastlane.tools/actions/ # can also be listed using the `fastlane actions` command # Change the syntax highlighting to Ruby @@ -11,7 +11,7 @@ # This is the minimum version number required. # Update this, if you use features of a newer version -fastlane_version "2.69.3" +fastlane_version "2.115.0" default_platform :android @@ -27,14 +27,14 @@ platform :android do desc "Submit a new Beta Build to Crashlytics Beta" lane :beta do - gradle(task: "assembleRelease") + gradle(task: "assembleDebug") crashlytics # sh "your_script.sh" # You can also use other beta testing services here end - desc "Deploy a new version to the Google Play" + desc "Deploy a new version to Google Play" lane :deploy do gradle(task: "assembleRelease") upload_to_play_store @@ -46,7 +46,7 @@ platform :android do # This block is called, only if the executed lane was successful # slack( - # message: "Successfully deployed new App Update." + # message: "Successfully deployed the new app update." # ) end @@ -58,8 +58,8 @@ platform :android do end end -# More information about multiple platforms in fastlane: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform -# All available actions: https://docs.fastlane.tools/actions +# More information about multiple platforms in fastlane: https://docs.fastlane.tools/advanced/lanes/#control-configuration-by-lane-and-by-platform +# All available actions: https://docs.fastlane.tools/actions/ # fastlane reports which actions are used. No personal data is recorded. # Learn more at https://docs.fastlane.tools/#metrics diff --git a/gradle.properties b/gradle.properties @@ -9,6 +9,8 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. +android.enableJetifier=true +android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar Binary files differ. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.2-rc-1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew @@ -28,7 +28,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome