diff --git a/common.h b/common.h index 471c170..c7af27f 100644 --- a/common.h +++ b/common.h @@ -15,6 +15,8 @@ extern guchar *StoredLum; extern pthread_t thread1; extern guchar VISmap[]; +#define VIS_PARITY_ODD (1 << 7) + typedef struct _FFTStuff FFTStuff; struct _FFTStuff { double *in; @@ -93,12 +95,12 @@ extern PicMeta CurrentPic; // SSTV modes enum { UNKNOWN=0, - M1, M2, M3, M4, - S1, S2, SDX, - R72, R36, R24, R24BW, R12BW, R8BW, - PD50, PD90, PD120, PD160, PD180, PD240, PD290, - P3, P5, P7, - W2120, W2180 + M1, M2, M3, M4, + S1, S2, SDX, + R72, R36, R24, R24BW, R12BW, R8BW, + PD50, PD90, PD120, PD160, PD180, PD240, PD290, + P3, P5, P7, + W260, W2120, W2180 }; // Color encodings diff --git a/modespec.c b/modespec.c index ff9d7b4..5ff0059 100644 --- a/modespec.c +++ b/modespec.c @@ -204,7 +204,22 @@ _ModeSpec ModeSpec[] = { .NumLines = 120, .LineHeight = 2, .ColorEnc = BW }, - + + [W260] = { + // Reverse-engineered by taking half the W2120 pixel time as an educated guess then + // tweaking the generated image timings until QSSTV decoded them without slant. -- VK4MSL + .Name = "Wraase SC-2 60", + .ShortName = "W260", + .SyncTime = 5.5225e-3, + .PorchTime = 0.0e-3, + .SeptrTime = 0.5e-3, + .PixelTime = 0.2425859375e-3, + .LineTime = 240.405e-3, + .ImgWidth = 320, + .NumLines = 256, + .LineHeight = 1, + .ColorEnc = RGB }, + [W2120] = { // KB4YZ, 1999 .Name = "Wraase SC-2 120", .ShortName = "W2120", @@ -371,15 +386,26 @@ _ModeSpec ModeSpec[] = { * */ -// 0 1 2 3 4 5 6 7 8 9 A B C D E F - -guchar VISmap[] = { 0, 0, R8BW, 0, R24, 0, R12BW,0, R36, 0, R24BW,0, R72, 0, 0, 0, // 0 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 - M4, 0, 0, 0, M3, 0, 0, 0, M2, 0, 0, 0, M1, 0, 0, 0, // 2 - 0, 0, 0, 0, 0, 0, 0, W2180,S2, 0, 0, 0, S1, 0, 0, W2120, // 3 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SDX, 0, 0, 0, // 4 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PD50,PD290,PD120, // 5 - PD180,PD240,PD160,PD90,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 - 0, P3, P5, P7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // 7 - -// 0 1 2 3 4 5 6 7 8 9 A B C D E F +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + +guchar VISmap[] = { + // Normal (even) parity + 0, 0, R8BW, 0, R24, 0, 0, 0, R36, 0, R24BW,0, R72, 0, 0, 0, // 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 + M4, 0, 0, 0, M3, 0, 0, 0, M2, 0, 0, 0, M1, 0, 0, 0, // 2 + 0, 0, 0, 0, 0, 0, 0, W2180,S2, 0, 0, 0, S1, 0, 0, W2120, // 3 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SDX, 0, 0, 0, // 4 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PD50,PD290,PD120, // 5 + PD180,PD240,PD160,PD90,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, P3, P5, P7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 + // Inverted (odd) parity + 0, 0, 0, 0, 0, 0, R12BW,0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W260, 0, 0, 0, 0, // B + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // F + +// 0 1 2 3 4 5 6 7 8 9 A B C D E F diff --git a/slowrx.ui b/slowrx.ui index 85e5d62..8125b7e 100644 --- a/slowrx.ui +++ b/slowrx.ui @@ -638,6 +638,7 @@ Pasokon P3 Pasokon P5 Pasokon P7 + Wraase SC-2 60 Wraase SC-2 120 Wraase SC-2 180 diff --git a/vis.c b/vis.c index 6f7eb26..0adf3bd 100644 --- a/vis.c +++ b/vis.c @@ -7,6 +7,14 @@ #include "common.h" +/* Handle selection of the VIS mode in the GUI */ +static void onGotVis(guchar VIS) { + gdk_threads_enter(); + gtk_combo_box_set_active (GTK_COMBO_BOX(gui.combo_mode), VISmap[VIS]-1); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(gui.spin_shift), CurrentPic.HedrShift); + gdk_threads_leave(); +} + /* * * Detect VIS & frequency shift @@ -113,19 +121,24 @@ guchar GetVIS () { Parity = Bit[0] ^ Bit[1] ^ Bit[2] ^ Bit[3] ^ Bit[4] ^ Bit[5] ^ Bit[6]; - if (VISmap[VIS] == R12BW) Parity = !Parity; - if (Parity != ParityBit) { - printf(" Parity fail\n"); - gotvis = FALSE; + // Maybe this mode uses odd parity? + printf(" Parity inconclusive, trying odd parity\n"); + if (VISmap[VIS | VIS_PARITY_ODD] == UNKNOWN) { + // Nope! + printf(" Parity fail\n"); + gotvis = FALSE; + } else { + // Yep, that was it. Inverted parity. + VIS |= VIS_PARITY_ODD; + onGotVis(VIS); + break; + } } else if (VISmap[VIS] == UNKNOWN) { printf(" Unknown VIS\n"); gotvis = FALSE; } else { - gdk_threads_enter(); - gtk_combo_box_set_active (GTK_COMBO_BOX(gui.combo_mode), VISmap[VIS]-1); - gtk_spin_button_set_value (GTK_SPIN_BUTTON(gui.spin_shift), CurrentPic.HedrShift); - gdk_threads_leave(); + onGotVis(VIS); break; } }