added raw, toggles for debug and autodetect mode

made debug mode much more useful
pull/6/head
Ahmet Inan 2015-01-04 17:47:28 +01:00
rodzic ab075cca27
commit 3dfa1b4c86
10 zmienionych plików z 132 dodań i 95 usunięć

2
README
Wyświetl plik

@ -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:

Wyświetl plik

@ -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;

Wyświetl plik

@ -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);

Wyświetl plik

@ -7,6 +7,12 @@
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_toggle_scaling" android:title="@string/action_toggle_scaling"
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_toggle_debug" android:title="@string/action_toggle_debug"
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_toggle_auto" android:title="@string/action_toggle_auto"
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_raw_mode" android:title="@string/action_raw_mode"
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_robot36_mode" android:title="@string/action_robot36_mode"
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_robot72_mode" android:title="@string/action_robot72_mode"
@ -23,10 +29,4 @@
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_wrasseSC2_180_mode" android:title="@string/action_wrasseSC2_180_mode"
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_debug_sync" android:title="@string/action_debug_sync"
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_debug_image" android:title="@string/action_debug_image"
android:orderInCategory="100" android:showAsAction="never" />
<item android:id="@+id/action_debug_both" android:title="@string/action_debug_both"
android:orderInCategory="100" android:showAsAction="never" />
</menu>

Wyświetl plik

@ -3,10 +3,9 @@
<string name="app_name">Robot36</string>
<string name="decoder_running">"decoder is running</string>
<string name="action_debug_sync">Debug Sync</string>
<string name="action_debug_image">Debug Image</string>
<string name="action_debug_both">Debug Image and Sync</string>
<string name="action_debug_mode">Debug Mode</string>
<string name="action_toggle_auto">Toggle Auto Mode</string>
<string name="action_toggle_debug">Toggle Debug Mode</string>
<string name="action_raw_mode">Raw Mode</string>
<string name="action_robot36_mode">Robot36 Mode</string>
<string name="action_robot72_mode">Robot72 Mode</string>
<string name="action_martin1_mode">Martin1 Mode</string>

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;