diff --git a/app/src/androidTest/java/com/github/axet/audiorecorder/ApplicationTest.java b/app/src/androidTest/java/com/github/axet/audiorecorder/ApplicationTest.java index 2ac4be3..0e33c79 100644 --- a/app/src/androidTest/java/com/github/axet/audiorecorder/ApplicationTest.java +++ b/app/src/androidTest/java/com/github/axet/audiorecorder/ApplicationTest.java @@ -15,7 +15,5 @@ public class ApplicationTest extends ApplicationTestCase { } public void testFFT() { - short[] buf = RawSamples.generateSound(16000, 4500, 100); - short[] fft = RawSamples.fft(buf, 0, buf.length); } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2d94f30..a753a6d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,7 +14,7 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" - android:theme="@style/AppTheme"> + android:theme="@style/AppThemeLight"> + android:theme="@style/AppThemeLight.NoActionBar"> diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/AppCompatPreferenceActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/AppCompatPreferenceActivity.java index 9b0052d..bc6ae27 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/AppCompatPreferenceActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/AppCompatPreferenceActivity.java @@ -12,6 +12,8 @@ import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; +import com.github.axet.audiorecorder.app.MainApplication; + /** * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls * to be used with AppCompat. @@ -22,6 +24,7 @@ public abstract class AppCompatPreferenceActivity extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { + setTheme(((MainApplication) getApplication()).getUserTheme()); getDelegate().installViewFactory(); getDelegate().onCreate(savedInstanceState); super.onCreate(savedInstanceState); diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java index 896a5d7..52182b4 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java @@ -435,6 +435,9 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + setTheme(((MainApplication) getApplication()).getMainTheme()); + setContentView(R.layout.activity_main); // ATTENTION: This was auto-generated to implement the App Indexing API. diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java index 1f10142..1670e24 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java @@ -147,6 +147,9 @@ public class RecordingActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + setTheme(((MainApplication) getApplication()).getUserTheme()); + setContentView(R.layout.activity_recording); pitch = (PitchView) findViewById(R.id.recording_pitch); @@ -273,9 +276,7 @@ public class RecordingActivity extends AppCompatActivity { pitch.clear(cut / samplesUpdate); for (int i = 0; i < len; i += samplesUpdate) { double dB = RawSamples.getDB(buf, i, samplesUpdate); - short[] ss = new short[samplesUpdate]; - System.arraycopy(buf, i, ss, 0, ss.length); - pitch.add(dB, ss); + pitch.add(dB); } updateSamples(samplesTime); } @@ -615,12 +616,10 @@ public class RecordingActivity extends AppCompatActivity { for (int i = 0; i < readSize; i += samplesUpdate) { final double dB = RawSamples.getDB(buffer, i, samplesUpdate); - final short[] ss = new short[samplesUpdate]; - System.arraycopy(buffer, i, ss, 0, ss.length); handle.post(new Runnable() { @Override public void run() { - pitch.add(dB, ss); + pitch.add(dB); } }); } diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java index b468dcd..4fa81ae 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java @@ -6,6 +6,7 @@ import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.media.Ringtone; @@ -23,6 +24,7 @@ import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.ActionBar; import android.view.MenuItem; +import android.widget.ListView; import android.widget.Toast; import com.github.axet.audiorecorder.R; @@ -41,7 +43,7 @@ import java.util.List; * href="http://developer.android.com/guide/topics/ui/settings.html">Settings * API Guide for more information on developing a Settings UI. */ -public class SettingsActivity extends AppCompatPreferenceActivity { +public class SettingsActivity extends AppCompatPreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { /** * A preference value change listener that updates the preference's summary * to reflect its new value. @@ -120,8 +122,12 @@ public class SettingsActivity extends AppCompatPreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setupActionBar(); + final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); + shared.registerOnSharedPreferenceChangeListener(this); + getFragmentManager().beginTransaction().replace(android.R.id.content, new GeneralPreferenceFragment()).commit(); } @@ -195,6 +201,23 @@ public class SettingsActivity extends AppCompatPreferenceActivity { return true; } + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if(key.equals(MainApplication.PREFERENCE_THEME)) { + finish(); + startActivity(new Intent(this, SettingsActivity.class)); + overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); + shared.unregisterOnSharedPreferenceChangeListener(this); + } + /** * This fragment shows general preferences only. It is used when the * activity is showing a two-pane settings UI. @@ -226,6 +249,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { } bindPreferenceSummaryToValue(findPreference(MainApplication.PREFERENCE_RATE)); + bindPreferenceSummaryToValue(findPreference(MainApplication.PREFERENCE_THEME)); } @Override diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/MainApplication.java b/app/src/main/java/com/github/axet/audiorecorder/app/MainApplication.java index 793d3fd..fdf7213 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/app/MainApplication.java +++ b/app/src/main/java/com/github/axet/audiorecorder/app/MainApplication.java @@ -1,9 +1,14 @@ package com.github.axet.audiorecorder.app; import android.app.Application; +import android.content.Context; import android.content.SharedPreferences; +import android.content.res.TypedArray; import android.preference.PreferenceManager; +import android.util.Log; +import android.util.TypedValue; +import com.github.axet.androidlibrary.widgets.ThemeUtils; import com.github.axet.audiorecorder.R; public class MainApplication extends Application { @@ -13,12 +18,37 @@ public class MainApplication extends Application { 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"; @Override public void onCreate() { super.onCreate(); PreferenceManager.setDefaultValues(this, R.xml.pref_general, false); + + Context context = this; + context.setTheme(getUserTheme()); + Log.d("123", "color " + Integer.toHexString(ThemeUtils.getThemeColor(context, android.R.attr.textColorSecondary))); + } + + public int getUserTheme() { + final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); + String theme = shared.getString(MainApplication.PREFERENCE_THEME, ""); + if (theme.equals("Theme_Dark")) { + return R.style.AppThemeDark; + } else { + return R.style.AppThemeLight; + } + } + + public int getMainTheme() { + final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); + String theme = shared.getString(MainApplication.PREFERENCE_THEME, ""); + if (theme.equals("Theme_Dark")) { + return R.style.AppThemeDark_NoActionBar; + } else { + return R.style.AppThemeLight_NoActionBar; + } } static public String formatTime(int tt) { diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/RawSamples.java b/app/src/main/java/com/github/axet/audiorecorder/app/RawSamples.java index ab6bba8..6e704d1 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/app/RawSamples.java +++ b/app/src/main/java/com/github/axet/audiorecorder/app/RawSamples.java @@ -143,43 +143,7 @@ public class RawSamples { public static double getDB(double amplitude) { // https://en.wikipedia.org/wiki/Sound_pressure - return 20.0 * Math.log10(amplitude / 32768d); - } - - 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 short[] 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]; - - for (int i = 0; i < len; i++) { - dataR[i] = buffer[offset + i]; - } - - FastFourierTransformer.transformInPlace(dataRI, DftNormalization.STANDARD, TransformType.FORWARD); - - short[] data = new short[len2 / 2]; - - for (int i = 0; i < data.length; i++) { - Complex c = new Complex(dataR[i], dataI[i]); - data[i] = (short) (2.0 / len * c.abs()); - } - - return data; + return 20.0 * Math.log10(amplitude / 0x7FFF); } public void close() { diff --git a/app/src/main/java/com/github/axet/audiorecorder/services/RecordingService.java b/app/src/main/java/com/github/axet/audiorecorder/services/RecordingService.java index adfb693..b05f623 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/services/RecordingService.java +++ b/app/src/main/java/com/github/axet/audiorecorder/services/RecordingService.java @@ -5,8 +5,11 @@ import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; +import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.content.res.Resources; import android.os.Build; import android.os.IBinder; import android.support.annotation.Nullable; @@ -16,6 +19,7 @@ import android.widget.RemoteViews; import com.github.axet.audiorecorder.R; import com.github.axet.audiorecorder.activities.RecordingActivity; +import com.github.axet.audiorecorder.app.MainApplication; /** * RecordingActivity more likly to be removed from memory when paused then service. Notification button @@ -140,6 +144,19 @@ public class RecordingService extends Service { view.setOnClickPendingIntent(R.id.notification_pause, pe); view.setImageViewResource(R.id.notification_pause, !recording ? R.drawable.play : R.drawable.pause); + getBaseContext().setTheme(((MainApplication) getApplication()).getUserTheme()); + + view.apply(new ContextWrapper(getBaseContext()) { + public Context createPackageContext(String packageName, int flags) throws PackageManager.NameNotFoundException { + return new ContextWrapper(getBaseContext().createPackageContext(packageName, flags)) { + @Override + public Resources.Theme getTheme() { + return getBaseContext().getTheme(); + } + }; + } + }, null); + NotificationCompat.Builder builder = new NotificationCompat.Builder(this) .setOngoing(true) .setContentTitle("Recording") diff --git a/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTBarView.java b/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTBarView.java index 7429a84..a2bee4b 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTBarView.java +++ b/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTBarView.java @@ -11,21 +11,13 @@ import android.view.View; import com.github.axet.audiorecorder.app.RawSamples; -public class FFTBarView extends View { +public class FFTBarView extends FFTView { public static final String TAG = FFTBarView.class.getSimpleName(); - Paint paint; - short[] buffer; - int barCount; float barWidth; float barDeli; - int max; - - Paint textPaint; - Rect textBounds; - public FFTBarView(Context context) { this(context, null); } @@ -41,46 +33,11 @@ public class FFTBarView extends View { } void create() { - paint = new Paint(); - paint.setColor(0xff0433AE); - paint.setStrokeWidth(dp2px(1)); - - textBounds = new Rect(); - - textPaint = new Paint(); - textPaint.setColor(Color.GRAY); - textPaint.setAntiAlias(true); - textPaint.setTextSize(20f); - - if (isInEditMode()) { - //buffer = simple(); - buffer = RawSamples.generateSound(16000, 4000, 100); - buffer = RawSamples.fft(buffer, 0, buffer.length); - } + super.create(); } - public void setBuffer(short[] buf) { - buffer = RawSamples.fft(buf, 0, buf.length); - - max = Integer.MIN_VALUE; - for (int i = 0; i < buffer.length; i++) { - max = Math.max(buffer[i], max); - } - } - - short[] simple() { - int sampleRate = 1000; - int count = sampleRate; - short[] samples = new short[count]; - for (int i = 0; i < count; i++) { - double x = i / (double) sampleRate; - double y = 0; - y += 0.9 * Math.sin(50 * 2 * Math.PI * x); - y += 0.5 * Math.sin(80 * 2 * Math.PI * x); - y += 0.7 * Math.sin(40 * 2 * Math.PI * x); - samples[i] = (short) (y / 2.1 * 0x7fff); - } - return samples; + public void setBuffer(double[] buf) { + super.setBuffer(buf); } @Override @@ -113,10 +70,6 @@ public class FFTBarView extends View { protected void onLayout(boolean changed, int l, int t, int r, int b) { } - int dp2px(float dp) { - return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); - } - @Override public void onDraw(Canvas canvas) { if (barCount == 0) @@ -134,7 +87,7 @@ public class FFTBarView extends View { int offset = i * step; int end = Math.min(offset + step, buffer.length); for (int k = offset; k < end; k++) { - short s = buffer[k]; + double s = buffer[k]; max = Math.max(max, s); } } diff --git a/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTChartView.java b/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTChartView.java index 1eab256..dfcd50e 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTChartView.java +++ b/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTChartView.java @@ -13,15 +13,9 @@ import android.view.View; import com.github.axet.audiorecorder.app.RawSamples; -public class FFTChartView extends View { +public class FFTChartView extends FFTView { public static final String TAG = FFTChartView.class.getSimpleName(); - Paint paint; - short[] buffer; - - Paint textPaint; - Rect textBounds; - public FFTChartView(Context context) { this(context, null); } @@ -37,42 +31,13 @@ public class FFTChartView extends View { } void create() { - paint = new Paint(); - paint.setColor(0xff0433AE); - paint.setStrokeWidth(dp2px(1)); - - textBounds = new Rect(); - - textPaint = new Paint(); - textPaint.setColor(Color.GRAY); - textPaint.setAntiAlias(true); - textPaint.setTextSize(20f); - - if (isInEditMode()) { - buffer = simple(); - //buffer = RawSamples.generateSound(16000, 4000, 100); - //buffer = RawSamples.fft(buffer, 0, buffer.length); - } + super.create(); } - public void setBuffer(short[] buf) { - buffer = RawSamples.fft(buf, 0, buf.length); + public void setBuffer(double[] buf) { + super.setBuffer(buf); } - short[] simple() { - int sampleRate = 1000; - int count = sampleRate; - short[] samples = new short[count]; - for (int i = 0; i < count; i++) { - double x = i / (double) sampleRate; - double y = 0; - y += 0.9 * Math.sin(50 * 2 * Math.PI * x); - y += 0.5 * Math.sin(80 * 2 * Math.PI * x); - y += 0.7 * Math.sin(40 * 2 * Math.PI * x); - samples[i] = (short) (y / 2.1 * 0x7fff); - } - return samples; - } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { @@ -83,33 +48,34 @@ public class FFTChartView extends View { protected void onLayout(boolean changed, int l, int t, int r, int b) { } - int dp2px(float dp) { - return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); - } - @Override public void onDraw(Canvas canvas) { - int min = Integer.MAX_VALUE; - int max = Integer.MIN_VALUE; + if (buffer == null) + return; - for (int i = 0; i < buffer.length; i++) { - min = Math.min(buffer[i], min); - max = Math.max(buffer[i], max); - } + canvas.drawColor(Color.RED); int h = getHeight(); - if (min < 0) { - h = h / 2; - } - float startX = 0, startY = h; - float step = canvas.getWidth() / (float) buffer.length; + 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 = (RawSamples.MAXIMUM_DB + v) / RawSamples.MAXIMUM_DB; + float endX = startX; - float endY = h - h * (buffer[i] / (float) 0x7fff); + float endY = (float) (h - h * v); canvas.drawLine(startX, startY, endX, endY, paint); @@ -122,7 +88,7 @@ public class FFTChartView extends View { String tMax = "" + max; textPaint.getTextBounds(tMax, 0, tMax.length(), textBounds); - canvas.drawText("" + max, getWidth() - textBounds.width(), getHeight(), textPaint); + canvas.drawText("" + max, w - textBounds.width(), getHeight(), textPaint); } } diff --git a/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTView.java b/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTView.java new file mode 100644 index 0000000..3a57222 --- /dev/null +++ b/app/src/main/java/com/github/axet/audiorecorder/widgets/FFTView.java @@ -0,0 +1,151 @@ +package com.github.axet.audiorecorder.widgets; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.View; + +import com.github.axet.audiorecorder.app.RawSamples; + +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(dp2px(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; + } + + int dp2px(float dp) { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); + } + +} diff --git a/app/src/main/java/com/github/axet/audiorecorder/widgets/PitchView.java b/app/src/main/java/com/github/axet/audiorecorder/widgets/PitchView.java index e3a94b5..272bdf4 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/widgets/PitchView.java +++ b/app/src/main/java/com/github/axet/audiorecorder/widgets/PitchView.java @@ -2,6 +2,7 @@ package com.github.axet.audiorecorder.widgets; import android.content.Context; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; @@ -15,6 +16,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import com.github.axet.androidlibrary.widgets.ThemeUtils; +import com.github.axet.audiorecorder.R; +import com.github.axet.audiorecorder.app.MainApplication; import com.github.axet.audiorecorder.app.RawSamples; import java.util.LinkedList; @@ -39,10 +43,7 @@ public class PitchView extends ViewGroup { // in other words how many milliseconds do we need to show whole pitch. int pitchTime; - Paint paint; - Paint paintRed; List data = new LinkedList<>(); - List dataSamples = new LinkedList<>(); // how many pitches we can fit on screen int pitchScreenCount; @@ -56,7 +57,6 @@ public class PitchView extends ViewGroup { int pitchSize; PitchGraphView graph; - FFTBarView fft; PitchCurrentView current; long time = 0; @@ -77,9 +77,6 @@ public class PitchView extends ViewGroup { Handler handler; - int pitchColor = 0xff0433AE; - Paint cutColor = new Paint(); - public static class HandlerUpdate implements Runnable { long start; long updateSpeed; @@ -123,8 +120,11 @@ public class PitchView extends ViewGroup { } public class PitchGraphView extends View { + Paint paint; + Paint paintRed; Paint editPaint; Paint playPaint; + Paint cutColor; public PitchGraphView(Context context) { this(context, null); @@ -137,12 +137,24 @@ public class PitchView extends ViewGroup { 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(Color.BLACK); + editPaint.setColor(getThemeColor(R.attr.colorPrimaryDark)); editPaint.setStrokeWidth(pitchWidth); playPaint = new Paint(); - playPaint.setColor(Color.BLUE); + playPaint.setColor(getThemeColor(R.attr.colorPrimaryDark)); playPaint.setStrokeWidth(pitchWidth / 2); } @@ -270,7 +282,7 @@ public class PitchView extends ViewGroup { textPaint.setTextSize(20f); paint = new Paint(); - paint.setColor(pitchColor); + paint.setColor(getThemeColor(R.attr.colorPrimary)); paint.setStrokeWidth(pitchWidth); } @@ -309,6 +321,10 @@ public class PitchView extends ViewGroup { @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; @@ -351,15 +367,24 @@ public class PitchView extends ViewGroup { pitchTime = pitchSize * UPDATE_SPEED; - // bg = getThemeColor(android.R.attr.windowBackground); - cutColor.setColor(0xff0443BE); // getThemeColor(android.R.attr.textColorPrimaryDisableOnly)); - graph = new PitchGraphView(getContext()); addView(graph); - fft = new FFTBarView(getContext()); - fft.setPadding(0, dp2px(2), 0, 0); - addView(fft); +// 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, dp2px(2), 0, 0); +// addView(fft); current = new PitchCurrentView(getContext()); current.setPadding(0, dp2px(2), 0, 0); @@ -367,23 +392,17 @@ public class PitchView extends ViewGroup { if (isInEditMode()) { for (int i = 0; i < 3000; i++) { - data.add(-Math.random() * RawSamples.MAXIMUM_DB); - short[] buf = new short[1600]; - dataSamples.add(buf); + data.add(-Math.sin(i) * RawSamples.MAXIMUM_DB); } } - paint = new Paint(); - paint.setColor(0xff0433AE); - paint.setStrokeWidth(pitchWidth); - - paintRed = new Paint(); - paintRed.setColor(Color.RED); - paintRed.setStrokeWidth(pitchWidth); - time = System.currentTimeMillis(); } + public int getThemeColor(int id) { + return ThemeUtils.getThemeColor(getContext(), id); + } + public int getMaxPitchCount(int width) { int pitchScreenCount = width / pitchSize + 1; @@ -405,7 +424,6 @@ public class PitchView extends ViewGroup { if (data.size() > max) { int cut = data.size() - max; data.subList(0, cut).clear(); - dataSamples.subList(0, cut).clear(); samples += cut; int m = data.size() - 1; @@ -417,9 +435,8 @@ public class PitchView extends ViewGroup { } } - public void add(double a, short[] ss) { + public void add(double a) { data.add(a); - dataSamples.add(ss); } public void drawCalc() { @@ -472,15 +489,6 @@ public class PitchView extends ViewGroup { public void draw() { graph.invalidate(); - - if (data.size() > 0) { - fft.setBuffer(dataSamples.get(getEnd())); - } - fft.invalidate(); - - if (data.size() > 0) { - current.update(getEnd()); - } current.invalidate(); } @@ -488,51 +496,35 @@ public class PitchView extends ViewGroup { return pitchTime; } - int getThemeColor(int id) { - TypedValue typedValue = new TypedValue(); - Context context = getContext(); - Resources.Theme theme = context.getTheme(); - if (theme.resolveAttribute(id, typedValue, true)) { - if (Build.VERSION.SDK_INT >= 23) - return context.getResources().getColor(typedValue.resourceId, theme); - else - return context.getResources().getColor(typedValue.resourceId); - } else { - return Color.TRANSPARENT; - } - } - @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); - current.measure(widthMeasureSpec, heightMeasureSpec); + int ww = getMeasuredWidth() - getPaddingRight() - getPaddingLeft(); + int hh = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); - fft.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(dp2px(20), MeasureSpec.getMode(widthMeasureSpec))); + current.measure(MeasureSpec.makeMeasureSpec(ww, MeasureSpec.AT_MOST), + MeasureSpec.makeMeasureSpec(hh, MeasureSpec.AT_MOST)); - int hh = MeasureSpec.getSize(heightMeasureSpec) - current.getMeasuredHeight() - fft.getMeasuredHeight(); - graph.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(hh, MeasureSpec.getMode(widthMeasureSpec))); + 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(0, 0, graph.getMeasuredWidth(), graph.getMeasuredHeight()); - fft.layout(0, graph.getMeasuredHeight(), fft.getMeasuredWidth(), - graph.getMeasuredHeight() + fft.getMeasuredHeight()); - current.layout(0, fft.getBottom(), current.getMeasuredWidth(), - fft.getBottom() + current.getMeasuredHeight()); + graph.layout(getPaddingLeft(), getPaddingTop(), + getPaddingLeft() + graph.getMeasuredWidth(), getPaddingTop() + graph.getMeasuredHeight()); + + current.layout(getPaddingLeft(), graph.getBottom(), + getPaddingLeft() + current.getMeasuredWidth(), graph.getBottom() + current.getMeasuredHeight()); } int dp2px(float dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); } - @Override - protected void onDraw(Canvas canvas) { - graph.draw(canvas); - current.draw(canvas); - } - public void stop() { if (edit != null) HandlerUpdate.stop(handler, edit); diff --git a/app/src/main/res/drawable/round.xml b/app/src/main/res/drawable/round.xml deleted file mode 100644 index 5589315..0000000 --- a/app/src/main/res/drawable/round.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 6700b32..e6f67ec 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -10,14 +10,14 @@ + android:theme="@style/AppThemeLight.AppBarOverlay"> + app:popupTheme="@style/AppThemeLight.PopupOverlay" /> diff --git a/app/src/main/res/layout/activity_recording.xml b/app/src/main/res/layout/activity_recording.xml index 70748fb..1bb525a 100644 --- a/app/src/main/res/layout/activity_recording.xml +++ b/app/src/main/res/layout/activity_recording.xml @@ -38,7 +38,8 @@ android:id="@+id/recording_pitch" android:layout_width="match_parent" android:layout_height="120dp" - android:layout_centerInParent="true" /> + android:layout_centerInParent="true" + android:padding="5dp" /> - - - - @@ -96,28 +93,24 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - - - - diff --git a/app/src/main/res/layout/notifictaion_recording.xml b/app/src/main/res/layout/notifictaion_recording.xml index 0e921aa..7caff47 100644 --- a/app/src/main/res/layout/notifictaion_recording.xml +++ b/app/src/main/res/layout/notifictaion_recording.xml @@ -3,13 +3,13 @@ android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="64dp" - android:background="@android:color/white"> + android:background="?android:windowBackground"> + android:tint="?android:attr/colorForeground" /> + android:textColor="?android:attr/colorForeground" /> diff --git a/app/src/main/res/layout/recording.xml b/app/src/main/res/layout/recording.xml index 19391cb..461335b 100644 --- a/app/src/main/res/layout/recording.xml +++ b/app/src/main/res/layout/recording.xml @@ -70,8 +70,8 @@ android:layout_marginBottom="5dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" - android:background="#dedede" android:orientation="vertical" + android:background="?attr/secondBackground" android:padding="5dp"> + android:tint="?attr/colorAccent" /> + android:tint="?attr/colorAccent" /> + android:tint="?attr/colorAccent" /> diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml index 251fb9f..d7d6ad1 100644 --- a/app/src/main/res/values-v21/styles.xml +++ b/app/src/main/res/values-v21/styles.xml @@ -1,6 +1,11 @@ -> - - + - - + + diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index a031aa0..d4d59d5 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -1,4 +1,5 @@ - + + +