kopia lustrzana https://github.com/xdsopl/robot36
added raw, toggles for debug and autodetect mode
made debug mode much more usefulpull/6/head
rodzic
ab075cca27
commit
3dfa1b4c86
2
README
2
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:
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Ładowanie…
Reference in New Issue