added decoder for PD modes and did cleanup

This commit is contained in:
Ahmet Inan 2024-04-19 22:09:39 +02:00
parent 3eda3a44ef
commit 0649ac48d5
8 changed files with 62 additions and 20 deletions

View file

@ -0,0 +1,24 @@
/*
Color converter
Copyright 2024 Ahmet Inan <xdsopl@gmail.com>
*/
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;
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}