mirror of
https://github.com/xdsopl/robot36.git
synced 2026-01-04 23:39:59 +01:00
keep aspect-ratio for each mode but PD290
This commit is contained in:
parent
527a4e3818
commit
97bdad4b8c
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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<String> permissions = new ArrayList<>();
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue