removed bufferWidth argument

This commit is contained in:
Ahmet Inan 2024-04-20 17:48:55 +02:00
parent 0556940817
commit 6584934516
7 changed files with 50 additions and 38 deletions

View file

@ -55,23 +55,23 @@ public class Decoder {
scanLineToleranceSamples = (int) Math.round(scanLineToleranceSeconds * sampleRate); scanLineToleranceSamples = (int) Math.round(scanLineToleranceSeconds * sampleRate);
rawMode = new RawDecoder(); rawMode = new RawDecoder();
syncPulse5msModes = new ArrayList<>(); syncPulse5msModes = new ArrayList<>();
syncPulse5msModes.add(RGBModes.Wraase_SC2_180(sampleRate, scopeWidth)); syncPulse5msModes.add(RGBModes.Wraase_SC2_180(sampleRate));
syncPulse5msModes.add(RGBModes.Martin("1", 0.146432, sampleRate, scopeWidth)); syncPulse5msModes.add(RGBModes.Martin("1", 0.146432, sampleRate));
syncPulse5msModes.add(RGBModes.Martin("2", 0.073216, sampleRate, scopeWidth)); syncPulse5msModes.add(RGBModes.Martin("2", 0.073216, sampleRate));
syncPulse9msModes = new ArrayList<>(); syncPulse9msModes = new ArrayList<>();
syncPulse9msModes.add(new Robot_36_Color(sampleRate, scopeWidth)); syncPulse9msModes.add(new Robot_36_Color(sampleRate));
syncPulse9msModes.add(new Robot_72_Color(sampleRate, scopeWidth)); syncPulse9msModes.add(new Robot_72_Color(sampleRate));
syncPulse9msModes.add(RGBModes.Scottie("1", 0.138240, sampleRate, scopeWidth)); syncPulse9msModes.add(RGBModes.Scottie("1", 0.138240, sampleRate));
syncPulse9msModes.add(RGBModes.Scottie("2", 0.088064, sampleRate, scopeWidth)); syncPulse9msModes.add(RGBModes.Scottie("2", 0.088064, sampleRate));
syncPulse9msModes.add(RGBModes.Scottie("DX", 0.3456, sampleRate, scopeWidth)); syncPulse9msModes.add(RGBModes.Scottie("DX", 0.3456, sampleRate));
syncPulse20msModes = new ArrayList<>(); syncPulse20msModes = new ArrayList<>();
syncPulse20msModes.add(new PaulDon("50", 0.09152, sampleRate, scopeWidth)); syncPulse20msModes.add(new PaulDon("50", 0.09152, sampleRate));
syncPulse20msModes.add(new PaulDon("90", 0.17024, sampleRate, scopeWidth)); syncPulse20msModes.add(new PaulDon("90", 0.17024, sampleRate));
syncPulse20msModes.add(new PaulDon("120", 0.1216, sampleRate, scopeWidth)); syncPulse20msModes.add(new PaulDon("120", 0.1216, sampleRate));
syncPulse20msModes.add(new PaulDon("160", 0.195584, sampleRate, scopeWidth)); syncPulse20msModes.add(new PaulDon("160", 0.195584, sampleRate));
syncPulse20msModes.add(new PaulDon("180", 0.18304, sampleRate, scopeWidth)); syncPulse20msModes.add(new PaulDon("180", 0.18304, sampleRate));
syncPulse20msModes.add(new PaulDon("240", 0.24448, sampleRate, scopeWidth)); syncPulse20msModes.add(new PaulDon("240", 0.24448, sampleRate));
syncPulse20msModes.add(new PaulDon("290", 0.2288, sampleRate, scopeWidth)); syncPulse20msModes.add(new PaulDon("290", 0.2288, sampleRate));
} }
private void adjustSyncPulses(int[] pulses, int shift) { private void adjustSyncPulses(int[] pulses, int shift) {

View file

@ -7,15 +7,27 @@ Copyright 2024 Ahmet Inan <xdsopl@gmail.com>
package xdsopl.robot36; package xdsopl.robot36;
public class ExponentialMovingAverage { public class ExponentialMovingAverage {
private final float alpha; private float alpha;
private float prev; private float prev;
ExponentialMovingAverage() {
this.alpha = 1;
}
ExponentialMovingAverage(float alpha) { ExponentialMovingAverage(float alpha) {
this.alpha = alpha; this.alpha = alpha;
} }
public float avg(float input) { public float avg(float input) {
return prev = prev * (1 - alpha) + alpha * input; return prev = prev * (1 - alpha) + alpha * input;
} }
public void reset() { public void reset() {
prev = 0; prev = 0;
} }
public void reset(float alpha) {
this.alpha = alpha;
prev = 0;
}
} }

View file

@ -18,7 +18,7 @@ public class PaulDon implements Mode {
private final int endSamples; private final int endSamples;
private final String name; private final String name;
PaulDon(String name, double channelSeconds, int sampleRate, int bufferWidth) { PaulDon(String name, double channelSeconds, int sampleRate) {
this.name = "PD " + name; this.name = "PD " + name;
double syncPulseSeconds = 0.02; double syncPulseSeconds = 0.02;
double syncPorchSeconds = 0.00208; double syncPorchSeconds = 0.00208;
@ -36,7 +36,7 @@ public class PaulDon implements Mode {
yOddBeginSamples = (int) Math.round(yOddBeginSeconds * sampleRate); yOddBeginSamples = (int) Math.round(yOddBeginSeconds * sampleRate);
double yOddEndSeconds = yOddBeginSeconds + channelSeconds; double yOddEndSeconds = yOddBeginSeconds + channelSeconds;
endSamples = (int) Math.round(yOddEndSeconds * sampleRate); endSamples = (int) Math.round(yOddEndSeconds * sampleRate);
lowPassFilter = new ExponentialMovingAverage((float) (bufferWidth / (sampleRate * channelSeconds))); lowPassFilter = new ExponentialMovingAverage();
} }
@Override @Override
@ -53,10 +53,10 @@ public class PaulDon implements Mode {
public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples) { public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples) {
if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length) if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length)
return 0; return 0;
lowPassFilter.reset(); lowPassFilter.reset(evenBuffer.length / (float) channelSamples);
for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i) for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i)
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]); scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
lowPassFilter.reset(); lowPassFilter.reset(evenBuffer.length / (float) channelSamples);
for (int i = prevPulseIndex + endSamples - 1; i >= scanLineSamples + beginSamples; --i) for (int i = prevPulseIndex + endSamples - 1; i >= scanLineSamples + beginSamples; --i)
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]); scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
for (int i = 0; i < evenBuffer.length; ++i) { for (int i = 0; i < evenBuffer.length; ++i) {

View file

@ -19,7 +19,7 @@ public class RGBDecoder implements Mode {
private final int endSamples; private final int endSamples;
private final String name; 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, int bufferWidth) { RGBDecoder(String name, double scanLineSeconds, double beginSeconds, double redBeginSeconds, double redEndSeconds, double greenBeginSeconds, double greenEndSeconds, double blueBeginSeconds, double blueEndSeconds, double endSeconds, int sampleRate) {
this.name = name; this.name = name;
scanLineSamples = (int) Math.round(scanLineSeconds * sampleRate); scanLineSamples = (int) Math.round(scanLineSeconds * sampleRate);
beginSamples = (int) Math.round(beginSeconds * sampleRate); beginSamples = (int) Math.round(beginSeconds * sampleRate);
@ -30,7 +30,7 @@ public class RGBDecoder implements Mode {
blueBeginSamples = (int) Math.round(blueBeginSeconds * sampleRate); blueBeginSamples = (int) Math.round(blueBeginSeconds * sampleRate);
blueSamples = (int) Math.round((blueEndSeconds - blueBeginSeconds) * sampleRate); blueSamples = (int) Math.round((blueEndSeconds - blueBeginSeconds) * sampleRate);
endSamples = (int) Math.round(endSeconds * sampleRate); endSamples = (int) Math.round(endSeconds * sampleRate);
lowPassFilter = new ExponentialMovingAverage((float) (bufferWidth / (sampleRate * (greenEndSeconds - greenBeginSeconds)))); lowPassFilter = new ExponentialMovingAverage();
} }
@Override @Override
@ -47,10 +47,10 @@ public class RGBDecoder implements Mode {
public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples) { public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples) {
if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length) if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length)
return 0; return 0;
lowPassFilter.reset(); lowPassFilter.reset(evenBuffer.length / (float) greenSamples);
for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i) for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i)
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]); scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
lowPassFilter.reset(); lowPassFilter.reset(evenBuffer.length / (float) greenSamples);
for (int i = prevPulseIndex + endSamples - 1; i >= scanLineSamples + beginSamples; --i) for (int i = prevPulseIndex + endSamples - 1; i >= scanLineSamples + beginSamples; --i)
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]); scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
for (int i = 0; i < evenBuffer.length; ++i) { for (int i = 0; i < evenBuffer.length; ++i) {

View file

@ -8,7 +8,7 @@ package xdsopl.robot36;
public final class RGBModes { public final class RGBModes {
public static RGBDecoder Martin(String name, double channelSeconds, int sampleRate, int bufferWidth) { public static RGBDecoder Martin(String name, double channelSeconds, int sampleRate) {
double syncPulseSeconds = 0.004862; double syncPulseSeconds = 0.004862;
double separatorSeconds = 0.000572; double separatorSeconds = 0.000572;
double scanLineSeconds = syncPulseSeconds + separatorSeconds + 3 * (channelSeconds + separatorSeconds); double scanLineSeconds = syncPulseSeconds + separatorSeconds + 3 * (channelSeconds + separatorSeconds);
@ -18,10 +18,10 @@ public final class RGBModes {
double blueEndSeconds = blueBeginSeconds + channelSeconds; double blueEndSeconds = blueBeginSeconds + channelSeconds;
double redBeginSeconds = blueEndSeconds + separatorSeconds; double redBeginSeconds = blueEndSeconds + separatorSeconds;
double redEndSeconds = redBeginSeconds + channelSeconds; double redEndSeconds = redBeginSeconds + channelSeconds;
return new RGBDecoder("Martin " + name, scanLineSeconds, greenBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, redEndSeconds, sampleRate, bufferWidth); return new RGBDecoder("Martin " + name, scanLineSeconds, greenBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, redEndSeconds, sampleRate);
} }
public static RGBDecoder Scottie(String name, double channelSeconds, int sampleRate, int bufferWidth) { public static RGBDecoder Scottie(String name, double channelSeconds, int sampleRate) {
double syncPulseSeconds = 0.009; double syncPulseSeconds = 0.009;
double separatorSeconds = 0.0015; double separatorSeconds = 0.0015;
double scanLineSeconds = syncPulseSeconds + 3 * (channelSeconds + separatorSeconds); double scanLineSeconds = syncPulseSeconds + 3 * (channelSeconds + separatorSeconds);
@ -31,10 +31,10 @@ public final class RGBModes {
double greenBeginSeconds = greenEndSeconds - channelSeconds; double greenBeginSeconds = greenEndSeconds - channelSeconds;
double redBeginSeconds = syncPulseSeconds / 2 + separatorSeconds; double redBeginSeconds = syncPulseSeconds / 2 + separatorSeconds;
double redEndSeconds = redBeginSeconds + channelSeconds; double redEndSeconds = redBeginSeconds + channelSeconds;
return new RGBDecoder("Scottie " + name, scanLineSeconds, greenBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, redEndSeconds, sampleRate, bufferWidth); return new RGBDecoder("Scottie " + name, scanLineSeconds, greenBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, redEndSeconds, sampleRate);
} }
public static RGBDecoder Wraase_SC2_180(int sampleRate, int bufferWidth) { public static RGBDecoder Wraase_SC2_180(int sampleRate) {
double syncPulseSeconds = 0.0055225; double syncPulseSeconds = 0.0055225;
double syncPorchSeconds = 0.0005; double syncPorchSeconds = 0.0005;
double channelSeconds = 0.235; double channelSeconds = 0.235;
@ -45,6 +45,6 @@ public final class RGBModes {
double greenEndSeconds = greenBeginSeconds + channelSeconds; double greenEndSeconds = greenBeginSeconds + channelSeconds;
double blueBeginSeconds = greenEndSeconds; double blueBeginSeconds = greenEndSeconds;
double blueEndSeconds = blueBeginSeconds + channelSeconds; double blueEndSeconds = blueBeginSeconds + channelSeconds;
return new RGBDecoder("Wraase SC2-180", scanLineSeconds, redBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, blueEndSeconds, sampleRate, bufferWidth); return new RGBDecoder("Wraase SC2-180", scanLineSeconds, redBeginSeconds, redBeginSeconds, redEndSeconds, greenBeginSeconds, greenEndSeconds, blueBeginSeconds, blueEndSeconds, blueEndSeconds, sampleRate);
} }
} }

View file

@ -18,7 +18,7 @@ public class Robot_36_Color implements Mode {
private final int chrominanceBeginSamples; private final int chrominanceBeginSamples;
private final int endSamples; private final int endSamples;
Robot_36_Color(int sampleRate, int bufferWidth) { Robot_36_Color(int sampleRate) {
double syncPulseSeconds = 0.009; double syncPulseSeconds = 0.009;
double syncPorchSeconds = 0.003; double syncPorchSeconds = 0.003;
double luminanceSeconds = 0.088; double luminanceSeconds = 0.088;
@ -40,7 +40,7 @@ public class Robot_36_Color implements Mode {
chrominanceBeginSamples = (int) Math.round(chrominanceBeginSeconds * sampleRate); chrominanceBeginSamples = (int) Math.round(chrominanceBeginSeconds * sampleRate);
double chrominanceEndSeconds = chrominanceBeginSeconds + chrominanceSeconds; double chrominanceEndSeconds = chrominanceBeginSeconds + chrominanceSeconds;
endSamples = (int) Math.round(chrominanceEndSeconds * sampleRate); endSamples = (int) Math.round(chrominanceEndSeconds * sampleRate);
lowPassFilter = new ExponentialMovingAverage((float) (bufferWidth / (sampleRate * luminanceSeconds))); lowPassFilter = new ExponentialMovingAverage();
} }
@Override @Override
@ -62,10 +62,10 @@ public class Robot_36_Color implements Mode {
separator += scanLineBuffer[prevPulseIndex + separatorBeginSamples + i]; separator += scanLineBuffer[prevPulseIndex + separatorBeginSamples + i];
separator /= separatorSamples; separator /= separatorSamples;
boolean even = separator < 0.5f; boolean even = separator < 0.5f;
lowPassFilter.reset(); lowPassFilter.reset(evenBuffer.length / (float) luminanceSamples);
for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i) for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i)
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]); scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
lowPassFilter.reset(); lowPassFilter.reset(evenBuffer.length / (float) luminanceSamples);
for (int i = prevPulseIndex + endSamples - 1; i >= scanLineSamples + beginSamples; --i) for (int i = prevPulseIndex + endSamples - 1; i >= scanLineSamples + beginSamples; --i)
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]); scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
for (int i = 0; i < evenBuffer.length; ++i) { for (int i = 0; i < evenBuffer.length; ++i) {

View file

@ -17,7 +17,7 @@ public class Robot_72_Color implements Mode {
private final int uBeginSamples; private final int uBeginSamples;
private final int endSamples; private final int endSamples;
Robot_72_Color(int sampleRate, int bufferWidth) { Robot_72_Color(int sampleRate) {
double syncPulseSeconds = 0.009; double syncPulseSeconds = 0.009;
double syncPorchSeconds = 0.003; double syncPorchSeconds = 0.003;
double luminanceSeconds = 0.138; double luminanceSeconds = 0.138;
@ -39,7 +39,7 @@ public class Robot_72_Color implements Mode {
uBeginSamples = (int) Math.round(uBeginSeconds * sampleRate); uBeginSamples = (int) Math.round(uBeginSeconds * sampleRate);
double uEndSeconds = uBeginSeconds + chrominanceSeconds; double uEndSeconds = uBeginSeconds + chrominanceSeconds;
endSamples = (int) Math.round(uEndSeconds * sampleRate); endSamples = (int) Math.round(uEndSeconds * sampleRate);
lowPassFilter = new ExponentialMovingAverage((float) (bufferWidth / (sampleRate * luminanceSeconds))); lowPassFilter = new ExponentialMovingAverage();
} }
@Override @Override
@ -56,10 +56,10 @@ public class Robot_72_Color implements Mode {
public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples) { public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples) {
if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length) if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length)
return 0; return 0;
lowPassFilter.reset(); lowPassFilter.reset(evenBuffer.length / (float) luminanceSamples);
for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i) for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i)
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]); scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
lowPassFilter.reset(); lowPassFilter.reset(evenBuffer.length / (float) luminanceSamples);
for (int i = prevPulseIndex + endSamples - 1; i >= scanLineSamples + beginSamples; --i) for (int i = prevPulseIndex + endSamples - 1; i >= scanLineSamples + beginSamples; --i)
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]); scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
for (int i = 0; i < evenBuffer.length; ++i) { for (int i = 0; i < evenBuffer.length; ++i) {