diff options
| author | rimio <vasi.vilvoiu@gmail.com> | 2019-01-09 13:50:34 +0200 |
|---|---|---|
| committer | rimio <vasi.vilvoiu@gmail.com> | 2019-01-09 13:50:34 +0200 |
| commit | 41f3b5f445a98500a345b00bc4a3ce111af652e8 (patch) | |
| tree | 012aaa511abfbb73a444928e50b065e3ceab474c | |
| parent | dcc04103eca47554f6bd673b21e07afd5b8fbcfe (diff) | |
PD modes start
| -rw-r--r-- | src/encoder.c | 142 | ||||
| -rw-r--r-- | src/tools/sstv-encode.cpp | 1 | ||||
| -rw-r--r-- | util/view.py | 8 |
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 |
