diff --git a/app/build.gradle b/app/build.gradle index 6418229..9bf5dff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.github.axet.audiorecorder" minSdkVersion 16 targetSdkVersion 23 - versionCode 49 - versionName "1.1.28" + versionCode 50 + versionName "1.1.29" } signingConfigs { release { 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 0bc963b..97880e9 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 @@ -24,6 +24,7 @@ import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; import android.view.Display; +import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; @@ -451,8 +452,9 @@ public class RecordingActivity extends AppCompatActivity { return; RawSamples rs = new RawSamples(storage.getTempRecording()); - rs.trunk(editSample); + rs.trunk(editSample + samplesUpdate); rs.close(); + edit(false, true); loadSamples(); pitch.drawCalc(); @@ -552,7 +554,6 @@ public class RecordingActivity extends AppCompatActivity { long start = System.currentTimeMillis(); recorder.startRecording(); - int samplesUpdateCount = 0; int samplesTimeCount = 0; // how many samples we need to update 'samples'. time clock. every 1000ms. int samplesTimeUpdate = 1000 / 1000 * sampleRate * (RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_MONO ? 1 : 2); @@ -584,17 +585,13 @@ public class RecordingActivity extends AppCompatActivity { rs.write(buffer); - samplesUpdateCount += s; - if (samplesUpdateCount >= samplesUpdate) { - final float dB = RawSamples.getdB(buffer, 0, readSize); - handle.post(new Runnable() { - @Override - public void run() { - pitch.add(dB); - } - }); - samplesUpdateCount -= samplesUpdate; - } + final float dB = RawSamples.getdB(buffer, 0, readSize); + handle.post(new Runnable() { + @Override + public void run() { + pitch.add(dB); + } + }); samplesTime += s; samplesTimeCount += s; @@ -647,7 +644,17 @@ public class RecordingActivity extends AppCompatActivity { void updateBufferSize(boolean pause) { synchronized (bufferSize) { if (pause) { - samplesUpdate = (int) (1000 * sampleRate / 1000.0); + // we need make buffer multiply of pitch.getPitchTime() (100 ms). + // to prevent missing blocks from view otherwise: + + // file may contain not multiply 'samplesUpdate' count of samples. it is about 100ms. + // we can't show on pitchView sorter then 100ms samples. we can't add partial sample because on + // resumeRecording we have to apply rest of samplesUpdate or reload all samples again + // from file. better then confusing user we cut them on next resumeRecording. + + long l = 1000; + l = l / pitch.getPitchTime() * pitch.getPitchTime(); + samplesUpdate = (int) (l * sampleRate / 1000.0); } else { samplesUpdate = (int) (pitch.getPitchTime() * sampleRate / 1000.0); } 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 db9b59e..4211e88 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 @@ -116,21 +116,26 @@ public class RawSamples { public void trunk(long pos) { try { FileChannel outChan = new FileOutputStream(in, true).getChannel(); - outChan.truncate(getBufferLen(pos + 1)); + outChan.truncate(getBufferLen(pos)); outChan.close(); } catch (IOException e) { throw new RuntimeException(e); } } - public static float getdB(short[] buffer, int offset, int len) { + 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); + } - double amplitude = Math.sqrt(sum / len); + public static float getdB(short[] buffer, int offset, int len) { + return getdB(getAmplitude(buffer, offset, len)); + } + public static float getdB(double amplitude) { // https://en.wikipedia.org/wiki/Sound_pressure double decibel = 20.0 * Math.log10(amplitude / 32768f); 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 bcda926..68e5aa7 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 @@ -39,6 +39,7 @@ public class PitchView extends ViewGroup { int pitchTime; Paint paint; + Paint paintRed; List data = new LinkedList<>(); // how many pitches we can fit on screen @@ -166,6 +167,12 @@ public class PitchView extends ViewGroup { Paint p = paint; + if (data.get(i) < 0) { + p = paintRed; + left = 1; + right = 1; + } + if ((edit != null || play != null) && i >= editPos) p = cutColor; @@ -275,15 +282,15 @@ public class PitchView extends ViewGroup { y += dp2px(2); - float left = filterdB(end); - float right = filterdB(end); + float left = data.get(end); + float right = data.get(end); float mid = getWidth() / 2f; y = y + dp2px(pitchDlimiter) / 2; - canvas.drawLine(mid, y, mid - mid * left, y, paint); - canvas.drawLine(mid, y, mid + mid * right, y, paint); + canvas.drawLine(mid, y, mid - mid * left - 1, y, paint); + canvas.drawLine(mid, y, mid + mid * right + 1, y, paint); } } } @@ -331,6 +338,10 @@ public class PitchView extends ViewGroup { paint.setColor(0xff0433AE); paint.setStrokeWidth(pitchWidth); + paintRed = new Paint(); + paintRed.setColor(Color.RED); + paintRed.setStrokeWidth(pitchWidth); + time = System.currentTimeMillis(); } @@ -455,6 +466,7 @@ public class PitchView extends ViewGroup { public long edit(float offset) { if (offset < 0) offset = 0; + editPos = ((int) offset) / pitchSize; if (editPos >= pitchScreenCount)