From 1f67e185bc37d088cb1fff1e5854c93908e27c33 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Sun, 5 May 2024 20:46:38 +0200 Subject: [PATCH] added option to force mode --- app/src/main/java/xdsopl/robot36/Decoder.java | 59 ++++++++++---- .../java/xdsopl/robot36/MainActivity.java | 78 ++++++++++++++++++- .../main/java/xdsopl/robot36/RGBModes.java | 2 +- .../main/java/xdsopl/robot36/RawDecoder.java | 2 +- app/src/main/res/menu/menu_main.xml | 78 ++++++++++++++++++- app/src/main/res/values/strings.xml | 24 +++++- 6 files changed, 221 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/xdsopl/robot36/Decoder.java b/app/src/main/java/xdsopl/robot36/Decoder.java index 9e56330..b28cffd 100644 --- a/app/src/main/java/xdsopl/robot36/Decoder.java +++ b/app/src/main/java/xdsopl/robot36/Decoder.java @@ -42,7 +42,8 @@ public class Decoder { private final ArrayList syncPulse9msModes; private final ArrayList syncPulse20msModes; - public Mode lastMode; + protected Mode currentMode; + private boolean lockMode; private int currentSample; private int leaderBreakIndex; private int lastSyncPulseIndex; @@ -95,7 +96,7 @@ public class Decoder { scanLineToleranceSamples = (int) Math.round(scanLineToleranceSeconds * sampleRate); rawMode = new RawDecoder(sampleRate); Mode robot36 = new Robot_36_Color(sampleRate); - lastMode = robot36; + currentMode = robot36; lastScanLineSamples = robot36.getScanLineSamples(); syncPulse5msModes = new ArrayList<>(); syncPulse5msModes.add(RGBModes.Wraase_SC2_180(sampleRate)); @@ -160,6 +161,13 @@ private Mode findMode(ArrayList modes, int code) { return null; } + private Mode findMode(ArrayList modes, String name) { + for (Mode mode : modes) + if (mode.getName().equals(name)) + return mode; + return null; + } + private void copyUnscaled() { for (int row = 0; row < pixelBuffer.height; ++row) { int line = scopeBuffer.width * scopeBuffer.line; @@ -316,14 +324,17 @@ private boolean handleHeader() { pulses = last20msSyncPulses; lines = last20msScanLines; } else { - drawLines(0xffff0000, 8); + if (!lockMode) + drawLines(0xffff0000, 8); return false; } + if (lockMode && mode != currentMode) + return false; mode.reset(); imageBuffer.width = mode.getWidth(); imageBuffer.height = mode.getHeight(); imageBuffer.line = 0; - lastMode = mode; + currentMode = mode; lastSyncPulseIndex = syncPulseIndex + mode.getFirstSyncPulseIndex(); lastScanLineSamples = mode.getScanLineSamples(); lastFrequencyOffset = leaderFreqOffset; @@ -358,14 +369,15 @@ private boolean processSyncPulse(ArrayList modes, float[] freqOffs, int[] if (scanLineStdDev(lines, mean) > scanLineToleranceSamples) return false; boolean pictureChanged = false; - if (imageBuffer.line < 0 || imageBuffer.line >= imageBuffer.height) { - Mode prevMode = lastMode; - lastMode = detectMode(modes, scanLineSamples); - pictureChanged = lastMode != prevMode + if (lockMode || imageBuffer.line >= 0 && imageBuffer.line < imageBuffer.height) { + if (currentMode != rawMode && Math.abs(scanLineSamples - currentMode.getScanLineSamples()) > scanLineToleranceSamples) + return false; + } else { + Mode prevMode = currentMode; + currentMode = detectMode(modes, scanLineSamples); + pictureChanged = currentMode != prevMode || Math.abs(lastScanLineSamples - scanLineSamples) > scanLineToleranceSamples || Math.abs(lastSyncPulseIndex + scanLineSamples - pulses[pulses.length - 1]) > syncPulseToleranceSamples; - } else if (Math.abs(scanLineSamples - lastMode.getScanLineSamples()) > scanLineToleranceSamples) { - return false; } if (pictureChanged) { drawLines(0xff000000, 10); @@ -378,14 +390,14 @@ private boolean processSyncPulse(ArrayList modes, float[] freqOffs, int[] int extrapolate = endPulse / scanLineSamples; int firstPulse = endPulse - extrapolate * scanLineSamples; for (int pulseIndex = firstPulse; pulseIndex < endPulse; pulseIndex += scanLineSamples) - copyLines(lastMode.decodeScanLine(pixelBuffer, scratchBuffer, scanLineBuffer, scopeBuffer.width, pulseIndex, scanLineSamples, frequencyOffset)); + copyLines(currentMode.decodeScanLine(pixelBuffer, scratchBuffer, scanLineBuffer, scopeBuffer.width, pulseIndex, scanLineSamples, frequencyOffset)); } for (int i = pictureChanged ? 0 : lines.length - 1; i < lines.length; ++i) - copyLines(lastMode.decodeScanLine(pixelBuffer, scratchBuffer, scanLineBuffer, scopeBuffer.width, pulses[i], lines[i], frequencyOffset)); + copyLines(currentMode.decodeScanLine(pixelBuffer, scratchBuffer, scanLineBuffer, scopeBuffer.width, pulses[i], lines[i], frequencyOffset)); lastSyncPulseIndex = pulses[pulses.length - 1]; lastScanLineSamples = scanLineSamples; lastFrequencyOffset = frequencyOffset; - shiftSamples(lastSyncPulseIndex + lastMode.getBegin()); + shiftSamples(lastSyncPulseIndex + currentMode.getBegin()); return true; } @@ -417,10 +429,29 @@ public boolean process(float[] recordBuffer, int channelSelect) { if (handleHeader()) return true; if (currentSample > lastSyncPulseIndex + (lastScanLineSamples * 5) / 4) { - copyLines(lastMode.decodeScanLine(pixelBuffer, scratchBuffer, scanLineBuffer, scopeBuffer.width, lastSyncPulseIndex, lastScanLineSamples, lastFrequencyOffset)); + copyLines(currentMode.decodeScanLine(pixelBuffer, scratchBuffer, scanLineBuffer, scopeBuffer.width, lastSyncPulseIndex, lastScanLineSamples, lastFrequencyOffset)); lastSyncPulseIndex += lastScanLineSamples; return true; } return false; } + + public void forceMode(String name) { + lockMode = true; + Mode mode = findMode(syncPulse5msModes, name); + if (mode == null) + mode = findMode(syncPulse9msModes, name); + if (mode == null) + mode = findMode(syncPulse20msModes, name); + if (mode == currentMode) + return; + imageBuffer.line = -1; + if (mode == null) + mode = rawMode; + currentMode = mode; + } + + public void autoMode() { + lockMode = false; + } } diff --git a/app/src/main/java/xdsopl/robot36/MainActivity.java b/app/src/main/java/xdsopl/robot36/MainActivity.java index 9164a28..2f66138 100644 --- a/app/src/main/java/xdsopl/robot36/MainActivity.java +++ b/app/src/main/java/xdsopl/robot36/MainActivity.java @@ -83,6 +83,16 @@ private void setStatus(String str) { setTitle(str); } + private void forceMode(int id) { + if (decoder != null) + decoder.forceMode(getString(id)); + } + + private void autoMode() { + if (decoder != null) + decoder.autoMode(); + } + private final AudioRecord.OnRecordPositionUpdateListener recordListener = new AudioRecord.OnRecordPositionUpdateListener() { @Override public void onMarkerReached(AudioRecord ignore) { @@ -97,7 +107,7 @@ public void onPeriodicNotification(AudioRecord audioRecord) { if (newLines) { processScope(); processImage(); - setStatus(decoder.lastMode.getName()); + setStatus(decoder.currentMode.getName()); } } }; @@ -128,7 +138,7 @@ private void processFreqPlot() { for (int i = 0; i < samples; ++i) { int x = Math.round((recordBuffer[i] + 2.5f) * 0.25f * stride); if (x >= spread && x < stride - spread) - for (int j = - spread; j <= spread; ++j) + for (int j = -spread; j <= spread; ++j) freqPlotBuffer.pixels[line + x + j] += 1 + spread * spread - j * j; } int factor = 960 / samples; @@ -401,6 +411,70 @@ public boolean onOptionsItemSelected(MenuItem item) { storeBitmap(scopeBitmap); return true; } + if (id == R.id.action_auto_mode) { + autoMode(); + return true; + } + if (id == R.id.action_force_raw_mode) { + forceMode(R.string.raw_mode); + return true; + } + if (id == R.id.action_force_robot36_color) { + forceMode(R.string.robot36_color); + return true; + } + if (id == R.id.action_force_robot72_color) { + forceMode(R.string.robot72_color); + return true; + } + if (id == R.id.action_force_pd50) { + forceMode(R.string.pd50); + return true; + } + if (id == R.id.action_force_pd90) { + forceMode(R.string.pd90); + return true; + } + if (id == R.id.action_force_pd120) { + forceMode(R.string.pd120); + return true; + } + if (id == R.id.action_force_pd160) { + forceMode(R.string.pd160); + return true; + } + if (id == R.id.action_force_pd180) { + forceMode(R.string.pd180); + return true; + } + if (id == R.id.action_force_pd240) { + forceMode(R.string.pd240); + return true; + } + if (id == R.id.action_force_martin1) { + forceMode(R.string.martin1); + return true; + } + if (id == R.id.action_force_martin2) { + forceMode(R.string.martin2); + return true; + } + if (id == R.id.action_force_scottie1) { + forceMode(R.string.scottie1); + return true; + } + if (id == R.id.action_force_scottie2) { + forceMode(R.string.scottie2); + return true; + } + if (id == R.id.action_force_scottie_dx) { + forceMode(R.string.scottie_dx); + return true; + } + if (id == R.id.action_force_wraase_sc2_180) { + forceMode(R.string.wraase_sc2_180); + return true; + } if (id == R.id.action_set_record_rate_8000) { setRecordRate(8000); return true; diff --git a/app/src/main/java/xdsopl/robot36/RGBModes.java b/app/src/main/java/xdsopl/robot36/RGBModes.java index 9d56b51..7b92323 100644 --- a/app/src/main/java/xdsopl/robot36/RGBModes.java +++ b/app/src/main/java/xdsopl/robot36/RGBModes.java @@ -47,6 +47,6 @@ public static RGBDecoder Wraase_SC2_180(int sampleRate) { double greenEndSeconds = greenBeginSeconds + channelSeconds; double blueBeginSeconds = greenEndSeconds; double blueEndSeconds = blueBeginSeconds + channelSeconds; - return new RGBDecoder("Wraase SC2-180", 55, 320, 256, 0, scanLineSeconds, redBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, blueEndSeconds, sampleRate); + return new RGBDecoder("Wraase SC2–180", 55, 320, 256, 0, scanLineSeconds, redBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, blueEndSeconds, sampleRate); } } diff --git a/app/src/main/java/xdsopl/robot36/RawDecoder.java b/app/src/main/java/xdsopl/robot36/RawDecoder.java index 33700d9..a565275 100644 --- a/app/src/main/java/xdsopl/robot36/RawDecoder.java +++ b/app/src/main/java/xdsopl/robot36/RawDecoder.java @@ -23,7 +23,7 @@ private float freqToLevel(float frequency, float offset) { @Override public String getName() { - return "Raw"; + return "Raw Mode"; } @Override diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 7f9bf38..9f3ea07 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -1,20 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 65d5d0f..1d7493e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,7 +1,29 @@ Robot36 - Share + Share Store Scope + Auto Mode + Force Mode + Robot Modes + PD Modes + Martin Modes + Scottie Modes + Wraase Modes + Raw Mode + Robot 36 Color + Robot 72 Color + PD 50 + PD 90 + PD 120 + PD 160 + PD 180 + PD 240 + Martin 1 + Martin 2 + Scottie 1 + Scottie 2 + Scottie DX + Wraase SC2–180 Listening Audio Settings Sample Rate