Skip to content

Commit

Permalink
added option to force mode
Browse files Browse the repository at this point in the history
  • Loading branch information
xdsopl committed May 5, 2024
1 parent 2ed8f98 commit 1f67e18
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 22 deletions.
59 changes: 45 additions & 14 deletions app/src/main/java/xdsopl/robot36/Decoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public class Decoder {
private final ArrayList<Mode> syncPulse9msModes;
private final ArrayList<Mode> syncPulse20msModes;

public Mode lastMode;
protected Mode currentMode;
private boolean lockMode;
private int currentSample;
private int leaderBreakIndex;
private int lastSyncPulseIndex;
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -160,6 +161,13 @@ private Mode findMode(ArrayList<Mode> modes, int code) {
return null;
}

private Mode findMode(ArrayList<Mode> 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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -358,14 +369,15 @@ private boolean processSyncPulse(ArrayList<Mode> 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);
Expand All @@ -378,14 +390,14 @@ private boolean processSyncPulse(ArrayList<Mode> 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;
}

Expand Down Expand Up @@ -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;
}
}
78 changes: 76 additions & 2 deletions app/src/main/java/xdsopl/robot36/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -97,7 +107,7 @@ public void onPeriodicNotification(AudioRecord audioRecord) {
if (newLines) {
processScope();
processImage();
setStatus(decoder.lastMode.getName());
setStatus(decoder.currentMode.getName());
}
}
};
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/xdsopl/robot36/RGBModes.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 SC2180", 55, 320, 256, 0, scanLineSeconds, redBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, blueEndSeconds, sampleRate);
}
}
2 changes: 1 addition & 1 deletion app/src/main/java/xdsopl/robot36/RawDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private float freqToLevel(float frequency, float offset) {

@Override
public String getName() {
return "Raw";
return "Raw Mode";
}

@Override
Expand Down
78 changes: 75 additions & 3 deletions app/src/main/res/menu/menu_main.xml
Original file line number Diff line number Diff line change
@@ -1,20 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="xdsopl.robot36.MainActivity">
<item
android:id="@+id/action_store_scope"
android:title="@string/store_scope"
android:icon="@drawable/baseline_save_alt_24"
android:title="@string/store_scope"
app:iconTint="@color/tint"
app:showAsAction="always"
tools:ignore="AlwaysShowAction" />
<item
android:id="@+id/menu_item_share"
android:title="@string/action_share"
android:title="@string/share"
app:actionProviderClass="androidx.appcompat.widget.ShareActionProvider"
app:showAsAction="always" />
<item
android:id="@+id/action_auto_mode"
android:title="@string/auto_mode" />
<item android:title="@string/force_mode">
<menu>
<item
android:id="@+id/action_force_raw_mode"
android:title="@string/raw_mode" />
<item android:title="@string/robot_modes">
<menu>
<item
android:id="@+id/action_force_robot36_color"
android:title="@string/robot36_color" />
<item
android:id="@+id/action_force_robot72_color"
android:title="@string/robot72_color" />
</menu>
</item>
<item android:title="@string/pd_modes">
<menu>
<item
android:id="@+id/action_force_pd50"
android:title="@string/pd50" />
<item
android:id="@+id/action_force_pd90"
android:title="@string/pd90" />
<item
android:id="@+id/action_force_pd120"
android:title="@string/pd120" />
<item
android:id="@+id/action_force_pd160"
android:title="@string/pd160" />
<item
android:id="@+id/action_force_pd180"
android:title="@string/pd180" />
<item
android:id="@+id/action_force_pd240"
android:title="@string/pd240" />
</menu>
</item>
<item android:title="@string/martin_modes">
<menu>
<item
android:id="@+id/action_force_martin1"
android:title="@string/martin1" />
<item
android:id="@+id/action_force_martin2"
android:title="@string/martin2" />
</menu>
</item>
<item android:title="@string/scottie_modes">
<menu>
<item
android:id="@+id/action_force_scottie1"
android:title="@string/scottie1" />
<item
android:id="@+id/action_force_scottie2"
android:title="@string/scottie2" />
<item
android:id="@+id/action_force_scottie_dx"
android:title="@string/scottie_dx" />
</menu>
</item>
<item android:title="@string/wraase_modes">
<menu>
<item
android:id="@+id/action_force_wraase_sc2_180"
android:title="@string/wraase_sc2_180" />
</menu>
</item>
</menu>
</item>
<item android:title="@string/audio_settings">
<menu>
<item android:title="@string/sample_rate">
Expand Down
24 changes: 23 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
<resources>
<string name="app_name">Robot36</string>
<string name="action_share">Share</string>
<string name="share">Share</string>
<string name="store_scope">Store Scope</string>
<string name="auto_mode">Auto Mode</string>
<string name="force_mode">Force Mode</string>
<string name="robot_modes">Robot Modes</string>
<string name="pd_modes">PD Modes</string>
<string name="martin_modes">Martin Modes</string>
<string name="scottie_modes">Scottie Modes</string>
<string name="wraase_modes">Wraase Modes</string>
<string name="raw_mode">Raw Mode</string>
<string name="robot36_color">Robot 36 Color</string>
<string name="robot72_color">Robot 72 Color</string>
<string name="pd50">PD 50</string>
<string name="pd90">PD 90</string>
<string name="pd120">PD 120</string>
<string name="pd160">PD 160</string>
<string name="pd180">PD 180</string>
<string name="pd240">PD 240</string>
<string name="martin1">Martin 1</string>
<string name="martin2">Martin 2</string>
<string name="scottie1">Scottie 1</string>
<string name="scottie2">Scottie 2</string>
<string name="scottie_dx">Scottie DX</string>
<string name="wraase_sc2_180">Wraase SC2–180</string>
<string name="listening">Listening</string>
<string name="audio_settings">Audio Settings</string>
<string name="sample_rate">Sample Rate</string>
Expand Down

0 comments on commit 1f67e18

Please sign in to comment.