summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrimio <vasi.vilvoiu@gmail.com>2019-01-09 13:50:34 +0200
committerrimio <vasi.vilvoiu@gmail.com>2019-01-09 13:50:34 +0200
commit41f3b5f445a98500a345b00bc4a3ce111af652e8 (patch)
tree012aaa511abfbb73a444928e50b065e3ceab474c
parentdcc04103eca47554f6bd673b21e07afd5b8fbcfe (diff)
PD modes start
-rw-r--r--src/encoder.c142
-rw-r--r--src/tools/sstv-encode.cpp1
-rw-r--r--util/view.py8
3 files changed, 142 insertions, 9 deletions
diff --git a/src/encoder.c b/src/encoder.c
index 29abbe9..7170b58 100644
--- a/src/encoder.c
+++ b/src/encoder.c
@@ -19,16 +19,31 @@
* Encoder state
*/
typedef enum {
+ /* start of coding */
SSTV_ENCODER_STATE_START,
+ /* transmission header */
SSTV_ENCODER_STATE_LEADER_TONE_1,
SSTV_ENCODER_STATE_BREAK,
SSTV_ENCODER_STATE_LEADER_TONE_2,
+ /* VIS */
SSTV_ENCODER_STATE_VIS_START_BIT,
SSTV_ENCODER_STATE_VIS_BIT,
SSTV_ENCODER_STATE_VIS_STOP_BIT,
+ /* sync and porch */
+ SSTV_ENCODER_STATE_SYNC,
+ SSTV_ENCODER_STATE_PORCH,
+
+ /* scan */
+ SSTV_ENCODER_STATE_Y_SCAN,
+ SSTV_ENCODER_STATE_Y_ODD_SCAN,
+ SSTV_ENCODER_STATE_Y_EVEN_SCAN,
+ SSTV_ENCODER_STATE_RY_SCAN,
+ SSTV_ENCODER_STATE_BY_SCAN,
+
+ /* end of coding */
SSTV_ENCODER_STATE_END
} sstv_encoder_state_t;
@@ -59,6 +74,11 @@ typedef struct {
uint8_t visp;
uint8_t curr_bit;
} vis;
+
+ struct {
+ size_t curr_line;
+ size_t curr_col;
+ } scan;
} extra;
} sstv_encoder_context_t;
@@ -167,7 +187,123 @@ sstv_delete_encoder(void *ctx)
static sstv_error_t
sstv_encode_pd_state_change(sstv_encoder_context_t *context)
{
- /* done */
+ /* start communication */
+ if (context->state == SSTV_ENCODER_STATE_VIS_STOP_BIT) {
+ context->state = SSTV_ENCODER_STATE_SYNC;
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1200, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(20000, context->sample_rate);
+ context->extra.scan.curr_line = 0;
+ return SSTV_OK;
+ }
+
+ /* advance line (odd->sync) */
+ if ((context->state == SSTV_ENCODER_STATE_Y_ODD_SCAN)
+ && (context->extra.scan.curr_col >= context->image.width)
+ && (context->extra.scan.curr_line < context->image.height-1))
+ {
+ context->state = SSTV_ENCODER_STATE_SYNC;
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1200, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(20000, context->sample_rate);
+ context->extra.scan.curr_line += 2;
+ return SSTV_OK;
+ }
+
+ /* sync->porch */
+ if (context->state == SSTV_ENCODER_STATE_SYNC) {
+ context->state = SSTV_ENCODER_STATE_PORCH;
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1500, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(2080, context->sample_rate);
+ return SSTV_OK;
+ }
+
+ /* porch->even or even->even */
+ if ((context->state == SSTV_ENCODER_STATE_PORCH)
+ || (context->state == SSTV_ENCODER_STATE_Y_EVEN_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_PORCH) {
+ context->extra.scan.curr_col = 0;
+ }
+
+ context->state = SSTV_ENCODER_STATE_Y_EVEN_SCAN;
+
+ size_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];
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1500 + y * 800 / 255, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(190, context->sample_rate);
+
+ context->extra.scan.curr_col ++;
+ return SSTV_OK;
+ }
+
+ /* even->R or R->R */
+ if ((context->state == SSTV_ENCODER_STATE_Y_EVEN_SCAN)
+ || (context->state == SSTV_ENCODER_STATE_RY_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_Y_EVEN_SCAN) {
+ context->extra.scan.curr_col = 0;
+ }
+
+ context->state = SSTV_ENCODER_STATE_RY_SCAN;
+
+ size_t pix_offset_l0 = context->image.width * context->extra.scan.curr_line + context->extra.scan.curr_col;
+ size_t pix_offset_l1 = context->image.width * (context->extra.scan.curr_line + 1) + context->extra.scan.curr_col;
+ uint8_t r1 = context->image.buffer[pix_offset_l0 * 3 + 2];
+ uint8_t r2 = context->image.buffer[pix_offset_l1 * 3 + 2];
+ uint8_t r = (r1 + r2) / 2;
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1500 + r * 800 / 255, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(190, context->sample_rate);
+
+ context->extra.scan.curr_col ++;
+ return SSTV_OK;
+ }
+
+ /* R->B or B->B */
+ if ((context->state == SSTV_ENCODER_STATE_RY_SCAN)
+ || (context->state == SSTV_ENCODER_STATE_BY_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_RY_SCAN) {
+ context->extra.scan.curr_col = 0;
+ }
+
+ context->state = SSTV_ENCODER_STATE_BY_SCAN;
+
+ size_t pix_offset_l0 = context->image.width * context->extra.scan.curr_line + context->extra.scan.curr_col;
+ size_t pix_offset_l1 = context->image.width * (context->extra.scan.curr_line + 1) + context->extra.scan.curr_col;
+ uint8_t b1 = context->image.buffer[pix_offset_l0 * 3 + 1];
+ uint8_t b2 = context->image.buffer[pix_offset_l1 * 3 + 1];
+ uint8_t b = (b1 + b2) / 2;
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1500 + b * 800 / 255, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(190, context->sample_rate);
+
+ context->extra.scan.curr_col ++;
+ return SSTV_OK;
+ }
+
+ /* B->odd or odd->odd */
+ if ((context->state == SSTV_ENCODER_STATE_BY_SCAN)
+ || (context->state == SSTV_ENCODER_STATE_Y_ODD_SCAN
+ && context->extra.scan.curr_col < context->image.width))
+ {
+ if (context->state == SSTV_ENCODER_STATE_BY_SCAN) {
+ context->extra.scan.curr_col = 0;
+ }
+
+ context->state = SSTV_ENCODER_STATE_Y_ODD_SCAN;
+
+ size_t pix_offset = context->image.width * (context->extra.scan.curr_line + 1) + context->extra.scan.curr_col;
+ uint8_t y = context->image.buffer[pix_offset * 3];
+ context->fsk.phase_delta = DPHASE_FROM_FREQ(1500 + y * 800 / 255, context->sample_rate);
+ context->fsk.remaining_samples = REMAINING_SAMPLES_US(190, context->sample_rate);
+
+ context->extra.scan.curr_col ++;
+ return SSTV_OK;
+ }
+
+ /* no more state changes, done */
+ context->state = SSTV_ENCODER_STATE_END;
return SSTV_OK;
}
@@ -228,10 +364,6 @@ sstv_encode_state_change(sstv_encoder_context_t *context)
return SSTV_OK;
}
- /* debug */
- context->state = SSTV_ENCODER_STATE_END;
- return SSTV_OK;
-
/* call state change routine for specific mode */
switch (context->mode) {
/* PD modes */
diff --git a/src/tools/sstv-encode.cpp b/src/tools/sstv-encode.cpp
index 0b79e69..3919968 100644
--- a/src/tools/sstv-encode.cpp
+++ b/src/tools/sstv-encode.cpp
@@ -102,6 +102,7 @@ int main(int argc, char **argv)
/* write to sound file */
sf_write_short(wavfile, (int16_t *)signal.buffer, signal.count);
+ LOG(INFO) << "Written " << signal.count << " samples";
/* exit case */
if (rc == SSTV_ENCODE_END) {
diff --git a/util/view.py b/util/view.py
index 60b3a47..f1b7470 100644
--- a/util/view.py
+++ b/util/view.py
@@ -17,10 +17,10 @@ if spf.getnchannels() == 2:
print('Just mono files')
sys.exit(0)
-#plt.figure(1)
-#plt.title('Signal Wave...')
-#plt.plot(signal)
-#plt.show()
+plt.figure(1)
+plt.title('Signal Wave...')
+plt.plot(signal)
+plt.show()
plt.specgram(signal, Fs=48000)
plt.show() \ No newline at end of file