From 3234a8e01f96f29c4a58cf3ef6fdae70ddb47dc1 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Fri, 24 Feb 2017 18:10:14 +0300 Subject: [PATCH] drop library --- android-audio-library/.gitignore | 1 - android-audio-library/build.gradle | 130 ---- android-audio-library/proguard-rules.pro | 17 - .../audiolibrary/ExampleInstrumentedTest.java | 26 - .../src/main/AndroidManifest.xml | 9 - .../animations/RecordingAnimation.java | 113 --- .../audiolibrary/app/MainApplication.java | 82 --- .../axet/audiolibrary/app/RawSamples.java | 145 ---- .../axet/audiolibrary/app/Recordings.java | 451 ------------ .../github/axet/audiolibrary/app/Sound.java | 61 -- .../github/axet/audiolibrary/app/Storage.java | 283 ------- .../axet/audiolibrary/encoders/Encoder.java | 7 - .../audiolibrary/encoders/EncoderInfo.java | 13 - .../axet/audiolibrary/encoders/Factory.java | 96 --- .../audiolibrary/encoders/FileEncoder.java | 89 --- .../axet/audiolibrary/encoders/Format3GP.java | 36 - .../axet/audiolibrary/encoders/FormatM4A.java | 24 - .../axet/audiolibrary/encoders/FormatMKA.java | 187 ----- .../axet/audiolibrary/encoders/FormatOGG.java | 43 -- .../axet/audiolibrary/encoders/FormatWAV.java | 133 ---- .../axet/audiolibrary/encoders/MuxerMP4.java | 182 ----- .../axet/audiolibrary/widgets/FFTBarView.java | 100 --- .../audiolibrary/widgets/FFTChartView.java | 89 --- .../axet/audiolibrary/widgets/FFTView.java | 146 ---- .../axet/audiolibrary/widgets/PitchView.java | 693 ------------------ .../res/drawable/ic_create_black_24dp.xml | 9 - .../res/drawable/ic_delete_black_24dp.xml | 9 - .../src/main/res/drawable/ic_mic_24dp.xml | 9 - .../main/res/drawable/ic_pause_black_24dp.xml | 9 - .../res/drawable/ic_play_arrow_black_24dp.xml | 9 - .../main/res/drawable/ic_share_black_24dp.xml | 9 - .../main/res/drawable/round_button_dark.xml | 12 - .../main/res/drawable/round_button_light.xml | 12 - .../res/layout/notifictaion_recording.xml | 60 -- .../layout/notifictaion_recording_dark.xml | 8 - .../layout/notifictaion_recording_light.xml | 8 - .../src/main/res/layout/recording.xml | 166 ----- .../src/main/res/menu/menu_context.xml | 15 - .../src/main/res/values-ru/strings.xml | 17 - .../src/main/res/values/attrs.xml | 6 - .../src/main/res/values/colors.xml | 8 - .../src/main/res/values/strings.xml | 23 - .../src/main/res/values/styles.xml | 48 -- .../axet/audiolibrary/ExampleUnitTest.java | 17 - 44 files changed, 3610 deletions(-) delete mode 100644 android-audio-library/.gitignore delete mode 100644 android-audio-library/build.gradle delete mode 100644 android-audio-library/proguard-rules.pro delete mode 100644 android-audio-library/src/androidTest/java/com/github/axet/audiolibrary/ExampleInstrumentedTest.java delete mode 100644 android-audio-library/src/main/AndroidManifest.xml delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/animations/RecordingAnimation.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/app/MainApplication.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/app/RawSamples.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Recordings.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Sound.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Storage.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Encoder.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/EncoderInfo.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Factory.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FileEncoder.java delete mode 100755 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Format3GP.java delete mode 100755 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatM4A.java delete mode 100755 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatMKA.java delete mode 100755 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatOGG.java delete mode 100755 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatWAV.java delete mode 100755 android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/MuxerMP4.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTBarView.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTChartView.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTView.java delete mode 100644 android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/PitchView.java delete mode 100644 android-audio-library/src/main/res/drawable/ic_create_black_24dp.xml delete mode 100644 android-audio-library/src/main/res/drawable/ic_delete_black_24dp.xml delete mode 100644 android-audio-library/src/main/res/drawable/ic_mic_24dp.xml delete mode 100644 android-audio-library/src/main/res/drawable/ic_pause_black_24dp.xml delete mode 100644 android-audio-library/src/main/res/drawable/ic_play_arrow_black_24dp.xml delete mode 100644 android-audio-library/src/main/res/drawable/ic_share_black_24dp.xml delete mode 100644 android-audio-library/src/main/res/drawable/round_button_dark.xml delete mode 100644 android-audio-library/src/main/res/drawable/round_button_light.xml delete mode 100644 android-audio-library/src/main/res/layout/notifictaion_recording.xml delete mode 100644 android-audio-library/src/main/res/layout/notifictaion_recording_dark.xml delete mode 100644 android-audio-library/src/main/res/layout/notifictaion_recording_light.xml delete mode 100644 android-audio-library/src/main/res/layout/recording.xml delete mode 100644 android-audio-library/src/main/res/menu/menu_context.xml delete mode 100644 android-audio-library/src/main/res/values-ru/strings.xml delete mode 100644 android-audio-library/src/main/res/values/attrs.xml delete mode 100644 android-audio-library/src/main/res/values/colors.xml delete mode 100644 android-audio-library/src/main/res/values/strings.xml delete mode 100644 android-audio-library/src/main/res/values/styles.xml delete mode 100644 android-audio-library/src/test/java/com/github/axet/audiolibrary/ExampleUnitTest.java diff --git a/android-audio-library/.gitignore b/android-audio-library/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/android-audio-library/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/android-audio-library/build.gradle b/android-audio-library/build.gradle deleted file mode 100644 index aef4c41..0000000 --- a/android-audio-library/build.gradle +++ /dev/null @@ -1,130 +0,0 @@ -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' - } -} - -repositories { - jcenter() - mavenLocal() -} - -apply plugin: 'com.android.library' -apply plugin: 'maven' -apply plugin: 'signing' -apply plugin: 'com.github.dcendents.android-maven' // 'gradle install' task - -android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" - - defaultConfig { - minSdkVersion 9 - targetSdkVersion 25 - versionCode 2 - versionName "0.0.2" - - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -task javadoc(type: Javadoc) { - source = android.sourceSets.main.java.srcDirs - classpath += project.files(project.android.getBootClasspath().join(File.pathSeparator)) - android.libraryVariants.all { variant -> - classpath += files(variant.javaCompile.classpath.files) - } -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -task sourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.java.srcDirs -} - -artifacts { - archives javadocJar, sourcesJar -} - -signing { - sign configurations.archives -} - -group = "com.github.axet" -archivesBaseName = "android-audio-library" -version = android.defaultConfig.versionName - -uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - - snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - - pom.project { - name 'Android Library' - packaging 'jar' - // optionally artifactId can be defined here - description 'Android Simple Widgets and Support classes.' - url 'https://gitlab.com/axet/android-audio-library' - - scm { - connection 'scm:git:https://gitlab.com/axet/android-library' - developerConnection 'scm:git:https://gitlab.com/axet/android-library' - url 'https://gitlab.com/axet/android-audio-library' - } - - licenses { - license { - name 'GNU LESSER GENERAL PUBLIC LICENSE 3.0' - url 'http://www.gnu.org/copyleft/lesser.html' - } - } - - developers { - developer { - id 'axet' - name 'Alexey Kuznetsov' - email 'axet@me.com' - } - } - } - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - compile 'com.android.support:design:25.2.0' - compile 'com.android.support:appcompat-v7:25.2.0' - compile 'com.google.android.gms:play-services-appindexing:9.8.0' - compile 'org.apache.commons:commons-math3:3.6.1' - compile 'com.github.axet:android-library:1.9.9' //compile project(':android-library') - compile 'com.github.axet:jebml:0.0.2' // compile project(':jebml') - compile 'com.github.axet:vorbis:1.0.0' // compile project(':vorbis') - testCompile 'junit:junit:4.12' -} diff --git a/android-audio-library/proguard-rules.pro b/android-audio-library/proguard-rules.pro deleted file mode 100644 index f45cfad..0000000 --- a/android-audio-library/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/axet/Library/Android/sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/android-audio-library/src/androidTest/java/com/github/axet/audiolibrary/ExampleInstrumentedTest.java b/android-audio-library/src/androidTest/java/com/github/axet/audiolibrary/ExampleInstrumentedTest.java deleted file mode 100644 index 886cace..0000000 --- a/android-audio-library/src/androidTest/java/com/github/axet/audiolibrary/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.axet.audiolibrary; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumentation test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("com.github.axet.audiolibrary.test", appContext.getPackageName()); - } -} diff --git a/android-audio-library/src/main/AndroidManifest.xml b/android-audio-library/src/main/AndroidManifest.xml deleted file mode 100644 index dbe8071..0000000 --- a/android-audio-library/src/main/AndroidManifest.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/animations/RecordingAnimation.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/animations/RecordingAnimation.java deleted file mode 100644 index d7d8f93..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/animations/RecordingAnimation.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.github.axet.audiolibrary.animations; - -import android.annotation.TargetApi; -import android.os.Build; -import android.os.Handler; -import android.view.View; -import android.view.animation.Transformation; -import android.widget.ListView; - -import com.github.axet.androidlibrary.animations.MarginAnimation; -import com.github.axet.audiolibrary.R; - -public class RecordingAnimation extends MarginAnimation { - ListView list; - - View convertView; - - boolean partial; - Handler handler; - - // if we have two concurrent animations on the same listview - // the only one 'expand' should have control of showChild function. - static RecordingAnimation atomicExpander; - - public static void apply(final ListView list, final View v, final boolean expand, boolean animate) { - apply(new LateCreator() { - @Override - public MarginAnimation create() { - RecordingAnimation a = new RecordingAnimation(list, v, expand); - if (expand) - atomicExpander = a; - return a; - } - }, v, expand, animate); - } - - public RecordingAnimation(ListView list, View v, boolean expand) { - super(v.findViewById(R.id.recording_player), expand); - - handler = new Handler(); - - this.convertView = v; - this.list = list; - } - - @Override - public void init() { - super.init(); - - { - final int paddedTop = list.getListPaddingTop(); - final int paddedBottom = list.getHeight() - list.getListPaddingTop() - list.getListPaddingBottom(); - - partial = false; - - partial |= convertView.getTop() < paddedTop; - partial |= convertView.getBottom() > paddedBottom; - } - } - - @Override - public void calc(final float i, Transformation t) { - super.calc(i, t); - - float ii = expand ? i : 1 - i; - - // ViewGroup will crash on null pointer without this post pone. - // seems like some views are removed by RecyvingView when they - // gone off screen. - if (Build.VERSION.SDK_INT >= 19) { - if (!expand && atomicExpander != null && !atomicExpander.hasEnded()) { - // do not showChild; - } else { - handler.post(new Runnable() { - @Override - public void run() { - showChild(i); - } - }); - } - } - } - - @TargetApi(19) - void showChild(float i) { - final int paddedTop = list.getListPaddingTop(); - final int paddedBottom = list.getHeight() - list.getListPaddingTop() - list.getListPaddingBottom(); - - if (convertView.getTop() < paddedTop) { - int off = convertView.getTop() - paddedTop; - if (partial) - off = (int) (off * i); - list.scrollListBy(off); - } - - if (convertView.getBottom() > paddedBottom) { - int off = convertView.getBottom() - paddedBottom; - if (partial) - off = (int) (off * i); - list.scrollListBy(off); - } - } - - @Override - public void restore() { - super.restore(); - } - - @Override - public void end() { - super.end(); - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/MainApplication.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/MainApplication.java deleted file mode 100644 index 9884783..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/MainApplication.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.github.axet.audiolibrary.app; - -import android.app.Application; -import android.content.Context; -import android.content.SharedPreferences; -import android.media.AudioFormat; -import android.preference.PreferenceManager; - -import com.github.axet.androidlibrary.app.MainLibrary; -import com.github.axet.audiolibrary.R; - -public class MainApplication extends Application { - public static final String PREFERENCE_STORAGE = "storage_path"; - public static final String PREFERENCE_RATE = "sample_rate"; - public static final String PREFERENCE_CALL = "call"; - public static final String PREFERENCE_SILENT = "silence"; - public static final String PREFERENCE_ENCODING = "encoding"; - public static final String PREFERENCE_LAST = "last_recording"; - public static final String PREFERENCE_THEME = "theme"; - public static final String PREFERENCE_CHANNELS = "channels"; - - @Override - public void onCreate() { - super.onCreate(); - Context context = this; - context.setTheme(getUserTheme()); - } - - public int getUserTheme() { - return getTheme(this, R.style.AppThemeLight, R.style.AppThemeDark); - } - - public static int getTheme(Context context, int light, int dark) { - final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context); - String theme = shared.getString(PREFERENCE_THEME, ""); - if (theme.equals("Theme_Dark")) { - return dark; - } else { - return light; - } - } - - public String formatFree(long free, long left) { - String str = ""; - - long diff = left; - - int diffSeconds = (int) (diff / 1000 % 60); - int diffMinutes = (int) (diff / (60 * 1000) % 60); - int diffHours = (int) (diff / (60 * 60 * 1000) % 24); - int diffDays = (int) (diff / (24 * 60 * 60 * 1000)); - - if (diffDays > 0) { - str = getResources().getQuantityString(R.plurals.days, diffDays, diffDays); - } else if (diffHours > 0) { - str = getResources().getQuantityString(R.plurals.hours, diffHours, diffHours); - } else if (diffMinutes > 0) { - str = getResources().getQuantityString(R.plurals.minutes, diffMinutes, diffMinutes); - } else if (diffSeconds > 0) { - str = getResources().getQuantityString(R.plurals.seconds, diffSeconds, diffSeconds); - } - - return getString(R.string.title_header, MainLibrary.formatSize(this, free), str); - } - - public static int getChannels(Context context) { - final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context); - int i = Integer.parseInt(shared.getString(MainApplication.PREFERENCE_CHANNELS, "1")); - return i; - } - - public static int getMode(Context context) { - switch (getChannels(context)) { - case 1: - return AudioFormat.CHANNEL_IN_MONO; - case 2: - return AudioFormat.CHANNEL_IN_STEREO; - default: - throw new RuntimeException("unknown mode"); - } - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/RawSamples.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/RawSamples.java deleted file mode 100644 index 4b4d943..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/RawSamples.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.github.axet.audiolibrary.app; - -import android.media.AudioFormat; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; - -public class RawSamples { - File in; - - InputStream is; - byte[] readBuffer; - - OutputStream os; - - public RawSamples(File in) { - this.in = in; - } - - // open for writing with specified offset to truncate file - public void open(long writeOffset) { - trunk(writeOffset); - try { - os = new BufferedOutputStream(new FileOutputStream(in, true)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - // open for reading - // - // bufReadSize - samples count - public void open(int bufReadSize) { - try { - readBuffer = new byte[(int) getBufferLen(bufReadSize)]; - is = new FileInputStream(in); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - // open for read with initial offset and buffer read size - // - // offset - samples offset - // bufReadSize - samples size - public void open(long offset, int bufReadSize) { - try { - readBuffer = new byte[(int) getBufferLen(bufReadSize)]; - is = new FileInputStream(in); - is.skip(offset * (Sound.AUDIO_FORMAT == AudioFormat.ENCODING_PCM_16BIT ? 2 : 1)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public int read(short[] buf) { - try { - int len = is.read(readBuffer); - if (len <= 0) - return 0; - ByteBuffer.wrap(readBuffer, 0, len).order(ByteOrder.BIG_ENDIAN).asShortBuffer().get(buf, 0, (int) getSamples(len)); - return (int) getSamples(len); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void write(short val) { - try { - ByteBuffer bb = ByteBuffer.allocate(Short.SIZE / Byte.SIZE); - bb.order(ByteOrder.BIG_ENDIAN); - bb.putShort(val); - os.write(bb.array(), 0, bb.limit()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void write(short[] buf, int len) { - for (int i = 0; i < len; i++) { - write(buf[i]); - } - } - - public long getSamples() { - return getSamples(in.length()); - } - - public static long getSamples(long len) { - return len / (Sound.AUDIO_FORMAT == AudioFormat.ENCODING_PCM_16BIT ? 2 : 1); - } - - public static long getBufferLen(long samples) { - return samples * (Sound.AUDIO_FORMAT == AudioFormat.ENCODING_PCM_16BIT ? 2 : 1); - } - - public void trunk(long pos) { - try { - FileChannel outChan = new FileOutputStream(in, true).getChannel(); - outChan.truncate(getBufferLen(pos)); - outChan.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static double getAmplitude(short[] buffer, int offset, int len) { - double sum = 0; - for (int i = offset; i < offset + len; i++) { - sum += buffer[i] * buffer[i]; - } - return Math.sqrt(sum / len); - } - - public static double getDB(short[] buffer, int offset, int len) { - return getDB(getAmplitude(buffer, offset, len)); - } - - public static double getDB(double amplitude) { - // https://en.wikipedia.org/wiki/Sound_pressure - return 20.0 * Math.log10(amplitude / 0x7FFF); - } - - public void close() { - try { - if (is != null) - is.close(); - is = null; - - if (os != null) - os.close(); - os = null; - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Recordings.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Recordings.java deleted file mode 100644 index 5300cf7..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Recordings.java +++ /dev/null @@ -1,451 +0,0 @@ -package com.github.axet.audiolibrary.app; - -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.media.MediaPlayer; -import android.net.Uri; -import android.os.Handler; -import android.support.v7.app.AlertDialog; -import android.support.v7.widget.PopupMenu; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AbsListView; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.SeekBar; -import android.widget.TextView; -import android.widget.Toast; - -import com.github.axet.androidlibrary.animations.RemoveItemAnimation; -import com.github.axet.androidlibrary.app.MainLibrary; -import com.github.axet.androidlibrary.widgets.OpenFileDialog; -import com.github.axet.androidlibrary.widgets.PopupShareActionProvider; -import com.github.axet.audiolibrary.R; -import com.github.axet.audiolibrary.animations.RecordingAnimation; -import com.github.axet.audiolibrary.encoders.Factory; - -import java.io.File; -import java.text.SimpleDateFormat; -import java.util.Comparator; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -public class Recordings extends ArrayAdapter implements AbsListView.OnScrollListener { - public static String TAG = Recordings.class.getSimpleName(); - - static final int TYPE_COLLAPSED = 0; - static final int TYPE_EXPANDED = 1; - static final int TYPE_DELETED = 2; - - public static class SortFiles implements Comparator { - @Override - public int compare(File file, File file2) { - if (file.isDirectory() && file2.isFile()) - return -1; - else if (file.isFile() && file2.isDirectory()) - return 1; - else - return file.getPath().compareTo(file2.getPath()); - } - } - - Handler handler; - Storage storage; - MediaPlayer player; - Runnable updatePlayer; - int selected = -1; - ListView list; - PopupShareActionProvider shareProvider; - int scrollState; - - Map durations = new TreeMap<>(); - - public Recordings(Context context, ListView list) { - super(context, 0); - this.list = list; - this.handler = new Handler(); - this.storage = new Storage(context); - this.list.setOnScrollListener(this); - } - - - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - this.scrollState = scrollState; - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - } - - public void scan(File dir) { - setNotifyOnChange(false); - clear(); - durations.clear(); - - List ff = storage.scan(dir); - - for (File f : ff) { - if (f.isFile()) { - MediaPlayer mp = null; - try { - mp = MediaPlayer.create(getContext(), Uri.fromFile(f)); - } catch (IllegalStateException e) { - Log.d(TAG, f.toString(), e); - } - if (mp != null) { - int d = mp.getDuration(); - mp.release(); - durations.put(f, d); - add(f); - } else { - Log.e(TAG, f.toString()); - } - } - } - - sort(); - notifyDataSetChanged(); - } - - public void sort() { - sort(new SortFiles()); - } - - public void close() { - if (player != null) { - player.release(); - player = null; - } - if (updatePlayer != null) { - handler.removeCallbacks(updatePlayer); - updatePlayer = null; - } - } - - public void load() { - scan(storage.getStoragePath()); - } - - @Override - public View getView(final int position, View convertView, ViewGroup parent) { - LayoutInflater inflater = LayoutInflater.from(getContext()); - - if (convertView == null) { - convertView = inflater.inflate(R.layout.recording, parent, false); - convertView.setTag(-1); - } - - final View view = convertView; - final View base = convertView.findViewById(R.id.recording_base); - - if ((int) convertView.getTag() == TYPE_DELETED) { - RemoveItemAnimation.restore(base); - convertView.setTag(-1); - } - - final File f = getItem(position); - - TextView title = (TextView) convertView.findViewById(R.id.recording_title); - title.setText(f.getName()); - - SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - TextView time = (TextView) convertView.findViewById(R.id.recording_time); - time.setText(s.format(new Date(f.lastModified()))); - - TextView dur = (TextView) convertView.findViewById(R.id.recording_duration); - dur.setText(MainLibrary.formatDuration(getContext(), durations.get(f))); - - TextView size = (TextView) convertView.findViewById(R.id.recording_size); - size.setText(MainLibrary.formatSize(getContext(), f.length())); - - final View playerBase = convertView.findViewById(R.id.recording_player); - playerBase.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - } - }); - - final Runnable delete = new Runnable() { - @Override - public void run() { - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - builder.setTitle(R.string.delete_recording); - builder.setMessage("...\\" + f.getName() + "\n\n" + getContext().getString(R.string.are_you_sure)); - builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - playerStop(); - dialog.cancel(); - RemoveItemAnimation.apply(list, base, new Runnable() { - @Override - public void run() { - f.delete(); - view.setTag(TYPE_DELETED); - select(-1); - load(); - } - }); - } - }); - builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - builder.show(); - } - }; - - final Runnable rename = new Runnable() { - @Override - public void run() { - final OpenFileDialog.EditTextDialog e = new OpenFileDialog.EditTextDialog(getContext()); - e.setTitle(getContext().getString(R.string.rename_recording)); - e.setText(Storage.getNameNoExt(f)); - e.setPositiveButton(new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - String ext = Storage.getExt(f); - String s = String.format("%s.%s", e.getText(), ext); - File ff = new File(f.getParent(), s); - f.renameTo(ff); - load(); - } - }); - e.show(); - - } - }; - - if (selected == position) { - RecordingAnimation.apply(list, convertView, true, scrollState == SCROLL_STATE_IDLE && (int) convertView.getTag() == TYPE_COLLAPSED); - convertView.setTag(TYPE_EXPANDED); - - updatePlayerText(convertView, f); - - final View play = convertView.findViewById(R.id.recording_player_play); - play.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (player == null) { - playerPlay(playerBase, f); - } else if (player.isPlaying()) { - playerPause(playerBase, f); - } else { - playerPlay(playerBase, f); - } - } - }); - - final View edit = convertView.findViewById(R.id.recording_player_edit); - edit.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - rename.run(); - } - }); - - final View share = convertView.findViewById(R.id.recording_player_share); - share.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - shareProvider = new PopupShareActionProvider(getContext(), share); - - Intent emailIntent = new Intent(Intent.ACTION_SEND); - emailIntent.setType(Factory.MP4A); - emailIntent.putExtra(Intent.EXTRA_EMAIL, ""); - emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f)); - emailIntent.putExtra(Intent.EXTRA_SUBJECT, f.getName()); - emailIntent.putExtra(Intent.EXTRA_TEXT, getContext().getString(R.string.shared_via, getContext().getString(R.string.app_name))); - - shareProvider.setShareIntent(emailIntent); - - shareProvider.show(); - } - }); - - View trash = convertView.findViewById(R.id.recording_player_trash); - trash.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - delete.run(); - } - }); - - convertView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - select(-1); - } - }); - } else { - RecordingAnimation.apply(list, convertView, false, scrollState == SCROLL_STATE_IDLE && (int) convertView.getTag() == TYPE_EXPANDED); - convertView.setTag(TYPE_COLLAPSED); - - convertView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - select(position); - } - }); - } - - convertView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - PopupMenu popup = new PopupMenu(getContext(), v); - MenuInflater inflater = popup.getMenuInflater(); - inflater.inflate(R.menu.menu_context, popup.getMenu()); - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - if (item.getItemId() == R.id.action_delete) { - delete.run(); - return true; - } - if (item.getItemId() == R.id.action_rename) { - rename.run(); - return true; - } - return false; - } - }); - popup.show(); - return true; - } - }); - - return convertView; - } - - void playerPlay(View v, File f) { - if (player == null) - player = MediaPlayer.create(getContext(), Uri.fromFile(f)); - if (player == null) { - Toast.makeText(getContext(), R.string.file_not_found, Toast.LENGTH_SHORT).show(); - return; - } - player.start(); - - updatePlayerRun(v, f); - } - - void playerPause(View v, File f) { - if (player != null) { - player.pause(); - } - if (updatePlayer != null) { - handler.removeCallbacks(updatePlayer); - updatePlayer = null; - } - updatePlayerText(v, f); - } - - void playerStop() { - if (updatePlayer != null) { - handler.removeCallbacks(updatePlayer); - updatePlayer = null; - } - if (player != null) { - player.stop(); - player.release(); - player = null; - } - } - - void updatePlayerRun(final View v, final File f) { - boolean playing = updatePlayerText(v, f); - - if (updatePlayer != null) { - handler.removeCallbacks(updatePlayer); - updatePlayer = null; - } - - if (!playing) { - playerStop(); // clear player instance - updatePlayerText(v, f); // update length - return; - } - - updatePlayer = new Runnable() { - @Override - public void run() { - updatePlayerRun(v, f); - } - }; - handler.postDelayed(updatePlayer, 200); - } - - boolean updatePlayerText(final View v, final File f) { - ImageView i = (ImageView) v.findViewById(R.id.recording_player_play); - - final boolean playing = player != null && player.isPlaying(); - - i.setImageResource(playing ? R.drawable.ic_pause_black_24dp : R.drawable.ic_play_arrow_black_24dp); - - TextView start = (TextView) v.findViewById(R.id.recording_player_start); - SeekBar bar = (SeekBar) v.findViewById(R.id.recording_player_seek); - TextView end = (TextView) v.findViewById(R.id.recording_player_end); - - int c = 0; - int d = durations.get(f); - - if (player != null) { - c = player.getCurrentPosition(); - d = player.getDuration(); - } - - bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (!fromUser) - return; - - if (player == null) - playerPlay(v, f); - - if (player != null) { - player.seekTo(progress); - if (!player.isPlaying()) - playerPlay(v, f); - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - - start.setText(MainLibrary.formatDuration(getContext(), c)); - bar.setMax(d); - bar.setKeyProgressIncrement(1); - bar.setProgress(c); - end.setText("-" + MainLibrary.formatDuration(getContext(), d - c)); - - return playing; - } - - public void select(int pos) { - selected = pos; - notifyDataSetChanged(); - playerStop(); - } - - public int getSelected() { - return selected; - } -} \ No newline at end of file diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Sound.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Sound.java deleted file mode 100644 index 543b3e5..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Sound.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.github.axet.audiolibrary.app; - -import android.content.Context; -import android.content.SharedPreferences; -import android.media.AudioFormat; -import android.media.AudioManager; -import android.media.AudioTrack; -import android.preference.PreferenceManager; - -public class Sound extends com.github.axet.androidlibrary.sound.Sound { - public static int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; - // quite root gives me 20db - public static int NOISE_DB = 20; - // max 90 dB detection for android mic - public static int MAXIMUM_DB = 90; - - public Sound(Context context) { - super(context); - } - - public void silent() { - SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context); - if (shared.getBoolean(MainApplication.PREFERENCE_SILENT, false)) { - super.silent(); - } - } - - public void unsilent() { - SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context); - if (shared.getBoolean(MainApplication.PREFERENCE_SILENT, false)) { - super.unsilent(); - } - } - - public AudioTrack generateTrack(int sampleRate, short[] buf, int len) { - int end = len; - - int c = 0; - - switch (MainApplication.getChannels(context)) { - case 1: - c = AudioFormat.CHANNEL_OUT_MONO; - break; - case 2: - c = AudioFormat.CHANNEL_OUT_STEREO; - break; - default: - throw new RuntimeException("unknown mode"); - } - - // old phones bug. - // http://stackoverflow.com/questions/27602492 - // - // with MODE_STATIC setNotificationMarkerPosition not called - AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, c, AUDIO_FORMAT, len * (Short.SIZE / 8), AudioTrack.MODE_STREAM); - track.write(buf, 0, len); - if (track.setNotificationMarkerPosition(end) != AudioTrack.SUCCESS) - throw new RuntimeException("unable to set marker"); - return track; - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Storage.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Storage.java deleted file mode 100644 index 37c0379..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/app/Storage.java +++ /dev/null @@ -1,283 +0,0 @@ -package com.github.axet.audiolibrary.app; - -import android.Manifest; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.StatFs; -import android.preference.PreferenceManager; -import android.support.v4.content.ContextCompat; - -import com.github.axet.audiolibrary.encoders.Factory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -public class Storage { - public static final String TMP_REC = "recorind.data"; - public static final String RECORDINGS = "recordings"; - - protected Context context; - - public Storage(Context context) { - this.context = context; - } - - public static final String[] PERMISSIONS = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; - - public boolean permitted(String[] ss) { - if (Build.VERSION.SDK_INT < 11) - return true; - for (String s : ss) { - if (ContextCompat.checkSelfPermission(context, s) != PackageManager.PERMISSION_GRANTED) { - return false; - } - } - return true; - } - - public File getLocalStorage() { - return new File(context.getApplicationInfo().dataDir, RECORDINGS); - } - - public boolean isLocalStorageEmpty() { - return getLocalStorage().listFiles().length == 0; - } - - public boolean isExternalStoragePermitted() { - return permitted(PERMISSIONS); - } - - public boolean recordingPending() { - return getTempRecording().exists(); - } - - public File getStoragePath() { - SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context); - String path = shared.getString(MainApplication.PREFERENCE_STORAGE, ""); - if (permitted(PERMISSIONS)) { - return new File(path); - } else { - return getLocalStorage(); - } - } - - public void migrateLocalStorage() { - if (!permitted(PERMISSIONS)) { - return; - } - - SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context); - String path = shared.getString(MainApplication.PREFERENCE_STORAGE, ""); - - File l = getLocalStorage(); - File t = new File(path); - - t.mkdirs(); - - File[] ff = l.listFiles(); - - if (ff == null) - return; - - for (File f : ff) { - File tt = getNextFile(t, f); - move(f, tt); - } - } - - public File getNewFile() { - SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH.mm.ss"); - - SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context); - String ext = shared.getString(MainApplication.PREFERENCE_ENCODING, ""); - - File parent = getStoragePath(); - if (!parent.exists()) { - if (!parent.mkdirs()) - throw new RuntimeException("Unable to create: " + parent); - } - - return getNextFile(parent, s.format(new Date()), ext); - } - - public static String getNameNoExt(File f) { - String fileName = f.getName(); - - int i = fileName.lastIndexOf('.'); - if (i > 0) { - fileName = fileName.substring(0, i); - } - return fileName; - } - - public static String getExt(File f) { - String fileName = f.getName(); - - int i = fileName.lastIndexOf('.'); - if (i > 0) { - return fileName.substring(i + 1); - } - return ""; - } - - File getNextFile(File parent, File f) { - String fileName = f.getName(); - - String extension = ""; - - int i = fileName.lastIndexOf('.'); - if (i > 0) { - extension = fileName.substring(i + 1); - fileName = fileName.substring(0, i); - } - - return getNextFile(parent, fileName, extension); - } - - protected File getNextFile(File parent, String name, String ext) { - String fileName; - if (ext.isEmpty()) - fileName = name; - else - fileName = String.format("%s.%s", name, ext); - - File file = new File(parent, fileName); - - int i = 1; - while (file.exists()) { - fileName = String.format("%s (%d).%s", name, i, ext); - file = new File(parent, fileName); - i++; - } - -// try { -// file.createNewFile(); -// } catch (IOException e) { -// throw new RuntimeException("Unable to create: " + file, e); -// } - - return file; - } - - public List scan(File dir) { - ArrayList list = new ArrayList<>(); - - File[] ff = dir.listFiles(); - if (ff == null) - return list; - - for (File f : ff) { - if (f.length() > 0) { - String[] ee = Factory.getEncodingValues(context); - String n = f.getName().toLowerCase(); - for (String e : ee) { - if (n.endsWith("." + e)) - list.add(f); - } - } - } - - return list; - } - - // get average recording miliseconds based on compression format - public long average(long free) { - final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context); - int rate = Integer.parseInt(shared.getString(MainApplication.PREFERENCE_RATE, "")); - String ext = shared.getString(MainApplication.PREFERENCE_ENCODING, ""); - - int m = MainApplication.getChannels(context); - long perSec = Factory.getEncoderRate(ext, rate) * m; - return free / perSec * 1000; - } - - public long getFree(File f) { - while (!f.exists()) - f = f.getParentFile(); - - StatFs fsi = new StatFs(f.getPath()); - if (Build.VERSION.SDK_INT < 18) - return fsi.getBlockSize() * (long) fsi.getAvailableBlocks(); - else - return fsi.getBlockSizeLong() * fsi.getAvailableBlocksLong(); - } - - public File getTempRecording() { - File internal = new File(context.getApplicationInfo().dataDir, TMP_REC); - - if (internal.exists()) - return internal; - - // Starting in KITKAT, no permissions are required to read or write to the returned path; - // it's always accessible to the calling app. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - if (!permitted(PERMISSIONS)) - return internal; - } - - File c = context.getExternalCacheDir(); - if (c == null) // some old phones 11 with disabled sdcard return null - return internal; - - File external = new File(c, TMP_REC); - - if (external.exists()) - return external; - - long freeI = getFree(internal); - long freeE = getFree(external); - - if (freeI > freeE) - return internal; - else - return external; - } - - public FileOutputStream open(File f) { - File tmp = f; - File parent = tmp.getParentFile(); - if (!parent.exists() && !parent.mkdirs()) { - throw new RuntimeException("unable to create: " + parent); - } - if (!parent.isDirectory()) - throw new RuntimeException("target is not a dir: " + parent); - try { - return new FileOutputStream(tmp, true); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void delete(File f) { - f.delete(); - } - - public void move(File f, File to) { - try { - InputStream in = new FileInputStream(f); - OutputStream out = new FileOutputStream(to); - - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - in.close(); - out.close(); - f.delete(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Encoder.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Encoder.java deleted file mode 100644 index 69620fb..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Encoder.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -public interface Encoder { - void encode(short[] buf, int len); - - void close(); -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/EncoderInfo.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/EncoderInfo.java deleted file mode 100644 index 3213f8a..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/EncoderInfo.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -public class EncoderInfo { - public int channels; - public int sampleRate; - public int bps; - - public EncoderInfo(int channels, int sampleRate, int bps) { - this.channels = channels; - this.sampleRate = sampleRate; - this.bps = bps; - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Factory.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Factory.java deleted file mode 100644 index 7f281b7..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Factory.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -import android.content.Context; -import android.media.AudioFormat; -import android.os.Build; - -import com.github.axet.audiolibrary.R; -import com.github.axet.audiolibrary.app.RawSamples; -import com.github.axet.audiolibrary.app.Sound; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; - -public class Factory { - - public static String MP4 = "audio/mp4"; - public static String MP4A = "audio/mp4a-latm"; - - public static CharSequence[] getEncodingTexts(Context context) { - String[] aa = context.getResources().getStringArray(R.array.encodings_text); - ArrayList ll = new ArrayList<>(Arrays.asList(aa)); - if (Build.VERSION.SDK_INT >= 18) - ll.add(".m4a"); - if (Build.VERSION.SDK_INT >= 16) - ll.add(".mka"); - ll.add(".ogg"); - return ll.toArray(new String[]{}); - } - - public static String[] getEncodingValues(Context context) { - String[] aa = context.getResources().getStringArray(R.array.encodings_values); - ArrayList ll = new ArrayList<>(Arrays.asList(aa)); - if (Build.VERSION.SDK_INT >= 18) - ll.add("m4a"); - if (Build.VERSION.SDK_INT >= 16) - ll.add("mka"); - ll.add("ogg"); - return ll.toArray(new String[]{}); - } - - public static Encoder getEncoder(String ext, EncoderInfo info, File out) { - if (ext.equals("wav")) { - return new FormatWAV(info, out); - } - if (ext.equals("3gp")) { - return new Format3GP(info, out); - } - if (ext.equals("m4a")) { - return new FormatM4A(info, out); - } - if (ext.equals("mka")) { - return new FormatMKA(info, out); - } - if (ext.equals("ogg")) { - return new FormatOGG(info, out); - } - return null; - } - - public static long getEncoderRate(String ext, int rate) { - if (ext.equals("m4a")) { - long y1 = 365723; // one minute sample 16000Hz - long x1 = 16000; // at 16000 - long y2 = 493743; // one minute sample - long x2 = 44000; // at 44000 - long x = rate; - long y = (x - x1) * (y2 - y1) / (x2 - x1) + y1; - return y / 60; - } - - if (ext.equals("mka")) { // same codec as m4a, but different container - long y1 = 365723; // one minute sample 16000Hz - long x1 = 16000; // at 16000 - long y2 = 493743; // one minute sample - long x2 = 44000; // at 44000 - long x = rate; - long y = (x - x1) * (y2 - y1) / (x2 - x1) + y1; - return y / 60; - } - - if (ext.equals("ogg")) { - long y1 = 174892; // one minute sample 16000Hz - long x1 = 16000; // at 16000 - long y2 = 405565; // one minute sample - long x2 = 44000; // at 44000 - long x = rate; - long y = (x - x1) * (y2 - y1) / (x2 - x1) + y1; - return y / 60; - } - - // default raw - int c = Sound.AUDIO_FORMAT == AudioFormat.ENCODING_PCM_16BIT ? 2 : 1; - return c * rate; - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FileEncoder.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FileEncoder.java deleted file mode 100644 index a3f538e..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FileEncoder.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -import android.content.Context; -import android.os.Handler; -import android.util.Log; - -import com.github.axet.audiolibrary.app.RawSamples; - -import java.io.File; - -public class FileEncoder { - public static final String TAG = FileEncoder.class.getSimpleName(); - - Context context; - Handler handler; - - File in; - Encoder encoder; - Thread thread; - long samples; - long cur; - Throwable t; - - public FileEncoder(Context context, File in, Encoder encoder) { - this.context = context; - this.in = in; - this.encoder = encoder; - handler = new Handler(); - } - - public void run(final Runnable progress, final Runnable done, final Runnable error) { - thread = new Thread(new Runnable() { - @Override - public void run() { - cur = 0; - - RawSamples rs = new RawSamples(in); - - samples = rs.getSamples(); - - short[] buf = new short[1000]; - - rs.open(buf.length); - - try { - while (!Thread.currentThread().isInterrupted()) { - int len = rs.read(buf); - if (len <= 0) { - break; - } else { - encoder.encode(buf, len); - handler.post(progress); - synchronized (thread) { - cur += len; - } - } - } - encoder.close(); - if (rs != null) { - rs.close(); - } - handler.post(done); - } catch (RuntimeException e) { - Log.e(TAG, "Exception", e); - t = e; - handler.post(error); - } - } - }); - thread.start(); - } - - public int getProgress() { - synchronized (thread) { - return (int) (cur * 100 / samples); - } - } - - public Throwable getException() { - return t; - } - - public void close() { - if (thread != null) { - thread.interrupt(); - thread = null; - } - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Format3GP.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Format3GP.java deleted file mode 100755 index dd77c0a..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/Format3GP.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -import android.annotation.TargetApi; -import android.media.MediaFormat; - -import java.io.File; - -@TargetApi(21) -public class Format3GP extends MuxerMP4 { - - public Format3GP(EncoderInfo info, File out) { - MediaFormat format = new MediaFormat(); - - // for high bitrate AMR_WB - { -// final int kBitRates[] = {6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850}; - -// format.setString(MediaFormat.KEY_MIME, "audio/amr-wb"); -// format.setInteger(MediaFormat.KEY_SAMPLE_RATE, info.sampleRate); -// format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, info.channels); -// format.setInteger(MediaFormat.KEY_BIT_RATE, 23850); // set maximum - } - - // for low bitrate, AMR_NB - { -// final int kBitRates[] = {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; - - format.setString(MediaFormat.KEY_MIME, "audio/3gpp"); - format.setInteger(MediaFormat.KEY_SAMPLE_RATE, info.sampleRate); // 8000 only supported - format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, info.channels); - format.setInteger(MediaFormat.KEY_BIT_RATE, 12200); // set maximum - } - - create(info, format, out); - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatM4A.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatM4A.java deleted file mode 100755 index f03eff4..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatM4A.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -import android.annotation.TargetApi; -import android.media.MediaCodecInfo; -import android.media.MediaFormat; - -import java.io.File; -import java.util.Map; - -@TargetApi(18) -public class FormatM4A extends MuxerMP4 { - - public FormatM4A(EncoderInfo info, File out) { - Map map = MuxerMP4.findEncoder(Factory.MP4); - if (map.isEmpty()) - throw new RuntimeException("mp4 not supported"); - MediaFormat format = MuxerMP4.getDefault(Factory.MP4A, map); - format.setInteger(MediaFormat.KEY_SAMPLE_RATE, info.sampleRate); - format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, info.channels); - format.setInteger(MediaFormat.KEY_BIT_RATE, 64000); - create(info, format, out); - } - -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatMKA.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatMKA.java deleted file mode 100755 index 80f86a9..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatMKA.java +++ /dev/null @@ -1,187 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -import android.annotation.TargetApi; -import android.media.MediaCodec; -import android.media.MediaCodecInfo; -import android.media.MediaFormat; -import android.os.Build; - -import org.ebml.io.FileDataWriter; -import org.ebml.matroska.MatroskaFileFrame; -import org.ebml.matroska.MatroskaFileTrack; -import org.ebml.matroska.MatroskaFileWriter; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; - -@TargetApi(16) // mp4/aac codec -public class FormatMKA implements Encoder { - public static final String KEY_AAC_SBR_MODE = "aac-sbr-mode"; // MediaFormat.KEY_AAC_SBR_MODE - - EncoderInfo info; - MediaCodec encoder; - long NumSamples; - ByteBuffer input; - int inputIndex; - MatroskaFileWriter writer; - MatroskaFileTrack track; - MatroskaFileTrack.MatroskaAudioTrack audio; - - MatroskaFileFrame old; - - public FormatMKA(EncoderInfo info, File out) { - MediaFormat format = new MediaFormat(); - format.setString(MediaFormat.KEY_MIME, Factory.MP4A); - format.setInteger(MediaFormat.KEY_SAMPLE_RATE, info.sampleRate); - format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, info.channels); - format.setInteger(MediaFormat.KEY_BIT_RATE, 64000); - format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE); - format.setInteger(KEY_AAC_SBR_MODE, 0); - create(info, format, out); - } - - public void create(EncoderInfo info, MediaFormat format, File out) { - this.info = info; - try { - encoder = MediaCodec.createEncoderByType(format.getString(MediaFormat.KEY_MIME)); - encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); - encoder.start(); - writer = new MatroskaFileWriter(new FileDataWriter(out.getAbsolutePath())); - audio = new MatroskaFileTrack.MatroskaAudioTrack(); - audio.setSamplingFrequency(info.sampleRate); - audio.setOutputSamplingFrequency(info.sampleRate); - audio.setBitDepth(info.bps); - audio.setChannels((short) info.channels); - track = new MatroskaFileTrack(); - track.setCodecID("A_AAC"); - track.setAudio(audio); - track.setTrackType(MatroskaFileTrack.TrackType.AUDIO); - writer.addTrack(track); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void encode(short[] buf, int len) { - for (int offset = 0; offset < len; offset++) { - if (input == null) { - inputIndex = encoder.dequeueInputBuffer(-1); - if (inputIndex < 0) - throw new RuntimeException("unable to open encoder input buffer"); - if (Build.VERSION.SDK_INT >= 21) - input = encoder.getInputBuffer(inputIndex); - else - input = encoder.getInputBuffers()[inputIndex]; - input.clear(); - } - input.putShort(buf[offset]); - if (!input.hasRemaining()) { - queue(); - } - } - } - - void queue() { - if (input == null) - return; - encoder.queueInputBuffer(inputIndex, 0, input.position(), getCurrentTimeStamp(), 0); - NumSamples += input.position() / info.channels / (Short.SIZE / 8); - input = null; - while (encode()) - ;// do encode() - } - - public static ByteBuffer clone(ByteBuffer original) { - ByteBuffer clone = ByteBuffer.allocate(original.capacity()); - original.rewind();//copy from the beginning - clone.put(original); - original.rewind(); - clone.flip(); - return clone; - } - - public static final int BUFFER_FLAG_KEY_FRAME = 1; // MediaCodec.BUFFER_FLAG_KEY_FRAME - - boolean encode() { - MediaCodec.BufferInfo outputInfo = new MediaCodec.BufferInfo(); - int outputIndex = encoder.dequeueOutputBuffer(outputInfo, 0); - if (outputIndex == MediaCodec.INFO_TRY_AGAIN_LATER) - return false; - - if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { // never get called on API 16 - return true; - } - - if (outputIndex >= 0) { - ByteBuffer output; - if (Build.VERSION.SDK_INT >= 21) - output = encoder.getOutputBuffer(outputIndex); - else - output = encoder.getOutputBuffers()[outputIndex]; - output.position(outputInfo.offset); - output.limit(outputInfo.offset + outputInfo.size); - old(outputInfo.presentationTimeUs / 1000); - if ((outputInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == MediaCodec.BUFFER_FLAG_CODEC_CONFIG) { - track.setCodecPrivate(clone(output)); - writer.flush(); - encoder.releaseOutputBuffer(outputIndex, false); - } else { - MatroskaFileFrame frame = new MatroskaFileFrame(); - frame.setKeyFrame((outputInfo.flags & BUFFER_FLAG_KEY_FRAME) == BUFFER_FLAG_KEY_FRAME); - frame.setTimecode(outputInfo.presentationTimeUs / 1000); - frame.setTrackNo(track.getTrackNo()); - frame.setData(clone(output)); - encoder.releaseOutputBuffer(outputIndex, false); - old = frame; - } - } - - return true; - } - - void old(long cur) { - if (old != null) { - old.setDuration(cur - old.getTimecode()); - writer.addFrame(old); - writer.flush(); - old = null; - } - } - - public void close() { - end(); - encoder.release(); - writer.close(); - } - - long getCurrentTimeStamp() { - return NumSamples * 1000 * 1000 / info.sampleRate; - } - - public void end() { - if (input != null) { - queue(); - } - int inputIndex = encoder.dequeueInputBuffer(-1); - if (inputIndex >= 0) { - ByteBuffer input; - if (Build.VERSION.SDK_INT >= 21) - input = encoder.getInputBuffer(inputIndex); - else - input = encoder.getInputBuffers()[inputIndex]; - input.clear(); - encoder.queueInputBuffer(inputIndex, 0, 0, getCurrentTimeStamp(), MediaCodec.BUFFER_FLAG_END_OF_STREAM); - } - while (encode()) - ;// do encode() - old(getCurrentTimeStamp() / 1000); - writer.setDuration(getCurrentTimeStamp() / 1000); - encoder.stop(); - } - - public EncoderInfo getInfo() { - return info; - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatOGG.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatOGG.java deleted file mode 100755 index 3a94ac0..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatOGG.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -import com.github.axet.vorbisjni.Vorbis; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -public class FormatOGG implements Encoder { - FileOutputStream writer; - Vorbis vorbis; - - public FormatOGG(EncoderInfo info, File out) { - vorbis = new Vorbis(); - vorbis.open(info.channels, info.sampleRate, 0.4f); - try { - writer = new FileOutputStream(out); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void encode(short[] buf, int len) { - byte[] bb = vorbis.encode(buf, len); - try { - writer.write(bb); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void close() { - try { - byte[] bb = vorbis.encode(null, 0); - writer.write(bb); - } catch (IOException e) { - throw new RuntimeException(e); - } - vorbis.close(); - } -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatWAV.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatWAV.java deleted file mode 100755 index 4dad027..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/FormatWAV.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -// based on http://soundfile.sapp.org/doc/WaveFormat/ - -import java.io.*; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class FormatWAV implements Encoder { - int NumSamples; - EncoderInfo info; - int BytesPerSample; - RandomAccessFile outFile; - - ByteOrder order = ByteOrder.LITTLE_ENDIAN; - - public FormatWAV(EncoderInfo info, File out) { - this.info = info; - NumSamples = 0; - - BytesPerSample = info.bps / 8; - - try { - outFile = new RandomAccessFile(out, "rw"); - } catch (IOException e) { - throw new RuntimeException(e); - } - - save(); - } - - public void save() { - int SubChunk1Size = 16; - int SubChunk2Size = NumSamples * info.channels * BytesPerSample; - int ChunkSize = 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size); - - write("RIFF", ByteOrder.BIG_ENDIAN); - write(ChunkSize, order); - write("WAVE", ByteOrder.BIG_ENDIAN); - - int ByteRate = info.sampleRate * info.channels * BytesPerSample; - short AudioFormat = 1; // PCM = 1 (i.e. Linear quantization) - int BlockAlign = BytesPerSample * info.channels; - - write("fmt ", ByteOrder.BIG_ENDIAN); - write(SubChunk1Size, order); - write((short)AudioFormat, order); //short - write((short) info.channels, order); // short - write(info.sampleRate, order); - write(ByteRate, order); - write((short)BlockAlign, order); // short - write((short)info.bps, order); // short - - write("data", ByteOrder.BIG_ENDIAN); - write(SubChunk2Size, order); - } - - void write(String str, ByteOrder order) { - try { - byte[] cc = str.getBytes("UTF-8"); - ByteBuffer bb = ByteBuffer.allocate(cc.length); - bb.order(order); - bb.put(cc); - bb.flip(); - - outFile.write(bb.array()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - void write(int i, ByteOrder order) { - ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE); - bb.order(order); - bb.putInt(i); - bb.flip(); - - try { - outFile.write(bb.array()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - void write(short i, ByteOrder order) { - ByteBuffer bb = ByteBuffer.allocate(Short.SIZE / Byte.SIZE); - bb.order(order); - bb.putShort(i); - bb.flip(); - - try { - outFile.write(bb.array()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void encode(short[] buf, int buflen) { - NumSamples += buflen / info.channels; - try { - ByteBuffer bb = ByteBuffer.allocate(buflen * (Short.SIZE / Byte.SIZE)); - bb.order(order); - for (int i = 0; i < buflen; i++) - bb.putShort(buf[i]); - bb.flip(); - outFile.write(bb.array()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void end() { - try { - outFile.seek(0); - save(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void close() { - try { - outFile.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public EncoderInfo getInfo() { - return info; - } - -} \ No newline at end of file diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/MuxerMP4.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/MuxerMP4.java deleted file mode 100755 index e460a34..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/encoders/MuxerMP4.java +++ /dev/null @@ -1,182 +0,0 @@ -package com.github.axet.audiolibrary.encoders; - -import android.annotation.TargetApi; -import android.media.MediaCodec; -import android.media.MediaCodecInfo; -import android.media.MediaCodecList; -import android.media.MediaFormat; -import android.media.MediaMuxer; -import android.os.Build; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -@TargetApi(18) // depends on MediaMuxer -public class MuxerMP4 implements Encoder { - EncoderInfo info; - MediaCodec encoder; - MediaMuxer muxer; - int audioTrackIndex; - long NumSamples; - ByteBuffer input; - int inputIndex; - - public static Map findEncoder(String mime) { - Map map = new HashMap<>(); - - mime = mime.toLowerCase(); - - int numCodecs = MediaCodecList.getCodecCount(); - for (int i = 0; i < numCodecs; i++) { - MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i); - - if (!codecInfo.isEncoder()) { - continue; - } - - String[] types = codecInfo.getSupportedTypes(); - for (int j = 0; j < types.length; j++) { - String t = types[j].toLowerCase(); - if (t.startsWith(mime)) { - map.put(t, codecInfo); - } - } - } - return map; - } - - public static String prefered(String pref, Map map) { - pref = pref.toLowerCase(); - Iterator i = map.keySet().iterator(); - while (i.hasNext()) { - String m = (String) i.next(); - m = m.toLowerCase(); - if (m.startsWith(pref)) - return m; - } - i = map.keySet().iterator(); - if (i.hasNext()) { - return (String) i.next(); - } - return null; - } - - public static MediaFormat getDefault(String pref, Map map) { - String p = prefered(pref, map); - if (Build.VERSION.SDK_INT >= 21) { - return map.get(p).getCapabilitiesForType(p).getDefaultFormat(); - } else { - MediaFormat format = new MediaFormat(); - format.setString(MediaFormat.KEY_MIME, pref); - return format; - } - } - - public void create(EncoderInfo info, MediaFormat format, File out) { - this.info = info; - try { - encoder = MediaCodec.createEncoderByType(format.getString(MediaFormat.KEY_MIME)); - encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); - encoder.start(); - muxer = new MediaMuxer(out.getAbsolutePath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void encode(short[] buf, int len) { - for (int offset = 0; offset < len; offset++) { - if (input == null) { - inputIndex = encoder.dequeueInputBuffer(-1); - if (inputIndex < 0) - throw new RuntimeException("unable to open encoder input buffer"); - if (Build.VERSION.SDK_INT >= 21) - input = encoder.getInputBuffer(inputIndex); - else - input = encoder.getInputBuffers()[inputIndex]; - input.clear(); - } - input.putShort(buf[offset]); - if (!input.hasRemaining()) { - queue(); - } - } - } - - void queue() { - if (input == null) - return; - encoder.queueInputBuffer(inputIndex, 0, input.position(), getCurrentTimeStamp(), 0); - NumSamples += input.position() / info.channels / (Short.SIZE / 8); - input = null; - while (encode()) - ;// do encode() - } - - boolean encode() { - MediaCodec.BufferInfo outputInfo = new MediaCodec.BufferInfo(); - int outputIndex = encoder.dequeueOutputBuffer(outputInfo, 0); - if (outputIndex == MediaCodec.INFO_TRY_AGAIN_LATER) - return false; - - if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { - audioTrackIndex = muxer.addTrack(encoder.getOutputFormat()); - muxer.start(); - return true; - } - - if (outputIndex >= 0) { - ByteBuffer output; - if (Build.VERSION.SDK_INT >= 21) - output = encoder.getOutputBuffer(outputIndex); - else - output = encoder.getOutputBuffers()[outputIndex]; - output.position(outputInfo.offset); - output.limit(outputInfo.offset + outputInfo.size); - muxer.writeSampleData(audioTrackIndex, output, outputInfo); - encoder.releaseOutputBuffer(outputIndex, false); - } - - return true; - } - - public void close() { - end(); - encoder.release(); - muxer.release(); - } - - long getCurrentTimeStamp() { - return NumSamples * 1000 * 1000 / info.sampleRate; - } - - public void end() { - if (input != null) { - queue(); - } - int inputIndex = encoder.dequeueInputBuffer(-1); - if (inputIndex >= 0) { - ByteBuffer input; - if (Build.VERSION.SDK_INT >= 21) - input = encoder.getInputBuffer(inputIndex); - else - input = encoder.getInputBuffers()[inputIndex]; - input.clear(); - encoder.queueInputBuffer(inputIndex, 0, 0, getCurrentTimeStamp(), MediaCodec.BUFFER_FLAG_END_OF_STREAM); - } - while (encode()) - ;// do encode() - encoder.stop(); - muxer.stop(); - } - - public EncoderInfo getInfo() { - return info; - } - -} \ No newline at end of file diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTBarView.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTBarView.java deleted file mode 100644 index 63aad5c..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTBarView.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.github.axet.audiolibrary.widgets; - -import android.content.Context; -import android.graphics.Canvas; -import android.util.AttributeSet; - -import com.github.axet.androidlibrary.widgets.ThemeUtils; - -public class FFTBarView extends FFTView { - public static final String TAG = FFTBarView.class.getSimpleName(); - - int barCount; - float barWidth; - float barDeli; - - public FFTBarView(Context context) { - this(context, null); - } - - public FFTBarView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public FFTBarView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - create(); - } - - void create() { - super.create(); - } - - public void setBuffer(double[] buf) { - super.setBuffer(buf); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - // set initial width - int w = ThemeUtils.dp2px(getContext(), 15); - int d = ThemeUtils.dp2px(getContext(), 4); - int s = w + d; - - int mw = getMeasuredWidth() - getPaddingLeft() - getPaddingRight(); - - // get count of bars and delimeters - int dc = (mw - w) / s; - int bc = dc + 1; - - // get rate - float k = w / d; - - // get one part of (bar+del) size - float e = mw / (bc * k + dc); - - barCount = bc; - barWidth = e * k; - barDeli = e; - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - } - - @Override - public void onDraw(Canvas canvas) { - if (barCount == 0) - return; - - int h = getHeight() - getPaddingTop() - getPaddingBottom(); - - float left = getPaddingLeft(); - - for (int i = 0; i < barCount; i++) { - double max = 0; - - if (buffer != null) { - int step = buffer.length / barCount; - int offset = i * step; - int end = Math.min(offset + step, buffer.length); - for (int k = offset; k < end; k++) { - double s = buffer[k]; - max = Math.max(max, s); - } - } - - float y = getPaddingTop() + h - h * ((float) max / 0x7fff) - ThemeUtils.dp2px(getContext(), 1); - - if (y < getPaddingTop()) - y = getPaddingTop(); - - canvas.drawRect(left, y, left + barWidth, getPaddingTop() + h, paint); - left += barWidth + barDeli; - } - } - -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTChartView.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTChartView.java deleted file mode 100644 index fa98488..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTChartView.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.github.axet.audiolibrary.widgets; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.util.AttributeSet; - -import com.github.axet.audiolibrary.app.RawSamples; -import com.github.axet.audiolibrary.app.Sound; - -public class FFTChartView extends FFTView { - public static final String TAG = FFTChartView.class.getSimpleName(); - - public FFTChartView(Context context) { - this(context, null); - } - - public FFTChartView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public FFTChartView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - create(); - } - - void create() { - super.create(); - } - - public void setBuffer(double[] buf) { - super.setBuffer(buf); - } - - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - } - - @Override - public void onDraw(Canvas canvas) { - if (buffer == null) - return; - - canvas.drawColor(Color.RED); - - int h = getHeight(); - - float startX = 0, startY = h; - - int w = getWidth() - getPaddingLeft() - getPaddingRight(); - - float step = w / (float) buffer.length; - - double min = Integer.MAX_VALUE; - double max = Integer.MIN_VALUE; - - for (int i = 0; i < buffer.length; i++) { - double v = buffer[i]; - - min = Math.min(v, min); - max = Math.max(v, max); - - v = (Sound.MAXIMUM_DB + v) / Sound.MAXIMUM_DB; - - float endX = startX; - float endY = (float) (h - h * v); - - canvas.drawLine(startX, startY, endX, endY, paint); - - startX = endX + step; - startY = endY; - } - - String tMin = "" + min; - canvas.drawText(tMin, 0, getHeight(), textPaint); - - String tMax = "" + max; - textPaint.getTextBounds(tMax, 0, tMax.length(), textBounds); - canvas.drawText("" + max, w - textBounds.width(), getHeight(), textPaint); - } - -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTView.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTView.java deleted file mode 100644 index 508eabd..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/FFTView.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.github.axet.audiolibrary.widgets; - -import android.content.Context; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Rect; -import android.util.AttributeSet; -import android.view.View; - -import com.github.axet.androidlibrary.widgets.ThemeUtils; - -import org.apache.commons.math3.complex.Complex; -import org.apache.commons.math3.transform.DftNormalization; -import org.apache.commons.math3.transform.FastFourierTransformer; -import org.apache.commons.math3.transform.TransformType; - -public class FFTView extends View { - public static final String TAG = FFTView.class.getSimpleName(); - - Paint paint; - double[] buffer; - - Paint textPaint; - Rect textBounds; - - public FFTView(Context context) { - this(context, null); - } - - public FFTView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public FFTView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - create(); - } - - void create() { - paint = new Paint(); - paint.setColor(0xff0433AE); - paint.setStrokeWidth(ThemeUtils.dp2px(getContext(), 1)); - - textBounds = new Rect(); - - textPaint = new Paint(); - textPaint.setColor(Color.GRAY); - textPaint.setAntiAlias(true); - textPaint.setTextSize(20f); - - if (isInEditMode()) { - short[] b = simple(); - b = generateSound(16000, 4000, 100); - buffer = fft(b, 0, b.length); - //buffer = RawSamples.generateSound(16000, 4000, 100); - //buffer = RawSamples.fft(buffer, 0, buffer.length); - } - } - - public void setBuffer(double[] buf) { - buffer = buf; - } - - public static short[] generateSound(int sampleRate, int freqHz, int durationMs) { - int count = sampleRate * durationMs / 1000; - short[] samples = new short[count]; - for (int i = 0; i < count; i++) { - short sample = (short) (Math.sin(2 * Math.PI * i / (sampleRate / freqHz)) * 0x7FFF); - samples[i] = sample; - } - return samples; - } - - public static double[] asDouble(short[] buffer, int offset, int len) { - double[] dd = new double[len]; - for (int i = 0; i < len; i++) { - dd[i] = buffer[offset + i] / (float) 0x7fff; - } - return dd; - } - - public static double[] fft(short[] buffer, int offset, int len) { - int len2 = (int) Math.pow(2, Math.ceil(Math.log(len) / Math.log(2))); - - final double[][] dataRI = new double[][]{ - new double[len2], new double[len2] - }; - - double[] dataR = dataRI[0]; - double[] dataI = dataRI[1]; - - double powerInput = 0; - for (int i = 0; i < len; i++) { - dataR[i] = buffer[offset + i] / (float) 0x7fff; - powerInput += dataR[i] * dataR[i]; - } - powerInput = Math.sqrt(powerInput / len); - - FastFourierTransformer.transformInPlace(dataRI, DftNormalization.STANDARD, TransformType.FORWARD); - - double[] data = new double[len2 / 2]; - - data[0] = 10 * Math.log10(Math.pow(new Complex(dataR[0], dataI[0]).abs() / len2, 2)); - - double powerOutput = 0; - for (int i = 1; i < data.length; i++) { - Complex c = new Complex(dataR[i], dataI[i]); - double p = c.abs(); - p = p / len2; - p = p * p; - p = p * 2; - double dB = 10 * Math.log10(p); - - powerOutput += p; - data[i] = dB; - } - powerOutput = Math.sqrt(powerOutput); - -// if(powerInput != powerOutput) { -// throw new RuntimeException("in " + powerInput + " out " + powerOutput); -// } - - return data; - } - - public static short[] simple() { - int sampleRate = 1000; - int count = sampleRate; - short[] samples = new short[count]; - for (int i = 0; i < count; i++) { - double x = i / (double) count; - double y = 0; - //y += 0.6 * Math.sin(20 * 2 * Math.PI * x); - //y += 0.4 * Math.sin(50 * 2 * Math.PI * x); - //y += 0.2 * Math.sin(80 * 2 * Math.PI * x); - y += Math.sin(100 * 2 * Math.PI * x); - y += Math.sin(200 * 2 * Math.PI * x); - y += Math.sin(300 * 2 * Math.PI * x); - // max = 2.2; - samples[i] = (short) (y / 3 * 0x7fff); - } - return samples; - } - -} diff --git a/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/PitchView.java b/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/PitchView.java deleted file mode 100644 index 680f4f5..0000000 --- a/android-audio-library/src/main/java/com/github/axet/audiolibrary/widgets/PitchView.java +++ /dev/null @@ -1,693 +0,0 @@ -package com.github.axet.audiolibrary.widgets; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Rect; -import android.os.Handler; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; - -import com.github.axet.androidlibrary.widgets.ThemeUtils; -import com.github.axet.audiolibrary.R; -import com.github.axet.audiolibrary.app.RawSamples; -import com.github.axet.audiolibrary.app.Sound; - -import java.util.LinkedList; -import java.util.List; - -public class PitchView extends ViewGroup { - public static final String TAG = PitchView.class.getSimpleName(); - - // pitch delimiter length in dp - public static final float PITCH_DELIMITER = 1f; - // pitch length in dp - public static final float PITCH_WIDTH = 2f; - - // update pitchview in milliseconds - public static final int UPDATE_SPEED = 10; - - // edit update time - public static final int EDIT_UPDATE_SPEED = 250; - - // 'pitch length' in milliseconds (100ms) - // - // in other words how many milliseconds do we need to show whole pitch. - int pitchTime; - - List data = new LinkedList<>(); - - // how many pitches we can fit on screen - int pitchScreenCount; - // how many pitches we should fit in memory - int pitchMemCount; - // pitch delimiter length in px - int pitchDlimiter; - // pitch length in px - int pitchWidth; - // pitch length in pn + pitch delimiter length in px - int pitchSize; - - PitchGraphView graph; - PitchCurrentView current; - - long time = 0; - - // how many samples were cut from begining of 'data' list - long samples = 0; - - Runnable edit; - // index - int editPos = -1; - boolean editFlash = false; - // current playing position in samples - float playPos = -1; - Runnable play; - - Runnable draw; - float offset = 0; - - Handler handler; - - public static class HandlerUpdate implements Runnable { - long start; - long updateSpeed; - Handler handler; - Runnable run; - - public static HandlerUpdate start(HandlerUpdate r, Handler handler, Runnable run, long updateSpeed) { - r.run = run; - r.start = System.currentTimeMillis(); - r.updateSpeed = updateSpeed; - r.handler = handler; - // post instead of draw.run() so 'start' will measure actual queue time - handler.postDelayed(r, updateSpeed); - return r; - } - - public static HandlerUpdate start(Handler handler, Runnable run, long updateSpeed) { - HandlerUpdate r = new HandlerUpdate(); - return start(r, handler, run, updateSpeed); - } - - - public static void stop(Handler handler, Runnable run) { - handler.removeCallbacks(run); - } - - @Override - public void run() { - long cur = System.currentTimeMillis(); - - long diff = cur - start; - - start = cur; - - long delay = updateSpeed + (updateSpeed - diff); - if (delay > updateSpeed) - delay = updateSpeed; - - post(delay); - } - - void post(long delay) { - this.run.run(); - - if (delay > 0) - this.handler.postDelayed(this, delay); - else - this.handler.post(this); - } - } - - // if CPU speed not enough skip frames - public static class FallbackUpdate extends HandlerUpdate { - Runnable fallback; - long slow; - - public static FallbackUpdate start(Handler handler, Runnable run, Runnable fallback, long updateSpeed) { - FallbackUpdate r = new FallbackUpdate(); - r.fallback = fallback; - r.slow = updateSpeed / 4; - return (FallbackUpdate) start(r, handler, run, updateSpeed); - } - - @Override - void post(long delay) { - if (delay < slow) { - this.fallback.run(); - } else { - this.run.run(); - } - if (delay > 0) - this.handler.postDelayed(this, delay); - else - this.handler.post(this); - } - } - - public class PitchGraphView extends View { - Paint paint; - Paint paintRed; - Paint editPaint; - Paint playPaint; - Paint cutColor; - - public PitchGraphView(Context context) { - this(context, null); - } - - public PitchGraphView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public PitchGraphView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - paint = new Paint(); - paint.setColor(getThemeColor(R.attr.colorPrimary)); - paint.setStrokeWidth(pitchWidth); - - paintRed = new Paint(); - paintRed.setColor(Color.RED); - paintRed.setStrokeWidth(pitchWidth); - - cutColor = new Paint(); - cutColor.setColor(getThemeColor(android.R.attr.textColorHint)); - cutColor.setStrokeWidth(pitchWidth); - - editPaint = new Paint(); - editPaint.setColor(getThemeColor(R.attr.colorPrimaryDark)); - editPaint.setStrokeWidth(pitchWidth); - - playPaint = new Paint(); - playPaint.setColor(getThemeColor(R.attr.colorPrimaryDark)); - playPaint.setStrokeWidth(pitchWidth / 2); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - int w = MeasureSpec.getSize(widthMeasureSpec); - - pitchScreenCount = w / pitchSize + 1; - - pitchMemCount = pitchScreenCount + 1; - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); - - fit(pitchScreenCount); - } - - public void calc() { - if (data.size() >= pitchMemCount) { - long cur = System.currentTimeMillis(); - - float tick = (cur - time) / (float) pitchTime; - - // force clear queue - if (data.size() > pitchMemCount + 1) { - tick = 0; - time = cur; - fit(pitchMemCount); - } - - if (tick > 1) { - if (data.size() > pitchMemCount) { - tick -= 1; - time += pitchTime; - } else if (data.size() == pitchMemCount) { - tick = 0; - time = cur; - } - fit(data.size() - 1); - } - - offset = pitchSize * tick; - } - } - - @Override - public void onDraw(Canvas canvas) { - int m = Math.min(pitchMemCount, data.size()); - -// if (edit != null) { -// float x = editPos * pitchSize + pitchSize / 2f; -// canvas.drawRect(x, 0, getWidth(), getHeight(), bg_cut); -// } - - for (int i = 0; i < m; i++) { - double dB = filterDB(i); - - float left = (float) dB; - float right = (float) dB; - - float mid = getHeight() / 2f; - - float x = -offset + i * pitchSize + pitchSize / 2f; - - Paint p = paint; - - if (getDB(i) < 0) { - p = paintRed; - left = 1; - right = 1; - } - - if (editPos != -1 && i >= editPos) - p = cutColor; - - // left channel pitch - canvas.drawLine(x, mid, x, mid - mid * left - 1, p); - // right channel pitch - canvas.drawLine(x, mid, x, mid + mid * right + 1, p); - } - - // paint edit mark - if (editPos != -1 && editFlash) { - float x = editPos * pitchSize + pitchSize / 2f; - canvas.drawLine(x, 0, x, getHeight(), editPaint); - } - - // paint play mark - if (playPos > 0) { - float x = playPos * pitchSize + pitchSize / 2f; - canvas.drawLine(x, 0, x, getHeight(), playPaint); - } - } - } - - public class PitchCurrentView extends View { - Paint paint; - Paint textPaint; - String text; - Rect textBounds; - - double dB; - - public PitchCurrentView(Context context) { - this(context, null); - } - - public PitchCurrentView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public PitchCurrentView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - text = "100 " + getContext().getString(R.string.db); - textBounds = new Rect(); - - textPaint = new Paint(); - textPaint.setColor(Color.GRAY); - textPaint.setAntiAlias(true); - textPaint.setTextSize(20f); - - paint = new Paint(); - paint.setColor(getThemeColor(R.attr.colorPrimary)); - paint.setStrokeWidth(pitchWidth); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int w = MeasureSpec.getSize(widthMeasureSpec); - textPaint.getTextBounds(this.text, 0, this.text.length(), textBounds); - - int h = getPaddingTop(); - h += textBounds.height(); - h += ThemeUtils.dp2px(getContext(), 2); - h += pitchWidth + getPaddingBottom(); - - setMeasuredDimension(w, h); - } - - public void setText(String text) { - this.text = text; - textPaint.getTextBounds(this.text, 0, this.text.length(), textBounds); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); - } - - void update(int end) { - dB = getDB(end) / Sound.MAXIMUM_DB; - - String str = ""; - - str = Integer.toString((int) getDB(end)) + " " + getContext().getString(R.string.db); - - setText(str); - } - - @Override - public void onDraw(Canvas canvas) { - if (data.size() > 0) { - current.update(getEnd()); - } - - float y = getPaddingTop() + textBounds.height(); - - int x = getWidth() / 2 - textBounds.width() / 2; - canvas.drawText(text, x, y, textPaint); - - y += ThemeUtils.dp2px(getContext(), 2); - - float left = (float) dB; - float right = (float) dB; - - float mid = getWidth() / 2f; - - y += pitchWidth / 2; - - canvas.drawLine(mid, y, mid - mid * left - 1, y, paint); - canvas.drawLine(mid, y, mid + mid * right + 1, y, paint); - } - } - - public PitchView(Context context) { - this(context, null); - } - - public PitchView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public PitchView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - create(); - } - - void create() { - handler = new Handler(); - - pitchDlimiter = ThemeUtils.dp2px(getContext(), PITCH_DELIMITER); - pitchWidth = ThemeUtils.dp2px(getContext(), PITCH_WIDTH); - pitchSize = pitchWidth + pitchDlimiter; - - pitchTime = pitchSize * UPDATE_SPEED; - - graph = new PitchGraphView(getContext()); - addView(graph); - -// fft = new FFTChartView(getContext()) { -// @Override -// public void onDraw(Canvas canvas) { -// if (data.size() > 0) { -// short[] buf = dataSamples.get(getEnd()); -// double[] d = FFTView.fft(buf, 0, buf.length); -// //double[] d = asDouble(buf, 0, buf.length); -// fft.setBuffer(d); -// } -// -// super.onDraw(canvas); -// } -// }; -// fft.setPadding(0, ThemeUtils.dp2px(2), 0, 0); -// addView(fft); - - current = new PitchCurrentView(getContext()); - current.setPadding(0, ThemeUtils.dp2px(getContext(), 2), 0, 0); - addView(current); - - if (isInEditMode()) { - for (int i = 0; i < 3000; i++) { - data.add(-Math.sin(i) * Sound.MAXIMUM_DB); - } - } - - time = System.currentTimeMillis(); - } - - public int getThemeColor(int id) { - return ThemeUtils.getThemeColor(getContext(), id); - } - - public int getMaxPitchCount(int width) { - int pitchScreenCount = width / pitchSize + 1; - - int pitchMemCount = pitchScreenCount + 1; - - return pitchMemCount; - } - - public void clear(long s) { - data.clear(); - samples = s; - offset = 0; - edit = null; - draw = null; - play = null; - } - - public void fit(int max) { - if (max < 0) // -1 - return; - if (data.size() > max) { - int cut = data.size() - max; - data.subList(0, cut).clear(); - samples += cut; - int m = data.size() - 1; - // screen rotate may cause play/edit offsets off screen - if (editPos > m) - editPos = m; - if (playPos > m) - playPos = m; - } - } - - public void add(double a) { - data.add(a); - } - - public void drawCalc() { - graph.calc(); - draw(); - } - - public void drawEnd() { - fit(pitchMemCount); - offset = 0; - draw(); - } - - public int getEnd() { - int end = data.size() - 1; - - if (editPos != -1) { - end = editPos; - } - if (playPos > 0) { - end = (int) playPos; - } - - return end; - } - - public double getDB(int i) { - double db = data.get(i); - - db = Sound.MAXIMUM_DB + db; - - return db; - } - - public double filterDB(int i) { - double db = getDB(i); - - // do not show below NOISE_DB - db = db - Sound.NOISE_DB; - - if (db < 0) - db = 0; - - int rest = Sound.MAXIMUM_DB - Sound.NOISE_DB; - - db = db / rest; - - return db; - } - - public void draw() { - graph.invalidate(); - current.invalidate(); - } - - public int getPitchTime() { - return pitchTime; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - int ww = getMeasuredWidth() - getPaddingRight() - getPaddingLeft(); - int hh = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); - - current.measure(MeasureSpec.makeMeasureSpec(ww, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(hh, MeasureSpec.AT_MOST)); - - hh = hh - current.getMeasuredHeight(); - - graph.measure(MeasureSpec.makeMeasureSpec(ww, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(hh, MeasureSpec.AT_MOST)); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - graph.layout(getPaddingLeft(), getPaddingTop(), - getPaddingLeft() + graph.getMeasuredWidth(), getPaddingTop() + graph.getMeasuredHeight()); - - current.layout(getPaddingLeft(), graph.getBottom(), - getPaddingLeft() + current.getMeasuredWidth(), graph.getBottom() + current.getMeasuredHeight()); - } - - public void stop() { - if (edit != null) - HandlerUpdate.stop(handler, edit); - edit = null; - - if (draw != null) - HandlerUpdate.stop(handler, draw); - draw = null; - - if (play != null) - HandlerUpdate.stop(handler, play); - play = null; - - draw(); - } - - public long edit(float offset) { - if (offset < 0) - editPos = -1; - else - editPos = ((int) offset) / pitchSize; - - playPos = -1; - - if (editPos >= pitchScreenCount) - editPos = pitchScreenCount - 1; - - if (editPos >= data.size()) - editPos = data.size() - 1; - - if (draw != null) { - HandlerUpdate.stop(handler, draw); - draw = null; - } - - if (play != null) { - HandlerUpdate.stop(handler, play); - play = null; - } - - draw(); - - edit(); - - return samples + editPos; - } - - public void edit() { - if (edit == null) { - editFlash = true; - edit = FallbackUpdate.start(handler, new Runnable() { - @Override - public void run() { - draw(); - editFlash = !editFlash; - } - }, new Runnable() { - @Override - public void run() { - graph.calc(); - editFlash = !editFlash; - } - }, EDIT_UPDATE_SPEED); - } - } - - public void record() { - if (edit != null) - HandlerUpdate.stop(handler, edit); - edit = null; - editPos = -1; - - if (play != null) - HandlerUpdate.stop(handler, play); - play = null; - playPos = -1; - - if (draw == null) { - time = System.currentTimeMillis(); - draw = FallbackUpdate.start(handler, new Runnable() { - @Override - public void run() { - drawCalc(); - } - }, new Runnable() { - @Override - public void run() { - graph.calc(); - } - }, UPDATE_SPEED); - } - } - - // current paying pos in actual samples - public void play(float pos) { - if (pos < 0) { - playPos = -1; - if (play != null) { - HandlerUpdate.stop(handler, play); - play = null; - } - if (edit == null) { - edit(); - } - return; - } - - playPos = pos - samples; - - editFlash = true; - - int max = data.size() - 1; - - if (playPos > max) - playPos = max; - - if (edit != null) - HandlerUpdate.stop(handler, edit); - edit = null; - - if (draw != null) - HandlerUpdate.stop(handler, draw); - draw = null; - - if (play == null) { - time = System.currentTimeMillis(); - play = FallbackUpdate.start(handler, new Runnable() { - @Override - public void run() { - draw(); - } - }, new Runnable() { - @Override - public void run() { - graph.calc(); - } - }, UPDATE_SPEED); - } - } -} diff --git a/android-audio-library/src/main/res/drawable/ic_create_black_24dp.xml b/android-audio-library/src/main/res/drawable/ic_create_black_24dp.xml deleted file mode 100644 index 2ab2fb7..0000000 --- a/android-audio-library/src/main/res/drawable/ic_create_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/android-audio-library/src/main/res/drawable/ic_delete_black_24dp.xml b/android-audio-library/src/main/res/drawable/ic_delete_black_24dp.xml deleted file mode 100644 index 39e64d6..0000000 --- a/android-audio-library/src/main/res/drawable/ic_delete_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/android-audio-library/src/main/res/drawable/ic_mic_24dp.xml b/android-audio-library/src/main/res/drawable/ic_mic_24dp.xml deleted file mode 100644 index 351c058..0000000 --- a/android-audio-library/src/main/res/drawable/ic_mic_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/android-audio-library/src/main/res/drawable/ic_pause_black_24dp.xml b/android-audio-library/src/main/res/drawable/ic_pause_black_24dp.xml deleted file mode 100644 index 8356ff5..0000000 --- a/android-audio-library/src/main/res/drawable/ic_pause_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/android-audio-library/src/main/res/drawable/ic_play_arrow_black_24dp.xml b/android-audio-library/src/main/res/drawable/ic_play_arrow_black_24dp.xml deleted file mode 100644 index 81a8f74..0000000 --- a/android-audio-library/src/main/res/drawable/ic_play_arrow_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/android-audio-library/src/main/res/drawable/ic_share_black_24dp.xml b/android-audio-library/src/main/res/drawable/ic_share_black_24dp.xml deleted file mode 100644 index e3fe874..0000000 --- a/android-audio-library/src/main/res/drawable/ic_share_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/android-audio-library/src/main/res/drawable/round_button_dark.xml b/android-audio-library/src/main/res/drawable/round_button_dark.xml deleted file mode 100644 index 0c2a26c..0000000 --- a/android-audio-library/src/main/res/drawable/round_button_dark.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/android-audio-library/src/main/res/drawable/round_button_light.xml b/android-audio-library/src/main/res/drawable/round_button_light.xml deleted file mode 100644 index 33a8bec..0000000 --- a/android-audio-library/src/main/res/drawable/round_button_light.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/android-audio-library/src/main/res/layout/notifictaion_recording.xml b/android-audio-library/src/main/res/layout/notifictaion_recording.xml deleted file mode 100644 index 3faf37f..0000000 --- a/android-audio-library/src/main/res/layout/notifictaion_recording.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/android-audio-library/src/main/res/layout/notifictaion_recording_dark.xml b/android-audio-library/src/main/res/layout/notifictaion_recording_dark.xml deleted file mode 100644 index e573589..0000000 --- a/android-audio-library/src/main/res/layout/notifictaion_recording_dark.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/android-audio-library/src/main/res/layout/notifictaion_recording_light.xml b/android-audio-library/src/main/res/layout/notifictaion_recording_light.xml deleted file mode 100644 index 1a71872..0000000 --- a/android-audio-library/src/main/res/layout/notifictaion_recording_light.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/android-audio-library/src/main/res/layout/recording.xml b/android-audio-library/src/main/res/layout/recording.xml deleted file mode 100644 index 6348a79..0000000 --- a/android-audio-library/src/main/res/layout/recording.xml +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android-audio-library/src/main/res/menu/menu_context.xml b/android-audio-library/src/main/res/menu/menu_context.xml deleted file mode 100644 index 84b9fb5..0000000 --- a/android-audio-library/src/main/res/menu/menu_context.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - diff --git a/android-audio-library/src/main/res/values-ru/strings.xml b/android-audio-library/src/main/res/values-ru/strings.xml deleted file mode 100644 index 42ea624..0000000 --- a/android-audio-library/src/main/res/values-ru/strings.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - .wav (по умолчанию) - - - %1$s свободно ~ %2$s - дБ - Нет - Да - Вы уверены? - Удалить запись - Переименовать запись - "Создано с помощью: %1$s" - Файл не найден - Переименовать - Удалить - diff --git a/android-audio-library/src/main/res/values/attrs.xml b/android-audio-library/src/main/res/values/attrs.xml deleted file mode 100644 index 4a34715..0000000 --- a/android-audio-library/src/main/res/values/attrs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/android-audio-library/src/main/res/values/colors.xml b/android-audio-library/src/main/res/values/colors.xml deleted file mode 100644 index cb49d2e..0000000 --- a/android-audio-library/src/main/res/values/colors.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - #3F51B5 - #303F9F - #33333333 - #FF4081 - #a4a4a4 - diff --git a/android-audio-library/src/main/res/values/strings.xml b/android-audio-library/src/main/res/values/strings.xml deleted file mode 100644 index 11b27e9..0000000 --- a/android-audio-library/src/main/res/values/strings.xml +++ /dev/null @@ -1,23 +0,0 @@ - - Audio Library - - - .wav (default) - - - - wav - - - %1$s free ~ %2$s left - dB - No - Yes - "Are you sure ? " - Delete Recording - Rename Recording - "Shared via %1$s" - File not found - Rename - Delete - diff --git a/android-audio-library/src/main/res/values/styles.xml b/android-audio-library/src/main/res/values/styles.xml deleted file mode 100644 index a86375b..0000000 --- a/android-audio-library/src/main/res/values/styles.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/android-audio-library/src/test/java/com/github/axet/audiolibrary/ExampleUnitTest.java b/android-audio-library/src/test/java/com/github/axet/audiolibrary/ExampleUnitTest.java deleted file mode 100644 index 7e1eec6..0000000 --- a/android-audio-library/src/test/java/com/github/axet/audiolibrary/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.github.axet.audiolibrary; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file