summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrimio <vasi.vilvoiu@gmail.com>2019-02-15 02:17:41 +0200
committerrimio <vasi.vilvoiu@gmail.com>2019-02-15 02:17:41 +0200
commitd7972c361d6fbad81a9a7c4dbe180515dfca7f02 (patch)
treea72fd74c09d38e474e35c70ad19ae6754f7ca173
parentc0c48f54a4dc69adfe6e41ad88aa5a8d34bcf2c8 (diff)
VIS codes in mode enum; Added Scottie and Martin; Added Robot skel
-rw-r--r--src/encoder.c271
-rw-r--r--src/libsstv.template.h51
-rw-r--r--src/sstv.c276
-rw-r--r--src/sstv.h3
-rw-r--r--src/tools/sstv-encode.cpp52
5 files changed, 610 insertions, 43 deletions
diff --git a/src/encoder.c b/src/encoder.c
index ff1aea6..2824ab6 100644
--- a/src/encoder.c
+++ b/src/encoder.c
@@ -42,7 +42,11 @@ typedef enum {
/* sync and porch */
SSTV_ENCODER_STATE_SYNC,
+ SSTV_ENCODER_STATE_SYNC_FIRST,
SSTV_ENCODER_STATE_PORCH,
+ SSTV_ENCODER_STATE_PORCH_R,
+ SSTV_ENCODER_STATE_PORCH_G,
+ SSTV_ENCODER_STATE_PORCH_B,
/* scan */
SSTV_ENCODER_STATE_Y_SCAN,
@@ -51,6 +55,10 @@ typedef enum {
SSTV_ENCODER_STATE_RY_SCAN,
SSTV_ENCODER_STATE_BY_SCAN,
+ SSTV_ENCODER_STATE_R_SCAN,
+ SSTV_ENCODER_STATE_G_SCAN,
+ SSTV_ENCODER_STATE_B_SCAN,
+
/* end of coding */
SSTV_ENCODER_STATE_END
} sstv_encoder_state_t;
@@ -207,6 +215,233 @@ sstv_delete_encoder(void *ctx)
}
static sstv_error_t
+sstv_encode_robot_state_change(sstv_encoder_context_t *context)
+{
+ return SSTV_OK;
+}
+
+static sstv_error_t
+sstv_encode_scottie_state_change(sstv_encoder_context_t *context)
+{
+ /* start communication */
+ if (context->state == SSTV_ENCODER_STATE_VIS_STOP_BIT) {
+ context->state = SSTV_ENCODER_STATE_SYNC_FIRST;
+ context->extra.scan.curr_line = 0;
+ FSK(context, context->descriptor.sync.time, context->descriptor.sync.freq);
+ return SSTV_OK;
+ }
+
+ /* sync_first->porch_g */
+ if (context->state == SSTV_ENCODER_STATE_SYNC_FIRST) {
+ context->state = SSTV_ENCODER_STATE_PORCH_G;
+ FSK(context, context->descriptor.porch.time, context->descriptor.porch.freq);
+ return SSTV_OK;
+ }
+
+ /* porch_g->scan_g or scan_g->scan_g */
+ if ((context->state == SSTV_ENCODER_STATE_PORCH_G)
+ || (context->state == SSTV_ENCODER_STATE_G_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_PORCH_G) {
+ context->extra.scan.curr_col = 0;
+ }
+ context->state = SSTV_ENCODER_STATE_G_SCAN;
+
+ uint32_t pix_offset = context->image.width * context->extra.scan.curr_line + context->extra.scan.curr_col;
+ uint8_t y = context->image.buffer[pix_offset * 3 + 1];
+ FSK_PIXEL(context, context->descriptor.pixel.time, y);
+
+ context->extra.scan.curr_col ++;
+
+ return SSTV_OK;
+ }
+
+ /* scan_g->porch_b */
+ if (context->state == SSTV_ENCODER_STATE_G_SCAN) {
+ context->state = SSTV_ENCODER_STATE_PORCH_B;
+ FSK(context, context->descriptor.porch.time, context->descriptor.porch.freq);
+ return SSTV_OK;
+ }
+
+ /* porch_b->scan_b or scan_b->scan_b */
+ if ((context->state == SSTV_ENCODER_STATE_PORCH_B)
+ || (context->state == SSTV_ENCODER_STATE_B_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_PORCH_B) {
+ context->extra.scan.curr_col = 0;
+ }
+ context->state = SSTV_ENCODER_STATE_B_SCAN;
+
+ uint32_t pix_offset = context->image.width * context->extra.scan.curr_line + context->extra.scan.curr_col;
+ uint8_t y = context->image.buffer[pix_offset * 3 + 2];
+ FSK_PIXEL(context, context->descriptor.pixel.time, y);
+
+ context->extra.scan.curr_col ++;
+
+ return SSTV_OK;
+ }
+
+ /* blue->sync */
+ if (context->state == SSTV_ENCODER_STATE_B_SCAN) {
+ context->state = SSTV_ENCODER_STATE_SYNC;
+ FSK(context, context->descriptor.sync.time, context->descriptor.sync.freq);
+ return SSTV_OK;
+ }
+
+ /* sync->porch_r */
+ if (context->state == SSTV_ENCODER_STATE_SYNC) {
+ context->state = SSTV_ENCODER_STATE_PORCH_R;
+ FSK(context, context->descriptor.porch.time, context->descriptor.porch.freq);
+ return SSTV_OK;
+ }
+
+ /* porch_r->scan_r or scan_r->scan_r */
+ if ((context->state == SSTV_ENCODER_STATE_PORCH_R)
+ || (context->state == SSTV_ENCODER_STATE_R_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_PORCH_R) {
+ context->extra.scan.curr_col = 0;
+ }
+ context->state = SSTV_ENCODER_STATE_R_SCAN;
+
+ uint32_t pix_offset = context->image.width * context->extra.scan.curr_line + context->extra.scan.curr_col;
+ uint8_t y = context->image.buffer[pix_offset * 3];
+ FSK_PIXEL(context, context->descriptor.pixel.time, y);
+
+ context->extra.scan.curr_col ++;
+
+ return SSTV_OK;
+ }
+
+ /* scan_r->porch_g */
+ if ((context->state == SSTV_ENCODER_STATE_R_SCAN)
+ && (context->extra.scan.curr_line < context->image.height-1)) {
+ context->extra.scan.curr_line ++;
+ context->state = SSTV_ENCODER_STATE_PORCH_G;
+ FSK(context, context->descriptor.porch.time, context->descriptor.porch.freq);
+ return SSTV_OK;
+ }
+
+ /* no more state changes, done */
+ context->state = SSTV_ENCODER_STATE_END;
+ return SSTV_OK;
+}
+
+static sstv_error_t
+sstv_encode_martin_state_change(sstv_encoder_context_t *context)
+{
+ /* start communication */
+ if (context->state == SSTV_ENCODER_STATE_VIS_STOP_BIT) {
+ context->state = SSTV_ENCODER_STATE_SYNC;
+ context->extra.scan.curr_line = 0;
+ FSK(context, context->descriptor.sync.time, context->descriptor.sync.freq);
+ return SSTV_OK;
+ }
+
+ /* sync->porch_g */
+ if (context->state == SSTV_ENCODER_STATE_SYNC) {
+ context->state = SSTV_ENCODER_STATE_PORCH_G;
+ FSK(context, context->descriptor.porch.time, context->descriptor.porch.freq);
+ return SSTV_OK;
+ }
+
+ /* porch_g->scan_g or scan_g->scan_g */
+ if ((context->state == SSTV_ENCODER_STATE_PORCH_G)
+ || (context->state == SSTV_ENCODER_STATE_G_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_PORCH_G) {
+ context->extra.scan.curr_col = 0;
+ }
+ context->state = SSTV_ENCODER_STATE_G_SCAN;
+
+ uint32_t pix_offset = context->image.width * context->extra.scan.curr_line + context->extra.scan.curr_col;
+ uint8_t y = context->image.buffer[pix_offset * 3 + 1];
+ FSK_PIXEL(context, context->descriptor.pixel.time, y);
+
+ context->extra.scan.curr_col ++;
+
+ return SSTV_OK;
+ }
+
+ /* scan_g->porch_b */
+ if (context->state == SSTV_ENCODER_STATE_G_SCAN) {
+ context->state = SSTV_ENCODER_STATE_PORCH_B;
+ FSK(context, context->descriptor.porch.time, context->descriptor.porch.freq);
+ return SSTV_OK;
+ }
+
+ /* porch_b->scan_b or scan_b->scan_b */
+ if ((context->state == SSTV_ENCODER_STATE_PORCH_B)
+ || (context->state == SSTV_ENCODER_STATE_B_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_PORCH_B) {
+ context->extra.scan.curr_col = 0;
+ }
+ context->state = SSTV_ENCODER_STATE_B_SCAN;
+
+ uint32_t pix_offset = context->image.width * context->extra.scan.curr_line + context->extra.scan.curr_col;
+ uint8_t y = context->image.buffer[pix_offset * 3 + 2];
+ FSK_PIXEL(context, context->descriptor.pixel.time, y);
+
+ context->extra.scan.curr_col ++;
+
+ return SSTV_OK;
+ }
+
+ /* scan_b->porch_r */
+ if (context->state == SSTV_ENCODER_STATE_B_SCAN) {
+ context->state = SSTV_ENCODER_STATE_PORCH_R;
+ FSK(context, context->descriptor.porch.time, context->descriptor.porch.freq);
+ return SSTV_OK;
+ }
+
+ /* porch_r->scan_r or scan_r->scan_r */
+ if ((context->state == SSTV_ENCODER_STATE_PORCH_R)
+ || (context->state == SSTV_ENCODER_STATE_R_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_PORCH_R) {
+ context->extra.scan.curr_col = 0;
+ }
+ context->state = SSTV_ENCODER_STATE_R_SCAN;
+
+ uint32_t pix_offset = context->image.width * context->extra.scan.curr_line + context->extra.scan.curr_col;
+ uint8_t y = context->image.buffer[pix_offset * 3];
+ FSK_PIXEL(context, context->descriptor.pixel.time, y);
+
+ context->extra.scan.curr_col ++;
+
+ return SSTV_OK;
+ }
+
+ /* scan_r->porch */
+ if (context->state == SSTV_ENCODER_STATE_R_SCAN) {
+ context->state = SSTV_ENCODER_STATE_PORCH;
+ FSK(context, context->descriptor.porch.time, context->descriptor.porch.freq);
+ return SSTV_OK;
+ }
+
+ /* porch->sync */
+ if ((context->state == SSTV_ENCODER_STATE_PORCH)
+ && (context->extra.scan.curr_line < context->image.height-1))
+ {
+ context->extra.scan.curr_line ++;
+ context->state = SSTV_ENCODER_STATE_SYNC;
+ FSK(context, context->descriptor.sync.time, context->descriptor.sync.freq);
+ return SSTV_OK;
+ }
+
+ /* no more state changes, done */
+ context->state = SSTV_ENCODER_STATE_END;
+ return SSTV_OK;
+}
+
+static sstv_error_t
sstv_encode_pd_state_change(sstv_encoder_context_t *context)
{
/* start communication */
@@ -355,7 +590,7 @@ sstv_encode_state_change(sstv_encoder_context_t *context)
/* VIS start bit */
if (context->state == SSTV_ENCODER_STATE_LEADER_TONE_2) {
context->state = SSTV_ENCODER_STATE_VIS_START_BIT;
- context->extra.vis.visp = sstv_get_visp_code(context->mode);
+ context->extra.vis.visp = (uint8_t) context->mode;
context->extra.vis.curr_bit = 0;
FSK(context,
context->descriptor.vis.time,
@@ -393,6 +628,40 @@ sstv_encode_state_change(sstv_encoder_context_t *context)
/* call state change routine for specific mode */
switch (context->mode) {
+ /* Robot modes */
+ case SSTV_MODE_ROBOT_BW8_R:
+ case SSTV_MODE_ROBOT_BW8_G:
+ case SSTV_MODE_ROBOT_BW8_B:
+ case SSTV_MODE_ROBOT_BW12_R:
+ case SSTV_MODE_ROBOT_BW12_G:
+ case SSTV_MODE_ROBOT_BW12_B:
+ case SSTV_MODE_ROBOT_BW24_R:
+ case SSTV_MODE_ROBOT_BW24_G:
+ case SSTV_MODE_ROBOT_BW24_B:
+ case SSTV_MODE_ROBOT_BW36_R:
+ case SSTV_MODE_ROBOT_BW36_G:
+ case SSTV_MODE_ROBOT_BW36_B:
+ case SSTV_MODE_ROBOT_C12:
+ case SSTV_MODE_ROBOT_C24:
+ case SSTV_MODE_ROBOT_C36:
+ case SSTV_MODE_ROBOT_C72:
+ return sstv_encode_robot_state_change(context);
+
+ /* Scottie modes */
+ case SSTV_MODE_SCOTTIE_S1:
+ case SSTV_MODE_SCOTTIE_S2:
+ case SSTV_MODE_SCOTTIE_S3:
+ case SSTV_MODE_SCOTTIE_S4:
+ case SSTV_MODE_SCOTTIE_DX:
+ return sstv_encode_scottie_state_change(context);
+
+ /* Martin modes */
+ case SSTV_MODE_MARTIN_M1:
+ case SSTV_MODE_MARTIN_M2:
+ case SSTV_MODE_MARTIN_M3:
+ case SSTV_MODE_MARTIN_M4:
+ return sstv_encode_martin_state_change(context);
+
/* PD modes */
case SSTV_MODE_PD50:
case SSTV_MODE_PD90:
diff --git a/src/libsstv.template.h b/src/libsstv.template.h
index 7338da9..3ef620c 100644
--- a/src/libsstv.template.h
+++ b/src/libsstv.template.h
@@ -59,17 +59,52 @@ typedef enum {
} sstv_error_t;
/*
- * SSTV modes
+ * SSTV modes (value is VIS+Parity)
*/
typedef enum {
+ /* Robot modes */
+ SSTV_MODE_ROBOT_BW8_R = 129,
+ SSTV_MODE_ROBOT_BW8_G = 130,
+ SSTV_MODE_ROBOT_BW8_B = 3,
+
+ SSTV_MODE_ROBOT_BW12_R = 5,
+ SSTV_MODE_ROBOT_BW12_G = 6,
+ SSTV_MODE_ROBOT_BW12_B = 135,
+
+ SSTV_MODE_ROBOT_BW24_R = 9,
+ SSTV_MODE_ROBOT_BW24_G = 10,
+ SSTV_MODE_ROBOT_BW24_B = 139,
+
+ SSTV_MODE_ROBOT_BW36_R = 141,
+ SSTV_MODE_ROBOT_BW36_G = 142,
+ SSTV_MODE_ROBOT_BW36_B = 15,
+
+ SSTV_MODE_ROBOT_C12 = 0,
+ SSTV_MODE_ROBOT_C24 = 132,
+ SSTV_MODE_ROBOT_C36 = 136,
+ SSTV_MODE_ROBOT_C72 = 12,
+
+ /* Scottie modes */
+ SSTV_MODE_SCOTTIE_S1 = 60,
+ SSTV_MODE_SCOTTIE_S2 = 184,
+ SSTV_MODE_SCOTTIE_S3 = 180,
+ SSTV_MODE_SCOTTIE_S4 = 48,
+ SSTV_MODE_SCOTTIE_DX = 204,
+
+ /* Martin modes */
+ SSTV_MODE_MARTIN_M1 = 172,
+ SSTV_MODE_MARTIN_M2 = 40,
+ SSTV_MODE_MARTIN_M3 = 36,
+ SSTV_MODE_MARTIN_M4 = 160,
+
/* PD modes */
- SSTV_MODE_PD50,
- SSTV_MODE_PD90,
- SSTV_MODE_PD120,
- SSTV_MODE_PD160,
- SSTV_MODE_PD180,
- SSTV_MODE_PD240,
- SSTV_MODE_PD290
+ SSTV_MODE_PD50 = 221,
+ SSTV_MODE_PD90 = 99,
+ SSTV_MODE_PD120 = 95,
+ SSTV_MODE_PD160 = 226,
+ SSTV_MODE_PD180 = 96,
+ SSTV_MODE_PD240 = 225,
+ SSTV_MODE_PD290 = 222
} sstv_mode_t;
/*
diff --git a/src/sstv.c b/src/sstv.c
index 22c7654..bfe9319 100644
--- a/src/sstv.c
+++ b/src/sstv.c
@@ -160,6 +160,119 @@ sstv_error_t
sstv_get_mode_image_props(sstv_mode_t mode, uint32_t *width, uint32_t *height, sstv_image_format_t *format)
{
switch (mode) {
+ /* Robot modes */
+ case SSTV_MODE_ROBOT_BW8_R:
+ case SSTV_MODE_ROBOT_BW8_G:
+ case SSTV_MODE_ROBOT_BW8_B:
+ if (width) *width = 160;
+ if (height) *height = 120;
+ if (format) *format = SSTV_FORMAT_Y;
+ break;
+
+ case SSTV_MODE_ROBOT_BW12_R:
+ case SSTV_MODE_ROBOT_BW12_G:
+ case SSTV_MODE_ROBOT_BW12_B:
+ if (width) *width = 320;
+ if (height) *height = 120;
+ if (format) *format = SSTV_FORMAT_Y;
+ break;
+
+ case SSTV_MODE_ROBOT_BW24_R:
+ case SSTV_MODE_ROBOT_BW24_G:
+ case SSTV_MODE_ROBOT_BW24_B:
+ if (width) *width = 320;
+ if (height) *height = 240;
+ if (format) *format = SSTV_FORMAT_Y;
+ break;
+
+ case SSTV_MODE_ROBOT_BW36_R:
+ case SSTV_MODE_ROBOT_BW36_G:
+ case SSTV_MODE_ROBOT_BW36_B:
+ if (width) *width = 320;
+ if (height) *height = 240;
+ if (format) *format = SSTV_FORMAT_Y;
+ break;
+
+ case SSTV_MODE_ROBOT_C12:
+ if (width) *width = 160;
+ if (height) *height = 120;
+ if (format) *format = SSTV_FORMAT_YCBCR;
+ break;
+
+ case SSTV_MODE_ROBOT_C24:
+ if (width) *width = 320;
+ if (height) *height = 120;
+ if (format) *format = SSTV_FORMAT_YCBCR;
+ break;
+
+ case SSTV_MODE_ROBOT_C36:
+ if (width) *width = 320;
+ if (height) *height = 240;
+ if (format) *format = SSTV_FORMAT_YCBCR;
+ break;
+
+ case SSTV_MODE_ROBOT_C72:
+ if (width) *width = 320;
+ if (height) *height = 240;
+ if (format) *format = SSTV_FORMAT_YCBCR;
+ break;
+
+ /* Scottie modes */
+ case SSTV_MODE_SCOTTIE_S1:
+ if (width) *width = 320;
+ if (height) *height = 256;
+ if (format) *format = SSTV_FORMAT_RGB;
+ break;
+
+ case SSTV_MODE_SCOTTIE_S2:
+ if (width) *width = 320;
+ if (height) *height = 256;
+ if (format) *format = SSTV_FORMAT_RGB;
+ break;
+
+ case SSTV_MODE_SCOTTIE_S3:
+ if (width) *width = 320;
+ if (height) *height = 128;
+ if (format) *format = SSTV_FORMAT_RGB;
+ break;
+
+ case SSTV_MODE_SCOTTIE_S4:
+ if (width) *width = 320;
+ if (height) *height = 128;
+ if (format) *format = SSTV_FORMAT_RGB;
+ break;
+
+ case SSTV_MODE_SCOTTIE_DX:
+ if (width) *width = 320;
+ if (height) *height = 256;
+ if (format) *format = SSTV_FORMAT_RGB;
+ break;
+
+ /* Martin modes */
+ case SSTV_MODE_MARTIN_M1:
+ if (width) *width = 320;
+ if (height) *height = 256;
+ if (format) *format = SSTV_FORMAT_RGB;
+ break;
+
+ case SSTV_MODE_MARTIN_M2:
+ if (width) *width = 320;
+ if (height) *height = 256;
+ if (format) *format = SSTV_FORMAT_RGB;
+ break;
+
+ case SSTV_MODE_MARTIN_M3:
+ if (width) *width = 320;
+ if (height) *height = 128;
+ if (format) *format = SSTV_FORMAT_RGB;
+ break;
+
+ case SSTV_MODE_MARTIN_M4:
+ if (width) *width = 320;
+ if (height) *height = 128;
+ if (format) *format = SSTV_FORMAT_RGB;
+ break;
+
/* PD modes */
case SSTV_MODE_PD50:
if (width) *width = 320;
@@ -341,36 +454,6 @@ sstv_pack_signal(sstv_signal_t *sig, sstv_sample_type_t type, uint32_t capacity,
return SSTV_OK;
}
-uint8_t
-sstv_get_visp_code(sstv_mode_t mode)
-{
- switch (mode) {
- case SSTV_MODE_PD50:
- return 221;
-
- case SSTV_MODE_PD90:
- return 99;
-
- case SSTV_MODE_PD120:
- return 95;
-
- case SSTV_MODE_PD160:
- return 226;
-
- case SSTV_MODE_PD180:
- return 96;
-
- case SSTV_MODE_PD240:
- return 225;
-
- case SSTV_MODE_PD290:
- return 222;
-
- default:
- return 0;
- }
-}
-
sstv_error_t
sstv_get_mode_descriptor(sstv_mode_t mode, uint32_t sample_rate, sstv_mode_descriptor_t *desc)
{
@@ -393,6 +476,58 @@ sstv_get_mode_descriptor(sstv_mode_t mode, uint32_t sample_rate, sstv_mode_descr
/* Mode frequencies */
switch (mode) {
/*
+ * Robot modes
+ */
+ case SSTV_MODE_ROBOT_BW8_R:
+ case SSTV_MODE_ROBOT_BW8_G:
+ case SSTV_MODE_ROBOT_BW8_B:
+ case SSTV_MODE_ROBOT_BW12_R:
+ case SSTV_MODE_ROBOT_BW12_G:
+ case SSTV_MODE_ROBOT_BW12_B:
+ case SSTV_MODE_ROBOT_BW24_R:
+ case SSTV_MODE_ROBOT_BW24_G:
+ case SSTV_MODE_ROBOT_BW24_B:
+ case SSTV_MODE_ROBOT_BW36_R:
+ case SSTV_MODE_ROBOT_BW36_G:
+ case SSTV_MODE_ROBOT_BW36_B:
+ case SSTV_MODE_ROBOT_C12:
+ case SSTV_MODE_ROBOT_C24:
+ case SSTV_MODE_ROBOT_C36:
+ case SSTV_MODE_ROBOT_C72:
+ desc->sync.freq = FREQ_DESC_INIT(1200, sample_rate);
+ desc->porch.freq = FREQ_DESC_INIT(1500, sample_rate);
+ desc->pixel.low_freq = FREQ_DESC_INIT(1500, sample_rate);
+ desc->pixel.bandwidth = FREQ_DESC_INIT(800, sample_rate);
+ break;
+
+ /*
+ * Scottie modes
+ */
+ case SSTV_MODE_SCOTTIE_S1:
+ case SSTV_MODE_SCOTTIE_S2:
+ case SSTV_MODE_SCOTTIE_S3:
+ case SSTV_MODE_SCOTTIE_S4:
+ case SSTV_MODE_SCOTTIE_DX:
+ desc->sync.freq = FREQ_DESC_INIT(1200, sample_rate);
+ desc->porch.freq = FREQ_DESC_INIT(1500, sample_rate);
+ desc->pixel.low_freq = FREQ_DESC_INIT(1500, sample_rate);
+ desc->pixel.bandwidth = FREQ_DESC_INIT(800, sample_rate);
+ break;
+
+ /*
+ * Martin modes
+ */
+ case SSTV_MODE_MARTIN_M1:
+ case SSTV_MODE_MARTIN_M2:
+ case SSTV_MODE_MARTIN_M3:
+ case SSTV_MODE_MARTIN_M4:
+ desc->sync.freq = FREQ_DESC_INIT(1200, sample_rate);
+ desc->porch.freq = FREQ_DESC_INIT(1500, sample_rate);
+ desc->pixel.low_freq = FREQ_DESC_INIT(1500, sample_rate);
+ desc->pixel.bandwidth = FREQ_DESC_INIT(800, sample_rate);
+ break;
+
+ /*
* PD modes
*/
case SSTV_MODE_PD50:
@@ -418,6 +553,87 @@ sstv_get_mode_descriptor(sstv_mode_t mode, uint32_t sample_rate, sstv_mode_descr
/* Mode desc */
switch (mode) {
/*
+ * Robot modes
+ */
+ case SSTV_MODE_ROBOT_BW8_R:
+ case SSTV_MODE_ROBOT_BW8_G:
+ case SSTV_MODE_ROBOT_BW8_B:
+ case SSTV_MODE_ROBOT_BW12_R:
+ case SSTV_MODE_ROBOT_BW12_G:
+ case SSTV_MODE_ROBOT_BW12_B:
+ case SSTV_MODE_ROBOT_BW24_R:
+ case SSTV_MODE_ROBOT_BW24_G:
+ case SSTV_MODE_ROBOT_BW24_B:
+ case SSTV_MODE_ROBOT_BW36_R:
+ case SSTV_MODE_ROBOT_BW36_G:
+ case SSTV_MODE_ROBOT_BW36_B:
+ case SSTV_MODE_ROBOT_C12:
+ case SSTV_MODE_ROBOT_C24:
+ case SSTV_MODE_ROBOT_C36:
+ case SSTV_MODE_ROBOT_C72:
+ break;
+
+ /*
+ * Scottie modes
+ */
+ case SSTV_MODE_SCOTTIE_S1:
+ desc->sync.time = TIME_DESC_INIT(9000, sample_rate);
+ desc->porch.time = TIME_DESC_INIT(1500, sample_rate);
+ desc->pixel.time = TIME_DESC_INIT(432, sample_rate);
+ break;
+
+ case SSTV_MODE_SCOTTIE_S2:
+ desc->sync.time = TIME_DESC_INIT(9000, sample_rate);
+ desc->porch.time = TIME_DESC_INIT(1500, sample_rate);
+ desc->pixel.time = TIME_DESC_INIT(275, sample_rate);
+ break;
+
+ case SSTV_MODE_SCOTTIE_S3:
+ desc->sync.time = TIME_DESC_INIT(9000, sample_rate);
+ desc->porch.time = TIME_DESC_INIT(1500, sample_rate);
+ desc->pixel.time = TIME_DESC_INIT(432, sample_rate);
+ break;
+
+ case SSTV_MODE_SCOTTIE_S4:
+ desc->sync.time = TIME_DESC_INIT(9000, sample_rate);
+ desc->porch.time = TIME_DESC_INIT(1500, sample_rate);
+ desc->pixel.time = TIME_DESC_INIT(275, sample_rate);
+ break;
+
+ case SSTV_MODE_SCOTTIE_DX:
+ desc->sync.time = TIME_DESC_INIT(9000, sample_rate);
+ desc->porch.time = TIME_DESC_INIT(1500, sample_rate);
+ desc->pixel.time = TIME_DESC_INIT(1080, sample_rate);
+ break;
+
+ /*
+ * Martin modes
+ */
+ case SSTV_MODE_MARTIN_M1:
+ desc->sync.time = TIME_DESC_INIT(4862, sample_rate);
+ desc->porch.time = TIME_DESC_INIT(572, sample_rate);
+ desc->pixel.time = TIME_DESC_INIT(458, sample_rate);
+ break;
+
+ case SSTV_MODE_MARTIN_M2:
+ desc->sync.time = TIME_DESC_INIT(4862, sample_rate);
+ desc->porch.time = TIME_DESC_INIT(572, sample_rate);
+ desc->pixel.time = TIME_DESC_INIT(229, sample_rate);
+ break;
+
+ case SSTV_MODE_MARTIN_M3:
+ desc->sync.time = TIME_DESC_INIT(4862, sample_rate);
+ desc->porch.time = TIME_DESC_INIT(572, sample_rate);
+ desc->pixel.time = TIME_DESC_INIT(458, sample_rate);
+ break;
+
+ case SSTV_MODE_MARTIN_M4:
+ desc->sync.time = TIME_DESC_INIT(4862, sample_rate);
+ desc->porch.time = TIME_DESC_INIT(572, sample_rate);
+ desc->pixel.time = TIME_DESC_INIT(229, sample_rate);
+ break;
+
+ /*
* PD modes
*/
case SSTV_MODE_PD50:
diff --git a/src/sstv.h b/src/sstv.h
index c056381..6a8f819 100644
--- a/src/sstv.h
+++ b/src/sstv.h
@@ -72,9 +72,6 @@ extern sstv_free_t sstv_free_user;
/*
* Utility functions
*/
-extern uint8_t
-sstv_get_visp_code(sstv_mode_t mode);
-
extern sstv_error_t
sstv_get_mode_descriptor(sstv_mode_t mode, uint32_t sample_rate, sstv_mode_descriptor_t *desc);
diff --git a/src/tools/sstv-encode.cpp b/src/tools/sstv-encode.cpp
index a4d1284..aa7798b 100644
--- a/src/tools/sstv-encode.cpp
+++ b/src/tools/sstv-encode.cpp
@@ -28,7 +28,57 @@ sstv_mode_t mode_from_string(std::string mode)
{
std::transform(mode.begin(), mode.end(), mode.begin(), ::toupper);
- if (mode == "PD50") {
+ if (mode == "ROBOT_BW8_R"){
+ return SSTV_MODE_ROBOT_BW8_R;
+ } else if (mode == "ROBOT_BW8_G"){
+ return SSTV_MODE_ROBOT_BW8_G;
+ } else if (mode == "ROBOT_BW8_B"){
+ return SSTV_MODE_ROBOT_BW8_B;
+ } else if (mode == "ROBOT_BW12_R") {
+ return SSTV_MODE_ROBOT_BW12_R;
+ } else if (mode == "ROBOT_BW12_G") {
+ return SSTV_MODE_ROBOT_BW12_G;
+ } else if (mode == "ROBOT_BW12_B") {
+ return SSTV_MODE_ROBOT_BW12_B;
+ } else if (mode == "ROBOT_BW24_R") {
+ return SSTV_MODE_ROBOT_BW24_R;
+ } else if (mode == "ROBOT_BW24_G") {
+ return SSTV_MODE_ROBOT_BW24_G;
+ } else if (mode == "ROBOT_BW24_B") {
+ return SSTV_MODE_ROBOT_BW24_B;
+ } else if (mode == "ROBOT_BW36_R") {
+ return SSTV_MODE_ROBOT_BW36_R;
+ } else if (mode == "ROBOT_BW36_G") {
+ return SSTV_MODE_ROBOT_BW36_G;
+ } else if (mode == "ROBOT_BW36_B") {
+ return SSTV_MODE_ROBOT_BW36_B;
+ } else if (mode == "ROBOT_C12") {
+ return SSTV_MODE_ROBOT_C12;
+ } else if (mode == "ROBOT_C24") {
+ return SSTV_MODE_ROBOT_C24;
+ } else if (mode == "ROBOT_C36") {
+ return SSTV_MODE_ROBOT_C36;
+ } else if (mode == "ROBOT_C72") {
+ return SSTV_MODE_ROBOT_C72;
+ } else if (mode == "SCOTTIE_S1") {
+ return SSTV_MODE_SCOTTIE_S1;
+ } else if (mode == "SCOTTIE_S2") {
+ return SSTV_MODE_SCOTTIE_S2;
+ } else if (mode == "SCOTTIE_S3") {
+ return SSTV_MODE_SCOTTIE_S3;
+ } else if (mode == "SCOTTIE_S4") {
+ return SSTV_MODE_SCOTTIE_S4;
+ } else if (mode == "SCOTTIE_DX") {
+ return SSTV_MODE_SCOTTIE_DX;
+ } else if (mode == "MARTIN_M1") {
+ return SSTV_MODE_MARTIN_M1;
+ } else if (mode == "MARTIN_M2") {
+ return SSTV_MODE_MARTIN_M2;
+ } else if (mode == "MARTIN_M3") {
+ return SSTV_MODE_MARTIN_M3;
+ } else if (mode == "MARTIN_M4") {
+ return SSTV_MODE_MARTIN_M4;
+ } else if (mode == "PD50") {
return SSTV_MODE_PD50;
} else if (mode == "PD90") {
return SSTV_MODE_PD90;