diff --git a/app/src/main/java/xdsopl/robot36/MainActivity.java b/app/src/main/java/xdsopl/robot36/MainActivity.java index 47d50cc..6ec2005 100644 --- a/app/src/main/java/xdsopl/robot36/MainActivity.java +++ b/app/src/main/java/xdsopl/robot36/MainActivity.java @@ -32,6 +32,7 @@ import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class MainActivity extends AppCompatActivity { @@ -39,6 +40,9 @@ public class MainActivity extends AppCompatActivity { private Bitmap scopeBitmap; private PixelBuffer scopeBuffer; private ImageView scopeView; + private Bitmap freqPlotBitmap; + private PixelBuffer freqPlotBuffer; + private ImageView freqPlotView; private float[] recordBuffer; private AudioRecord audioRecord; private Decoder decoder; @@ -65,17 +69,40 @@ public class MainActivity extends AppCompatActivity { public void onPeriodicNotification(AudioRecord audioRecord) { audioRecord.read(recordBuffer, 0, recordBuffer.length, AudioRecord.READ_BLOCKING); if (decoder.process(recordBuffer, recordChannel)) { - int width = scopeBitmap.getWidth(); - int height = scopeBitmap.getHeight(); - int stride = scopeBuffer.width; - int offset = stride * (scopeBuffer.line + scopeBuffer.height / 2 - height); - scopeBitmap.setPixels(scopeBuffer.pixels, offset, stride, 0, 0, width, height); - scopeView.invalidate(); + processScope(); + processFreqPlot(); setStatus(decoder.lastMode.getName()); } } }; + private void processFreqPlot() { + int width = freqPlotBitmap.getWidth(); + int height = freqPlotBitmap.getHeight(); + int stride = freqPlotBuffer.width; + int line = stride * freqPlotBuffer.line; + int channels = recordChannel > 0 ? 2 : 1; + Arrays.fill(freqPlotBuffer.pixels, line, line + stride, 0); + for (int i = 0; i < recordBuffer.length / channels; ++i) { + int x = Math.min(Math.max(Math.round((recordBuffer[i] + 3) * stride / 6), 0), stride - 1); + freqPlotBuffer.pixels[line + x] = tint; + } + System.arraycopy(freqPlotBuffer.pixels, line, freqPlotBuffer.pixels, line + stride * (freqPlotBuffer.height / 2), stride); + freqPlotBuffer.line = (freqPlotBuffer.line + 1) % (freqPlotBuffer.height / 2); + int offset = stride * (freqPlotBuffer.line + freqPlotBuffer.height / 2 - height); + freqPlotBitmap.setPixels(freqPlotBuffer.pixels, offset, stride, 0, 0, width, height); + freqPlotView.invalidate(); + } + + private void processScope() { + int width = scopeBitmap.getWidth(); + int height = scopeBitmap.getHeight(); + int stride = scopeBuffer.width; + int offset = stride * (scopeBuffer.line + scopeBuffer.height / 2 - height); + scopeBitmap.setPixels(scopeBuffer.pixels, offset, stride, 0, 0, width, height); + scopeView.invalidate(); + } + private void initAudioRecord() { boolean rateChanged = true; if (audioRecord != null) { @@ -280,6 +307,10 @@ public class MainActivity extends AppCompatActivity { scopeView = findViewById(R.id.scope); scopeBuffer = new PixelBuffer(640, 2 * 1280); createScope(getResources().getConfiguration()); + freqPlotView = findViewById(R.id.freq_plot); + freqPlotBuffer = new PixelBuffer(640, 2 * 640); + freqPlotBitmap = Bitmap.createBitmap(freqPlotBuffer.width, freqPlotBuffer.height / 2, Bitmap.Config.ARGB_8888); + freqPlotView.setImageBitmap(freqPlotBitmap); List permissions = new ArrayList<>(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { permissions.add(Manifest.permission.RECORD_AUDIO); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index df31c92..a653495 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,9 +3,9 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" - android:keepScreenOn="true" android:layout_width="match_parent" android:layout_height="match_parent" + android:keepScreenOn="true" tools:context=".MainActivity"> - + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 717cf95..1bd74d7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -24,7 +24,8 @@ Audio setup failed Audio permission denied Audio recording error - Visualization of audio signal + Decoded SSTV picture + Frequency plot Night Mode Enable Disable