mirror of
https://github.com/xdsopl/robot36.git
synced 2026-01-20 15:00:16 +01:00
provide a scratch buffer
This commit is contained in:
parent
b24e7d0730
commit
558120116d
|
|
@ -12,6 +12,7 @@ public class Decoder {
|
|||
|
||||
private final Demodulator demodulator;
|
||||
private final float[] scanLineBuffer;
|
||||
private final float[] scratchBuffer;
|
||||
private final int[] evenBuffer;
|
||||
private final int[] oddBuffer;
|
||||
private final int[] scopePixels;
|
||||
|
|
@ -51,6 +52,7 @@ public class Decoder {
|
|||
double scanLineMaxSeconds = 7;
|
||||
int scanLineMaxSamples = (int) Math.round(scanLineMaxSeconds * sampleRate);
|
||||
scanLineBuffer = new float[scanLineMaxSamples];
|
||||
scratchBuffer = new float[sampleRate];
|
||||
int scanLineCount = 4;
|
||||
last5msScanLines = new int[scanLineCount];
|
||||
last9msScanLines = new int[scanLineCount];
|
||||
|
|
@ -171,10 +173,10 @@ public class Decoder {
|
|||
int extrapolate = endPulse / scanLineSamples;
|
||||
int firstPulse = endPulse - extrapolate * scanLineSamples;
|
||||
for (int pulseIndex = firstPulse; pulseIndex < endPulse; pulseIndex += scanLineSamples)
|
||||
copyLines(mode.decodeScanLine(evenBuffer, oddBuffer, scanLineBuffer, pulseIndex, scanLineSamples, frequencyOffset));
|
||||
copyLines(mode.decodeScanLine(evenBuffer, oddBuffer, scratchBuffer, scanLineBuffer, pulseIndex, scanLineSamples, frequencyOffset));
|
||||
}
|
||||
for (int i = pictureChanged ? 0 : lines.length - 1; i < lines.length; ++i)
|
||||
copyLines(mode.decodeScanLine(evenBuffer, oddBuffer, scanLineBuffer, pulses[i], lines[i], frequencyOffset));
|
||||
copyLines(mode.decodeScanLine(evenBuffer, oddBuffer, scratchBuffer, scanLineBuffer, pulses[i], lines[i], frequencyOffset));
|
||||
int shift = pulses[pulses.length - 1] - scanLineReserveSamples;
|
||||
if (shift > scanLineReserveSamples) {
|
||||
adjustSyncPulses(last5msSyncPulses, shift);
|
||||
|
|
@ -219,7 +221,7 @@ public class Decoder {
|
|||
return processSyncPulse(syncPulse20msModes, last20msFrequencyOffsets, last20msSyncPulses, last20msScanLines, syncPulseIndex);
|
||||
}
|
||||
} else if (lastSyncPulseIndex >= scanLineReserveSamples && curSample > lastSyncPulseIndex + (lastScanLineSamples * 5) / 4) {
|
||||
copyLines(lastMode.decodeScanLine(evenBuffer, oddBuffer, scanLineBuffer, lastSyncPulseIndex, lastScanLineSamples, lastFrequencyOffset));
|
||||
copyLines(lastMode.decodeScanLine(evenBuffer, oddBuffer, scratchBuffer, scanLineBuffer, lastSyncPulseIndex, lastScanLineSamples, lastFrequencyOffset));
|
||||
lastSyncPulseIndex += lastScanLineSamples;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ public interface Mode {
|
|||
|
||||
int getScanLineSamples();
|
||||
|
||||
int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples, float frequencyOffset);
|
||||
int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scratchBuffer, float[] scanLineBuffer, int syncPulseIndex, int scanLineSamples, float frequencyOffset);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,24 +55,24 @@ public class PaulDon implements Mode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples, float frequencyOffset) {
|
||||
if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length)
|
||||
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.reset();
|
||||
for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i)
|
||||
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
|
||||
for (int i = beginSamples; i < endSamples; ++i)
|
||||
scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + i]);
|
||||
lowPassFilter.reset();
|
||||
for (int i = prevPulseIndex + endSamples - 1; i >= prevPulseIndex + beginSamples; --i)
|
||||
scanLineBuffer[i] = freqToLevel(lowPassFilter.avg(scanLineBuffer[i]), frequencyOffset);
|
||||
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 + prevPulseIndex;
|
||||
int position = (i * channelSamples) / evenBuffer.length;
|
||||
int yEvenPos = position + yEvenBeginSamples;
|
||||
int vAvgPos = position + vAvgBeginSamples;
|
||||
int uAvgPos = position + uAvgBeginSamples;
|
||||
int yOddPos = position + yOddBeginSamples;
|
||||
evenBuffer[i] = ColorConverter.YUV2RGB(scanLineBuffer[yEvenPos], scanLineBuffer[uAvgPos], scanLineBuffer[vAvgPos]);
|
||||
oddBuffer[i] = ColorConverter.YUV2RGB(scanLineBuffer[yOddPos], scanLineBuffer[uAvgPos], scanLineBuffer[vAvgPos]);
|
||||
evenBuffer[i] = ColorConverter.YUV2RGB(scratchBuffer[yEvenPos], scratchBuffer[uAvgPos], scratchBuffer[vAvgPos]);
|
||||
oddBuffer[i] = ColorConverter.YUV2RGB(scratchBuffer[yOddPos], scratchBuffer[uAvgPos], scratchBuffer[vAvgPos]);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,21 +48,21 @@ public class RGBDecoder implements Mode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples, float frequencyOffset) {
|
||||
if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length)
|
||||
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.reset();
|
||||
for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i)
|
||||
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
|
||||
for (int i = beginSamples; i < endSamples; ++i)
|
||||
scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + i]);
|
||||
lowPassFilter.reset();
|
||||
for (int i = prevPulseIndex + endSamples - 1; i >= prevPulseIndex + beginSamples; --i)
|
||||
scanLineBuffer[i] = freqToLevel(lowPassFilter.avg(scanLineBuffer[i]), frequencyOffset);
|
||||
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 redPos = redBeginSamples + (i * redSamples) / evenBuffer.length + prevPulseIndex;
|
||||
int greenPos = greenBeginSamples + (i * greenSamples) / evenBuffer.length + prevPulseIndex;
|
||||
int bluePos = blueBeginSamples + (i * blueSamples) / evenBuffer.length + prevPulseIndex;
|
||||
evenBuffer[i] = ColorConverter.RGB(scanLineBuffer[redPos], scanLineBuffer[greenPos], scanLineBuffer[bluePos]);
|
||||
int redPos = redBeginSamples + (i * redSamples) / evenBuffer.length;
|
||||
int greenPos = greenBeginSamples + (i * greenSamples) / evenBuffer.length;
|
||||
int bluePos = blueBeginSamples + (i * blueSamples) / evenBuffer.length;
|
||||
evenBuffer[i] = ColorConverter.RGB(scratchBuffer[redPos], scratchBuffer[greenPos], scratchBuffer[bluePos]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,19 +28,19 @@ public class RawDecoder implements Mode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples, float frequencyOffset) {
|
||||
if (prevPulseIndex < 0 || prevPulseIndex + scanLineSamples > scanLineBuffer.length)
|
||||
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);
|
||||
lowPassFilter.reset();
|
||||
for (int i = prevPulseIndex; i < prevPulseIndex + scanLineSamples; ++i)
|
||||
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
|
||||
for (int i = 0; i < scanLineSamples; ++i)
|
||||
scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + i]);
|
||||
lowPassFilter.reset();
|
||||
for (int i = prevPulseIndex + scanLineSamples - 1; i >= prevPulseIndex; --i)
|
||||
scanLineBuffer[i] = freqToLevel(lowPassFilter.avg(scanLineBuffer[i]), frequencyOffset);
|
||||
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 + prevPulseIndex;
|
||||
evenBuffer[i] = ColorConverter.GRAY(scanLineBuffer[position]);
|
||||
int position = (i * scanLineSamples) / evenBuffer.length;
|
||||
evenBuffer[i] = ColorConverter.GRAY(scratchBuffer[position]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,12 +60,12 @@ public class Robot_36_Color implements Mode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples, float frequencyOffset) {
|
||||
if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length)
|
||||
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;
|
||||
float separator = 0;
|
||||
for (int i = 0; i < separatorSamples; ++i)
|
||||
separator += scanLineBuffer[prevPulseIndex + separatorBeginSamples + i];
|
||||
separator += scanLineBuffer[syncPulseIndex + separatorBeginSamples + i];
|
||||
separator /= separatorSamples;
|
||||
separator -= frequencyOffset;
|
||||
boolean even = separator < 0;
|
||||
|
|
@ -74,19 +74,19 @@ public class Robot_36_Color implements Mode {
|
|||
lastEven = even;
|
||||
lowPassFilter.cutoff(evenBuffer.length, 2 * luminanceSamples, 2);
|
||||
lowPassFilter.reset();
|
||||
for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i)
|
||||
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
|
||||
for (int i = beginSamples; i < endSamples; ++i)
|
||||
scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + i]);
|
||||
lowPassFilter.reset();
|
||||
for (int i = prevPulseIndex + endSamples - 1; i >= prevPulseIndex + beginSamples; --i)
|
||||
scanLineBuffer[i] = freqToLevel(lowPassFilter.avg(scanLineBuffer[i]), frequencyOffset);
|
||||
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 + prevPulseIndex;
|
||||
int chrominancePos = chrominanceBeginSamples + (i * chrominanceSamples) / evenBuffer.length + prevPulseIndex;
|
||||
int luminancePos = luminanceBeginSamples + (i * luminanceSamples) / evenBuffer.length;
|
||||
int chrominancePos = chrominanceBeginSamples + (i * chrominanceSamples) / evenBuffer.length;
|
||||
if (even) {
|
||||
evenBuffer[i] = ColorConverter.RGB(scanLineBuffer[luminancePos], 0, scanLineBuffer[chrominancePos]);
|
||||
evenBuffer[i] = ColorConverter.RGB(scratchBuffer[luminancePos], 0, scratchBuffer[chrominancePos]);
|
||||
} else {
|
||||
int evenYUV = evenBuffer[i];
|
||||
int oddYUV = ColorConverter.RGB(scanLineBuffer[luminancePos], scanLineBuffer[chrominancePos], 0);
|
||||
int oddYUV = ColorConverter.RGB(scratchBuffer[luminancePos], scratchBuffer[chrominancePos], 0);
|
||||
evenBuffer[i] = ColorConverter.YUV2RGB((evenYUV & 0x00ff00ff) | (oddYUV & 0x0000ff00));
|
||||
oddBuffer[i] = ColorConverter.YUV2RGB((oddYUV & 0x00ffff00) | (evenYUV & 0x000000ff));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,21 +58,21 @@ public class Robot_72_Color implements Mode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int decodeScanLine(int[] evenBuffer, int[] oddBuffer, float[] scanLineBuffer, int prevPulseIndex, int scanLineSamples, float frequencyOffset) {
|
||||
if (prevPulseIndex + beginSamples < 0 || prevPulseIndex + endSamples > scanLineBuffer.length)
|
||||
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.reset();
|
||||
for (int i = prevPulseIndex + beginSamples; i < prevPulseIndex + endSamples; ++i)
|
||||
scanLineBuffer[i] = lowPassFilter.avg(scanLineBuffer[i]);
|
||||
for (int i = beginSamples; i < endSamples; ++i)
|
||||
scratchBuffer[i] = lowPassFilter.avg(scanLineBuffer[syncPulseIndex + i]);
|
||||
lowPassFilter.reset();
|
||||
for (int i = prevPulseIndex + endSamples - 1; i >= prevPulseIndex + beginSamples; --i)
|
||||
scanLineBuffer[i] = freqToLevel(lowPassFilter.avg(scanLineBuffer[i]), frequencyOffset);
|
||||
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 + prevPulseIndex;
|
||||
int uPos = uBeginSamples + (i * chrominanceSamples) / evenBuffer.length + prevPulseIndex;
|
||||
int vPos = vBeginSamples + (i * chrominanceSamples) / evenBuffer.length + prevPulseIndex;
|
||||
evenBuffer[i] = ColorConverter.YUV2RGB(scanLineBuffer[yPos], scanLineBuffer[uPos], scanLineBuffer[vPos]);
|
||||
int yPos = yBeginSamples + (i * luminanceSamples) / evenBuffer.length;
|
||||
int uPos = uBeginSamples + (i * chrominanceSamples) / evenBuffer.length;
|
||||
int vPos = vBeginSamples + (i * chrominanceSamples) / evenBuffer.length;
|
||||
evenBuffer[i] = ColorConverter.YUV2RGB(scratchBuffer[yPos], scratchBuffer[uPos], scratchBuffer[vPos]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue