diff --git a/README b/README
index 9fb7d6f..2a15234 100644
--- a/README
+++ b/README
@@ -31,7 +31,7 @@ Martin Modes: 1 & 2
Scottie Modes: 1, 2 & DX
Wrasse Modes: SC2 180
-Watching of old B/W or unsupported transmission modes works even in the raw "Debug Image" mode.
+Watching of old B/W or unsupported transmission modes works even in the "Raw Mode".
I created the "Robot36 SSTV Alpha Testers" Community, which you can join and help test prebuilt apk's from the Google Play Store for free:
diff --git a/app/src/main/java/xdsopl/robot36/ImageView.java b/app/src/main/java/xdsopl/robot36/ImageView.java
index b4098f1..5005baa 100644
--- a/app/src/main/java/xdsopl/robot36/ImageView.java
+++ b/app/src/main/java/xdsopl/robot36/ImageView.java
@@ -64,7 +64,7 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
private final Allocation rsDecoderSavedHeight;
private final ScriptC_decoder rsDecoder;
- private final int mode_debug = 0;
+ private final int mode_raw = 0;
private final int mode_robot36 = 1;
private final int mode_robot72 = 2;
private final int mode_martin1 = 3;
@@ -138,9 +138,9 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
void toggle_scaling() { intScale ^= true; }
void softer_image() { rsDecoder.invoke_incr_blur(); }
void sharper_image() { rsDecoder.invoke_decr_blur(); }
- void debug_sync() { rsDecoder.invoke_debug_sync(); }
- void debug_image() { rsDecoder.invoke_debug_image(); }
- void debug_both() { rsDecoder.invoke_debug_both(); }
+ void toggle_debug() { rsDecoder.invoke_toggle_debug(); }
+ void toggle_auto() { rsDecoder.invoke_toggle_auto(); }
+ void raw_mode() { rsDecoder.invoke_raw_mode(); }
void robot36_mode() { rsDecoder.invoke_robot36_mode(); }
void robot72_mode() { rsDecoder.invoke_robot72_mode(); }
void martin1_mode() { rsDecoder.invoke_martin1_mode(); }
@@ -154,10 +154,10 @@ public class ImageView extends SurfaceView implements SurfaceHolder.Callback {
void switch_mode(int mode)
{
switch (mode) {
- case mode_debug:
+ case mode_raw:
imageWidth = bitmap.getWidth();
imageHeight = bitmap.getHeight();
- updateTitle(R.string.action_debug_mode);
+ updateTitle(R.string.action_raw_mode);
break;
case mode_robot36:
imageWidth = 320;
diff --git a/app/src/main/java/xdsopl/robot36/MainActivity.java b/app/src/main/java/xdsopl/robot36/MainActivity.java
index 4194138..59afd27 100644
--- a/app/src/main/java/xdsopl/robot36/MainActivity.java
+++ b/app/src/main/java/xdsopl/robot36/MainActivity.java
@@ -151,6 +151,15 @@ public class MainActivity extends Activity {
case R.id.action_toggle_scaling:
view.toggle_scaling();
return true;
+ case R.id.action_toggle_debug:
+ view.toggle_debug();
+ return true;
+ case R.id.action_toggle_auto:
+ view.toggle_auto();
+ return true;
+ case R.id.action_raw_mode:
+ view.raw_mode();
+ return true;
case R.id.action_robot36_mode:
view.robot36_mode();
return true;
@@ -175,15 +184,6 @@ public class MainActivity extends Activity {
case R.id.action_wrasseSC2_180_mode:
view.wrasseSC2_180_mode();
return true;
- case R.id.action_debug_sync:
- view.debug_sync();
- return true;
- case R.id.action_debug_image:
- view.debug_image();
- return true;
- case R.id.action_debug_both:
- view.debug_both();
- return true;
}
return super.onOptionsItemSelected(item);
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
index 919202e..0227b12 100644
--- a/app/src/main/res/menu/menu_main.xml
+++ b/app/src/main/res/menu/menu_main.xml
@@ -7,6 +7,12 @@
android:orderInCategory="100" android:showAsAction="never" />
+
+
+
-
-
-
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d3d9194..522ef17 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -3,10 +3,9 @@
Robot36
"decoder is running
- Debug Sync
- Debug Image
- Debug Image and Sync
- Debug Mode
+ Toggle Auto Mode
+ Toggle Debug Mode
+ Raw Mode
Robot36 Mode
Robot72 Mode
Martin1 Mode
diff --git a/app/src/main/rs/constants.rsh b/app/src/main/rs/constants.rsh
index 43fbe4e..c1e7c9d 100644
--- a/app/src/main/rs/constants.rsh
+++ b/app/src/main/rs/constants.rsh
@@ -23,7 +23,7 @@ static const int decoder_yuv = 2;
static const int decoder_rgb = 3;
static const int decoder_scottie = 4;
-static const int mode_debug = 0;
+static const int mode_raw = 0;
static const int mode_robot36 = 1;
static const int mode_robot72 = 2;
static const int mode_martin1 = 3;
@@ -33,7 +33,6 @@ static const int mode_scottie2 = 6;
static const int mode_scottieDX = 7;
static const int mode_wrasseSC2_180 = 8;
-
static const float sync_buildup_ms = 1.1f;
static const float robot36_scanline_ms = 150.0f;
static const float robot72_scanline_ms = 300.0f;
diff --git a/app/src/main/rs/decoder.rs b/app/src/main/rs/decoder.rs
index 4932735..82a6749 100644
--- a/app/src/main/rs/decoder.rs
+++ b/app/src/main/rs/decoder.rs
@@ -77,23 +77,47 @@ static void robot36_decoder(int sync_timeout)
mismatch_counter = 0;
}
prev_timeout = sync_timeout;
- static int even_sync_pos, odd_sync_pos;
- if (parity) {
- odd_sync_pos = prev_sync_pos;
- int even_vpos = vpos;
- int odd_vpos = (vpos + 1) % maximum_height;
+ if (debug_mode) {
for (int i = 0; i < bitmap_width; ++i) {
- uchar even_y = value_blur(i, even_sync_pos + y_begin, even_sync_pos + y_end);
- uchar v = value_blur(i, even_sync_pos + v_begin, even_sync_pos + v_end);
- uchar odd_y = value_blur(i, odd_sync_pos + y_begin, odd_sync_pos + y_end);
- uchar u = value_blur(i, odd_sync_pos + u_begin, odd_sync_pos + u_end);
- pixel_buffer[bitmap_width * even_vpos + i] = yuv(even_y, u, v);
- pixel_buffer[bitmap_width * odd_vpos + i] = yuv(odd_y, u, v);
+ uchar r, g, b;
+ r = g = b = value_blur(i, prev_sync_pos, sync_pos);
+ int pos = (i * (sync_pos - prev_sync_pos) + (sync_pos - prev_sync_pos) / 2) / bitmap_width;
+ if (y_begin <= pos && pos < y_end)
+ r = b = 0;
+ if (parity) {
+ if (v_begin <= pos && pos < v_end)
+ g = b = 0;
+ if (u_sep_begin <= pos && pos < u_sep_end)
+ b = 128;
+ } else {
+ if (u_begin <= pos && pos < u_end)
+ r = g = 0;
+ if (v_sep_begin <= pos && pos < v_sep_end)
+ r = g = 128;
+ }
+ pixel_buffer[bitmap_width * vpos + i] = rgb(r, g, b);
}
- vpos += 2;
latch = 0;
+ ++vpos;
} else {
- even_sync_pos = prev_sync_pos;
+ static int even_sync_pos, odd_sync_pos;
+ if (parity) {
+ odd_sync_pos = prev_sync_pos;
+ int even_vpos = vpos;
+ int odd_vpos = (vpos + 1) % maximum_height;
+ for (int i = 0; i < bitmap_width; ++i) {
+ uchar even_y = value_blur(i, even_sync_pos + y_begin, even_sync_pos + y_end);
+ uchar v = value_blur(i, even_sync_pos + v_begin, even_sync_pos + v_end);
+ uchar odd_y = value_blur(i, odd_sync_pos + y_begin, odd_sync_pos + y_end);
+ uchar u = value_blur(i, odd_sync_pos + u_begin, odd_sync_pos + u_end);
+ pixel_buffer[bitmap_width * even_vpos + i] = yuv(even_y, u, v);
+ pixel_buffer[bitmap_width * odd_vpos + i] = yuv(odd_y, u, v);
+ }
+ vpos += 2;
+ latch = 0;
+ } else {
+ even_sync_pos = prev_sync_pos;
+ }
}
parity ^= 1;
}
@@ -101,10 +125,27 @@ static void robot36_decoder(int sync_timeout)
static void yuv_decoder()
{
for (int i = 0; i < bitmap_width; ++i) {
- uchar y = value_blur(i, y_begin + prev_sync_pos, y_end + prev_sync_pos);
- uchar u = value_blur(i, u_begin + prev_sync_pos, u_end + prev_sync_pos);
- uchar v = value_blur(i, v_begin + prev_sync_pos, v_end + prev_sync_pos);
- pixel_buffer[bitmap_width * vpos + i] = yuv(y, u, v);
+ if (debug_mode) {
+ uchar r, g, b;
+ r = g = b = value_blur(i, prev_sync_pos, sync_pos);
+ int pos = (i * (sync_pos - prev_sync_pos) + (sync_pos - prev_sync_pos) / 2) / bitmap_width;
+ if (v_begin <= pos && pos < v_end)
+ g = b = 0;
+ if (y_begin <= pos && pos < y_end)
+ r = b = 0;
+ if (u_begin <= pos && pos < u_end)
+ r = g = 0;
+ if (u_sep_begin <= pos && pos < u_sep_end)
+ b = 128;
+ if (v_sep_begin <= pos && pos < v_sep_end)
+ r = g = 128;
+ pixel_buffer[bitmap_width * vpos + i] = rgb(r, g, b);
+ } else {
+ uchar y = value_blur(i, y_begin + prev_sync_pos, y_end + prev_sync_pos);
+ uchar u = value_blur(i, u_begin + prev_sync_pos, u_end + prev_sync_pos);
+ uchar v = value_blur(i, v_begin + prev_sync_pos, v_end + prev_sync_pos);
+ pixel_buffer[bitmap_width * vpos + i] = yuv(y, u, v);
+ }
}
++vpos;
}
@@ -112,9 +153,21 @@ static void yuv_decoder()
static void rgb_decoder()
{
for (int i = 0; i < bitmap_width; ++i) {
- uchar r = value_blur(i, r_begin + prev_sync_pos, r_end + prev_sync_pos);
- uchar g = value_blur(i, g_begin + prev_sync_pos, g_end + prev_sync_pos);
- uchar b = value_blur(i, b_begin + prev_sync_pos, b_end + prev_sync_pos);
+ uchar r, g, b;
+ if (debug_mode) {
+ r = g = b = value_blur(i, prev_sync_pos, sync_pos);
+ int pos = (i * (sync_pos - prev_sync_pos) + (sync_pos - prev_sync_pos) / 2) / bitmap_width;
+ if (r_begin <= pos && pos < r_end)
+ g = b = 0;
+ if (g_begin <= pos && pos < g_end)
+ r = b = 0;
+ if (b_begin <= pos && pos < b_end)
+ r = g = 0;
+ } else {
+ r = value_blur(i, r_begin + prev_sync_pos, r_end + prev_sync_pos);
+ g = value_blur(i, g_begin + prev_sync_pos, g_end + prev_sync_pos);
+ b = value_blur(i, b_begin + prev_sync_pos, b_end + prev_sync_pos);
+ }
pixel_buffer[bitmap_width * vpos + i] = rgb(r, g, b);
}
++vpos;
@@ -138,7 +191,25 @@ static void scottie_decoder()
return;
}
first_sync = 1;
- rgb_decoder();
+ for (int i = 0; i < bitmap_width; ++i) {
+ uchar r, g, b;
+ if (debug_mode) {
+ r = g = b = value_blur(i, g_begin + prev_sync_pos, r_end + prev_sync_pos);
+ int pos = (i * (r_end - g_begin) + (r_end - g_begin) / 2) / bitmap_width + g_begin;
+ if (r_begin <= pos && pos < r_end)
+ g = b = 0;
+ if (g_begin <= pos && pos < g_end)
+ r = b = 0;
+ if (b_begin <= pos && pos < b_end)
+ r = g = 0;
+ } else {
+ r = value_blur(i, r_begin + prev_sync_pos, r_end + prev_sync_pos);
+ g = value_blur(i, g_begin + prev_sync_pos, g_end + prev_sync_pos);
+ b = value_blur(i, b_begin + prev_sync_pos, b_end + prev_sync_pos);
+ }
+ pixel_buffer[bitmap_width * vpos + i] = rgb(r, g, b);
+ }
+ ++vpos;
}
void decode(int samples) {
@@ -162,8 +233,8 @@ void decode(int samples) {
int cnt_active = dat_amp < 1.1f * cnt_amp;
int dat_active = cnt_amp < 2.0f * dat_amp;
- uchar cnt_level = save_cnt && cnt_active ? 127.5f - 127.5f * cnt_value : 0.0f;
- uchar dat_level = save_dat && dat_active ? 127.5f + 127.5f * dat_value : 0.0f;
+ uchar cnt_level = debug_mode && cnt_active ? 127.5f - 127.5f * cnt_value : 0.0f;
+ uchar dat_level = dat_active ? 127.5f + 127.5f * dat_value : 0.0f;
value_buffer[buffer_pos & buffer_mask] = cnt_level | dat_level;
int cnt_quantized = round(cnt_value);
@@ -177,7 +248,7 @@ void decode(int samples) {
sync_pos = buffer_pos - sync_buildup_length;
}
- if (*current_mode != mode_debug) {
+ if (automatic_mode_detection) {
int detected_mode = calibration_detector(dat_value, dat_amp, cnt_amp, cnt_quantized);
if (detected_mode >= 0) {
free_running = 0;
diff --git a/app/src/main/rs/initialization.rsh b/app/src/main/rs/initialization.rsh
index 0716e29..6c4417f 100644
--- a/app/src/main/rs/initialization.rsh
+++ b/app/src/main/rs/initialization.rsh
@@ -32,6 +32,8 @@ void initialize(float rate, int length, int width, int height)
for (int i = 0; i < width * height; ++i)
pixel_buffer[i] = 0;
+ automatic_mode_detection = 1;
+ debug_mode = 0;
vpos = 0;
hpos = 0;
prev_sync_pos = sync_pos = 0;
diff --git a/app/src/main/rs/modes.rsh b/app/src/main/rs/modes.rsh
index fc003ce..44fe8f1 100644
--- a/app/src/main/rs/modes.rsh
+++ b/app/src/main/rs/modes.rsh
@@ -21,38 +21,18 @@ limitations under the License.
#include "state.rsh"
#include "exports.rsh"
-void debug_sync()
+void toggle_auto()
{
- save_cnt = 1;
- save_dat = 0;
- blur_power = -1;
- *current_mode = mode_debug;
- current_decoder = decoder_raw;
- bitmap_width = maximum_width;
- bitmap_height = maximum_height;
- sync_length = minimum_sync_length;
- maximum_length = buffer_length;
- scanline_length = maximum_length;
+ automatic_mode_detection ^= 1;
}
-void debug_image()
+void toggle_debug()
{
- save_dat = 1;
- save_cnt = 0;
- blur_power = -1;
- *current_mode = mode_debug;
- current_decoder = decoder_raw;
- bitmap_width = maximum_width;
- bitmap_height = maximum_height;
- sync_length = minimum_sync_length;
- maximum_length = buffer_length;
- scanline_length = maximum_length;
+ debug_mode ^= 1;
}
-void debug_both()
+void raw_mode()
{
- save_cnt = 1;
- save_dat = 1;
blur_power = -1;
- *current_mode = mode_debug;
+ *current_mode = mode_raw;
current_decoder = decoder_raw;
bitmap_width = maximum_width;
bitmap_height = maximum_height;
@@ -62,8 +42,6 @@ void debug_both()
}
void robot36_mode()
{
- save_dat = 1;
- save_cnt = 0;
blur_power = 2;
*current_mode = mode_robot36;
current_decoder = decoder_robot36;
@@ -98,8 +76,6 @@ void robot36_mode()
}
void robot72_mode()
{
- save_dat = 1;
- save_cnt = 0;
blur_power = 3;
*current_mode = mode_robot72;
current_decoder = decoder_yuv;
@@ -142,8 +118,6 @@ void robot72_mode()
}
void martin1_mode()
{
- save_cnt = 0;
- save_dat = 1;
blur_power = 3;
*current_mode = mode_martin1;
current_decoder = decoder_rgb;
@@ -176,8 +150,6 @@ void martin1_mode()
}
void martin2_mode()
{
- save_cnt = 0;
- save_dat = 1;
blur_power = 2;
*current_mode = mode_martin2;
current_decoder = decoder_rgb;
@@ -210,8 +182,6 @@ void martin2_mode()
}
void scottie1_mode()
{
- save_cnt = 0;
- save_dat = 1;
blur_power = 3;
*current_mode = mode_scottie1;
current_decoder = decoder_scottie;
@@ -244,8 +214,6 @@ void scottie1_mode()
}
void scottie2_mode()
{
- save_cnt = 0;
- save_dat = 1;
blur_power = 2;
*current_mode = mode_scottie2;
current_decoder = decoder_scottie;
@@ -278,8 +246,6 @@ void scottie2_mode()
}
void scottieDX_mode()
{
- save_cnt = 0;
- save_dat = 1;
blur_power = 5;
*current_mode = mode_scottieDX;
current_decoder = decoder_scottie;
@@ -312,8 +278,6 @@ void scottieDX_mode()
}
void wrasseSC2_180_mode()
{
- save_cnt = 0;
- save_dat = 1;
blur_power = 4;
*current_mode = mode_wrasseSC2_180;
current_decoder = decoder_rgb;
diff --git a/app/src/main/rs/state.rsh b/app/src/main/rs/state.rsh
index d47e4e9..61428f5 100644
--- a/app/src/main/rs/state.rsh
+++ b/app/src/main/rs/state.rsh
@@ -20,6 +20,8 @@ limitations under the License.
static ema_t avg_amplitude, leader_lowpass;
static ddc_t cnt_ddc, dat_ddc;
static fmd_t cnt_fmd, dat_fmd;
+static int automatic_mode_detection;
+static int debug_mode;
static int current_decoder;
static int blur_power, free_running;
static int sample_rate, sync_pos, prev_sync_pos;
@@ -34,7 +36,7 @@ static int buffer_cleared;
static int bitmap_width, bitmap_height;
static int maximum_width, maximum_height;
static int sync_length, sync_counter, vpos, hpos;
-static int save_cnt, save_dat, seperator_counter, seperator_length;
+static int seperator_counter, seperator_length;
static int u_sep_begin, u_sep_end, v_sep_begin, v_sep_end;
static int y_begin, y_end, u_begin, u_end, v_begin, v_end;
static int r_begin, r_end, b_begin, b_end, g_begin, g_end;