From 97bdad4b8cc7aa4203bc70ed0910be962a73f66a Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Thu, 25 Apr 2024 09:14:48 +0200 Subject: [PATCH] keep aspect-ratio for each mode but PD290 --- app/src/main/java/xdsopl/robot36/Decoder.java | 14 +++++++------- app/src/main/java/xdsopl/robot36/MainActivity.java | 3 +-- app/src/main/java/xdsopl/robot36/PaulDon.java | 10 ++++++---- app/src/main/java/xdsopl/robot36/RGBDecoder.java | 14 ++++++++------ app/src/main/java/xdsopl/robot36/RGBModes.java | 6 +++--- app/src/main/java/xdsopl/robot36/RawDecoder.java | 7 ++++--- .../main/java/xdsopl/robot36/Robot_36_Color.java | 10 ++++++---- .../main/java/xdsopl/robot36/Robot_72_Color.java | 12 +++++++----- 8 files changed, 42 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/xdsopl/robot36/Decoder.java b/app/src/main/java/xdsopl/robot36/Decoder.java index 31c1711..e940d9b 100644 --- a/app/src/main/java/xdsopl/robot36/Decoder.java +++ b/app/src/main/java/xdsopl/robot36/Decoder.java @@ -85,13 +85,13 @@ public class Decoder { syncPulse9msModes.add(RGBModes.Scottie("2", 0.088064, sampleRate)); syncPulse9msModes.add(RGBModes.Scottie("DX", 0.3456, sampleRate)); syncPulse20msModes = new ArrayList<>(); - syncPulse20msModes.add(new PaulDon("50", 0.09152, sampleRate)); - syncPulse20msModes.add(new PaulDon("90", 0.17024, sampleRate)); - syncPulse20msModes.add(new PaulDon("120", 0.1216, sampleRate)); - syncPulse20msModes.add(new PaulDon("160", 0.195584, sampleRate)); - syncPulse20msModes.add(new PaulDon("180", 0.18304, sampleRate)); - syncPulse20msModes.add(new PaulDon("240", 0.24448, sampleRate)); - syncPulse20msModes.add(new PaulDon("290", 0.2288, sampleRate)); + syncPulse20msModes.add(new PaulDon("50", 320, 0.09152, sampleRate)); + syncPulse20msModes.add(new PaulDon("90", 320, 0.17024, sampleRate)); + syncPulse20msModes.add(new PaulDon("120", 640, 0.1216, sampleRate)); + syncPulse20msModes.add(new PaulDon("160", 512, 0.195584, sampleRate)); + syncPulse20msModes.add(new PaulDon("180", 640, 0.18304, sampleRate)); + syncPulse20msModes.add(new PaulDon("240", 640, 0.24448, sampleRate)); + syncPulse20msModes.add(new PaulDon("290", 640, 0.2288, sampleRate)); } private void adjustSyncPulses(int[] pulses, int shift) { diff --git a/app/src/main/java/xdsopl/robot36/MainActivity.java b/app/src/main/java/xdsopl/robot36/MainActivity.java index b81fb5d..0172722 100644 --- a/app/src/main/java/xdsopl/robot36/MainActivity.java +++ b/app/src/main/java/xdsopl/robot36/MainActivity.java @@ -30,7 +30,7 @@ import java.util.List; public class MainActivity extends AppCompatActivity { - private final int scopeWidth = 640, scopeHeight = 640; + private final int scopeWidth = 640, scopeHeight = 1280; private Bitmap scopeBitmap; private int[] scopePixels; private ImageView scopeView; @@ -130,7 +130,6 @@ public class MainActivity extends AppCompatActivity { scopeView = findViewById(R.id.scope); scopeBitmap = Bitmap.createBitmap(scopeWidth, scopeHeight, Bitmap.Config.ARGB_8888); scopeView.setImageBitmap(scopeBitmap); - scopeView.setScaleType(ImageView.ScaleType.FIT_XY); scopePixels = new int[2 * scopeWidth * scopeHeight]; List permissions = new ArrayList<>(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { diff --git a/app/src/main/java/xdsopl/robot36/PaulDon.java b/app/src/main/java/xdsopl/robot36/PaulDon.java index 3428d7b..e779fd3 100644 --- a/app/src/main/java/xdsopl/robot36/PaulDon.java +++ b/app/src/main/java/xdsopl/robot36/PaulDon.java @@ -8,6 +8,7 @@ package xdsopl.robot36; public class PaulDon implements Mode { private final ExponentialMovingAverage lowPassFilter; + private final int horizontalPixels; private final int scanLineSamples; private final int channelSamples; private final int beginSamples; @@ -19,8 +20,9 @@ public class PaulDon implements Mode { private final String name; @SuppressWarnings("UnnecessaryLocalVariable") - PaulDon(String name, double channelSeconds, int sampleRate) { + PaulDon(String name, int horizontalPixels, double channelSeconds, int sampleRate) { this.name = "PD " + name; + this.horizontalPixels = horizontalPixels; double syncPulseSeconds = 0.02; double syncPorchSeconds = 0.00208; double scanLineSeconds = syncPulseSeconds + syncPorchSeconds + 4 * (channelSeconds); @@ -58,15 +60,15 @@ public class PaulDon implements Mode { public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scratchBuffer, float[] scanLineBuffer, int syncPulseIndex, int scanLineSamples, float frequencyOffset) { if (syncPulseIndex + beginSamples < 0 || syncPulseIndex + endSamples > scanLineBuffer.length) return 0; - lowPassFilter.cutoff(evenBuffer.length, 2 * channelSamples, 2); + lowPassFilter.cutoff(horizontalPixels, 2 * channelSamples, 2); lowPassFilter.reset(); for (int i = beginSamples; i < endSamples; ++i) scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + i]); lowPassFilter.reset(); for (int i = endSamples - 1; i >= beginSamples; --i) scratchBuffer[i] = freqToLevel(lowPassFilter.avg(scratchBuffer[i]), frequencyOffset); - for (int i = 0; i < evenBuffer.length; ++i) { - int position = (i * channelSamples) / evenBuffer.length; + for (int i = 0; i < horizontalPixels; ++i) { + int position = (i * channelSamples) / horizontalPixels; int yEvenPos = position + yEvenBeginSamples; int vAvgPos = position + vAvgBeginSamples; int uAvgPos = position + uAvgBeginSamples; diff --git a/app/src/main/java/xdsopl/robot36/RGBDecoder.java b/app/src/main/java/xdsopl/robot36/RGBDecoder.java index de434f5..aeec2a2 100644 --- a/app/src/main/java/xdsopl/robot36/RGBDecoder.java +++ b/app/src/main/java/xdsopl/robot36/RGBDecoder.java @@ -8,6 +8,7 @@ package xdsopl.robot36; public class RGBDecoder implements Mode { private final ExponentialMovingAverage lowPassFilter; + private final int horizontalPixels; private final int scanLineSamples; private final int beginSamples; private final int redBeginSamples; @@ -19,8 +20,9 @@ public class RGBDecoder implements Mode { private final int endSamples; private final String name; - RGBDecoder(String name, double scanLineSeconds, double beginSeconds, double redBeginSeconds, double redEndSeconds, double greenBeginSeconds, double greenEndSeconds, double blueBeginSeconds, double blueEndSeconds, double endSeconds, int sampleRate) { + RGBDecoder(String name, int horizontalPixels, double scanLineSeconds, double beginSeconds, double redBeginSeconds, double redEndSeconds, double greenBeginSeconds, double greenEndSeconds, double blueBeginSeconds, double blueEndSeconds, double endSeconds, int sampleRate) { this.name = name; + this.horizontalPixels = horizontalPixels; scanLineSamples = (int) Math.round(scanLineSeconds * sampleRate); beginSamples = (int) Math.round(beginSeconds * sampleRate); redBeginSamples = (int) Math.round(redBeginSeconds * sampleRate) - beginSamples; @@ -51,17 +53,17 @@ public class RGBDecoder implements Mode { public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scratchBuffer, float[] scanLineBuffer, int syncPulseIndex, int scanLineSamples, float frequencyOffset) { if (syncPulseIndex + beginSamples < 0 || syncPulseIndex + endSamples > scanLineBuffer.length) return 0; - lowPassFilter.cutoff(evenBuffer.length, 2 * greenSamples, 2); + lowPassFilter.cutoff(horizontalPixels, 2 * greenSamples, 2); lowPassFilter.reset(); for (int i = 0; i < endSamples - beginSamples; ++i) scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + beginSamples + i]); lowPassFilter.reset(); for (int i = endSamples - beginSamples - 1; i >= 0; --i) scratchBuffer[i] = freqToLevel(lowPassFilter.avg(scratchBuffer[i]), frequencyOffset); - for (int i = 0; i < evenBuffer.length; ++i) { - int redPos = redBeginSamples + (i * redSamples) / evenBuffer.length; - int greenPos = greenBeginSamples + (i * greenSamples) / evenBuffer.length; - int bluePos = blueBeginSamples + (i * blueSamples) / evenBuffer.length; + for (int i = 0; i < horizontalPixels; ++i) { + int redPos = redBeginSamples + (i * redSamples) / horizontalPixels; + int greenPos = greenBeginSamples + (i * greenSamples) / horizontalPixels; + int bluePos = blueBeginSamples + (i * blueSamples) / horizontalPixels; evenBuffer[i] = ColorConverter.RGB(scratchBuffer[redPos], scratchBuffer[greenPos], scratchBuffer[bluePos]); } return 1; diff --git a/app/src/main/java/xdsopl/robot36/RGBModes.java b/app/src/main/java/xdsopl/robot36/RGBModes.java index 6a9069c..5a16881 100644 --- a/app/src/main/java/xdsopl/robot36/RGBModes.java +++ b/app/src/main/java/xdsopl/robot36/RGBModes.java @@ -19,7 +19,7 @@ public final class RGBModes { double blueEndSeconds = blueBeginSeconds + channelSeconds; double redBeginSeconds = blueEndSeconds + separatorSeconds; double redEndSeconds = redBeginSeconds + channelSeconds; - return new RGBDecoder("Martin " + name, scanLineSeconds, greenBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, redEndSeconds, sampleRate); + return new RGBDecoder("Martin " + name, 320, scanLineSeconds, greenBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, redEndSeconds, sampleRate); } public static RGBDecoder Scottie(String name, double channelSeconds, int sampleRate) { @@ -32,7 +32,7 @@ public final class RGBModes { double greenBeginSeconds = greenEndSeconds - channelSeconds; double redBeginSeconds = separatorSeconds; double redEndSeconds = redBeginSeconds + channelSeconds; - return new RGBDecoder("Scottie " + name, scanLineSeconds, greenBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, redEndSeconds, sampleRate); + return new RGBDecoder("Scottie " + name, 320, scanLineSeconds, greenBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, redEndSeconds, sampleRate); } public static RGBDecoder Wraase_SC2_180(int sampleRate) { @@ -46,6 +46,6 @@ public final class RGBModes { double greenEndSeconds = greenBeginSeconds + channelSeconds; double blueBeginSeconds = greenEndSeconds; double blueEndSeconds = blueBeginSeconds + channelSeconds; - return new RGBDecoder("Wraase SC2-180", scanLineSeconds, redBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, blueEndSeconds, sampleRate); + return new RGBDecoder("Wraase SC2-180", 320, 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 92840e3..a85c80c 100644 --- a/app/src/main/java/xdsopl/robot36/RawDecoder.java +++ b/app/src/main/java/xdsopl/robot36/RawDecoder.java @@ -31,15 +31,16 @@ public class RawDecoder implements Mode { public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scratchBuffer, float[] scanLineBuffer, int syncPulseIndex, int scanLineSamples, float frequencyOffset) { if (syncPulseIndex < 0 || syncPulseIndex + scanLineSamples > scanLineBuffer.length) return 0; - lowPassFilter.cutoff(evenBuffer.length, 2 * scanLineSamples, 2); + int horizontalPixels = evenBuffer.length; + lowPassFilter.cutoff(horizontalPixels, 2 * scanLineSamples, 2); lowPassFilter.reset(); for (int i = 0; i < scanLineSamples; ++i) scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + i]); lowPassFilter.reset(); for (int i = scanLineSamples - 1; i >= 0; --i) scratchBuffer[i] = freqToLevel(lowPassFilter.avg(scratchBuffer[i]), frequencyOffset); - for (int i = 0; i < evenBuffer.length; ++i) { - int position = (i * scanLineSamples) / evenBuffer.length; + for (int i = 0; i < horizontalPixels; ++i) { + int position = (i * scanLineSamples) / horizontalPixels; evenBuffer[i] = ColorConverter.GRAY(scratchBuffer[position]); } return 1; diff --git a/app/src/main/java/xdsopl/robot36/Robot_36_Color.java b/app/src/main/java/xdsopl/robot36/Robot_36_Color.java index 28b8f2d..510e657 100644 --- a/app/src/main/java/xdsopl/robot36/Robot_36_Color.java +++ b/app/src/main/java/xdsopl/robot36/Robot_36_Color.java @@ -8,6 +8,7 @@ package xdsopl.robot36; public class Robot_36_Color implements Mode { private final ExponentialMovingAverage lowPassFilter; + private final int horizontalPixels; private final int scanLineSamples; private final int luminanceSamples; private final int separatorSamples; @@ -21,6 +22,7 @@ public class Robot_36_Color implements Mode { @SuppressWarnings("UnnecessaryLocalVariable") Robot_36_Color(int sampleRate) { + horizontalPixels = 320; double syncPulseSeconds = 0.009; double syncPorchSeconds = 0.003; double luminanceSeconds = 0.088; @@ -72,16 +74,16 @@ public class Robot_36_Color implements Mode { if (separator < -1.1 || separator > -0.9 && separator < 0.9 || separator > 1.1) even = !lastEven; lastEven = even; - lowPassFilter.cutoff(evenBuffer.length, 2 * luminanceSamples, 2); + lowPassFilter.cutoff(horizontalPixels, 2 * luminanceSamples, 2); lowPassFilter.reset(); for (int i = beginSamples; i < endSamples; ++i) scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + i]); lowPassFilter.reset(); for (int i = endSamples - 1; i >= beginSamples; --i) scratchBuffer[i] = freqToLevel(lowPassFilter.avg(scratchBuffer[i]), frequencyOffset); - for (int i = 0; i < evenBuffer.length; ++i) { - int luminancePos = luminanceBeginSamples + (i * luminanceSamples) / evenBuffer.length; - int chrominancePos = chrominanceBeginSamples + (i * chrominanceSamples) / evenBuffer.length; + for (int i = 0; i < horizontalPixels; ++i) { + int luminancePos = luminanceBeginSamples + (i * luminanceSamples) / horizontalPixels; + int chrominancePos = chrominanceBeginSamples + (i * chrominanceSamples) / horizontalPixels; if (even) { evenBuffer[i] = ColorConverter.RGB(scratchBuffer[luminancePos], 0, scratchBuffer[chrominancePos]); } else { diff --git a/app/src/main/java/xdsopl/robot36/Robot_72_Color.java b/app/src/main/java/xdsopl/robot36/Robot_72_Color.java index 9074100..a059d17 100644 --- a/app/src/main/java/xdsopl/robot36/Robot_72_Color.java +++ b/app/src/main/java/xdsopl/robot36/Robot_72_Color.java @@ -8,6 +8,7 @@ package xdsopl.robot36; public class Robot_72_Color implements Mode { private final ExponentialMovingAverage lowPassFilter; + private final int horizontalPixels; private final int scanLineSamples; private final int luminanceSamples; private final int chrominanceSamples; @@ -19,6 +20,7 @@ public class Robot_72_Color implements Mode { @SuppressWarnings("UnnecessaryLocalVariable") Robot_72_Color(int sampleRate) { + horizontalPixels = 320; double syncPulseSeconds = 0.009; double syncPorchSeconds = 0.003; double luminanceSeconds = 0.138; @@ -61,17 +63,17 @@ public class Robot_72_Color implements Mode { public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scratchBuffer, float[] scanLineBuffer, int syncPulseIndex, int scanLineSamples, float frequencyOffset) { if (syncPulseIndex + beginSamples < 0 || syncPulseIndex + endSamples > scanLineBuffer.length) return 0; - lowPassFilter.cutoff(evenBuffer.length, 2 * luminanceSamples, 2); + lowPassFilter.cutoff(horizontalPixels, 2 * luminanceSamples, 2); lowPassFilter.reset(); for (int i = beginSamples; i < endSamples; ++i) scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + i]); lowPassFilter.reset(); for (int i = endSamples - 1; i >= beginSamples; --i) scratchBuffer[i] = freqToLevel(lowPassFilter.avg(scratchBuffer[i]), frequencyOffset); - for (int i = 0; i < evenBuffer.length; ++i) { - int yPos = yBeginSamples + (i * luminanceSamples) / evenBuffer.length; - int uPos = uBeginSamples + (i * chrominanceSamples) / evenBuffer.length; - int vPos = vBeginSamples + (i * chrominanceSamples) / evenBuffer.length; + for (int i = 0; i < horizontalPixels; ++i) { + int yPos = yBeginSamples + (i * luminanceSamples) / horizontalPixels; + int uPos = uBeginSamples + (i * chrominanceSamples) / horizontalPixels; + int vPos = vBeginSamples + (i * chrominanceSamples) / horizontalPixels; evenBuffer[i] = ColorConverter.YUV2RGB(scratchBuffer[yPos], scratchBuffer[uPos], scratchBuffer[vPos]); } return 1;