From 0649ac48d5952ae2f17b37eb92b756784111e427 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Fri, 19 Apr 2024 22:09:39 +0200 Subject: [PATCH] added decoder for PD modes and did cleanup --- .../java/xdsopl/robot36/ColorConverter.java | 24 +++++++++++++ app/src/main/java/xdsopl/robot36/Martin.java | 5 ++- app/src/main/java/xdsopl/robot36/PaulDon.java | 36 +++++++++++++++---- app/src/main/java/xdsopl/robot36/Raw.java | 3 +- .../java/xdsopl/robot36/Robot_36_Color.java | 3 +- .../java/xdsopl/robot36/Robot_72_Color.java | 3 +- app/src/main/java/xdsopl/robot36/Scottie.java | 3 +- .../java/xdsopl/robot36/Wraase_SC2_180.java | 5 ++- 8 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 app/src/main/java/xdsopl/robot36/ColorConverter.java diff --git a/app/src/main/java/xdsopl/robot36/ColorConverter.java b/app/src/main/java/xdsopl/robot36/ColorConverter.java new file mode 100644 index 0000000..cf04624 --- /dev/null +++ b/app/src/main/java/xdsopl/robot36/ColorConverter.java @@ -0,0 +1,24 @@ +/* +Color converter + +Copyright 2024 Ahmet Inan +*/ + +package xdsopl.robot36; + +public final class ColorConverter { + + private static int clamp(int value) { + return Math.min(Math.max(value, 0), 255); + } + + public static int YUV2RGB(int Y, int U, int V) { + Y -= 16; + U -= 128; + V -= 128; + int R = clamp((298 * Y + 409 * V + 128) >> 8); + int G = clamp((298 * Y - 100 * U - 208 * V + 128) >> 8); + int B = clamp((298 * Y + 516 * U + 128) >> 8); + return 0xff000000 | (R << 16) | (G << 8) | B; + } +} diff --git a/app/src/main/java/xdsopl/robot36/Martin.java b/app/src/main/java/xdsopl/robot36/Martin.java index 13eecd0..13df6dc 100644 --- a/app/src/main/java/xdsopl/robot36/Martin.java +++ b/app/src/main/java/xdsopl/robot36/Martin.java @@ -45,7 +45,7 @@ public class Martin implements Mode { } @Override - public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int ignore) { + public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples) { if (prevPulseIndex + greenBeginSamples < 0 || prevPulseIndex + redEndSamples > scanLineBuffer.length) return 0; for (int i = 0; i < evenBuffer.length; ++i) { @@ -56,8 +56,7 @@ public class Martin implements Mode { int green = Math.round(255 * scanLineBuffer[greenPos]); int blue = Math.round(255 * scanLineBuffer[bluePos]); int red = Math.round(255 * scanLineBuffer[redPos]); - int pixelColor = 0xff000000 | (red << 16) | (green << 8) | blue; - evenBuffer[i] = pixelColor; + evenBuffer[i] = 0xff000000 | (red << 16) | (green << 8) | blue; } return 1; } diff --git a/app/src/main/java/xdsopl/robot36/PaulDon.java b/app/src/main/java/xdsopl/robot36/PaulDon.java index 3863e05..f35cb7d 100644 --- a/app/src/main/java/xdsopl/robot36/PaulDon.java +++ b/app/src/main/java/xdsopl/robot36/PaulDon.java @@ -8,6 +8,12 @@ package xdsopl.robot36; public class PaulDon implements Mode { private final int scanLineSamples; + private final int channelSamples; + private final int yEvenBeginSamples; + private final int vAvgBeginSamples; + private final int uAvgBeginSamples; + private final int yOddBeginSamples; + private final int yOddEndSamples; private final String name; PaulDon(String name, double channelSeconds, int sampleRate) { @@ -16,6 +22,17 @@ public class PaulDon implements Mode { double syncPorchSeconds = 0.00208; double scanLineSeconds = syncPulseSeconds + syncPorchSeconds + 4 * (channelSeconds); scanLineSamples = (int) Math.round(scanLineSeconds * sampleRate); + channelSamples = (int) Math.round(channelSeconds * sampleRate); + double yEvenBeginSeconds = syncPulseSeconds / 2 + syncPorchSeconds; + yEvenBeginSamples = (int) Math.round(yEvenBeginSeconds * sampleRate); + double vAvgBeginSeconds = yEvenBeginSeconds + channelSeconds; + vAvgBeginSamples = (int) Math.round(vAvgBeginSeconds * sampleRate); + double uAvgBeginSeconds = vAvgBeginSeconds + channelSeconds; + uAvgBeginSamples = (int) Math.round(uAvgBeginSeconds * sampleRate); + double yOddBeginSeconds = uAvgBeginSeconds + channelSeconds; + yOddBeginSamples = (int) Math.round(yOddBeginSeconds * sampleRate); + double yOddEndSeconds = yOddBeginSeconds + channelSeconds; + yOddEndSamples = (int) Math.round(yOddEndSeconds * sampleRate); } @Override @@ -30,14 +47,21 @@ public class PaulDon implements Mode { @Override public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples) { - if (prevPulseIndex < 0 || prevPulseIndex + scanLineSamples >= scanLineBuffer.length) + if (prevPulseIndex + yEvenBeginSamples < 0 || prevPulseIndex + yOddEndSamples > scanLineBuffer.length) return 0; for (int i = 0; i < evenBuffer.length; ++i) { - int position = (i * scanLineSamples) / evenBuffer.length + prevPulseIndex; - int intensity = (int) Math.round(255 * Math.sqrt(scanLineBuffer[position])); - int pixelColor = 0xff000000 | 0x00010101 * intensity; - evenBuffer[i] = pixelColor; + int position = (i * channelSamples) / evenBuffer.length + prevPulseIndex; + int yEvenPos = position + yEvenBeginSamples; + int vAvgPos = position + vAvgBeginSamples; + int uAvgPos = position + uAvgBeginSamples; + int yOddPos = position + yOddBeginSamples; + int yEven = Math.round(255 * scanLineBuffer[yEvenPos]); + int vAvg = Math.round(255 * scanLineBuffer[vAvgPos]); + int uAvg = Math.round(255 * scanLineBuffer[uAvgPos]); + int yOdd = Math.round(255 * scanLineBuffer[yOddPos]); + evenBuffer[i] = ColorConverter.YUV2RGB(yEven, uAvg, vAvg); + oddBuffer[i] = ColorConverter.YUV2RGB(yOdd, uAvg, vAvg); } - return 1; + return 2; } } diff --git a/app/src/main/java/xdsopl/robot36/Raw.java b/app/src/main/java/xdsopl/robot36/Raw.java index fa3c6a6..b112fc3 100644 --- a/app/src/main/java/xdsopl/robot36/Raw.java +++ b/app/src/main/java/xdsopl/robot36/Raw.java @@ -28,8 +28,7 @@ public class Raw implements Mode { for (int i = 0; i < evenBuffer.length; ++i) { int position = (i * scanLineSamples) / evenBuffer.length + prevPulseIndex; int intensity = (int) Math.round(255 * Math.sqrt(scanLineBuffer[position])); - int pixelColor = 0xff000000 | 0x00010101 * intensity; - evenBuffer[i] = pixelColor; + evenBuffer[i] = 0xff000000 | 0x00010101 * intensity; } 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 3ea3437..b789daf 100644 --- a/app/src/main/java/xdsopl/robot36/Robot_36_Color.java +++ b/app/src/main/java/xdsopl/robot36/Robot_36_Color.java @@ -37,8 +37,7 @@ public class Robot_36_Color implements Mode { for (int i = 0; i < evenBuffer.length; ++i) { int position = (i * scanLineSamples) / evenBuffer.length + prevPulseIndex; int intensity = (int) Math.round(255 * Math.sqrt(scanLineBuffer[position])); - int pixelColor = 0xff000000 | 0x00010101 * intensity; - evenBuffer[i] = pixelColor; + evenBuffer[i] = 0xff000000 | 0x00010101 * intensity; } return 1; } 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 14d9049..8d6c4d9 100644 --- a/app/src/main/java/xdsopl/robot36/Robot_72_Color.java +++ b/app/src/main/java/xdsopl/robot36/Robot_72_Color.java @@ -37,8 +37,7 @@ public class Robot_72_Color implements Mode { for (int i = 0; i < evenBuffer.length; ++i) { int position = (i * scanLineSamples) / evenBuffer.length + prevPulseIndex; int intensity = (int) Math.round(255 * Math.sqrt(scanLineBuffer[position])); - int pixelColor = 0xff000000 | 0x00010101 * intensity; - evenBuffer[i] = pixelColor; + evenBuffer[i] = 0xff000000 | 0x00010101 * intensity; } return 1; } diff --git a/app/src/main/java/xdsopl/robot36/Scottie.java b/app/src/main/java/xdsopl/robot36/Scottie.java index 839d162..2b445aa 100644 --- a/app/src/main/java/xdsopl/robot36/Scottie.java +++ b/app/src/main/java/xdsopl/robot36/Scottie.java @@ -35,8 +35,7 @@ public class Scottie implements Mode { for (int i = 0; i < evenBuffer.length; ++i) { int position = (i * scanLineSamples) / evenBuffer.length + prevPulseIndex; int intensity = (int) Math.round(255 * Math.sqrt(scanLineBuffer[position])); - int pixelColor = 0xff000000 | 0x00010101 * intensity; - evenBuffer[i] = pixelColor; + evenBuffer[i] = 0xff000000 | 0x00010101 * intensity; } return 1; } diff --git a/app/src/main/java/xdsopl/robot36/Wraase_SC2_180.java b/app/src/main/java/xdsopl/robot36/Wraase_SC2_180.java index ff5556b..81f0bac 100644 --- a/app/src/main/java/xdsopl/robot36/Wraase_SC2_180.java +++ b/app/src/main/java/xdsopl/robot36/Wraase_SC2_180.java @@ -42,7 +42,7 @@ public class Wraase_SC2_180 implements Mode { } @Override - public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int ignore) { + public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples) { if (prevPulseIndex + redBeginSamples < 0 || prevPulseIndex + blueEndSamples > scanLineBuffer.length) return 0; for (int i = 0; i < evenBuffer.length; ++i) { @@ -53,8 +53,7 @@ public class Wraase_SC2_180 implements Mode { int red = Math.round(255 * scanLineBuffer[redPos]); int green = Math.round(255 * scanLineBuffer[greenPos]); int blue = Math.round(255 * scanLineBuffer[bluePos]); - int pixelColor = 0xff000000 | (red << 16) | (green << 8) | blue; - evenBuffer[i] = pixelColor; + evenBuffer[i] = 0xff000000 | (red << 16) | (green << 8) | blue; } return 1; }